Docker Swarm with Load Balance

Watchara Ph
devopsthailand
Published in
4 min readJan 22, 2017

ช่วงนี้ไม่สนใจ Microservices ก็คงเป็นไปไม่ได้ จาก concept Monolithic เป็น Microservices ข้อแตกต่างก็คือ monolithic นั้นจะเป็น application เดียวที่รวมเอาทุก services เอาไว้ในตัวเอง ใน Enterprise Applications ที่เราคุ้นเคย แต่ว่าการเปลี่ยนแปลงอะไรก็ตามเพียงน้อยนิดในส่วนเล็กๆ ของ application นั้นจำเป็นที่จะต้องทำการ rebuilt และ deploy ระบบงานทั้งหมดใหม่ และถ้าหากต้องการที่จะ Scale ระบบก็จำเป็นที่จะต้องทำทั้ง application แทนที่จะทำเฉพาะส่วนที่จำเป็นต้องขยายเท่านั้น

และจากที่เริ่มใช่งาน Docker เอามาร่วมกับ Microservices ก็พบว่าเริ่มมี เจอข้อจำกัดต่างๆ ซึ่งข้อจำกัดนั้นคือ Microservices เรียกกันเอง ซึ่งถ้าเราเรียกกันเองแต่ในเครื่อง แล้ว Docker หรือ Service นั้นตายไปทำให้ application นั้น ไม่สามารถทำงานได้ ทั้งๆ ที่เรามี เครื่อง 2 เครื่องเพื่อทำ high availability (HA) ตามรูปด้านล่าง และเราก็ใช้ Docker ด้วยวันนี้เลยมาลอง Feature LoadBalance และมันต้อง Failover services ได้ด้วย Docker Swarm โดยไม่มี HW Loadbalace กันครับ

Objective

  1. Service จะต้อง Loadbalance ได้
  2. เมื่อ Server หรือ Service ข้างใดข้างหนึ่งตายไปยังคงต้องทำงานได้ปกติ
  3. สร้าง VIP ข้างใน Docker เพื่อให้ Service A เรียกไปยัง Service B มีแค่ endpoint เดียว

เรามาเริ่มทดลองกันเลยครับ เริ่มจาก download docker toolbox และ install เลยครับ และลง docker ที่เครื่อง Mac หรือ Notebook ของเราเลยครับ

Link for install Docker: https://docs.docker.com/engine/getstarted/step_one/

Link download Docker toolbox: https://www.docker.com/products/docker-toolbox

สำหรับการทำครั้งนี้ เราจะ สมุติว่าเรามี manager 1 node และ worker 2 node ครับ เรามาเริ่มสร้าง server กันด้วย docker machine ครับ

จากนั้นเราเข้าไปที่เครื่อง vm ที่เราสร้างไว้ด้วย command docker machine

- docker-machine ssh manager

- docker-machine ssh worker1

- docker-machine ssh worker2

จากนั้นเราลองใช้ command “docker node ls” จะพบว่าเรายังไม่ได้ทำการสร้าง swarm เลยงั้นเรามาเริ่มสร้าง docker swarm กันครับ ขั้นแรกเราต้องเข้าไปที่เครื่องที่เราอยากให้เป็น manager โดยจาก vm ที่เราสร้างไว้จะมี machine ที่ชื่อว่า manager และก่อนที่จะสร้าง swarm ได้เราจะต้องเลือก network ที่จะให้ docker swarm ใช้คุยกัน โดยการใช้ command “ifconfig -a” เพื่อดูว่ามี network วงในให้ใช้ได้บ้าง หรือจริงๆ เราจะลองใช้ command “docker swarm init” เลยก็ได้มันจะบอกว่าสามารถใช้ IP ชุดไหนได้บ้างสำหรับการทำ swarm ซึ่งผมได้เลือก 192.168.99.100 ซึ่งเป็น real IP จริงของเครื่องในการทำ swarm mode

หลังจากที่ทำการสั่ง docker swarm init แล้วมันจะให้ Token สำหรับในการ Join swarm เป็น mode woker แต่ถ้าเราต้องการให้มี manager มากกว่า 1 ตัว สามารถใช้ command เพื่อให้ gen Token แบบ swarm mode manager เพิ่มได้

- docker swarm join-token manager

คราวนี้เรามาลองใช้ “docker node ls” กันอีกทีจะเห็น Status ต่างๆ ของ mode swarm เป็นที่เรียบร้อยแล้ว แต่ยังไม่มี worker

