Sau bài này bạn làm được: cấu hình HPA scale theo CPU/custom metrics; đặt PDB tránh drain làm mất quorum; kết hợp HPA + PDB + rolling update không downtime.


HPA — Horizontal Pod Autoscaler

Cơ chế

HPA watch metric → so sánh với target → scale replicas Deployment/StatefulSet.

                    metrics-server
[HPA] ── desiredReplicas = ceil(currentReplicas × (currentMetric / targetMetric))
[Deployment] ← scale replicas

HPA spec

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-api-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-api
  minReplicas: 2
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70     # Scale khi CPU > 70% of requests
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300    # Chờ 5 phút trước khi scale down
      policies:
      - type: Percent
        value: 10                         # Giảm tối đa 10% mỗi lần
        periodSeconds: 60
    scaleUp:
      stabilizationWindowSeconds: 0       # Scale up ngay
      policies:
      - type: Percent
        value: 100                        # Tăng gấp đôi nếu cần
        periodSeconds: 60

HPA cần requests

Quan trọng: averageUtilization: 70 nghĩa là 70% of requests, không phải 70% node capacity. Request sai → HPA scale sai:

  • Request quá thấp → util% luôn cao → scale up mãi.
  • Request quá cao → util% luôn thấp → không bao giờ scale.

Custom metrics

metrics:
- type: Pods
  pods:
    metric:
      name: http_requests_per_second
    target:
      type: AverageValue
      averageValue: 1000
- type: External
  external:
    metric:
      name: sqs_queue_length
      selector:
        matchLabels:
          queue: orders
    target:
      type: AverageValue
      averageValue: 30

Cần Prometheus Adapter hoặc KEDA để expose custom metrics cho HPA.

KEDA — event-driven autoscaling

KEDA (Kubernetes Event-Driven Autoscaling) mở rộng HPA:

  • Scale từ 0 → N (HPA native không scale tới 0).
  • 60+ scalers: Kafka lag, SQS queue, Prometheus query, cron schedule.
  • Dùng cho: worker/consumer scale theo queue depth.

PDB — PodDisruptionBudget

Vấn đề

Khi drain node (upgrade OS, scale down), kubelet evict pod. Nếu evict quá nhiều pod cùng lúc → service mất quorum → downtime.

PDB spec

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: my-api-pdb
spec:
  selector:
    matchLabels:
      app: my-api
  minAvailable: 2                  # Luôn giữ ít nhất 2 pod running
  # Hoặc:
  # maxUnavailable: 1              # Tối đa 1 pod unavailable cùng lúc

minAvailable vs maxUnavailable

minAvailable: 2maxUnavailable: 1
3 replicasChỉ drain 1 tại một thời điểmChỉ drain 1 tại một thời điểm
5 replicasDrain 3 cùng lúc OKChỉ drain 1
HPA scale downCó thể blockLinh hoạt hơn

Recommendation: dùng maxUnavailable cho workload scale động (HPA), minAvailable khi cần absolute minimum (quorum-based: etcd 3 node cần ≥ 2).

PDB chỉ bảo vệ voluntary disruption

PDB không chặn:

  • Node crash (involuntary).
  • OOM kill.
  • Container crash.

PDB chặn:

  • kubectl drain (node upgrade, scale down).
  • Cluster autoscaler scale down node.
  • Spot instance termination (nếu dùng graceful).

PDB block drain

Nếu PDB không cho phép evict thêm pod → kubectl drain treo, chờ đến khi pod khác sẵn sàng.

# Kiểm tra PDB status
kubectl get pdb
# NAME         MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
# my-api-pdb   2               N/A               1                     5m

# ALLOWED DISRUPTIONS = 0 → drain bị block

Kết hợp HPA + PDB + Rolling Update

[HPA]                   Scale replicas 2–20 dựa trên CPU
[Deployment]            strategy: RollingUpdate
    │                   maxUnavailable: 0, maxSurge: 25%
[PDB]                   maxUnavailable: 1
[kubectl drain]         Evict tối đa 1 pod tại một thời điểm

Checklist deploy an toàn

  1. Deployment: maxUnavailable: 0, maxSurge: 25% (hoặc 1).
  2. Readiness probe: app phải pass trước khi nhận traffic.
  3. PDB: maxUnavailable: 1 (hoặc minAvailable: N-1).
  4. HPA: minReplicas ≥ 2 (tránh SPOF).
  5. preStop: sleep 5 cho kube-proxy drain.
  6. terminationGracePeriodSeconds: đủ cho app cleanup.

Pitfall: HPA + manual scale

# ❌ SAI: manual scale rồi HPA override
kubectl scale deploy my-api --replicas=10
# HPA sẽ scale lại về target utilization → replicas có thể giảm

# ✅ ĐÚNG: sửa HPA minReplicas nếu cần floor cao hơn
kubectl patch hpa my-api-hpa -p '{"spec":{"minReplicas":10}}'

Node drain và upgrade flow

# 1. Cordon node (ngưng schedule pod mới)
kubectl cordon node-1

# 2. Drain (evict pod, respect PDB)
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data

# 3. Upgrade node (OS patch, kubelet upgrade...)

# 4. Uncordon
kubectl uncordon node-1

--ignore-daemonsets: DaemonSet pod không evict (sẽ tự dừng khi node shutdown).


Tóm tắt

  • HPA: scale replica theo metric (CPU, memory, custom). Base trên requests — requests sai = HPA sai.
  • PDB: bảo vệ quorum khi drain/upgrade. Chỉ voluntary disruption.
  • Kết hợp: HPA minReplicas ≥ 2 + PDB maxUnavailable 1 + RollingUpdate maxUnavailable 0 = deploy an toàn.
  • KEDA cho scale từ 0 và event-driven (queue, cron).

Câu hỏi hay gặp

HPA scale up nhanh nhưng scale down rất chậm — có bình thường không?

Trả lời: , by design. stabilizationWindowSeconds (mặc định 300s cho scale down) ngăn flapping: load spike ngắn → scale up → load giảm → không scale down ngay (tránh scale up lại). Tuỳ chỉnh behavior.scaleDown nếu cần nhanh hơn.

PDB minAvailable: 100% có được không?

Trả lời: Về syntax được, nhưng block mọi voluntary disruptionkubectl drain treo mãi, cluster autoscaler không scale down node có pod này. Dùng cho service tuyệt đối không được gián đoạn — nhưng hầu hết service nên chấp nhận maxUnavailable: 1.

HPA và VPA có chạy cùng lúc được không?

Trả lời: Cẩn thận. HPA scale horizontally (replicas), VPA scale vertically (requests/limits). Nếu cả hai dùng CPU metric → conflict. Giải pháp: VPA ở mode Off (chỉ recommend), HPA scale thật. Hoặc VPA dùng memory metric, HPA dùng custom metric.


Bài tiếp theo (Giai đoạn V): Quan sát và debug: events, logs, metrics — khi nào xem gì, ở đâu.