มาลองสร้าง Docker Swarm ด้วย DigitalOcean กันดีกว่า

Natcha Luangaroonchai
5 min readNov 16, 2016

--

ปกติแล้วผมจะอยู่ในฐานะผู้ใช้งาน Docker Orchestration ที่อยู่บนคลาวด์ต่าง ๆ มากกว่าจะติดตั้งใช้เองแต่เมื่อดูค่าใช้จ่ายที่คาดว่าต้องจ่ายแต่ละเดือนแล้วมันช่างแพงเสียจริง ๆ อย่ากระนั้นเลยเรามาติดตั้งบน DigitalOcean ที่สามารถเลือกขั้นต่ำสุด $5 ต่อเดือนได้ดีกว่า

ใครที่ยังไม่มีบัญชีสามารถสมัครต่อจากลิงค์ของผม https://m.do.co/c/c8760bdc0474 โดยจะได้รับ credit $10 ครับ

ผมจะสร้าง Docker Swarm Cluster ซึ่งจะต้องประกอบไปด้วยเครื่องขั้นต่ำ 3 เครื่องเพื่อทำงานตามนี้

  1. Swarm Master สำหรับจัดสรรงานให้กับ Swarm Node ต่าง ๆ
  2. Swarm Node สำหรับรันงานที่ได้รับจัดสรรจาก Swarm Master

อัพเดท ผมเพิ่งเห็นว่าตั้งแต่ v1.12.0 มีวิธีสร้าง Docker Swarm ที่ง่ายกว่าเดิมมากสำหรับใครที่ใช้ v1.12.0 เป็นต้นไป

ก่อนอื่นก็เตรียมเครื่องไว้ 3 เครื่องสำหรับ

  • 1 เครื่องสำหรับ Manager และ Worker
  • 2 เครื่องสำหรับ Worker

รวมแล้วเราจะใช้ 3 เครื่องได้ 1 Manager และ 3 Workers จากนั้นให้สร้าง Droplets ตามปกติผ่าน DigitalOcean หรือจะสร้างด้วย API ย่อมได้ ไม่ต้องใช้ docker-machine อีกต่อไป หลังจากสร้าง Droplets เรียบร้อยให้ติดตั้ง Docker เวอร์ชันสูงกว่า 1.12.0 เป็นต้นไป ดูวิธีติดตั้ง Docker สำหรับ Linux ได้ ที่นี่

หลังจากนั้นให้ใช้ SSH เข้าไปยังเครื่องที่ต้องการจะให้เป็น Master และใช้คำสั่ง

manager$ docker swarm init
Swarm initialized: current node (...) is now a manager.
To add a worker to this swarm, run the following command:docker swarm join \
--token SWARM_DISCOVERY_TOKEN \
x.x.x.x:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

จะได้ผลลัพธ์บอกว่า Swarm ได้ถูกสร้างแล้วและเครื่องที่เราสั่งคำสั่งนี้จะกลายเป็น Manager โดยทันที ซึ่งแค่นี้เราก็ได้ 1 Manager และ 1 Worker แล้ว!

จากนั้นมาที่เครื่องที่จะให้เป็น Worker จัดการติดตั้ง Docker เช่นกันและทำการรันคำสั่งที่ได้จากตอนสั่ง swarm init เพื่อทำการ join เข้า cluster ที่เครื่อง Worker

worker$ docker swarm join \
--token SWARM_DISCOVERY_TOKEN \
x.x.x.x:2377

แค่นี้ก็ join เข้า Swarm Cluster แล้ว และถ้าใครที่ต้องการเรียกใช้ Manager จากเครื่องอื่นก็สามารถชี้ Docker Machine มาที่ Manager ด้วยคำสั่งนี้โดยที่ต้องมี SSH key สำหรับเข้าเครื่อง Manager ได้ด้วย

client$ docker-machine create -d generic \
--generic-ip-address x.x.x.x \
--generic-ssh-key /path/to/your/manager/ssh-key \
manager

จากนั้นรอจนกว่า docker-machine จะทำงานเสร็จจากนั้นให้ใช้คำสั่ง docker-machine ls เพื่อเรียกดูรายการ Docker Machine ทั้งหมดและใช้คำสั่ง

