Docker Swarm vs Kubernetes: Chọn cái nào khi cần scale?
Từ single server lên multi-node cluster so sánh thực tế giữa Docker Swarm và Kubernetes để biết khi nào dùng cái gì.
Nguyễn Nhật Long
@nguyennhatlong1303
Ở bài trước mình đã deploy app lên single server với Docker Compose, chạy ngon. Nhưng rồi có người hỏi: "Nếu server đó die thì sao?" và câu trả lời thực ra khá đau: toàn bộ app down, users không vào được, bạn nhận được một đống alert lúc 2 giờ sáng.
Đó là lúc container orchestration xuất hiện để giải quyết đúng cái bài toán này.
Tại sao single-host Docker không đủ cho production?
Khi chạy Docker trên một máy duy nhất, bạn đang chấp nhận một loạt rủi ro:
- Single point of failure: Server đó down là xong, không có fallback
- Không scale được theo chiều ngang: Muốn handle nhiều traffic hơn thì chỉ có cách nâng cấu hình máy (scale up), mà cách đó vừa đắt vừa có giới hạn
- Load balancing thủ công: Bạn phải tự config nginx hay HAProxy đứng trước
- Không có auto-healing: Container crash thì nằm đó, không ai restart nó trừ khi bạn có script riêng hoặc dùng
restart: alwaysmà cái đó cũng chỉ handle được một số case đơn giản
Orchestration sinh ra để giải quyết đúng mấy cái này: tự động phân phối workload across nhiều nodes, tự restart khi có gì đó fail, và load balance traffic vào đúng container đang healthy.
Docker Swarm Đơn giản đến mức bất ngờ
Mình bắt đầu với Swarm vì nó gần như không có learning curve nếu bạn đã quen Docker. Kiến trúc của nó straightforward:
- Manager nodes: Giữ cluster state, ra quyết định scheduling
- Worker nodes: Nhận task từ manager và chạy containers
Init một Swarm cluster chỉ cần:
1# Trên máy sẽ làm manager2docker swarm init --advertise-addr <IP_CỦA_MANAGER>34# Output sẽ cho bạn một câu lệnh để join worker nodes5# docker swarm join --token SWMTKN-xxx <IP>:2377
Sau đó trên các worker machines:
1docker swarm join --token SWMTKN-1-xxxxx <MANAGER_IP>:2377
Xong. Cluster đã sẵn sàng. Không cần install thêm gì, không cần config file phức tạp.
Services, Tasks và cái routing mesh thần kỳ
Trong Swarm, bạn không deploy containers trực tiếp nữa bạn khai báo services với desired state:
1docker service create \2 --name web \3 --replicas 3 \4 -p 80:80 \5 nginx
Swarm sẽ tự tìm cách distribute 3 replicas đó across các nodes. Nếu một node die, nó tự reschedule task sang node khác. Nếu một container crash, nó tự restart. Bạn không cần làm gì.
Cái hay nhất theo mình là routing mesh bất kể container đang chạy trên node nào, traffic vào port 80 của bất kỳ node nào trong cluster đều được route đúng đến container. Nghĩa là bạn có thể put load balancer trỏ vào bất kỳ IP nào trong cluster mà không cần biết container đang ở đâu.
Deploy cả stack với docker-compose
Swarm support luôn docker-compose format, chỉ cần thêm một số config Swarm-specific:
1version: '3.8'23services:4 web:5 image: myapp:latest6 deploy:7 replicas: 38 update_config:9 parallelism: 110 delay: 10s11 restart_policy:12 condition: on-failure13 ports:14 - "80:80"15 networks:16 - webnet1718 db:19 image: postgres:1420 deploy:21 replicas: 122 placement:23 constraints:24 - node.role == manager25 volumes:26 - db_data:/var/lib/postgresql/data27 networks:28 - webnet2930networks:31 webnet:32 driver: overlay3334volumes:35 db_data:
Deploy:
1docker stack deploy -c docker-compose.yml myapp
Scale service:
1docker service scale myapp_web=5
Rolling update:
1docker service update --image myapp:v2 myapp_web
Cái update_config với parallelism: 1 và delay: 10s nghĩa là update từng container một, chờ 10 giây giữa mỗi lần zero downtime deployment mà không cần setup phức tạp.
Theo kinh nghiệm của mình, Swarm phù hợp cho các team nhỏ 3-5 người, dưới 10 services, và không cần quá nhiều customization. Setup nhanh, maintain dễ, đủ dùng cho khá nhiều use case.
Kubernetes Powerful nhưng đừng underestimate độ phức tạp
K8s là một câu chuyện hoàn toàn khác. Nó mạnh hơn Swarm rất nhiều, nhưng cái giá phải trả là complexity.
Các concept cơ bản bạn cần nắm:
- Pod: Unit nhỏ nhất, chứa 1 hoặc nhiều containers chạy chung network namespace
- Deployment: Quản lý việc tạo và update Pods, đảm bảo đúng số replicas
- Service: Cung cấp stable network endpoint cho Pods (vì Pod IPs thay đổi liên tục)
- Ingress: HTTP routing, SSL termination cái này Swarm không có built-in
- ConfigMap / Secret: Quản lý configuration và sensitive data tách biệt khỏi image
Một Deployment đơn giản trông như này:
1apiVersion: apps/v12kind: Deployment3metadata:4 name: web5spec:6 replicas: 37 selector:8 matchLabels:9 app: web10 template:11 metadata:12 labels:13 app: web14 spec:15 containers:16 - name: web17 image: myapp:latest18 ports:19 - containerPort: 8020 resources:21 requests:22 memory: "64Mi"23 cpu: "250m"24 limits:25 memory: "128Mi"26 cpu: "500m"
Và Service để expose nó:
1apiVersion: v12kind: Service3metadata:4 name: web-service5spec:6 selector:7 app: web8 ports:9 - port: 8010 targetPort: 8011 type: ClusterIP
Auto-scaling Đây là thứ Swarm không làm được
K8s có Horizontal Pod Autoscaler (HPA) tự động tăng giảm số Pods dựa trên CPU/memory hoặc custom metrics:
1apiVersion: autoscaling/v22kind: HorizontalPodAutoscaler3metadata:4 name: web-hpa5spec:6 scaleTargetRef:7 apiVersion: apps/v18 kind: Deployment9 name: web10 minReplicas: 211 maxReplicas: 1012 metrics:13 - type: Resource14 resource:15 name: cpu16 target:17 type: Utilization18 averageUtilization: 70
Traffic spike lên, CPU tăng quá 70%, K8s tự scale up. Traffic giảm, nó tự scale down. Không cần ai ngồi canh.
Mình thấy cái này hay ở chỗ nó thực sự giải quyết được bài toán cost optimization bạn không cần chạy 10 replicas 24/7, chỉ scale khi cần.
Swarm vs Kubernetes So sánh thẳng thắn
| Tiêu chí | Docker Swarm | Kubernetes |
|---|---|---|
| Setup | `docker swarm init` là xong | kubeadm, hoặc dùng managed service |
| Learning curve | Thấp, quen Docker là dùng được | Cao, nhiều concept mới |
| Auto-scaling | Không có built-in | HPA, VPA, KEDA |
| Rolling update | Có, đơn giản | Có, nhiều strategy hơn |
| Ingress / SSL | Không built-in | Có (nginx-ingress, cert-manager) |
| Secret management | Có, cơ bản | Có, tích hợp với Vault, AWS Secrets Manager |
| Observability | Hạn chế | Prometheus, Grafana, Jaeger... |
| Community & ecosystem | Nhỏ, ít được update | Rất lớn, active |
| Phù hợp cho | Small-medium, team nhỏ | Medium-enterprise, cloud-native |
| Managed options | Không phổ biến | EKS, GKE, AKS rất trưởng thành |
Vậy chọn cái nào?
Mình hay bị hỏi câu này và câu trả lời thực ra không có công thức cố định, nhưng đây là cách mình nghĩ về nó:
Dùng Docker Swarm nếu:
- Team nhỏ, dưới 5-7 người
- Dưới 10-15 services
- Không cần auto-scaling phức tạp
- Muốn setup nhanh, không có thời gian học K8s
- Infrastructure đơn giản, ít traffic spike
Dùng Kubernetes nếu:
- Team lớn hơn, nhiều services
- Cần auto-scaling thực sự
- Muốn ecosystem phong phú: Helm charts, service mesh (Istio), advanced monitoring
- Đang build trên cloud và muốn dùng managed K8s (EKS/GKE/AKS)
- Long-term investment, không ngại learning curve ban đầu
Anh em lưu ý một điều: nếu bạn đang dùng cloud (AWS, GCP, Azure), managed Kubernetes là lựa chọn mình recommend thay vì tự setup. EKS, GKE, AKS lo hết phần control plane cho bạn bạn chỉ cần quan tâm đến workload. Chi phí cao hơn một chút nhưng tiết kiệm được rất nhiều ops effort.
Theo kinh nghiệm của mình, nhiều team Việt Nam đang ở giai đoạn early-stage hoặc startup nhỏ thì Swarm là đủ dùng và ít đau đầu hơn nhiều. Nhưng nếu bạn đang join một công ty có product đang scale, hoặc muốn career path theo hướng DevOps/Platform Engineering, thì đầu tư thời gian học K8s là xứng đáng nó đang là standard của industry.
Bài tiếp theo mình sẽ đi sâu hơn vào Kubernetes với hands-on thực tế: setup local cluster bằng kind hoặc minikube, deploy app thật, config HPA, và xem nó auto-scale như thế nào. Stay tuned.
Nguyễn Nhật Long
@nguyennhatlong1303Nguyễn Nhật Long is a Senior Frontend Engineer and Frontend Team Leader with 7 years of experience building real-time fintech platforms. Specializing in React, Next.js, TypeScript, and React Native, shipping 10+ products across Web, Mobile, Telegram Mini-Apps, and Web3.
Thấy hay? Chia sẻ cho bạn bè!