Sau bài này bạn làm được: chạy rolling deploy Kubernetes không gây 502; biết khi nào cần hạ TTL trước khi đổi DNS; điều hành incident call với checklist; viết post-mortem tập trung vào nguyên nhân mạng.


Rolling deploy — không downtime nhưng có rủi ro

Kubernetes rolling update thay Pod theo từng batch:

[v1: 3/3 running] ──deploy v2──▶

[v1: 2/3]  [v2: 1/3]  ← LB gửi traffic tới cả v1 và v2
[v1: 1/3]  [v2: 2/3]
[v1: 0/3]  [v2: 3/3]  ← hoàn thành

Nguyên nhân 502 hay gặp khi rolling deploy:

Lỗi 1: readiness probe chưa sẵn sàng nhưng traffic đã tới

spec:
  readinessProbe:
    httpGet:
      path: /ready
      port: 8080
    initialDelaySeconds: 10 # chờ 10s trước probe đầu tiên
    periodSeconds: 5
    failureThreshold: 3

Nếu initialDelaySeconds quá ngắn, LB gửi traffic vào Pod chưa sẵn sàng → 502.

Lỗi 2: Pod cũ bị terminate giữa chừng (thiếu graceful shutdown)

Xem lại bài 12: Pod phải handle SIGTERM và hoàn thành request đang xử lý trước khi exit.

spec:
  terminationGracePeriodSeconds: 60 # cho Pod 60s để graceful shutdown
  containers:
    - lifecycle:
        preStop:
          exec:
            command: ["sh", "-c", "sleep 5"] # chờ LB cập nhật endpoints

preStop sleep nhỏ (5–10s) đảm bảo LB đã remove Pod khỏi backend trước khi Pod bắt đầu shutdown.


Canary và blue-green

Canary — tăng dần traffic cho phiên bản mới

# Hai Deployment: v1 (9 replica) và v2 (1 replica)
# Cùng label selector trên Service → 10% traffic tới v2
# Tăng dần replica v2, giảm v1

# Hoặc dùng Ingress weight (NGINX Ingress Controller)
annotations:
  nginx.ingress.kubernetes.io/canary: "true"
  nginx.ingress.kubernetes.io/canary-weight: "10" # 10% traffic

Blue-Green — switch toàn bộ

[LB] ──▶ [Service: selector = app: blue]  (100% traffic)
          [Blue deployment: v1]
          [Green deployment: v2]  ← warm up song song

# Khi ready:
kubectl patch service my-app -p '{"spec":{"selector":{"app":"green"}}}'
# Switch ngay lập tức; rollback = switch lại về blue

DNS TTL strategy khi đổi endpoint

Tình huống: di chuyển service từ LB cũ sang LB mới, cần đổi DNS.

Sai (TTL cao):
  api.example.com → LB cũ (TTL 3600s = 1h)
  Đổi record → LB mới
  → 1h sau một số user mới dùng LB mới; user cũ còn LB cũ 1h nữa
  → Nếu LB cũ đã tắt → 502 cho user còn cache

Đúng (hạ TTL trước):
  Trước 1 ngày: đặt TTL = 60s
  Chờ 24h (TTL cũ expire hết)
  Đổi record → LB mới
  → Sau tối đa 60s, mọi user đã dùng LB mới
  Sau khi ổn: nâng TTL lại về 300–3600s

CDN và cache invalidation

Khi dùng CDN (Cloudflare, CloudFront, Fastly) trước origin:

User → CDN edge → origin (app)
              cache-control: public, max-age=300

Khi deploy mới:
  Origin trả nội dung mới
  CDN edge vẫn cache nội dung cũ trong 300s
  → User vẫn thấy phiên bản cũ

Chiến lược:

  • API dynamic: Cache-Control: no-store hoặc private (không cache CDN).
  • Static asset: đổi URL theo version hash (/app.v2.js), max-age dài.
  • Cần invalidate nhanh: dùng CDN purge API, hoặc tăng version path.

Checklist incident mạng

Khi nhận alert hoặc escalation “service không vào được”:

T+0: Xác nhận scope
  □ Tất cả user hay một nhóm cụ thể?
  □ Tất cả region hay một AZ?
  □ Mọi endpoint hay một path cụ thể?
  □ Bắt đầu từ khi nào? Có deploy gần đây không?