client$ docker-machine env manager

เพื่อชี้ Docker Host มายังเครื่องที่เราต้องการซึ่งในที่นี้คือเครื่อง Manager จากนั้นลองมา deploy service สักตัวกันดู

client$ docker create service --name simple-web --replicas 3 -p 8080:80 yeasy/simple-web

ซึ่งถ้าไม่มีอะไรผิดพลาด service จะต้องถูกสร้างและมี container รันอยู่ใน Swarm Cluster ของเรา 3 containers แบบนี้

client$ docker service ls
ID NAME REPLICAS IMAGE COMMAND
dgt4g4y04ywm simple-web 3/3 yeasy/simple-web:latest

และสามารถเรียกดูรายการ containers ได้ด้วยคำสั่งนี้

client$ docker service ps simple-web
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
78g6kjydk7d9iyxgop71vuqer simple-web.1 yeasy/simple-web:latest manager Running Running 57 minutes ago
ak9315b3vqn73sr8il0qzlqmx simple-web.2 yeasy/simple-web:latest worker-1 Running Running 56 minutes ago
0uwj3eehc1vwzjnad3fr8dwyc simple-web.3 yeasy/simple-web:latest worker-2 Running Running 56 minutes ago

สามารถดูรายการคำสั่งสำหรับ docker service เพิ่มเติมได้ด้วยการพิมพ์ --help ต่อท้ายที่คำสั่งทุก ๆ คำสั่งแบบนี้

client$ docker service create --help
Usage: docker service create [OPTIONS] IMAGE [COMMAND] [ARG...]
Create a new serviceOptions:
...

สำหรับวิธีการนี้สำหรับ Docker เวอร์ชันที่สูงกว่า 1.12.0 เป็นต้นไปเท่านั้น สำหรับใครที่ยังใช้เวอร์ชันที่เก่ากว่านี้สามารถทำตามขั้นตอนด้านล่างได้ครับ

ตั้งแต่ตรงนี้จะเป็นวิธีการสร้าง Docker Swarm ด้วยวิธีเดิมสำหรับ Docker Engine เวอร์ชันที่ต่ำกว่า v1.12.0

ก่อนอื่นเราจะไม่ใช้วิธีการสร้าง Droplets ตามปกติที่ทำผ่านหน้า dashboard แต่เราจะสร้างผ่าน docker-machine ซึ่งมี provider สำหรับ DigitalOcean มาให้แล้วเรียบร้อย ก่อนอื่นให้จัดการตรวจสอบก่อนว่าได้ติดตั้ง docker-machine เรียบร้อยแล้วหรือยัง (สำหรับ macOS ถ้าติดตั้งผ่านตัว installer จะมีมาด้วยอยู่แล้วครับ) ลองรันคำสั่งด้านล่างนี้

$ docker-machine create -d digitalocean --help

จะได้ผลลัพธ์ประมาณนี้

Usage: docker-machine create [OPTIONS] [arg...]Create a machineDescription:
Run 'docker-machine create --driver name' to include the create flags for that driver in the help text.
Options:
...

สำหรับใครที่ไม่มี docker-machine สามารถดูวิธีติดตั้งได้ตาม ลิงค์นี้ เอาล่ะมาลงมือทำกันเลยดีกว่าผมต้องการ Swarm Cluster ทั้งหมด 3 servers โดยที่มี

  • 1 เครื่องติดตั้ง Swarm Master และ Swarm Agent
  • 2 เครื่อง Swarm Agent

ก่อนอื่นผมจะใช้ Swarm Discovery เดิมที่มีมากับ Docker Swarm เริ่มต้น generate Swarm Discovery Token ด้วยคำสั่งนี้ (ที่เครื่องไหนก็ได้ที่มี Docker รันอยู่)

client$ docker run swarm create
d030ac6ecdcb92984ed782f961ca538b

