·

Quy trình Thực tế: Phân loại Sự cố & Rollback

Đi qua một quy trình thực tế dùng Kubernetes MCP để AI agent kiểm tra và quản lý cluster, pod và deployment từ đầu đến cuối.

Nếu bạn đã từng cầm điện thoại lúc 2 giờ sáng vì Alertmanager bắn tin "error rate spike 500%", bạn hiểu cảm giác: não còn ngủ mơ nhưng tay phải gõ kubectl cho chuẩn, không được sai một namespace. Đây chính là bài toán mà AI agent kết hợp với Kubernetes MCP (Model Context Protocol — giao thức chuẩn hoá cách AI agent gọi tool và lấy context từ hệ thống bên ngoài) giải quyết rất tốt: tăng tốc giai đoạn thu thập thông tin và root cause (nguyên nhân gốc) — vốn chiếm 70-80% thời gian một incident — để con người tập trung vào phần quyết định quan trọng nhất: rollback lúc nào, rollback gì, và có nên leo thang (escalate) hay không.

Bài này mình sẽ đi qua một workflow thực tế, từ lúc nhận alert cho tới lúc cluster ổn định và viết postmortem (báo cáo sự cố sau khi xử lý xong). Đây không phải bài lý thuyết — đây là quy trình mình dùng thật với các team đang vận hành production trên Kubernetes, dùng AI agent (qua Claude Code, Cursor hoặc bất kỳ client hỗ trợ MCP) kết nối tới Kubernetes MCP server để agent có quyền đọc (và trong một số case, quyền ghi có kiểm soát) trên cluster.

Tổng quan workflow: từ alert đến cluster ổn định

Trước khi đi vào từng bước, cần hình dung toàn cảnh. Một incident điển hình có 4 giai đoạn:

  1. Alert kích hoạt — Prometheus phát hiện metric bất thường (error rate, latency p99, restart count...), Alertmanager route alert tới Slack/PagerDuty.
  2. Triage — xác định phạm vi ảnh hưởng: namespace nào, service nào, bao nhiêu pod bị lỗi, đã kéo dài bao lâu.
  3. Root cause correlation — tương quan giữa các sự kiện gần nhất: deploy mới, config change, resource limit bị chạm, node pressure...
  4. Remediation — hành động khắc phục (thường là rollback), sau đó viết postmortem để rút kinh nghiệm.

Điểm khác biệt khi có AI agent qua MCP là ở giai đoạn 2 và 3: thay vì bạn tự chạy 15-20 lệnh kubectl dò từng namespace, bạn giao cho agent một prompt rõ ràng, agent tự gọi tool (tool calling — AI agent chủ động gọi các function được expose qua MCP) để lấy pod status, events, logs, sau đó tổng hợp thành báo cáo có cấu trúc trong vài chục giây.

Về kiến trúc, một setup chuẩn gồm:

AI Agent (Claude Code / Cursor / OpenCode)
        │  (MCP protocol - stdio hoặc HTTP)
        ▼
Kubernetes MCP Server (ví dụ: mcp-server-kubernetes)
        │  (kubeconfig, RBAC - Role-Based Access Control)
        ▼
Kubernetes API Server → cluster production

Có một nguyên tắc bất biến mình luôn nhấn mạnh với mọi team: agent chỉ nên có quyền đọc (read-only) trên cluster production theo mặc định. Muốn thực hiện hành động ghi (như rollback), nên có một bước xác nhận rõ ràng từ con người, hoặc dùng một service account riêng với RBAC giới hạn chỉ cho phép các action đã whitelist (ví dụ rollout undo, không cho delete namespace).

Mẹo: Trước khi có incident, hãy chuẩn bị sẵn 2 kubeconfig/context riêng cho agent — một context read-only dùng hàng ngày, một context có quyền rollback chỉ bật tạm thời (time-boxed) khi thật sự cần, ví dụ qua kubectl config use-context prod-incident-rw rồi revoke ngay sau khi xử lý xong.

Bước 1: Thu thập pod status, events và logs trên nhiều namespace