T+5: Kiểm tra nhanh (theo thứ tự tầng)
  □ DNS: dig +short A api.example.com
  □ TCP: nc -vz api.example.com 443
  □ HTTP: curl -sv https://api.example.com/health
  □ LB: kiểm tra healthy target count

T+10: Scope hẹp hơn
  □ LB log: có pattern 5xx nào không?
  □ App log: có exception cụ thể không?
  □ Infra: CPU, memory, connection count bình thường không?

T+15: Quyết định
  □ Rollback deploy? (nếu gần đây có deploy)
  □ Scale up? (nếu traffic tăng đột biến)
  □ Failover AZ? (nếu một AZ có vấn đề)
  □ Escalate? (nếu không xác định được nguyên nhân)

Post-mortem: tập trung nguyên nhân gốc rễ

Sau incident, viết post-mortem có cấu trúc:

## Incident: 502 sau deploy v2.3.1 (14:30–15:45 UTC)

### Timeline

- 14:30: Deploy v2.3.1 bắt đầu
- 14:35: Alert rate(5xx) > 5% trigger
- 14:42: Xác nhận readiness probe sai path (/health vs /ready)
- 14:45: Rollback về v2.3.0
- 15:00: Metric về normal
- 15:45: Deploy lại v2.3.1 với probe đúng

### Nguyên nhân gốc rễ

readinessProbe path trong v2.3.1 đổi từ /health sang /ready
nhưng endpoint /ready chỉ được thêm ở v2.3.2 (chưa merge lúc deploy).
Pod báo Not Ready → LB loại nhưng không đủ nhanh → 502 trong ~5 phút.

### Hành động khắc phục

1. [DONE] Rollback về v2.3.0
2. [TODO] Thêm CI test kiểm tra readiness probe endpoint tồn tại trước deploy
3. [TODO] Tăng initialDelaySeconds để buffer tốt hơn
4. [TODO] Alert sớm hơn: readiness probe fail > 30s trong rolling deploy

Nguyên tắc post-mortem tốt: không blame người, tập trung vào hệ thống và quy trình.


Tóm tắt

  • Graceful shutdown + readiness probe là bộ đôi bắt buộc để rolling deploy không 502.
  • Hạ TTL trước 24–48h khi plan đổi DNS endpoint.
  • CDN cacheDNS TTL là hai lý do user thấy phiên bản cũ dù deploy đã xong.
  • Incident checklist: DNS → TCP → HTTP → LB → App — cùng thứ tự như debug bình thường.

Câu hỏi hay gặp

Grace 30s, request dài 20s — có cần preStop không?

Trả lời: Về lý thuyết đủ nếu app shutdown nhanh. preStop hữu ích khi cần chờ LB gỡ backend (sleep vài giây) hoặc drain trước SIGTERM — tránh race với kube-proxy.

Đổi DNS lúc 14:00, TTL 3600s, 15:00 vẫn user trỏ LB cũ — vì sao? LB cũ xóa thì sao?

Trả lời: Resolver/client vẫn cache tới 1h. LB cũ xóa → user đó lỗi/timeout cho đến khi cache hết. Giảm TTL trước migration.

Post-mortem: lỗi do quên cập nhật probe — “ai chịu trách nhiệm”?

Trả lời: Nguyên tắc blameless: tìm thiếu sót hệ thống (CI không validate probe, checklist deploy). Trách nhiệm cá nhân không để “kỷ luật” trong doc — mà để cải quy trình.


Bạn đã hoàn thành nhánh vận hành chính của loạt bài (Giai đoạn I → IV).

Ôn lại lộ trình:

  • Giai đoạn I (01–04): Bản đồ giao thức — tầng, IP, TCP, DNS.
  • Giai đoạn II (05–07): HTTP stack — HTTPS, TLS, debug checklist.
  • Giai đoạn III (08–10): Nơi workload chạy — Linux, Docker, Kubernetes.
  • Giai đoạn IV (11–16): Hạ tầng và vòng đời — cloud, LB, cert, observability, IaC, release.

Bài tuỳ chọn nâng cao: Service mesh và mTLS — nếu hệ thống đã đủ lớn để quan tâm east-west traffic, retry mesh-level và zero-trust giữa service.

Xem lại mục lục loạt bài hoặc tiếp tục với các bài spin-off: tcpdump thực chiến, eBPF observability, hoặc đa cloud VPC.