เตาะแตะไปกับ Docker ตอนที่ 3 Swarms

ในตอนที่แล้ว เราทำ app ขึ้นมา และกำหนดค่าว่าจะรันเป็น service และเพิ่มจำนวน replicas เป็น 5x เพื่อให้บริการแบบ load-balancing แต่ทำบนเครื่อง host เครื่องเดียว
เรียกได้อีกอย่างว่าเป็นการใช้ Docker แบบ a single-host mode แต่ในบทความนี้ เราจะเปลี่ยนให้ Docker ไปทำงานแบบ swarm mode โดยที่เมื่อเราใช้คำสั่ง docker deploy จะเป็นการ deploy app ของเราไปรันบน cluster ของเครื่องจำนวนหลาย ๆ เครื่อง

ทำความเข้าใจกันสักเล็กน้อยเกี่ยวกับ Swarm Cluster
swarm คือ เครื่องจำนวนหนึ่งที่รัน docker และได้ join เข้ามายัง cluster หลังจากนี้ในการรันคำสั่งใด ๆ ของ docker จะเรียกว่าเป็นการรันโดย swarm manager และเครื่องเหล่านี้ซึ่งอาจเป็น physical หรือ virtual machine ก็ได้ จะถูกเรียกว่า nodes

swarm manager คือ เครื่องที่สามารถสั่งหรืออนุญาตให้เครื่องอื่น join เข้ามา และเครื่องนั้นจะถูกเรียกว่า workers เราจะเพิ่มเครื่อง workers เพื่อเป็นการนำมาช่วยในเรื่องของเพิ่มจำนวนหน่วยทำงานเท่านั้น และการสั่งคำสั่งเพื่อสร้าง app ยังคงต้องทำที่เครื่อง manager เหมือนเดิม

การสร้าง swarm
รันคำสั่ง docker swarm init เพื่อเปิดใช้ swarm mode ตอนนี้เราจะได้ swarm manager
จากนั้นไปรันคำสั่ง docker swarm join ที่เครื่องอื่น ๆ เพื่อ join เข้า swarm เป็น workers
ข้อควรระวัง
จะต้องตั้งชื่อ hostname ให้กับเครื่องทุกเครื่องเพื่อให้มีชื่อที่แตกต่างกัน อย่าใช้ชื่อว่า ubuntu ทั้งหมด จะงง ผมเจอมาแล้ว จงแก้ไขไฟล์ /etc/hosts และ ไฟล์ /etc/hostname แล้ว reboot ก่อนเริ่มสร้าง swarm

ผมทดสอบด้วย VM ใน Oracle VM VirtualBox อยู่ใน Windows 10 ตั้งค่า network adapter เป็น Bridge จึงใช้ IP ของที่ทำงานได้ ดังรูป


เช่น
เครื่องที่ 1 ให้ตั้งชื่อว่า docker-vm1 ซึ่งก็คือเครื่องที่ทำไว้ในบทความตอนที่ 1 และ 2 ต้องกลับไปเปลี่ยนชื่อ
เครื่องที่ 2 ให้ตั้งชื่อว่า docker-vm2 ซึ่งก็คือเครื่อง ubuntu server ว่าง ๆ ตัวใหม่ในบทความตอนที่ 3 นี้ที่จะเป็น worker

มาสร้าง two-machine cluster ให้เป็น swarm กัน
1. ติดตั้ง docker ลงใน ubuntu server ตัวใหม่ (ชื่อเครื่อง docker-vm2)
2. อยู่ที่เครื่องที่เป็น swarm manager (ชื่อเครื่อง docker-vm1) รันคำสั่ง

docker swarm init

จะได้ข้อความแจ้งว่า จะต้องใช้คำสั่งอย่างไรที่เครื่องที่จะ join เข้ามาเป็น worker (แบบ manual คือ จดบรรทัดที่ได้รับคำแนะนำเอาไว้)

3. ไปที่เครื่อง ubuntu server ตัวใหม่นี้ พิมพ์คำสั่ง เพื่อ join เข้า swarm เป็น worker

docker swarm join --token SWMTKN-1-5h25g0ywnp87ohk1pav8mon72zdmotqbbunj4bu88fq7sxm2go-57cqncfd2mzapxg2525q14nug 192.168.6.22:2377
This node joined a swarm as a worker.

หรือ

ทำแบบใช้คำสั่งที่ซับซ้อนขึ้น ต้องใช้ข้อมูล ชื่อ username กับ เลข IP ของ swarm manager (docker-vm1) ในตัวอย่างนี้ username คือ mama และ IP คือ 192.168.6.22 โดยพิมพ์คำสั่งข้างล่างนี้ที่เครื่องที่จะเป็น worker (docker-vm2)