Giả sử tình huống: Alertmanager bắn alert HighErrorRate cho service checkout-api, đồng thời Grafana dashboard cho thấy latency p99 tăng gấp 3 lần trong 10 phút gần nhất. Service checkout-api không chạy độc lập — nó gọi tới payment-gatewayinventory-service ở namespace khác, nên bạn không thể chỉ nhìn một namespace.

Đây là lúc AI agent qua Kubernetes MCP phát huy giá trị: nó có thể quét đồng thời nhiều namespace mà bạn không cần tự nhớ hết tên namespace hay cú pháp label selector.

Prompt thực tế mình dùng để mở đầu triage:

Prometheus vừa bắn alert HighErrorRate cho service checkout-api,
error rate tăng từ 0.5% lên 8% trong 10 phút qua.

Hãy giúp tôi triage:
1. Liệt kê status của toàn bộ pod thuộc deployment "checkout-api"
   trong namespace "checkout", bao gồm restart count và trạng thái
   readiness/liveness probe.
2. Lấy Kubernetes events (kubectl get events) trong namespace
   "checkout", "payment", và "inventory" trong 30 phút gần nhất,
   sắp xếp theo thời gian, lọc ra các event type Warning/Error.
3. Lấy 200 dòng log gần nhất của các pod đang crash hoặc restart
   nhiều lần nhất trong deployment checkout-api.
4. Tổng hợp lại thành bảng: namespace | pod | trạng thái | số lần
   restart | error đáng chú ý trong log.

Không thực hiện bất kỳ hành động ghi nào, chỉ đọc thông tin.

Agent sẽ tuần tự gọi các tool tương ứng với các lệnh dưới đây (tuỳ MCP server implement, tên tool có thể khác nhưng bản chất giống):

kubectl get pods -n checkout -l app=checkout-api -o wide
kubectl get events -n checkout --sort-by='.lastTimestamp' | grep -i warning
kubectl get events -n payment --sort-by='.lastTimestamp'
kubectl get events -n inventory --sort-by='.lastTimestamp'
kubectl logs -n checkout <pod-name> --tail=200 --previous

Cờ --previous rất quan trọng ở đây — nó lấy log của container instance trước khi bị restart, chỗ này thường chứa panic/stack trace thật, còn log của container hiện tại (mới start lại) thường sạch sẽ và gây hiểu lầm là "hệ thống ổn rồi".

Điều bạn cần AI agent làm không chỉ là "chạy lệnh" mà là tổng hợp có cấu trúc. Một kết quả tốt trông như thế này (rút gọn):

Namespace Pod Trạng thái Restart Ghi chú log
checkout checkout-api-7d9f-x2k CrashLoopBackOff 14 OOMKilled, panic: out of memory
checkout checkout-api-7d9f-p1m Running (unhealthy) 2 readiness probe timeout 5s
payment payment-gateway-3a Running 0 log sạch

Chỉ với bảng này, bạn đã khoanh vùng được: vấn đề nằm ở checkout-api, không phải downstream service, và có dấu hiệu OOMKilled (pod bị kill vì vượt memory limit) — một manh mối cực quan trọng cho bước tiếp theo.

Mẹo: Luôn yêu cầu agent lấy log với --previous cho pod đang CrashLoopBackOff, và luôn giới hạn --tail (ví dụ 200-500 dòng) để tránh agent "ngộp" context window (giới hạn lượng văn bản mà LLM — large language model, mô hình ngôn ngữ lớn — xử lý được trong một lần gọi) khi log quá dài, dẫn tới bỏ sót dòng lỗi quan trọng ở giữa.

Bước 2: AI phân tích tương quan root cause giữa deploy, config và resource limits

Có dữ liệu thô rồi, bước tiếp theo là thứ AI agent làm tốt hơn con người trong lúc gấp gáp: correlate (tương quan) nhiều nguồn dữ liệu cùng lúc để tìm ra root cause, thay vì con người phải tự nhớ "ủa sáng nay có ai deploy gì không nhỉ".

Ba nghi phạm kinh điển trong incident Kubernetes:

  1. Deploy mới — rollout gần nhất có thay đổi image, command, hoặc probe.
  2. Config change — ConfigMap/Secret bị sửa, gây sai env var hoặc feature flag.
  3. Resource limits — memory/CPU limit không đủ, hoặc traffic tăng đột biến vượt limit cũ.

