- Docker Swarm là gì?
- Tạo Docker Swarm
- Chạy các dịch vụ trên swarm
- Docker stack
- Mạng Overlay trong Swarm
- Ổ đĩa (volume) trên swarm
- Swarm có nhiều node Manager
Docker Swarm là gì
Khi một cụm các máy (cluster) cùng chạy Docker Engine tập hợp lại kết nối với nhau nó hình thành nên một Docker Swarm, mỗi máy này có thể là một máy vật lý thật, VPS hay là máy ảo tự tạo.
Biến cụm máy thành một Swarm trải qua các bước như sau:
-
Một máy trong cụm máy ra lệnh chuyển nó chạy ở chế độ Swarm (swarm mode), lập tức nó trở thành một nút
node
trong swarm, do máy này khởi tạo đầu tiên trên swarm nên nó nắm quyền kiểm soát toàn bộ swarm và nó gọi làmanager
, vì là manager nên chỉ có nó mới có quyền khởi tạo các dịch vụ (ứng dụng) chạy trên swarm, quyền xóa một nút khác ra khỏi swarm. - Các máy chạy Docker Engine khác gia nhập vào swarm nhờ một lệnh xin ra nhập, và khi trở thành một
node
của swarm nó gọi là cácworker node
, nó chỉ có khả năng cung cấp khả năng chạy các dịch vụ chứ không có quyền quản lý, các dịch vụ chạy trên node này donode manager ra lệnh và quản lý. - Khi sử dụng swarm, chủ yếu làm việc ở node manager để tạo và chạy các dịch vụ (ứng dụng), các dịch vụ khởi tạo từ node manager sẽ tạo ra nhiều container ở nhiều node worker (kể cả chạy ở node manager) khác nhau.
Thực hành tạo Docker Swarm
Tạo các máy ảo Docker Machine
Để tạo swarm cần có các máy trên đó có chạy Docker (Docker Deamon), sẽ nhiều người chưa có vài 3 server (hay VPS) thực thụ từ các DataCenter để thực hành, nên sẽ tạo ra máy ảo Docker Machine. (Trước tiên xem phần Docker Machine)
Tiến hành tạo 3 máy ảo Docker Machine đặt tên là vps1
, vps2
, vps3
(các máy ảo này dùng công cụ Virtualbox để tạo máy áo, trong các máy ảo Docker Machine thì Docker Daemon đã có sẵn)
docker-machine create --driver virtualbox vps1 docker-machine create --driver virtualbox vps2 docker-machine create --driver virtualbox vps3
Sau khi tạo nó có địa chỉ IP tương ứng là
192.168.99.117
(vps1), 192.168.99.120
(vps2), 192.168.99.119
(vps3),
có thể xem bằng lệnh liệt kê máy ảo:
docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
vps1 - virtualbox Running tcp://192.168.99.117:2376 v19.03.0
vps2 - virtualbox Running tcp://192.168.99.120:2376 v19.03.0
vps3 - virtualbox Running tcp://192.168.99.119:2376 v19.03.0
Các IP này có thể là khác trên hệ thống của bạn, nên hãy lưu ý áp dụng đúng IP tương ứng với từng máy vps1, vps2, vps3
Tạo Swarm với 3 node - vps1, vps2, vps3
vps1
ấn định là node manager, nên tại VPS1
(vào bằng lệnh docker-machine ssh vps1) gõ lệnh sau để tạo swarm
docker swarm init --advertise-addr=192.168.99.117
Chú ý địa chỉ IP chính là IP của vps1, sau lệnh này nó có thông báo:
Swarm initialized: current node (sfysjr8wstldv2wrmgqcrpozt) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-5xv7z2ijle1dhivalkl5cnwhoadp6h8ae0p7bs5tmanvkpbi3l-5ib6sjrd3w0wdhfsnt8ga7ybd 192.168.99.117:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
docker swarm join --token SWMTKN-1-5xv7z2ijle1dhivalkl5cnwhoadp6h8ae0p7bs5tmanvkpbi3l-5ib6sjrd3w0wdhfsnt8ga7ybd 192.168.99.111:2377được dùng để ở một máy chạy docker khác xin ra nhập vào swarm!
Như vậy hiện giờ đang có swarm, với node quản trị là ở máy VPS1. Giờ nếu liệt kê xem swarm có các node nào (có các máy nào tham gia) thì dùng lệnh (đang trong vps1):
docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
sfysjr8wstldv2wrmgqcrpozt * vps1 Ready Active Leader 18.09.5
Thấy có một node, với quền manager (Leader).
Bây giờ hãy ssh vào vps2 và vps3 gõ lệnh sau để ra nhập swarm! lệnh docker swarm join
kèm mã
token do node manager cung cấp ở trên.
docker swarm join --token SWMTKN-1-5xv7z2ijle1dhivalkl5cnwhoadp6h8ae0p7bs5tmanvkpbi3l-5ib6sjrd3w0wdhfsnt8ga7ybd 192.168.99.117:2377
Sau đó ssh vào vps1 gõ kiểm tra
docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
sfysjr8wstldv2wrmgqcrpozt * vps1 Ready Active Leader 18.09.5
z4i90rojpknedxn52aa764k38 vps2 Ready Active 18.09.5
7vdibj6lfdma874qc05tiuhr3 vps3 Ready Active 18.09.5
Giờ thì trong swarm đã có 3 node (3 máy) kết nối với nhau, dưới sự quản lý của node ở máy VPS1.
Thực hành chạy dịch vụ Docker Swarm
Các dịch vụ chạy trên Swarm thì nó sẽ tạo ra các container từ các Image, ở đây có xây dựng sẵn các ứng dụng
đạng lưu ở Hub Docker, đó là các ứng dụng chạy bằng Node, DotNet, PHP với tên Image tương ứng trên Hub Docker là
ichte/swarmtest:node
, ichte/swarmtest:dotnet
, ichte/swarmtest:php
(swarmtest). Xây dựng
sẵn để các Node trong Swarm có thể pull về khí nó cần.
Chạy dịch vụ đầu tiên:
docker service create --replicas 5 -p 8085:8085 --name testservice ichte/swarmtest:node
Lệnh trên tạo ra một dịch vụ đặt tên là testservcie --name testservice
, nó tạo 5 container trên swarm
cho dịch vụ này --replicas 5
, các container tạo từ Image ichte/swarmtest:node
, có ánh xạ
cổng qua tham số -p
Một số lệnh quản lý, cập nhật, scale dịch vụ (lệnh thi hành trên node manager)
# Liệt kê các service trên swarm docker service ls # Liệt kê các container cho dịch vụ có tên testservice docker service ps testservice # Kiểm tra log cho dịch vụ testservice docker service logs testservice # Scale - thay đổi số container cho dịch vụ testservice đang chạy thành n (1, 2, 3 ...) container docker service scale testservice=n # Cập nhật thiết lập cho dịch vụ testservice đang chạy # - Thay đổi Image docker service update --image=ichte/swarmtest:php testservice # - Thay đổi tài nguyên CPU, MEM docker service update --limit-cpu="0.5" --limit-memory=150MB testservice # - Các cập nhật khác update service # Xóa dịch vụ testservice docker service rm servicename
Lệnh docker stack
Lệnh docker stack
để quản lý các dịch vụ chạy trên swarm, các thành phần của dịch vụ đó được mô tả trong
file docker-compose.yml
Mạng Overlay trên Docker Swarm
Mạng mà các container chạy trên swarm kết nối vào là loại mạng overlay, mạng này kết nối các docker host lại với nhau, xem chi tiết video sau:
Các ổ đĩa - volume trên swarm
Để chia sẻ dữ liệu giữa các container chạy trên node khác nhau cần dùng đến các loại ổ đĩa mạng bằng các giao thức như nfs, smb, ssh ..., xem chi tiết video sau:
Đọc thêm - Tạo Registry riêng sử dụng bởi Swarm
B1) Chuẩn bị một image để kiểm tra
Mục đích để khởi chạy dịch vụ (sinh ra các container) từ image này. Image này sẽ tạo ra từ image cơ sở
httpd:latest
, khi chạy gọi đến cổng 8888
nó hiện thị hostname của container.
Trước tiên tạo ra thư mục máy host /mycode/swarm
(thư mục này phải chia sẻ quyền truy cập cho Docker - File Sharing) để chứa dữ liệu chuẩn bị. Trong này tạo ra các file sau:
Chạy lệnh sau để trích xuất httpd.conf của httpd ra thư mục trên để chỉnh sửa:
docker run --rm -v /mycode/swarm/:/home/ httpd:latest cp /usr/local/apache2/conf/httpd.conf /home/httpd.conf
Mở file httpd.conf (code /mycode/swarm/httpd.conf
) trích xuất được chỉnh sửa các mục sau:
#kích hoạt CGI để chạy script sh bằng HTTPD LoadModule cgid_module modules/mod_cgid.so DocumentRoot "/usr/local/apache2/htdocs" <Directory "/usr/local/apache2/htdocs"> Options Indexes FollowSymLinks ExecCGI AddHandler cgi-script .cgi .pl AllowOverride None Require all granted </Directory>
Tiếp theo tạo một file test.pl
(code /mycode/swarm/test.pl) có nội dung :
#!/usr/bin/env sh echo "Content-type: text/plain" echo "" cat /proc/sys/kernel/hostname
File này là một script sh (bash) sẽ copy vào /usr/local/apache2/htdocs
của Apache HTTPD, khi Apache gọi nó, nó trả về tên hostname của container (Hostname Linux). Vì hostname này là khác nhau ở các container khác nhau, điều này sau này giúp nhận biết được container nào chạy! Bạn sẽ phát hiện ra một dịch vụ được đảm nhận bởi nhiều container chạy trên swarm
Tạo file Dockerfile
(code /mycode/swarm/Dockerfile) để xây dựng Image (Image để khởi chạy các container cho dịch vụ trên swarm) với nội dung như sau:
FROM httpd:latest Add ./httpd.conf /usr/local/apache2/conf/httpd.conf Add ./test.pl /usr/local/apache2/htdocs/test.pl RUN chmod +x /usr/local/apache2/htdocs/test.pl
B2) Tạo registry kho chứa Image riêng dùng cho vps1, vps2, vps3
Sẽ chạy một Registry riêng ở máy vps1
, kho này sẽ có địa chỉ 192.168.99.117:5000
(Trên hệ thống của bạn áp dụng theo đúng IP của VPS1)
Vào trong vps1 bằng lệnh:
docker-machine ssh vps1
Tạo và chạy kho chứa riêng Registry:
docker run -d -p 5000:5000 --name registry --restart always registry:2.7
Sau đó biên tập file /etc/docker/daemon.json
sudo vi /etc/docker/daemon.json
Trong file này có nội dung sau:
{ "insecure-registries" : ["192.168.99.117:5000"] }
Lưu lại, exit
ra khỏi vps1 và gõ lệnh sau để khởi động lại máy ảo vps1
docker-machine restart vps1
Bạn cũng ssh
vào vps2, vps3 rồi biên tập /etc/docker/daemon.json
trong 2 máy này với nội dung như trên, sau đó khởi động lại vps2, vps3
Tạo image có tên 192.168.99.117:5000/httpdtest:latest
từ Dockerfile ở trên
Để đảm bảo Image được Push (đẩy lên) đúng kho chứa (Registry) riêng cần lưu ý về cách thiết lập tên (tag) cho Image như sau:
Tên image theo cấu trúc: [HOSTNAME]/[PROJECT-ID]/[IMAGE]
-
[HOSTNAME]
địa chỉ HOST của kho lưu trữ (gồm cả port nếu cần). Ví dụ192.168.99.117:5000
hoặcmyregistry.com:5000
, nếu tên không có thành phần này coi như mặc định Registry là tạihttps://hub.docker.com
(kho này bạn chỉ tạo được một Image riêng, còn lại phải public trừ khi bỏ tiền mua thêm). [PROJECT-ID]
bạn có thể đặt một tên dự án ví dụ dự ánmyproject
để tập hợp các Image thuộc về dự án này. Thành phần này có thể không cần thiết[IMAGE]
tên của Image, theo nguyên tắc gồmdịnh-danh:tag
ví dụhttpdtest:latest
Với nguyên tắc trên, một image có tên đầy đủ: 192.168.99.111:5000/httpdtest:latest
thì khi push nó đấy lên địa chỉ 192.168.99.111:5000
, tương tự pull nó cũng tìm từ địa chỉ 192.168.99.111:5000
Đầu tiên copy các file trong /mycode/swarm
vào thư mục /home/data
của vps1
docker-machine scp -r /mycode/swarm/ vps1:/home/data/
Sau đó vào vps1
tiến hành tạo Image từ Dockerfile
docker-machine ssh vps1 cd /home/data/ docker build -f Dockerfile . -t 192.168.99.117:5000/httpdtest:latest
Sau khi image được tạo, đẩy nó lên Registry
docker push 192.168.99.117:5000/httpdtest:latest
B3) Chạy thử dịch vụ trong swarm
Tại node manager (VPS1) chạy dịch vụ từ image 192.168.99.117:5000/httpdtest:latest
có ánh xạ cổng 8888 vào 80 của các container, nó là máy chủ apache httpd, khi chạy truy cập script test.pl
sẽ trả về hostname của container.
docker service create --replicas 5 -p 8888:80 --name website 192.168.99.117:5000/httpdtest:latest
curl http://192.168.99.117:8888/test.pl?[1-5000]s
Trước khi chạy bạn có thể dùng lệnh sau trong vps1, docker service logs website -f
để quan sát xem container nào đạng phục vụ cho truy vấn hiện tại
Swarm có nhiều Node Manager
Ở trên bạn đã tạo ra một Swarm với 1 node vài trò manager (vps1) và 2 node worker (vps3, vps2). Trong tình huống này, nếu node manager bị lỗi dẫn tới toàn bộ swarm không hoạt động. Trong tình huống đề phòng, bạn có thể đề xuất vps2, vps3 cũng có vai trò Manager, nếu node manager chính (vps1) chết, hệ thống tự động kích hoạt vps2 là node manager ...
Để làm điều đó, bạn chỉ việc thực hiện lệnh tại node manager đang hoạt động, lệnh này là đề xuất vps2 sẽ là node manager nếu vps1 die.
Tại vps1 bạn gõ lệnh
docker node promote NODEID
Trong đó NODEID là ID của Node cần đề xuất trở thành Manager, giả sử vps2 có ID là 8gh99fdy6vup0yjyaz9m5ucr5, (lấy được từ lệnh docker node ls
), thì bạn gõ
docker node promote 8gh99fdy6vup0yjyaz9m5ucr5
Từ giờ thì node vps2 cũng có vai trò Manager, nó sẽ thay thế cho vps1 nếu vps1 không còn hoạt động ...