จะได้ผลลัพธ์ออกมาเป็น Swarm Token ดังตัวอย่างให้จดเอาไว้ จากนั้นเราจะใช้คำสั่ง docker-machine สำหรับสร้าง Droplets บน DigitalOcean แต่ก่อนอื่นเราจำเป็นต้องสร้าง​ Access Token สำหรับใช้งานก่อนไปที่ https://cloud.digitalocean.com/settings/api/tokens คลิกที่ปุ่ม Generate New Token จะมีหน้าต่างเด้งขึ้นมาให้ใส่ชื่อของ Token ที่จะสร้างสามารถใส่อะไรก็ได้ครับ

DigitalOcean — New personal access token

จากนั้นกดที่ Generate Token ก็จะได้ Access Token มาให้จดเอาไว้ ณ จุดนี้จะมี Swarm Discovery Token และ DigitalOcean Access Token แล้วจากนั้นมาลงมื่อ deploy กันเลย

Swarm Master

พิมพ์คำสั่งด้านล่างนี้ลงไปโดยให้เปลี่ยน SWARM_DISCOVERY_TOKEN และ DO_ACCESS_TOKEN เป็นของเราเอง (โดยปกติแล้วขนาดของ Droplets จะอยู่ที่ 512MB และอยู่โซน US ผมต้องการให้อยู่ SGP1 จึงเพิ่ม --digitalocean-region ลงไป)

client$ docker-machine create -d digitalocean \
--swarm \
--swarm-master \
--swarm-discovery="token://SWARM_DISCOVERY_TOKEN" \
--digitalocean-region sgp1 \
--digitalocean-access-token DO_ACCESS_TOKEN \
swarm-master

ตรง swarm-master อันนี้คือชื่อของ Droplets สามารถตั้งชื่ออื่นได้ครับ จากนั้นรอจนกว่า docker-machine จะทำการ deploy และติดตั้ง Docker ให้เราซึ่ง OS ที่ติดตั้งจะเป็น Ubuntu 16.04.1 LTS ซึ่งถ้า LTS รุ่นถัดไปออกก็คงจะเปลี่ยน (รุ่นถัดไปคือ 18.04 LTS)

หลังจากที่สร้างเสร็จเรียบร้อยแล้วเราสามารถ SSH เข้าไปที่ Droplets ได้โดยที่ SSH Key จะเก็บไว้ที่ ~/.docker/machine/machines/swarm-master สามารถใช้คำสั่ง

client$ ssh -i ~/.docker/machine/machines/swarm-master/id_rsa root@$(docker-machine ip swarm-master)

หรือสามารถใช้คำสั่งด้านล่างและสั่ง export ตัวแปร env ตามที่ docker-machine บอก

client$ docker-machine env --swarm swarm-master
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://x.x.x.x:2376"
export DOCKER_CERT_PATH="~/.docker/machine/machines/swarm-master"
export DOCKER_MACHINE_NAME="swarm-master"
# Run this command to configure your shell:
# eval $(docker-machine env --swarm swarm-master)

จากนั้นใช้คำสั่ง docker info เพื่อเรียกดูรายละเอียดของ Swarm Cluster ได้

Containers: 2
Running: 2
Paused: 0
Stopped: 0
Images: 1
Server Version: swarm/1.2.5
Role: primary
Strategy: spread
Filters: health, port, containerslots, dependency, affinity, constraint
Nodes: 1
swarm-master: x.x.x.x:2376
└ ID: KHF7:REPD:SBF2:AHUI:2CHQ:B6R3:FBEQ:INHL:36OA:DR7X:73GS:3LUE
└ Status: Healthy
└ Containers: 2 (2 Running, 0 Paused, 0 Stopped)
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 512.9 MiB
└ Labels: kernelversion=4.4.0-47-generic, operatingsystem=Ubuntu 16.04.1 LTS, provider=digitalocean, storagedriver=aufs
└ UpdatedAt: 2016-11-16T01:44:09Z
└ ServerVersion: 1.12.3
...

ครับ ตอนนี้ Swarm Master จะถูกติดตั้งเรียบร้อยแล้วและมี Swarm Agent รันอยู่ในเครื่องแล้วสามารถดู containers ได้ด้วยคำสั่ง docker ps -a

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                      NAMES
363615fcc1ff swarm:latest "/swarm join --advert" 20 hours ago Up 20 hours 2375/tcp swarm-master/swarm-agent
7e4659594b2e swarm:latest "/swarm manage --tlsv" 20 hours ago Up 20 hours 2375/tcp, 188.166.190.207:3376->3376/tcp swarm-master/swarm-agent-master