เราได้ manager เป็นที่เรียบร้อยเรามาทำ worker ที่เราเตรียมเครื่องไว้อีก 2 เครื่องให้มา join กับเครื่อง manager กันโดยการ copy token ของ การ join swarm mode ในส่วน ของ worker ไป run ที่ vm ทั้ง 2 ที่จะเป็น worker

จากนั้นเรามาเช็คกันครับว่า join ครับยัง เหมือนเดิมใช้ command “docker node ls”

เรียบร้อยครับในส่วนของการทำ swarm คราวนี้เราจะหา app มาทดสอบเพื่อทำ service ใน docker swarm ให้ทำ Loadbalance ได้ ผมได้เตรียม images ได้การทดสอบทำ Loadbalance ไว้ให้โดยมีโครงสร้างที่ผมตั้งใจจะทำตามภาพด้านล่างครับ ซึ่งเราจะ pull มาไว้เลยก็ได้ หรือเดียวตอนเราสั่ง docker service create มันก็จะ pull มาให้เองครับ

- docker pull sal2apao/nginxswarm:1 (microservice contrainer สีอื่นๆ)

- docker pull sal2apao/gohelloworld:1 (microservice contrainer สีแดง)

แต่ก่อนอื่น เรามาทำ overlay network ซึ่งมีชื่อว่า goswarm เพื่อสร้างให้ swarm ใช้ ตาม command “docker network create -driver overlay goswarm” และทำให้ตัว manager เป็น mode drain ซึ่งหมายถึงว่าถ้าเรา scale service มันจะไม่ scale มาที่เครื่อง manager แต่จะ scale ไปยังเครื่องที่เป็น worker อย่างเดียวกันครับ โดยใช้ command “docker node update -availability drain manager” โอเคครับเรามาเริ่มสร้าง service กันต่อครับ

ขั้นแรกผมทำการสั่งให้ run container gohelloworld มา 5 node ตาม command ตามด้านล่างนี้ และหลังจากนั้นผมก็ใช้ command “docker service ls” เพื่อตรวจสอบว่า service ขึ้นมาหรือยัง

ถ้าขึ้นมาแล้วเราก็ ทดสอบ application ด้วยการ curl ดูครับจะพบว่าจะสามารถเรียกได้ และจะเห็นว่า container ID เปลี่ยนไปเรื่อยๆ ครับซึ่งถ้าเป็น mode swarm สามารถเรียกเครื่องไหนก็ได้ มันจะทำการ loadbalance ให้โดยอัตโนมัติ แต่ยังไม่ถึงจุดประสงค์ของการทำครั้ง ซึ่งจุดประสงค์ครั้งที่เราจะใช้ Nginx เรียกด้วย VIP name เพื่อจะได้ HA แบบสมบูรณ์แบบ

คราวนี้เราได้ application หลังบ้านมาเรียบร้อยแล้วเราจะไปเตรียม nginx เพื่อทำเป็น proxy และเรียก application หลังบ้านเพียง endpoint เดียวเพื่อทำการดูผลของการ loadbalace ผ่าน VIP in swarm กันครับ ซึ่งผมทำการ config nginx เพียงแค่ upstream เดียวและ ใช้ชื่อ VIP name ของ docker swarm ครับ

เรียบร้อยครับ เห็นว่าใน nginx เราใช้แค่ upstrem เพียง endpoint เดียวสามารถเรียกได้ทุก contrainer ครับ

ส่วนเรื่อง Failover ผมได้ทดสอบ Step ตามนี้ และได้ผลตามด้านล่าง

  1. ทำการ Shutdown server worker1 แล้ว services ทั้งหมดที่สั่ง scale ไว้จะย้ายไปอยู่ worker2 ทั้งหมดครับ
  2. ทำการ Start server worker1 กลับขึ้นมา contrainer จะไม่ย้ายกลับเพื่อให้ balance เหมือนเดิม
  3. ทำการ Shutdown server worker2 แล้ว services ทั้งหมดก็จะย้ายไปที่เครื่อง 1 ทั้งหมด
  4. ความนี้ผม stop และ start docker contrainer ใหม่ทั้งหมดเพื่อให้ balance กันและทำการ Shutdown server manager พบว่า contrainer ทั้งหมดยังอยู่ครบและทำงานได้เป็นอย่างดี
  5. ผมทดสอบ Shutdown server worker1 พบว่าถ้าไม่มี server manager แล้ว contrainer ที่อยู่ใน server worker1 จะไม่ทำการย้าย contrainer ไปยัง worker2 ให้
  6. ทำการ Start server manager กลับขึ้นมา และ manager พบว่า contrainer ไม่ครบตามที่ scale ไว้มันจะทำการ scale up ไปยัง worker2 ให้ครบตามจำนวน

--

--