Bài 3: Pod & Deployment — Chạy app đầu tiên
Pod là gì?
Pod là đơn vị nhỏ nhất trong K8s. Một Pod chứa 1 hoặc nhiều container:
- Share chung network namespace (cùng IP, cùng port space)
- Share chung storage volumes
- Luôn được schedule cùng nhau trên 1 node
- Là ephemeral (có thể bị xóa, thay thế bất cứ lúc nào)
Thực tế: 90% thời gian 1 Pod = 1 container. Multi-container Pod chỉ dùng cho sidecar pattern (ví dụ: app + log shipper).
Pod Manifest (YAML)
# pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-demo
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
Chạy thử:
kubectl apply -f pod-demo.yaml
kubectl get pods
kubectl get pods -o wide # xem IP, node
kubectl describe pod nginx-demo # chi tiết
kubectl logs nginx-demo # xem log
kubectl exec -it nginx-demo -- bash # shell vào container
kubectl delete pod nginx-demo # xóa
Vấn đề với Pod "trần"
Pod chạy trực tiếp có nhược điểm:
- Pod chết → không tự restart (trừ khi dùng RestartPolicy=Always)
- Muốn scale → phải tạo Pod mới thủ công
- Muốn update image → xóa Pod cũ, tạo Pod mới (downtime!)
- Node die → Pod trên node đó không được chuyển đi
→ Giải pháp: Deployment
Deployment
Deployment quản lý Pod thông qua ReplicaSet, đảm bảo:
- Luôn có đúng số Pod mong muốn (
replicas) - Pod chết → tự tạo Pod mới
- Rolling update: thay Pod cũ bằng Pod mới không downtime
- Rollback dễ dàng nếu có lỗi
Deployment Manifest
# deployment-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
labels:
app: nginx
spec:
replicas: 3 # chạy 3 Pod
selector:
matchLabels:
app: nginx # quản lý Pod có label app=nginx
template: # template cho Pod
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
resources: # giới hạn tài nguyên (nên khai báo!)
requests:
memory: "64Mi"
cpu: "100m" # 100 millicpu = 0.1 core
limits:
memory: "128Mi"
cpu: "200m"
Các lệnh với Deployment
kubectl apply -f deployment-demo.yaml
# Xem
kubectl get deployments
kubectl get pods # thấy 3 pod được tạo
kubectl describe deployment nginx-deploy
# Scale
kubectl scale deployment nginx-deploy --replicas=5
kubectl get pods # giờ có 5 pod
# Update image (rolling update)
kubectl set image deployment/nginx-deploy nginx=nginx:1.26
# Xem tiến trình rollout
kubectl rollout status deployment/nginx-deploy
kubectl rollout history deployment/nginx-deploy
# Rollback nếu có lỗi
kubectl rollout undo deployment/nginx-deploy
kubectl rollout undo deployment/nginx-deploy --to-revision=2
# Xóa
kubectl delete deployment nginx-deploy
Cấu trúc label & selector (RẤT QUAN TRỌNG)
Deployment dùng selector.matchLabels để biết Pod nào thuộc về mình.
Pod được tạo từ template.metadata.labels — phải khớp với selector.
Deployment (selector: app=nginx)
└── ReplicaSet
└── Pod (label: app=nginx)
└── Pod (label: app=nginx)
└── Pod (label: app=nginx)
→ Labels là cách K8s liên kết mọi thứ với nhau. Luôn đặt label rõ ràng!
Resources: requests vs limits
| Requests | Limits | |
|---|---|---|
| Ý nghĩa | Tài nguyên tối thiểu cần có | Tài nguyên tối đa được dùng |
| Ảnh hưởng scheduling | ✅ Scheduler dùng requests để chọn node | ❌ Không ảnh hưởng scheduling |
| Vượt quá | Không sao, có thể dùng hơn requests | CPU: throttle |
Best practice: Luôn set requests = limits cho môi trường production để được Guaranteed QoS.
Bài tập thực hành
- Tạo Deployment nginx với 3 replicas
- Scale lên 5 replicas, kiểm tra
kubectl get pods - Đổi image thành
nginx:1.26, theo dõi rollout - Rollback về image cũ
kubectl describe pod <tên-pod>xem chi tiết
⏭️ Bài tiếp: https://viblo.asia/p/bai-4-service-networking-trong-k8s-vbLbjXYoLnk — Service, kết nối đến Pod
All rights reserved