Imperative vs Declarative
1. Khái niệm
| Imperative (mệnh lệnh) | Declarative (khai báo) | |
|---|---|---|
| Nói gì | THẾ NÀO – chỉ từng bước | CÁI GÌ – kết quả mong muốn |
| Ví von | Đi taxi: "rẽ phải, đi thẳng, dừng ở đây" | Gọi Grab/Uber: nhập điểm đến, tài xế tự tìm đường |
Trong hạ tầng (IaC): imperative là viết script tạo VM, cài nginx, sửa port… từng bước. Declarative là viết file "cần 1 VM tên web, có nginx 1.18" – công cụ (Terraform, Ansible, Kubernetes) tự tính phải làm gì.
💡 Idempotency
Declarative chạy lại bao nhiêu lần cũng ra cùng kết quả. Imperative chạy lại lệnh "tạo" lần hai sẽ báo lỗi "đã tồn tại".
2. Imperative trong Kubernetes
a. Bằng lệnh (imperative commands)
| Việc | Lệnh |
|---|---|
| Tạo Pod | kubectl run |
| Tạo Deployment | kubectl create deployment |
| Tạo Service | kubectl expose |
| Sửa object | kubectl edit |
| Scale | kubectl scale |
| Đổi image | kubectl set image |
- ✅ Nhanh, không cần file.
- ❌ Không lưu lại lịch sử; khó làm việc phức tạp (multi-container, probe…); người khác không biết bạn đã làm gì.
b. Bằng file (imperative object configuration)
| Việc | Lệnh |
|---|---|
| Tạo | kubectl create -f <file> |
| Sửa | kubectl replace -f <file> |
| Thay thế hoàn toàn (xóa rồi tạo lại) | kubectl replace --force -f <file> |
| Xóa | kubectl delete -f <file> |
- Vẫn là imperative vì bạn phải biết object đang tồn tại hay chưa để chọn
createhayreplace.
cảnh báo
kubectl edit gây lệch filekubectl edit sửa trực tiếp live object. File YAML trên máy bạn không đổi. Lần sau replace -f file cũ → thay đổi qua edit bị mất.
3. Declarative trong Kubernetes
kubectl apply -f nginx.yaml # một file
kubectl apply -f ./manifests/ # cả thư mục
- Chưa có → tạo. Có rồi → cập nhật phần thay đổi. Không đổi gì →
unchanged. - Bạn chỉ sửa file rồi
applylại – không cần biết trạng thái hiện tại.
4. Dùng cách nào khi thi CKA?
| Tình huống | Nên dùng |
|---|---|
| Tạo nhanh Pod/Deployment/Service đơn giản | Imperative command |
| Sửa nhanh một field | kubectl edit |
| Object phức tạp (nhiều container, volume, probe…) | Sinh YAML bằng --dry-run, sửa, rồi apply |
5. Certification Tips: lệnh imperative
Hai tùy chọn dùng liên tục:
--dry-run=client: không tạo object, chỉ kiểm tra lệnh.-o yaml: in định nghĩa object ra YAML.
Pod
kubectl run nginx --image=nginx
kubectl run nginx --image=nginx --dry-run=client -o yaml
kubectl run redis --image=redis:alpine --labels="tier=db"
kubectl run custom-nginx --image=nginx --port=8080 # khai báo containerPort
kubectl run httpd --image=httpd:alpine --port=80 --expose # tạo Pod + Service ClusterIP cùng tên
Deployment
kubectl create deployment nginx --image=nginx --replicas=4
kubectl scale deployment nginx --replicas=4
kubectl create deployment nginx --image=nginx --dry-run=client -o yaml > nginx-deployment.yaml
Service
| Cần | Lệnh | Lưu ý |
|---|---|---|
ClusterIP cho Pod redis | kubectl expose pod redis --port=6379 --name=redis-service | ✅ Tự lấy label của Pod làm selector |
ClusterIP bằng create | kubectl create service clusterip redis --tcp=6379:6379 | ⚠️ Selector luôn là app=redis, không đổi được |
NodePort cho Pod nginx | kubectl expose pod nginx --type=NodePort --port=80 --name=nginx-service | ✅ Lấy label của Pod, nhưng không chọn được nodePort |
NodePort bằng create | kubectl create service nodeport nginx --tcp=80:80 --node-port=30080 | ⚠️ Chọn được nodePort, nhưng selector là app=nginx |
💡 Cách làm chắc chắn
Dùng expose ... --dry-run=client -o yaml > svc.yaml, thêm nodePort: 30080 vào file, rồi kubectl apply -f svc.yaml.
Tham khảo: kubectl reference và kubectl conventions.
Sinh YAML mẫu
kubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yaml
kubectl create deployment web --image=nginx --replicas=3 --dry-run=client -o yaml > deploy.yaml
kubectl expose deployment web --port=80 --dry-run=client -o yaml > svc.yaml
--dry-run=client: không tạo gì, chỉ in ra.-o yaml: in dạng YAML.