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 tạo một docker swarm lập tức nó trở thành một nút node trong swarm, do máy này khởi tạo 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.
  • 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ác worker 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 do node 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 swarm và chạy dịch vụ trên swarm

Bước 1) 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

Bước 2) 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.111 (vps1), 192.168.99.112 (vps2), 192.168.99.113 (vps3), các IP này lấy bằng lệnh docker-machine ip, ví dụ lấy IP của vps1:

docker-machine ip vps1

Bạn cũng có thể dùng lệnh liệt kế tất cả các máy ảo Docker Machine, nó cũng kèm IP của từng máy

docker-machine ls 
NAME   ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER     ERRORS
vps1   -        virtualbox   Running   tcp://192.168.99.111:2376           v19.03.0
vps2   -        virtualbox   Running   tcp://192.168.99.112:2376           v19.03.0
vps3   -        virtualbox   Running   tcp://192.168.99.113: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

Bước 3) 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.111: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.111: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

Bước 4) Tạo image có tên 192.168.99.111:5000/httpdtest:latest từ Dockerfile ở trên

Lưu ý đặt tên (Tag) image

Để đả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.111:5000 hoặc myregistry.com:5000, nếu tên không có thành phần này coi như mặc định Registry là tại https://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ự án myproject để 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ồm dị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.111:5000/httpdtest:latest

Sau khi image được tạo, đẩy nó lên Registry

docker push 192.168.99.111:5000/httpdtest:latest

Bước 5) Tạo Swarm với 3 node - vps1, vps2, vps3

vps1 ấn định là node manager, nên tại VPS1 gõ lệnh sau để tạo swarm

docker swarm init --advertise-addr=192.168.99.111

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.111:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
Đoạn mã:
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

docker swarm join --token SWMTKN-1-5xv7z2ijle1dhivalkl5cnwhoadp6h8ae0p7bs5tmanvkpbi3l-5ib6sjrd3w0wdhfsnt8ga7ybd 192.168.99.111: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.

Bước 6) Chạy thử dịch vụ trong swarm

Tại node manager (VPS1) chạy dịch vụ từ image 192.168.99.111: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.111:5000/httpdtest:latest

Trong câu lệnh chạy dịch vụ trên --replicas 5 có nghĩa là sẽ tạo ra 5 task (5 container) - giống như nhân bản dịch vụ - 5 container đó nằm phân tán ở 3 máy (node).

--name website dịch vụ tạo ra có tên là website.

Một vài lệnh quản lý, giám sát service:

#Kiểm tra danh sách các service
docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                                  PORTS
4rjx8jts2zjy        website             replicated          5/5                 192.168.99.111:5000/httpdtest:latest   *:8888->80/tcp
# Liệt kê Các container đang chạy cho dịch vụ có tên website
docker service ps website
ID                  NAME                IMAGE                                  NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
quetk4yh194y        website.1           192.168.99.111:5000/httpdtest:latest   vps2                Running             Running 6 minutes ago
yjmut5qkxrmi        website.2           192.168.99.111:5000/httpdtest:latest   vps3                Running             Running 6 minutes ago
uode8bpf8bk1        website.3           192.168.99.111:5000/httpdtest:latest   vps2                Running             Running 6 minutes ago
x9j1ref7xt9w        website.4           192.168.99.111:5000/httpdtest:latest   vps3                Running             Running 6 minutes ago
ocht85y20khj        website.5           192.168.99.111:5000/httpdtest:latest   vps1                Running             Running 6 minutes ago

Bạn thấy dịch vụ website trên swarm có 5 container, các container này nằm phân tán trên VPS1, VPS2, VPS3

Để theo dõi log service

docker service logs servicename

Để xóa service

docker service rm servicename

Để thay đổi số task (container) thành n cho service

docker service scale servicename=n

Giờ hãy truy cập đường dẫn http://192.168.99.111:8888/test.pl, mỗi lần truy cập là một container nào đó trong số các container chạy dịch vụ, nó có thể ở bất kỳ node nào chạy vào trả về kết quả.

Có thể chạy cript tạo ra 5000 truy cập đến địa chỉ trên để xem, lúc thì contaier này chạy lúc thì container khác:

curl http://192.168.99.111: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

Đăng ký theo dõi ủng hộ kênh