Câu hỏi “Kubernetes và Docker khác nhau thế nào?” thường xuất hiện khi một ứng dụng vượt qua giai đoạn chạy trên một máy chủ duy nhất. Cách trả lời ngắn gọn nhất: Docker đóng gói và chạy container, còn Kubernetes điều phối những container đó trên nhiều máy. Hai công cụ nằm ở hai tầng khác nhau, nên đặt chúng lên bàn cân để chọn một là so sánh sai đối tượng.
Bài viết này đi từ vai trò của từng công cụ, qua một ví dụ cấu hình, tới các tình huống nên dùng cái nào. Mục tiêu không phải học thuộc định nghĩa mà là biết mình đang thiếu tầng nào.
Docker: đóng gói và chạy container
Docker giải quyết bài toán “chạy ở đâu cũng giống nhau”. Bạn mô tả môi trường trong một Dockerfile, build thành image, rồi chạy image đó thành container. Image chứa mã nguồn, thư viện và cấu hình cần thiết, nhờ vậy máy của lập trình viên và máy chủ production dùng chung một gói.
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]Build và chạy image vẫn là hai lệnh quen thuộc:
docker build -t my-app:1.0 .
docker run -p 3000:3000 my-app:1.0Khi ứng dụng có vài service đi kèm, Docker Compose giúp khai báo chúng trong một tệp YAML và chạy chung một lệnh. Ở quy mô này, Docker đã đủ dùng và ít khái niệm hơn hẳn.
Kubernetes: điều phối container trên cụm máy
Kubernetes không build image và cũng không thay thế Docker. Nó nhận container image theo chuẩn OCI, quyết định chạy ở node nào, giữ số bản sao theo mong muốn, cân bằng tải và thay thế pod khi có sự cố. Đơn vị triển khai nhỏ nhất là pod, thường chứa một container chính cùng vài container phụ trợ.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: registry.example.com/my-app:1.0
ports:
- containerPort: 3000Ba bản sao trong ví dụ trên sẽ được phân bổ trên các node còn tài nguyên. Nếu một pod chết, bộ điều khiển tạo pod mới để đưa tổng số về 3. Đó là phần “tự chữa lành” mà người ta hay nhắc tới, và cũng là lý do Kubernetes phù hợp với hệ thống chạy dài hạn hơn là một lần thử nghiệm.
So sánh nhanh
Tiêu chíDockerKubernetes Vai tròCông cụ container: build, chạy, chia sẻ imageNền tảng điều phối container Phạm viMột máy, một tiến trình containerNhiều node trong một cụm Đơn vị làm việcContainer và imagePod, Deployment, Service Điểm mạnhĐóng gói nhất quán, vòng lặp phát triển nhanhTự phục hồi, mở rộng, triển khai không gián đoạn Độ phức tạp vận hànhThấpCao, cần kiến thức mạng, lưu trữ và quan sát
Ba hiểu nhầm hay gặp
Kubernetes không phải phiên bản lớn hơn của Docker. Nó là một lớp khác, được thiết kế để quản lý container do bất kỳ công cụ nào tạo ra.
“Cài Kubernetes là không cần Docker nữa.” Image vẫn được build bằng Docker, Buildah hoặc công cụ tương đương. Ở phía chạy, Kubernetes dùng container runtime như
containerd; từ phiên bản 1.24,dockershimđã bị loại bỏ nên Docker không còn là runtime mặc định bên trong cụm.“Chỉ công ty lớn mới cần Kubernetes.” Cần hay không phụ thuộc số service, yêu cầu sẵn sàng và số người vận hành. Một cụm Kubernetes tự dựng cho vài container là cái giá quá cao so với Compose hoặc một dịch vụ chạy container có sẵn.
“Docker Compose là Kubernetes thu nhỏ.” Compose mô tả container trên một máy và không có bộ điều khiển phân tán. Nó tuyệt vời cho môi trường phát triển, nhưng không tự chuyển pod sang node khác khi máy chủ gặp sự cố.
Khi nào nên dùng công cụ nào?
Chọn Docker cùng Compose khi bạn chạy một hoặc vài service trên một VPS, cần môi trường phát triển giống production, hoặc đang ở giai đoạn đầu và ưu tiên tốc độ thay đổi hơn khả năng mở rộng ngang.
Chọn Kubernetes khi số service tăng, cần nhiều bản sao chạy song song, muốn triển khai dần dần và tự động thay thế instance lỗi, hoặc đội ngũ đã có quy trình hạ tầng dưới dạng mã. Với đội nhỏ, một dịch vụ Kubernetes được quản lý thường hợp lý hơn tự vận hành control plane.
Một lộ trình thực tế là đi từ container hóa ứng dụng, thêm Compose cho môi trường phát triển, rồi chỉ chuyển sang Kubernetes khi các yêu cầu về sẵn sàng và quy mô thật sự xuất hiện. Công cụ nên theo bài toán, không phải ngược lại.
Kết luận
Docker và Kubernetes không cạnh tranh nhau. Docker trả lời câu hỏi “làm sao đóng gói ứng dụng để chạy giống nhau ở mọi nơi”, Kubernetes trả lời câu hỏi “làm sao giữ hàng trăm container đó chạy ổn định trên nhiều máy”. Hiểu ranh giới này giúp tránh cả việc dựng cụm quá sớm lẫn việc cố gắng giải quyết bài toán điều phối bằng những lệnh docker run thủ công.