ถ้าได้ผลลัพธ์ประมาณนี้แสดงว่าการติดตั้ง Swarm Master + Swarm Agent เครื่องแรกสำเร็จเรียบร้อย

Swarm Node 1

มาต่อกันที่ Swarm Node เครื่องแรกกันโดยจะติดตั้งด้วย docker-machine เช่นเดียวกับ Swarm Master ซึ่งคำสั่งก็จะคล้าย ๆ กันเพียงแต่ไม่ต้องใส่ --swarm-master

client$ docker-machine create -d digitalocean \
--swarm \
--swarm-discovery="token://SWARM_DISCOVERY_TOKEN" \
--digitalocean-region sgp1 \
--digitalocean-access-token DO_ACCESS_TOKEN \
swarm-node-1

แล้วก็รอจนกว่า docker-machine จะทำงานเสร็จระหว่างนี้ก็จิบกาแฟไปพลาง ๆ หลังจากที่ทุกอย่างเสร็จแล้วเมื่อเราใช้คำสั่ง docker info ตรงส่วนของ Nodes ควรจะแสดง 2 เครื่องแล้ว (ไม่ต้องสั่ง docker-machine env เพราะ Swarm Master จะรู้จัก Swarm Node 1 เองโดยอัตโนมัติ)

Swarm Node 2

สำหรับเครื่องนี้บังเอิญที่มีเครื่องอยู่ก่อนแล้วดังนั้นเครื่องนี้ผมจะไม่ใช้วิธีสร้างใหม่แต่จะเป็นการ join เข้า Swarm Cluster แทน

เริ่มต้นด้วยคำสั่ง docker-machine เช่นกันแต่จะแตกต่างกันตรงไม่ต้องใช้ DO_ACCESS_TOKEN เพราะเราไม่ได้จะสร้าง Droplets ใหม่ สิ่งที่ต้องเตรียมก่อน join คือจำเป็นต้องมี SSH key ที่สามารถ SSH login เข้าเครื่องได้โดยไม่ต้องใช้ password เสียก่อน ซึ่ง SSH ยอมให้เราเอา SSH public key ไปวางไว้ที่ ~/.ssh/authorized_keys ได้และมันจะไม่ถาม password เวลา login เพราะใช้ SSH key authentication แทน ดูวิธีตั้งค่า SSH login with key ได้ ที่นี่

client$ docker-machine create -d generic \
--generic-ip-address x.x.x.x \
--generic-ssh-key /path/to/your/swarm-node-2/ssh-key \
--swarm \
--swarm-discovery="token://SWARM_DISCOVERY_TOKEN" \
swarm-node-2

จากนั้นก็เช่นเดิมรอจนกว่า docker-machine จะทำงานเสร็จเราก็จะได้ Swarm Cluster ทั้ง 3 เครื่องแล้วลองทดสอบด้วยคำสั่ง docker info จะต้องมีทั้งหมด 3 nodes และ 4 containers รันอยู่ (3 swarm-agents, 1 swarm-agent-master) และสามารถเรียกดู containers ทั้งหมดด้วยคำสั่ง docker ps -a จะได้แบบนี้

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                      NAMES
c0e2ac906ea3 swarm:latest "/swarm join --advert" 19 hours ago Up 19 hours 2375/tcp swarm-node-1/swarm-agent
1ffb3585249b swarm:latest "/swarm join --advert" 21 hours ago Up 21 hours 2375/tcp swarm-node-2/swarm-agent
363615fcc1ff swarm:latest "/swarm join --advert" 22 hours ago Up 22 hours 2375/tcp swarm-master/swarm-agent
7e4659594b2e swarm:latest "/swarm manage --tlsv" 22 hours ago Up 22 hours 2375/tcp, x.x.x.x:3376->3376/tcp swarm-master/swarm-agent-master

แค่เพียงเดือนละ $15 ก็ได้ Swarm Cluster สำหรับใช้งานเบื้องต้นแล้วครับ

--

--