·

Kubernetes MCP với OpenCode

Cài đặt Kubernetes MCP trong OpenCode để AI agent có thể kiểm tra và quản lý cluster, pod và deployment ngay trong trình soạn thảo.

OpenCode là một AI coding agent chạy trong terminal, mã nguồn mở, được thiết kế để làm việc trực tiếp trong repo của bạn giống Claude Code hay Cursor Agent mode, nhưng ưu tiên trải nghiệm terminal-first (chạy hoàn toàn trong terminal, không cần IDE) và cho phép bạn tự chọn model (Claude, GPT, Gemini, model local qua Ollama...). Khi ghép OpenCode với Kubernetes 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), bạn có một agent có thể tự đọc trạng thái cluster, log, event, rồi đối chiếu ngay với source code đang mở trong session — mà không phải copy-paste output kubectl qua lại giữa hai cửa sổ.

Bài này mình đi thẳng vào phần thực hành: cấu hình Kubernetes MCP server cho OpenCode, các prompt để agent tự kiểm tra workload/service/configmap, một ca thực tế chẩn đoán rollout bị treo, và cuối cùng là những giới hạn bạn cần biết rõ trước khi đưa setup này vào quy trình làm việc hàng ngày — vì OpenCode còn khá mới so với Claude Code hay Cursor, một số hành vi MCP chưa ổn định như các tool lâu năm hơn.

Cài đặt và kết nối Kubernetes MCP vào OpenCode

OpenCode đọc cấu hình MCP từ file opencode.json, có thể đặt ở cấp project (nằm ngay tại root repo, chỉ áp dụng cho project đó) hoặc cấp global tại ~/.config/opencode/opencode.json (áp dụng cho mọi session OpenCode trên máy bạn). Với công việc liên quan Kubernetes, mình luôn khuyên đặt ở cấp project — mỗi repo chỉ nên "biết" về cluster liên quan trực tiếp đến nó, tránh trường hợp agent lỡ tay query nhầm cluster của project khác đang mở trong máy.

Khai báo MCP server

Trước tiên, xác nhận kubectl trên máy đã trỏ đúng context:

kubectl config current-context
kubectl get nodes

Sau đó tạo hoặc sửa file opencode.json ở root project:

{
  "mcp": {
    "kubernetes": {
      "type": "local",
      "command": ["npx", "-y", "mcp-server-kubernetes"],
      "environment": {
        "KUBECONFIG": "/Users/yourname/.kube/config"
      },
      "enabled": true
    }
  }
}

Ở đây type: "local" báo cho OpenCode biết đây là một tiến trình MCP chạy local (OpenCode sẽ tự spawn tiến trình khi cần, khác với type: "remote" dùng cho MCP server chạy qua HTTP/SSE ở nơi khác). Trường command là một array vì OpenCode chạy tiến trình qua exec trực tiếp, không qua shell interpolation — viết đúng từng phần tử tránh lỗi parse args.

Kiểm tra kết nối

Khởi động OpenCode trong repo:

opencode

Trong session, gõ /mcp để xem danh sách MCP server đã đăng ký và trạng thái kết nối (connected/failed). Nếu server kubernetes hiện connected, bạn có thể hỏi thử:

List all pods in the "checkout" namespace that are not in Running state.

Nếu agent trả về danh sách chính xác (hoặc báo "không có pod nào" nếu cluster sạch), tool call đã hoạt động đúng. Nếu bạn thấy agent chỉ trả lời chung chung kiểu "tôi không có quyền truy cập cluster", nhiều khả năng biến KUBECONFIG trong environment sai đường dẫn, hoặc file kubeconfig không có quyền đọc cho user chạy tiến trình npx.

Mẹo: Luôn test bằng một tool read-only (list_pods, get_events) ngay sau khi cấu hình, trước khi thử bất kỳ prompt nào có khả năng động tới state cluster. Việc này giúp bạn cách ly lỗi kết nối MCP khỏi lỗi logic prompt — hai loại lỗi rất dễ nhầm lẫn khi mới setup.

Kiểm tra Workload, Service và ConfigMap trực tiếp từ OpenCode

Sau khi kết nối ổn, phần việc hàng ngày là dùng OpenCode để soát nhanh trạng thái workload mà không cần rời terminal đang code. Điểm mạnh ở đây là agent có thể vừa gọi Kubernetes MCP, vừa đọc file trong workspace cùng một lượt trả lời — rất hợp khi bạn cần đối chiếu Deployment/Service/ConfigMap trên cluster với manifest YAML trong repo.

Soát nhanh trạng thái Deployment và Service

Show me the current replica count, available replicas, and image tag for the
"checkout-api" deployment in namespace "checkout". Compare the image tag with
the value in k8s/checkout/deployment.yaml in this repo and tell me if they match.

Agent sẽ gọi tool tương đương describe_resource (hoặc get_deployment tuỳ implementation server) để lấy state thật từ cluster, sau đó đọc file YAML local để so khớp field image. Đây chính là điểm khác biệt lớn nhất so với chạy kubectl thuần: bạn không cần tự mở hai cửa sổ để so tay.

