Swarm: Stack và Secrets — Triển Khai Hoàn Chỉnh

K
Kai··5 min read

Bài cuối ghép mọi thứ lại. Ở Bài 8 ta dùng Compose để chạy ứng dụng nhiều container trên một máy. Giờ ta đưa chính ý tưởng đó lên cụm Swarm bằng docker stack deploy, thêm cách quản lý mật khẩu an toàn bằng secrets, rồi dọn dẹp toàn bộ.

Stack: Compose file cho cả cụm

Một stack là một nhóm service được khai báo trong một compose file và triển khai lên swarm bằng một lệnh. Nó dùng đúng định dạng compose của Bài 8, chỉ thêm khối deploy: để khai báo những thứ riêng của swarm (số replica, chính sách update...).

stack.yaml:

services:
  web:
    image: nginx:alpine
    ports:
      - "9092:80"
    deploy:
      replicas: 3          # 3 bản, do swarm phân bổ
  app:
    image: alpine
    command: sh -c "cat /run/secrets/db_password && sleep 600"
    secrets:
      - db_password        # mount secret vào service này
    deploy:
      replicas: 1

secrets:
  db_password:
    external: true         # secret đã tạo sẵn ngoài stack

Điểm khác với compose ở Bài 8: khối deploy: (số replica, và có thể thêm update_config, restart_policy, placement...). Lưu ý build: không dùng được với stack — swarm cần image đã có trên registry để mọi node kéo về, nên bạn build và push image trước (Bài 4/9), rồi tham chiếu bằng image:.

Secrets: đừng để mật khẩu lộ thiên

Nhớ Bài 9: không nên nhúng mật khẩu vào image hay để lộ qua biến môi trường (biến môi trường có thể bị đọc qua docker inspect, log...). Swarm có cơ chế secret an toàn hơn: mật khẩu được lưu mã hóa trong Raft log của cụm, và chỉ được mount vào đúng service cần nó, dưới dạng file trong thư mục /run/secrets/.

Tạo một secret (đọc từ stdin để không lưu vào lịch sử shell dạng thô):

echo "sieu-bi-mat-123" | docker secret create db_password -
docker secret ls

Service khai báo dùng secret (như trong stack.yaml) sẽ thấy nó tại /run/secrets/db_password. Ứng dụng đọc file đó để lấy mật khẩu, thay vì đọc biến môi trường.

Triển khai stack

docker stack deploy -c stack.yaml mystack
Creating network mystack_default
Creating service mystack_web
Creating service mystack_app

Swarm tạo một overlay network riêng cho stack (nhớ Bài 12) và các service. Xem stack:

docker stack services mystack
NAME          REPLICAS
mystack_app   1/1
mystack_web   3/3

Kiểm chứng secret thật sự được mount vào container app:

docker exec $(docker ps --filter name=mystack_app -q) cat /run/secrets/db_password
sieu-bi-mat-123

Và web vào được qua routing mesh (Bài 12):

curl http://localhost:9092
HTTP 200

Các lệnh quản lý stack:

docker stack ls                 # các stack đang chạy
docker stack services mystack   # service trong stack
docker stack ps mystack         # task của stack (rải trên node nào)
docker stack rm mystack         # gỡ cả stack

So sánh docker composedocker stack: cùng định dạng file, nhưng compose chạy trên một máy (đọc cả build:), còn stack triển khai lên cụm swarm (đọc deploy:, cần image có sẵn). Cùng một file có thể dùng cho cả hai, mỗi bên đọc phần nó quan tâm.

🧹 Dọn dẹp toàn bộ và rời swarm

Đây là bài cuối nên ta dọn sạch tất cả những gì series tạo ra.

Gỡ stack và secret:

docker stack rm mystack
docker secret rm db_password

Rời swarm (node manager cuối cùng cần --force):

docker swarm leave --force

Kiểm tra đã thoát chế độ swarm:

docker info --format '{{.Swarm.LocalNodeState}}'
inactive

Dọn nốt container/image/network/volume còn sót của cả series:

docker system prune -a       # container dừng, image không dùng, network thừa
docker volume prune          # volume mồ côi (cẩn thận: mất dữ liệu)
docker system df             # xem còn tốn đĩa bao nhiêu

Tổng kết series

Đi hết 14 bài, bạn đã đi từ "container là gì" tới điều phối một ứng dụng nhiều service trên một cụm nhiều máy:

  • Nền tảng & deep-dive (Bài 0–2): container giải quyết vấn đề môi trường; kiến trúc client/daemon/containerd/runc; và lớp thấp nhất — namespaces, cgroups, union filesystem.
  • Thực hành cốt lõi (Bài 3–9): chạy và quản lý container; image và layer; viết Dockerfile và build cache; volume cho dữ liệu bền vững; mạng và service discovery; Compose cho ứng dụng nhiều container; tối ưu image bằng multi-stage.
  • Docker Swarm (Bài 10–13): kiến trúc cluster và Raft; service, scale, rolling update; overlay network và routing mesh; stack và secrets.

Vài nguyên tắc lặp lại đáng nhớ:

  • Container chỉ là tiến trình Linux được cô lập — không có ma thuật, chỉ là namespaces + cgroups + union FS.
  • Sắp xếp layer khôn ngoan — ít-thay-đổi trước, hay-thay-đổi sau, để build nhanh và image nhỏ.
  • Dữ liệu cần giữ phải ra ngoài container — dùng volume.
  • Khai báo desired-state, để hệ thống tự hội tụ — tư duy cốt lõi của orchestration.

Hướng học tiếp

Swarm là điểm khởi đầu tốt cho orchestration nhờ đơn giản. Khi cần đi xa hơn:

  • Kubernetes: tiêu chuẩn de facto cho orchestration ở quy mô lớn, nhiều tính năng hơn Swarm (nhưng phức tạp hơn nhiều). Hiểu Swarm giúp bạn học Kubernetes dễ hơn vì nhiều khái niệm tương đồng (service, desired-state, rolling update).
  • CI/CD với Docker: tự động build image và deploy mỗi khi push code.
  • Image registry riêng và quét bảo mật trong pipeline.
  • Quan sát (observability): thu thập log và metric từ container ở quy mô cụm.

Cảm ơn bạn đã theo hết series. Bạn giờ không chỉ dùng được Docker, mà còn hiểu nó hoạt động thế nào bên dưới — đó là khác biệt giữa gõ lệnh theo trí nhớ và thật sự làm chủ công cụ.