Gemini CLI là công cụ agent chạy trong terminal do Google phát hành, mã nguồn mở, hỗ trợ MCP (Model Context Protocol, giao thức chuẩn hoá cách AI agent gọi vào công cụ và nguồn dữ liệu bên ngoài) từ khá sớm trong quá trình phát triển. Ghép Gemini CLI với một Kubernetes MCP server biến nó thành một "kỹ sư SRE ảo" ngồi ngay trong terminal của bạn: có thể tự query trạng thái pod, tổng hợp log từ nhiều container, đối chiếu event để tìm root cause — tất cả bằng câu hỏi tiếng Anh (hoặc tiếng Việt) tự nhiên, không cần bạn nhớ chính xác cú pháp kubectl cho từng trường hợp.
Bài này tập trung vào cách cấu hình Kubernetes MCP cho Gemini CLI, cách viết prompt để truy vấn cluster state và log hiệu quả, một case thực tế truy vết lỗi 5xx tăng vọt về đúng một pod, và cuối cùng là so sánh trực tiếp cách Gemini CLI xử lý các tool call này khác gì so với Claude Code — hai công cụ mình dùng song song trong công việc và có những khác biệt đáng nói không phải ai cũng để ý.
Cài đặt và kết nối Kubernetes MCP vào Gemini CLI
Gemini CLI đọc cấu hình MCP từ file settings.json, có ba cấp: global (~/.gemini/settings.json, áp dụng cho mọi project), project (.gemini/settings.json tại root repo, chỉ áp dụng cho project đó), và system-level (dùng cho triển khai doanh nghiệp, ít gặp với cá nhân). Với công việc Kubernetes, mình luôn để ở cấp project để tránh một context cluster "rò" sang các project không liên quan đang mở trên máy.
Chuẩn bị kubeconfig
Xác nhận context đang trỏ đúng cluster trước khi đụng tới Gemini CLI:
kubectl config get-contexts
kubectl config use-context staging-cluster
kubectl get nodes
Khai báo MCP server trong settings.json
{
"mcpServers": {
"kubernetes": {
"command": "npx",
"args": ["-y", "mcp-server-kubernetes"],
"env": {
"KUBECONFIG": "/Users/yourname/.kube/config"
},
"trust": false
}
}
}
Trường trust đáng chú ý: khi để false (mặc định), Gemini CLI sẽ hỏi xác nhận mỗi lần agent muốn gọi một tool từ server này lần đầu trong session. Đặt true sẽ auto-approve mọi tool call từ server đó — với Kubernetes, mình luôn để false cho mọi cluster ngoài môi trường local/dev cá nhân.
Kiểm tra và xác thực kết nối
Mở Gemini CLI trong repo:
gemini
Trong session, gõ slash command:
/mcp
Lệnh này liệt kê tất cả MCP server đã cấu hình cùng trạng thái và danh sách tool mà mỗi server expose ra (thường gồm các tool dạng kubectl_get, kubectl_describe, kubectl_logs, kubectl_apply tuỳ implementation). Test nhanh bằng:
List all namespaces in the current cluster and show pod count per namespace.
Nếu Gemini trả lời đúng với dữ liệu thật (không phải câu trả lời chung kiểu "tôi không truy cập được cluster"), kết nối đã hoạt động.
Mẹo: Giữ
trust: falsecho mọi Kubernetes MCP server trừ khi bạn đang chạy trên cluster local hoàn toàn cách ly (kind/minikube dùng để học). Việc phải xác nhận từng tool call lần đầu tuy hơi chậm hơn, nhưng là lớp phòng vệ cuối trước khi một prompt injection ẩn trong log hoặc comment YAML độc hại có thể khiến agent tự ý gọi tool nguy hiểm.
Truy vấn trạng thái cluster và tổng hợp log pod từ Gemini CLI
Sức mạnh thực sự của việc ghép Gemini CLI với Kubernetes MCP nằm ở khả năng tổng hợp thông tin từ nhiều nguồn (nhiều pod, nhiều namespace, nhiều loại resource) trong một câu trả lời duy nhất — việc mà nếu làm tay bằng kubectl bạn phải chạy 4-5 lệnh rồi tự ghép kết quả trong đầu.
Truy vấn trạng thái tổng quan nhiều namespace
Across namespaces "checkout", "payment", and "inventory", list any pod that
is not in Running/Ready state, along with its restart count and the reason
from its last event.
Đây là dạng prompt mình dùng đầu ca làm việc mỗi sáng thay cho việc gõ kubectl get pods -A | grep -v Running rồi tự lọc — agent sẽ gọi tool list pod cho từng namespace, lọc theo trạng thái, và tự bổ sung phần "reason" bằng cách gọi thêm describe/get_events cho từng pod bất thường.
Tổng hợp log từ nhiều container trong một pod
Với pod có sidecar (ví dụ container chính + Envoy proxy sidecar của service mesh), việc gộp log từ nhiều container để tìm tương quan thời gian là việc rất tốn thời gian nếu làm tay.
Get the last 200 log lines from both the "app" container and the "envoy"
container in pod "payment-worker-7d9f8", merge them by timestamp, and
highlight any error or 5xx status appearing within 5 seconds of each other.
Yêu cầu "merge theo timestamp" là mấu chốt — nếu không nói rõ, agent có xu hướng trả log của từng container tách riêng, khiến bạn vẫn phải tự đối chiếu thời gian bằng mắt.
Tổng hợp log qua nhiều pod của cùng một Deployment
Khi lỗi chỉ xảy ra ở một số pod trong ReplicaSet (không phải toàn bộ), cần gộp log theo pod để so sánh:
For every pod belonging to deployment "payment-worker" in namespace
"payment", get the count of ERROR-level log lines in the last 15 minutes.
Tell me if the errors are concentrated in one specific pod or spread evenly
across all pods.
Câu trả lời cho câu hỏi "một pod hay tất cả pod" quyết định hướng debug hoàn toàn khác nhau: lỗi tập trung một pod thường là vấn đề node/pod cụ thể (disk, network, hoặc pod đang chạy version code cũ do rolling update chưa xong); lỗi trải đều thường là vấn đề ở tầng code hoặc dependency chung (database, upstream service).
Mẹo: Luôn yêu cầu Gemini nói rõ nó đã lấy log trong khoảng thời gian nào và bao nhiêu dòng (ví dụ "200 dòng cuối của 15 phút gần nhất" khác hẳn "200 dòng cuối" nếu pod log rất dày). Không nói rõ, agent có thể fetch log cách đây vài giờ mà bạn tưởng là log mới nhất.
Ví dụ thực tế: Truy vết một đợt tăng vọt lỗi 5xx về đúng một pod bất ổn
Ca này mô phỏng đúng một incident thật: dashboard monitoring báo tỉ lệ lỗi 5xx của service payment-worker tăng từ ~0.1% lên 8% trong 10 phút, nhưng không rõ do toàn bộ service hay chỉ một phần.
Bước 1: Xác nhận phạm vi lỗi ở tầng pod
Deployment "payment-worker" in namespace "payment" has 6 replicas. For each
pod, get the request count and 5xx error count from its logs in the last
15 minutes (look for HTTP status codes in the log lines). Rank pods by
error rate.
Agent phải tự parse log theo pattern HTTP status (thường log dạng structured JSON có field status hoặc access log dạng Nginx/Envoy) và tính tỉ lệ theo từng pod — nếu log không có field status rõ ràng, cần điều chỉnh prompt để chỉ định đúng format log đang dùng.
Bước 2: Khoanh vùng một pod bất ổn
Giả sử kết quả cho thấy 1 trong 6 pod chiếm tới 90% lỗi 5xx:
Pod "payment-worker-7d9f8" has an abnormally high 5xx rate compared to its
siblings. Describe this pod fully — node it's scheduled on, start time,
restart count, resource usage vs limits — and get its last 300 log lines.
Look for anything different from a healthy sibling pod like
"payment-worker-3a1c2".
Yêu cầu so sánh trực tiếp với một pod "healthy" (payment-worker-3a1c2) là kỹ thuật quan trọng: agent sẽ tự đối chiếu hai bộ dữ liệu (node, resource usage, log pattern) thay vì chỉ mô tả một pod đơn lẻ rồi đoán mò.
Bước 3: Đối chiếu với node và tài nguyên vật lý
Nếu pod bất ổn hoá ra nằm trên một node riêng biệt:
What node is "payment-worker-7d9f8" scheduled on? Get that node's CPU and
memory usage, and check if any other pods on the same node are also
showing abnormal behavior right now.
Ca thực tế mình từng gặp: một node bị đầy disk (do log driver không rotate đúng) khiến mọi pod trên node đó chậm bất thường dù CPU/memory trông vẫn ổn — nếu chỉ soi resource limit của riêng pod, bạn sẽ bỏ lỡ nguyên nhân thật nằm ở tầng node.
Bước 4: Cách ly pod và xác nhận phục hồi
Cordon the node hosting "payment-worker-7d9f8" so no new pods get scheduled
there, then delete pod "payment-worker-7d9f8" so it gets rescheduled to a
healthy node. After it's rescheduled, confirm its 5xx rate over the next
5 minutes.
cordon (đánh dấu node không nhận pod mới, nhưng không di dời pod đang chạy) là bước an toàn hơn drain (buộc di dời toàn bộ pod) trong lúc bạn chưa chắc chắn 100% nguyên nhân — nó cho phép bạn cách ly dần mà không gây gián đoạn diện rộng nếu chẩn đoán sai.
Mẹo: Luôn yêu cầu agent so sánh pod "nghi ngờ" với một pod "healthy" cùng Deployment trong cùng một câu hỏi, đừng hỏi tách rời hai lượt. Khi tách rời, agent dễ đưa ra hai câu trả lời không nhất quán về format hoặc mức độ chi tiết, khiến việc so sánh bằng mắt của bạn khó hơn thay vì dễ hơn.
So sánh output Kubernetes MCP giữa Gemini CLI và Claude Code
Sau khi dùng song song cả hai công cụ với cùng một Kubernetes MCP server trong nhiều tuần, đây là những khác biệt thực tế đáng nói — không phải để chọn "cái nào tốt hơn" tuyệt đối, mà để biết dùng cái nào cho tình huống nào.
Mức độ chủ động gọi tool nối tiếp
Claude Code có xu hướng tự chuỗi nhiều tool call liên tiếp trong một lượt trả lời (agentic tool calling) khá mạnh — hỏi một câu, nó có thể tự gọi list_pods → describe_pod → get_logs liên tục mà không cần bạn thúc thêm. Gemini CLI, ở nhiều phiên bản mình test, có xu hướng dừng lại hỏi xác nhận sớm hơn giữa các bước, đặc biệt nếu trust: false. Với debug nhanh một mình, Claude Code tiết kiệm số lượt hỏi-đáp hơn; với môi trường cần audit từng bước rõ ràng, hành vi "dừng hỏi" của Gemini CLI lại là ưu điểm.
Cách trình bày dữ liệu log/JSON trả về
Claude Code có xu hướng tự tóm tắt log thành đoạn văn diễn giải kèm trích dẫn dòng cụ thể. Gemini CLI có xu hướng giữ nguyên định dạng bảng/JSON gần với output gốc của tool hơn, ít diễn giải hơn nếu bạn không yêu cầu rõ. Với việc cần bằng chứng chính xác từng dòng log (ví dụ để đưa vào postmortem), format gần nguyên gốc của Gemini CLI đôi khi dễ copy trực tiếp hơn.
Khả năng đối chiếu với code trong workspace
Claude Code (đặc biệt qua VS Code extension) mạnh hơn khi cần đối chiếu output cluster với code, vì nó tích hợp sâu với ngữ cảnh file đang mở. Gemini CLI làm được việc tương tự qua đọc file trong thư mục project, nhưng ở một số phiên bản mình test, độ chính xác khi grep chuỗi lỗi cụ thể từ log để map ngược về source code chưa nhất quán bằng — đôi khi cần prompt chỉ định rõ đường dẫn file cần so sánh thay vì để agent tự tìm.
Chi phí và giới hạn rate limit
Gemini API có hạn mức free tier khá rộng cho use case cá nhân/nhỏ, phù hợp để mỗi engineer tự chạy Gemini CLI cho công việc debug hàng ngày mà không lo chi phí. Claude Code hiện gắn với subscription/API key riêng — với team lớn dùng liên tục cho nhiều cluster, cần tính toán chi phí theo token dùng thực tế, đặc biệt khi log/event trả về dài.
Mẹo: Đừng chọn một công cụ "chính thức duy nhất" cho toàn team quá sớm. Hãy để một vài kỹ sư dùng song song cả hai với đúng cùng một Kubernetes MCP server trong 2-3 tuần, ghi lại số lượt phải sửa prompt để agent hiểu đúng ý — dữ liệu thực tế từ chính workload của team luôn đáng tin hơn benchmark chung.
Tips
Tổng hợp kinh nghiệm sau nhiều lần dùng Kubernetes MCP với Gemini CLI trong các ca triage thực tế:
- Luôn để
trust: falsecho server Kubernetes trên mọi cluster ngoài môi trường học/local, chấp nhận việc phải xác nhận tool call đầu tiên mỗi session. - Khi hỏi về log, luôn chỉ rõ khoảng thời gian và số dòng cần lấy — đừng để agent tự chọn, vì mặc định của mỗi MCP server implementation khác nhau.
- Với các câu hỏi "pod nào bất thường", luôn yêu cầu agent so sánh trực tiếp với một pod cùng Deployment đang khoẻ mạnh, thay vì mô tả đơn lẻ.
- Dùng
/mcpđầu mỗi session mới để xác nhận server còn kết nối — kubeconfig dùng token OIDC/SSO hết hạn là nguyên nhân phổ biến nhất khiến MCP server "im lặng" không trả dữ liệu. - Với hành động có khả năng thay đổi cluster (
cordon,delete pod,apply), luôn yêu cầu agent trình bày rõ hành động sẽ thực hiện và chờ bạn xác nhận bằng lời trước khi gọi tool.
Mẹo: Ghi lại độ trễ và số bước tool call thực tế của một vài prompt "chuẩn" bạn hay dùng (như case truy vết 5xx ở trên) cho cả Gemini CLI và Claude Code, lưu vào một file so sánh nội bộ của team — dữ liệu này giúp quyết định công cụ nào phù hợp hơn cho từng loại incident, thay vì chọn theo cảm tính.