Đối chiếu ConfigMap với biến môi trường mà app đang đọc

Một lỗi rất phổ biến: ConfigMap trên cluster đã cũ, không khớp với code mới nhất trong repo.

Get the ConfigMap "checkout-api-config" in namespace "checkout" and list all
its keys. Then check src/config/loadEnv.ts in this repo and tell me which
environment variables the app expects but are missing from the ConfigMap.

Với prompt này, agent phải liệt kê đầy đủ key trong ConfigMap (không được tóm tắt, vì tóm tắt dễ bỏ sót key hiếm dùng), rồi grep code để đối chiếu — nếu code đọc PAYMENT_GATEWAY_URL nhưng ConfigMap không có key này, agent phải chỉ rõ ra.

Liệt kê Service và endpoint đang trỏ tới đâu

List all Services in namespace "checkout" along with their selectors, and
for the "checkout-api" service, list the actual pod endpoints it currently
resolves to (use the endpoints/endpointslice, not just the selector).

Câu này quan trọng vì selector đúng không có nghĩa endpoint đúng — nếu pod chưa pass readiness probe, Service sẽ không có endpoint nào trỏ tới nó dù selector khớp. Agent cần phân biệt rõ hai khái niệm này khi trả lời, đừng chỉ dừng ở "selector matches".

Mẹo: Khi hỏi agent về ConfigMap hoặc Secret, luôn yêu cầu nó liệt kê đầy đủ key (không tóm tắt) và trích dẫn đúng namespace/resource name trong câu trả lời. Agent có xu hướng tóm tắt cho gọn, nhưng với việc đối chiếu cấu hình thì thiếu một key là đủ để bạn debug sai hướng.

Ví dụ thực tế: Chẩn đoán một lần Rollout thất bại trong OpenCode

Đây là kịch bản mình gặp khá thường xuyên: chạy kubectl apply hoặc CI/CD pipeline deploy phiên bản mới, nhưng rollout đứng yên ở trạng thái "1 out of 3 new replicas updated" mãi không tiến thêm. Thay vì tự chạy từng lệnh kubectl rollout status, kubectl describe replicaset, kubectl get events theo trí nhớ, để OpenCode dẫn dắt cả quy trình.

Bước 1: Xác nhận rollout đang treo

Check the rollout status of deployment "checkout-api" in namespace "checkout".
If it's stuck, show me the rollout history and the current ReplicaSet status.

Agent chạy tương đương kubectl rollout status deployment/checkout-api -n checkoutkubectl rollout history, phát hiện rollout đang dừng ở giữa (ví dụ ReplicaSet mới chỉ có 1/3 pod Ready).

Bước 2: Truy nguyên nguyên nhân qua describe và events

Describe the newest ReplicaSet for "checkout-api" and show its recent events.
Focus on why the new pods are not becoming Ready — look for probe failures,
image pull errors, or resource scheduling issues.

Đây là bước agent thường tìm ra nguyên nhân nhanh hơn con người, vì nó đọc hết toàn bộ event list (thường vài chục dòng) trong một lượt, còn con người dễ bỏ sót event xảy ra sớm rồi bị các event mới hơn "che" trên terminal.

Ba nguyên nhân phổ biến nhất mình từng gặp với dạng lỗi này:

  • Readiness probe fail liên tục — image mới có thay đổi endpoint health check (ví dụ đổi từ /health sang /healthz) nhưng manifest chưa cập nhật path probe.
  • ImagePullBackOff âm thầm — tag image build ra nhưng chưa push xong lên registry, CI/CD chạy apply sớm hơn build.
  • Không đủ resource để schedule pod mới — node pool hết capacity, pod mới bị Pending mãi vì resources.requests cao hơn phần còn trống trên mọi node.

Bước 3: Đối chiếu với thay đổi trong Git

Compare the readiness probe path and resource requests in the currently
running ReplicaSet's pod template with the values in
k8s/checkout/deployment.yaml on the current git branch. Tell me exactly
what changed in this deploy.

Đây là chỗ OpenCode phát huy lợi thế "sống trong repo": nó có thể chạy git diff hoặc đọc trực tiếp file trên nhánh hiện tại, so với spec đang chạy thật trên cluster (lấy qua MCP), để chỉ ra đúng dòng thay đổi gây lỗi — thường nhanh hơn nhiều so với việc bạn tự mở PR diff và tự nhớ lại field nào đã đổi.

Bước 4: Rollback nếu cần, có xác nhận

The readiness probe path is wrong in this deploy. Roll back deployment
"checkout-api" in namespace "checkout" to the previous revision.

Chỉ để agent gọi hành động rollback (kubectl rollout undo hoặc tool apply_manifest tương đương) sau khi bạn đã xác nhận rõ nguyên nhân — đừng để agent tự quyết định rollback ngay khi vừa phát hiện bất thường, vì có trường hợp rollout "chậm" chỉ vì cluster đang bận, không phải lỗi thật.

Mẹo: Luôn yêu cầu agent tách rõ ba việc: (1) mô tả hiện trạng, (2) chỉ ra nguyên nhân kèm bằng chứng cụ thể (event, log, diff), (3) đề xuất hành động. Đừng để nó nhảy thẳng tới bước 3 mà bỏ qua bước 2 — agent rất dễ đề xuất "rollback ngay" mà không giải thích rõ vì sao, nếu bạn không ép nó trình bày bằng chứng trước.