Prompt correlation mình thường dùng, đưa agent quyền truy cập rộng hơn để nó tự đối chiếu thời gian:

Dựa trên dữ liệu triage vừa thu thập, hãy điều tra root cause theo
hướng sau:

1. Lấy rollout history của deployment checkout-api:
   "kubectl rollout history deployment/checkout-api -n checkout"
   và mô tả chi tiết revision gần nhất (kubectl rollout history
   deployment/checkout-api -n checkout --revision=<N>).
2. So sánh resource requests/limits hiện tại với revision trước đó
   - có thay đổi memory limit không?
3. Kiểm tra ConfigMap và Secret được mount vào pod checkout-api có
   bị sửa trong 2 giờ qua không (dựa trên annotation hoặc
   resourceVersion nếu có).
4. Đối chiếu thời điểm rollout gần nhất với thời điểm error rate
   bắt đầu tăng (theo alert timestamp) - có trùng khớp không?
5. Kết luận: root cause nhiều khả năng nhất là gì, kèm bằng chứng
   cụ thể (không suy đoán mơ hồ).

Với ví dụ OOMKilled ở trên, một agent làm việc tốt sẽ trả về phân tích dạng:

Phát hiện:
- Revision 47 (deploy 14 phút trước khi alert bắn) đổi image tag
  từ v2.3.1 sang v2.4.0, đồng thời revision 47 KHÔNG có khai báo
  lại "resources.limits.memory" -> giá trị default namespace
  áp vào là 256Mi, trong khi revision 46 có set explicit 512Mi.
- Log "OOMKilled" bắt đầu xuất hiện 6 phút sau khi rollout revision
  47 hoàn tất - trùng khớp thời gian với alert HighErrorRate.
- ConfigMap "checkout-api-config" không có thay đổi trong 6 giờ qua
  -> loại trừ nghi phạm config change.

Kết luận: root cause nhiều khả năng nhất là regression memory limit
khi deploy revision 47 - limit bị rơi về default 256Mi do thiếu
khai báo explicit trong manifest mới, khiến pod bị OOMKilled dưới
tải bình thường.

Đây chính là giá trị cốt lõi của agentic engineering (kỹ thuật xây dựng và vận hành AI agent) trong SRE: agent không đoán, nó đối chiếu timestamp, diff giá trị resource, và loại trừ nghi phạm có hệ thống — điều mà con người lúc nửa đêm dễ bỏ sót.

Một lưu ý quan trọng: đừng để agent tự suy luận nếu thiếu dữ liệu. Nếu bạn thấy agent trả lời "có thể do..." mà không kèm bằng chứng cụ thể (timestamp, diff, số liệu), hãy hỏi lại "bằng chứng cụ thể là gì" trước khi tin và hành động theo.

Mẹo: Luôn yêu cầu agent trích timestamp cụ thể khi kết luận root cause (ví dụ "rollout hoàn tất 14:32:10, error bắt đầu tăng 14:38:02") — nếu agent không đưa được bằng chứng theo thời gian, đó là dấu hiệu correlation chưa đủ chắc, cần thu thập thêm dữ liệu trước khi rollback.

Bước 3: Thực hiện rollback an toàn và viết postmortem

Có root cause rõ ràng rồi, đây là lúc quyết định — và đây là ranh giới mình luôn giữ: AI agent đề xuất, con người bấm nút. Với production, không có ngoại lệ.

Rollback với kubectl

Nếu deployment được quản lý bằng manifest thuần hoặc qua CI/CD apply trực tiếp:

kubectl rollout history deployment/checkout-api -n checkout

kubectl rollout undo deployment/checkout-api -n checkout

kubectl rollout undo deployment/checkout-api -n checkout --to-revision=46

kubectl rollout status deployment/checkout-api -n checkout --timeout=120s

Rollback với Helm

Nếu service được deploy qua Helm chart (công cụ quản lý package cho Kubernetes):

helm history checkout-api -n checkout

helm rollback checkout-api 46 -n checkout

helm status checkout-api -n checkout

Prompt để agent hỗ trợ giai đoạn này — nhưng chỉ ở vai trò chuẩn bị và giám sát, không tự thực thi:

Dựa trên root cause đã xác định (memory limit regression ở
revision 47), hãy:

1. Soạn sẵn lệnh rollback chính xác (kubectl rollout undo hoặc
   helm rollback tương ứng), ghi rõ namespace và revision target.
2. Đề xuất lệnh kiểm tra sức khỏe pod ngay sau khi rollback
   (ví dụ theo dõi restart count trong 5 phút tiếp theo).
3. KHÔNG tự chạy lệnh rollback. Chỉ đưa lệnh để tôi review và
   chạy thủ công.

Sau khi con người xác nhận và chạy lệnh, việc tiếp theo là verify: theo dõi error rate về mức bình thường trên Grafana, kiểm tra pod không còn CrashLoopBackOff, và giữ mắt trên dashboard thêm 15-30 phút trước khi coi incident đã đóng — rollback xong không có nghĩa incident đã kết thúc, traffic cần thời gian ổn định lại qua load balancer.

Viết postmortem có cấu trúc

Ngay sau khi cluster ổn định, dùng chính dữ liệu agent đã thu thập để dựng postmortem nhanh, tránh mất chi tiết khi trí nhớ phai theo thời gian:

Dựa trên toàn bộ dữ liệu triage và root cause đã thu thập trong
cuộc trò chuyện này, hãy soạn postmortem theo cấu trúc:

- Tóm tắt (1-2 câu, không kỹ thuật, dành cho stakeholder không
  chuyên)
- Timeline chi tiết (mốc thời gian: alert bắn, bắt đầu triage,
  xác định root cause, rollback, ổn định) - dùng đúng timestamp
  đã thu thập, không bịa
- Root cause (kỹ thuật, có bằng chứng)
- Impact (bao nhiêu request bị lỗi, thời gian downtime/degraded)
- Hành động khắc phục đã thực hiện
- Action items để tránh lặp lại (ví dụ: thêm CI check bắt buộc
  khai báo resource limits, thêm alert riêng cho OOMKilled)

Một postmortem tốt không đổ lỗi cá nhân — nó tập trung vào quy trình nào đã thiếu (ví dụ: thiếu CI check validate resource limits trước khi merge) để hệ thống tự "miễn nhiễm" với lỗi tương tự trong tương lai.

Mẹo: Lưu lại toàn bộ prompt và output của agent trong incident channel (Slack thread hoặc ticket) trước khi đóng incident — đây là nguồn dữ liệu quý để review lại độ chính xác của AI trong lần triage kế tiếp, và cũng là bằng chứng audit khi cần.

Tips

Tổng hợp lại một số nguyên tắc vận hành mình rút ra sau nhiều lần dùng AI agent qua Kubernetes MCP trong incident thật:

  • Phân quyền theo giai đoạn: agent chạy read-only trong toàn bộ giai đoạn triage và root cause; chỉ nâng quyền write (qua RBAC riêng, time-boxed) ở đúng thời điểm cần rollback, và revoke ngay sau đó.
  • Không tin kết luận thiếu bằng chứng thời gian: mọi kết luận root cause phải đi kèm timestamp cụ thể đối chiếu được, không chấp nhận suy đoán chung.
  • Luôn có bước con người xác nhận trước hành động ghi: agent soạn lệnh, con người review và chạy — không giao quyền tự động rollback cho agent trên production.
  • Giới hạn phạm vi log/events mỗi lần gọi: tránh để agent kéo toàn bộ log không giới hạn dòng, vừa tốn context window vừa dễ bỏ sót lỗi quan trọng giữa hàng ngàn dòng nhiễu.
  • Lưu lại toàn bộ session incident: dùng chính transcript làm nguyên liệu cho postmortem và để cải thiện prompt cho lần sau.

Mẹo: Định kỳ (hàng quý) review lại các incident đã dùng AI agent hỗ trợ, xem agent đã bỏ sót loại root cause nào (ví dụ network policy, DNS, node affinity) để bổ sung thêm tool hoặc prompt template chuyên biệt cho những case đó — Kubernetes MCP chỉ mạnh khi được nuôi dưỡng bằng kinh nghiệm thực tế của chính team bạn.