$(ssh username@IP "docker swarm join-token worker" | grep token)

4. กลับไปที่เครื่องที่เป็น swarm manager เพื่อรัน app

cd ~/myservice
docker stack deploy -c docker-compose.yml testlab

5. ตรวจสอบว่า มีการสร้าง container ไว้ใน node ทั้งสอง รันคำสั่งนี้

docker stack ps testlab

ผลลัพธ์

ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
jcd1rfvnglnv testlab_web.1 woonpsu/docsdocker:part1 docker-vm1 Running Running 6 seconds ago
lt98v35jw5y1 testlab_web.2 woonpsu/docsdocker:part1 docker-vm2 Running Running 6 seconds ago
nz4gq3ew2f3t testlab_web.3 woonpsu/docsdocker:part1 docker-vm1 Running Running 5 seconds ago
plnnmmmbm9hx testlab_web.4 woonpsu/docsdocker:part1 docker-vm2 Running Running 6 seconds ago
jr5a0nhs38zf testlab_web.5 woonpsu/docsdocker:part1 docker-vm1 Running Running 6 seconds ago
qvexlvmaw8ge testlab_web.6 woonpsu/docsdocker:part1 docker-vm2 Running Running 5 seconds ago

เสร็จแล้วครับ ลองใช้งานจาก http://node_ip โดยแทนที่ node_ip ด้วย IP ของเครื่องที่อยู่ใน swarm cluster

จะเห็นว่า หลังคำว่า Hostname: จะเป็นเลข container ID ที่อยู่ในเครื่อง docker-vm1 และ docker-vm2 ซึ่งเป็นการยืนยันว่า web page นี้เรียกมาจาก container ทั้ง 2 เครื่อง

โดยใช้คำสั่งเพื่อดู container ID ที่เกิดขึ้นของแต่ละ node

docker ps

ดูข้อมูลของแต่ละ node ด้วยคำสั่ง (คำสั่งนี้ต้องใช้ที่ swarm manager)

docker node ls
docker node inspect docker-vm1 --pretty
docker node inspect docker-vm2 --pretty

 

เพิ่มเติม
ขั้นตอนการเปลี่ยนชื่อเครื่องจากชื่อเดิม ubuntu เป็น docker-vm1
mama@ubuntu:~$ sudo vi /etc/hosts
[sudo] password for mama:
127.0.0.1 localhost
127.0.1.1 docker-vm1

mama@ubuntu:~$ sudo vi /etc/hosts
docker-vm1

mama@ubuntu:~$ sudo reboot

 

บันทึก output ที่ docker-vm1

mama@docker-vm1:~$ docker swarm init
Swarm initialized: current node (ph8gaptp7quk3cxv9lwt91c7n) is now a manager.

To add a worker to this swarm, run the following command:

docker swarm join --token SWMTKN-1-5h25g0ywnp87ohk1pav8mon72zdmotqbbunj4bu88fq7sxm2go-57cqncfd2mzapxg2525q14nug 192.168.6.22:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

mama@docker-vm1:~$ cd ~/myservice
mama@docker-vm1:~/myservice$ docker stack deploy -c docker-compose.yml testlab
Creating network testlab_webnet
Creating service testlab_web

mama@docker-vm1:~/myservice$ docker stack rm testlab
Removing service testlab_web
Removing network testlab_webnet

mama@docker-vm1:~/myservice$ docker stack deploy -c docker-compose.yml testlab
Creating network testlab_webnet
Creating service testlab_web

mama@docker-vm1:~/myservice$ docker stack ps testlab
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
jcd1rfvnglnv testlab_web.1 woonpsu/docsdocker:part1 docker-vm1 Running Running 6 seconds ago
lt98v35jw5y1 testlab_web.2 woonpsu/docsdocker:part1 docker-vm2 Running Running 6 seconds ago
nz4gq3ew2f3t testlab_web.3 woonpsu/docsdocker:part1 docker-vm1 Running Running 5 seconds ago
plnnmmmbm9hx testlab_web.4 woonpsu/docsdocker:part1 docker-vm2 Running Running 6 seconds ago
jr5a0nhs38zf testlab_web.5 woonpsu/docsdocker:part1 docker-vm1 Running Running 6 seconds ago
qvexlvmaw8ge testlab_web.6 woonpsu/docsdocker:part1 docker-vm2 Running Running 5 seconds ago

บันทึก output ที่ docker-vm2

mama@docker-vm2:~$ docker swarm join --token SWMTKN-1-5h25g0ywnp87ohk1pav8mon72zdmotqbbunj4bu88fq7sxm2go-57cqncfd2mzapxg2525q14nug 192.168.6.22:2377
This node joined a swarm as a worker.

 

References:
Get Started https://docs.docker.com/get-started/