Giới hạn hiện tại của Kubernetes MCP trong OpenCode

OpenCode là công cụ phát triển nhanh và cộng đồng khá năng động, nhưng hệ sinh thái MCP của nó chưa "chín" bằng Claude Code hay Cursor về độ ổn định lâu dài. Vài giới hạn mình đã thực tế đụng phải:

Không có cơ chế streaming log theo thời gian thực

Hầu hết Kubernetes MCP server hiện nay implement get_pod_logs như một lần fetch snapshot log, không phải stream liên tục kiểu kubectl logs -f. Nếu bạn cần theo dõi log real-time khi đang debug một lỗi đang xảy ra, OpenCode (qua MCP) không thay thế được việc mở một terminal riêng chạy kubectl logs -f song song.

Context window giới hạn khi log hoặc event quá dài

Context window (giới hạn lượng văn bản mô hình xử lý được trong một lượt) của model bạn chọn cho OpenCode (Claude, GPT, hay model khác) vẫn là giới hạn cứng. Với cluster có nhiều pod restart liên tục, log event có thể lên tới hàng nghìn dòng — agent sẽ tự cắt bớt hoặc tóm tắt, và bạn cần chủ động yêu cầu nó "lấy log theo trang" (ví dụ giới hạn 200 dòng mỗi lần, chỉ định rõ khoảng thời gian) để tránh bỏ sót thông tin quan trọng.

Chưa có RBAC scoping tích hợp sẵn trong OpenCode

OpenCode chỉ đơn giản chuyển tiếp quyền của kubeconfig mà bạn cấu hình trong environment.KUBECONFIG — bản thân OpenCode không có lớp kiểm soát quyền bổ sung nào (khác với một số nền tảng enterprise có thêm policy layer riêng). Việc giới hạn quyền hoàn toàn phải làm ở tầng Kubernetes RBAC (Role-Based Access Control, kiểm soát quyền theo vai trò), không thể trông chờ OpenCode tự chặn giúp bạn.

Rủi ro tool call nối tiếp không xác nhận

Vì OpenCode hướng tới trải nghiệm "agentic" mạnh (tool calling — mô hình tự quyết định gọi tool nhiều lần liên tiếp để hoàn thành tác vụ), một số phiên bản có thể auto-approve các tool call MCP nếu bạn không cấu hình chế độ approval chặt. Với tool có khả năng viết/xoá trên cluster, luôn kiểm tra kỹ setting approval trong OpenCode trước khi chạy trên bất kỳ cluster staging/production nào.

Cộng đồng MCP server cho Kubernetes vẫn phân mảnh

Không có một MCP server "chuẩn" duy nhất cho Kubernetes được toàn ngành công nhận — có nhiều implementation khác nhau (dựa trên client-go, dựa trên kubectl wrapper, dựa trên Kubernetes API trực tiếp qua REST), mỗi cái expose tên tool và tham số khác nhau. Trước khi dùng, luôn đọc kỹ danh sách tool mà server bạn chọn expose ra (qua /mcp trong OpenCode) — đừng giả định tool apply_manifest có hành vi giống nhau giữa hai server khác nhau.

Mẹo: Pin chính xác version của MCP server package trong opencode.json (ví dụ mcp-server-kubernetes@1.4.2 thay vì để trống hoặc @latest), và ghi lại version đó vào README của repo. Một bản update server có thể đổi tên tool hoặc thêm tool mới có quyền rộng hơn — pin version giúp cả team dùng chung một hành vi đã kiểm chứng.

Tips

Vài kinh nghiệm gom lại sau nhiều lần dùng Kubernetes MCP với OpenCode trong công việc thực tế:

  • Đặt file opencode.json ở cấp project, không dùng config global cho cluster — mỗi repo chỉ nên thấy đúng cluster liên quan tới nó.
  • Luôn kiểm tra /mcp ngay khi mở session mới để chắc server còn connected, vì tiến trình MCP local có thể chết âm thầm nếu kubeconfig hết hạn token (phổ biến với cluster dùng OIDC/SSO).
  • Với mọi prompt liên quan ConfigMap/Secret, luôn ép agent liệt kê đầy đủ key, không tóm tắt.
  • Tách rõ prompt "chỉ đọc, không hành động" và prompt "hãy thực hiện thay đổi" — đừng gộp chung, để bạn luôn có một điểm dừng xác nhận trước khi agent chạm vào cluster thật.
  • Với cluster production, dùng kubeconfig read-only làm mặc định, chỉ đổi sang kubeconfig có quyền viết khi thực sự cần và đã thống nhất với team.

Mẹo: Ghi lại các prompt đã dùng thành công (như ví dụ chẩn đoán rollout ở trên) thành một file PROMPTS.md trong repo, kèm tên MCP server và version đã test — giúp cả team tái sử dụng pattern đã kiểm chứng thay vì mỗi người tự mò lại từ đầu mỗi khi có incident.