Chuyển tới nội dung chính

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ướcCÁ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ệcLệnh
Tạo Podkubectl run
Tạo Deploymentkubectl create deployment
Tạo Servicekubectl expose
Sửa objectkubectl edit
Scalekubectl scale
Đổi imagekubectl 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ệcLệnh
Tạokubectl create -f <file>
Sửakubectl replace -f <file>
Thay thế hoàn toàn (xóa rồi tạo lại)kubectl replace --force -f <file>
Xóakubectl 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 create hay replace.
cảnh báo
kubectl edit gây lệch file

kubectl 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 apply lạ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ốngNên dùng
Tạo nhanh Pod/Deployment/Service đơn giảnImperative command
Sửa nhanh một fieldkubectl 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ầnLệnhLưu ý
ClusterIP cho Pod rediskubectl expose pod redis --port=6379 --name=redis-service✅ Tự lấy label của Pod làm selector
ClusterIP bằng createkubectl create service clusterip redis --tcp=6379:6379⚠️ Selector luôn là app=redis, không đổi được
NodePort cho Pod nginxkubectl 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 createkubectl 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.