Featured image of post kagent:在 Kubernetes 里跑一个完整的 AI Agent Case

kagent:在 Kubernetes 里跑一个完整的 AI Agent Case

从 CRD、controller、ModelConfig、MCPServer 到 Agent,记录一次用 kagent 在 Kubernetes 里部署可调用工具的 AI Agent 的完整流程。

前面看 kagent 的时候,我只把它当成一个 Kubernetes native 的 Agent 框架来理解。后来再翻官方文档,发现更值得记录的是完整落地链路:CRD 怎么装,controller 怎么起来,模型配置怎么声明,MCPServer 怎么接进来,最后 Agent 怎么引用这些东西。

这篇就按一个完整 case 记下来。目标不是让 agent 直接改生产集群,而是先做一个低风险的“集群观察 + 网页 fetch”助手:

  • 可以调用 kagent 内置 Kubernetes 工具查资源。
  • 可以通过一个 MCPServer 抓取网页内容。
  • Agent 使用显式的 ModelConfig
  • 所有对象都用 YAML 表达,方便放进 GitOps。

这个 case 里会出现哪些对象

先把关系画清楚:

1
2
3
4
5
6
7
8
Secret
  -> ModelConfig
      -> Agent
          -> RemoteMCPServer: kagent-tool-server
          -> MCPServer: mcp-website-fetcher

kagent CRDs + kagent controller
kmcp CRDs + kmcp controller

这里有两个容易混的对象:

  • RemoteMCPServer:kagent 里用来描述远程 MCP 服务的资源,内置的 kagent-tool-server 就属于这一类。
  • MCPServer:kmcp 管理的 MCP server 资源,可以把一个 stdio MCP server 包成 Kubernetes 里的服务。

官方文档里的 First MCP Tool 示例就是用 MCPServer 起了一个 fetch 工具,然后 Agent 通过 tools 引用它。

1. 安装 CRD 和 controller

我更偏向用 Helm 装,因为这套东西更适合放到平台环境里,不只是本地 demo。

先装 kagent CRD:

1
2
3
helm install kagent-crds oci://ghcr.io/kagent-dev/kagent/helm/kagent-crds \
  --namespace kagent \
  --create-namespace

再装 kagent controller 和 UI。这里用 OpenAI provider 举例,实际项目里可以换 Anthropic、Gemini、Azure OpenAI、Ollama 等。

1
2
3
4
5
6
export OPENAI_API_KEY="your-api-key"

helm install kagent oci://ghcr.io/kagent-dev/kagent/helm/kagent \
  --namespace kagent \
  --set providers.default=openAI \
  --set providers.openAI.apiKey="$OPENAI_API_KEY"

官方安装文档里提到,kagent 0.7 之后默认包含 kmcp 子项目。如果你已经单独装了 kmcp,可以通过 chart 配置关掉内置 kmcp。对第一次试用来说,先用默认就行。

确认 CRD 和 controller:

1
2
3
4
kubectl get crd | grep kagent.dev

kubectl get pods -n kagent
kubectl get svc -n kagent

如果要单独安装 kmcp controller,官方文档给的是这条线:

1
2
3
4
5
6
7
8
helm install kmcp-crds oci://ghcr.io/kagent-dev/kmcp/helm/kmcp-crds \
  --namespace kmcp-system \
  --create-namespace

kmcp install

kubectl get pods -n kmcp-system
kubectl logs -l app.kubernetes.io/name=kmcp -n kmcp-system

这里要注意:不要在同一个集群里重复装两套 kmcp controller。要么用 kagent 默认带的,要么明确自己单独安装并在 kagent chart 里关掉。

2. 准备模型 Secret 和 ModelConfig

Helm 安装时如果设置了 provider,通常会带默认配置。为了把流程讲完整,我这里单独写一个 ModelConfig,后续 Agent 明确引用它。

先创建 API key secret:

1
2
kubectl -n kagent create secret generic openai-api-key \
  --from-literal=api-key="$OPENAI_API_KEY"

然后创建 ModelConfig

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
apiVersion: kagent.dev/v1alpha2
kind: ModelConfig
metadata:
  name: ops-openai-model
  namespace: kagent
spec:
  provider: OpenAI
  model: "<your-openai-model>"
  apiKeySecret: openai-api-key
  apiKeySecretKey: api-key
  openAI:
    temperature: "0.2"
    maxTokens: 2048
    timeout: 60

我这里把 model 写成占位符,是因为不同账号、网关或代理支持的模型可能不一样。实际落地时要改成你环境里可用的模型名。

应用并检查:

1
2
3
4
kubectl apply -f modelconfig.yaml

kubectl get modelconfig -n kagent
kubectl describe modelconfig ops-openai-model -n kagent

ModelConfig 里有几个字段比较关键:

  • provider:模型提供方,API 里支持 OpenAI、Anthropic、AzureOpenAI、Ollama、Gemini、Bedrock 等。
  • model:具体模型名。
  • apiKeySecret / apiKeySecretKey:引用同 namespace 里的 Secret。
  • openAI:OpenAI provider 的额外参数,比如 temperature、maxTokens、timeout。

这个对象的价值是把模型配置从 Agent 里拆出来。多个 Agent 可以引用同一个 ModelConfig,模型切换也更清楚。

3. 创建一个 MCPServer:网页 fetch 工具

接下来创建一个最小 MCPServer。官方 First MCP Tool 文档里用的是 mcp-server-fetch,通过 uvx 启动 stdio MCP server,再由 kmcp controller 管理它的生命周期。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
apiVersion: kagent.dev/v1alpha1
kind: MCPServer
metadata:
  name: mcp-website-fetcher
  namespace: kagent
spec:
  deployment:
    cmd: uvx
    args:
      - mcp-server-fetch
    port: 3000
  stdioTransport: {}
  transportType: stdio

应用:

1
kubectl apply -f mcp-website-fetcher.yaml

检查状态:

1
2
3
4
kubectl get mcpserver -n kagent
kubectl describe mcpserver mcp-website-fetcher -n kagent

kubectl get pods -n kagent | grep mcp-website-fetcher

如果 MCPServer 没起来,我会先看 kmcp controller 日志,而不是直接怀疑 Agent:

1
kubectl logs -l app.kubernetes.io/name=kmcp -n kmcp-system

如果你用的是 kagent chart 内置 kmcp,controller 的 namespace 和 label 可能跟独立安装不同,直接用下面的方式先找:

1
2
kubectl get pods -A | grep -i kmcp
kubectl get deploy -A | grep -i kmcp

4. 创建 Agent:同时引用 Kubernetes 工具和 fetch 工具

现在创建 Agent。这个 Agent 做两件事:

  • 用内置 kagent-tool-server 查 Kubernetes 资源。
  • 用刚才的 mcp-website-fetcher 抓网页内容。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
apiVersion: kagent.dev/v1alpha2
kind: Agent
metadata:
  name: ops-readonly-agent
  namespace: kagent
spec:
  description: >
    A read-only Kubernetes operations assistant. It can inspect Kubernetes
    resources and fetch documentation pages, but it must not perform write
    operations.
  type: Declarative
  declarative:
    modelConfig: ops-openai-model
    stream: true
    systemMessage: |-
      You are a Kubernetes operations assistant.

      Rules:
      - Only use read-only tools.
      - Do not make up cluster state.
      - If a tool result is missing or ambiguous, say so.
      - Separate confirmed facts from guesses.
      - Never suggest deleting or modifying resources without human review.

      Response format:
      - Summary
      - Evidence from tools
      - Possible causes
      - Next checks
    tools:
      - type: McpServer
        mcpServer:
          apiGroup: kagent.dev
          kind: RemoteMCPServer
          name: kagent-tool-server
          toolNames:
            - k8s_get_available_api_resources
            - k8s_get_resources
      - type: McpServer
        mcpServer:
          kind: MCPServer
          name: mcp-website-fetcher
          toolNames:
            - fetch

应用:

1
kubectl apply -f ops-readonly-agent.yaml

检查 Agent:

1
2
3
kubectl get agent -n kagent

kubectl get agent ops-readonly-agent -n kagent -o yaml

官方示例里 Agent 的 status 会出现类似 Accepted=TrueReady=True 的 condition。如果这里不 Ready,优先看三类对象:

1
2
3
kubectl get modelconfig ops-openai-model -n kagent -o yaml
kubectl get mcpserver mcp-website-fetcher -n kagent -o yaml
kubectl get agent ops-readonly-agent -n kagent -o yaml

我会按这个顺序查:

  1. ModelConfig 是否能读到 secret。
  2. MCPServer 是否已经被 kmcp controller 拉起来。
  3. Agent 引用的 tool 名称是否存在。
  4. Agent 的 namespace 是否能引用对应 MCP server。

5. 打开 UI 验证

本地打开 kagent UI:

1
kubectl port-forward -n kagent svc/kagent-ui 8080:8080

然后访问:

1
http://localhost:8080

可以先问几个低风险问题:

1
列出当前集群里可以查询的 Kubernetes API resources。

再问一个会用到 fetch 的问题:

1
帮我读取 https://kagent.dev/docs/kagent/getting-started/first-mcp-tool ,总结创建 MCPServer 和 Agent 的关键步骤。

如果 Agent 正常,它应该会调用对应工具,而不是直接编造结果。这个时候我会重点看 UI 里有没有展示 tool call、参数和返回内容。kagent 这类工具的价值不只是回答,还在于能不能复盘它怎么回答的。

6. 权限边界:我不会一开始就给写权限

这个 case 里我故意只选了只读工具。原因很简单:Agent 最容易出事故的不是回答错,而是拿着写权限执行错。

如果未来要开放写操作,我会分三层:

1
2
3
read_only    get/list/watch/logs/events
reviewed     生成 YAML、生成 patch,但不 apply
approved     人工确认后才允许执行写操作

kagent 的 Tool 配置里支持 requireApproval,可以把敏感工具列进去,让工具调用前停下来等人工确认。这个设计比“相信系统提示词不会乱来”靠谱。

比如后续某个 MCP server 有一个 restart_deployment 工具,我不会直接放开,而是会写成:

1
2
3
4
5
6
7
8
9
tools:
  - type: McpServer
    mcpServer:
      kind: MCPServer
      name: ops-actions
      toolNames:
        - restart_deployment
      requireApproval:
        - restart_deployment

这套 case 的落地判断

如果只是本地试用,kagent install --profile demo 更快。官方 quickstart 里这条命令会预装一些 demo agents 和 MCP tools:

1
2
kagent install --profile demo
kagent dashboard

但如果要往团队环境里放,我更建议走 Helm + YAML:

  • CRD 和 controller 由平台侧统一安装。
  • ModelConfigMCPServerAgent 放进 Git 仓库。
  • 每个 Agent 的工具列表明确写出来。
  • 写操作默认要求人工确认。
  • 先把目标限定为“排查摘要”和“信息收集”,不要一上来自动修复。

kagent 这类项目让我感觉 Kubernetes 后面会多出一种新对象:不是 workload,也不是 controller,而是“会调用工具的运维助手”。但真正能不能用,不取决于它能不能聊天,而取决于工具边界、权限边界和运行记录是不是足够清楚。

参考资料

记录工程实践和排障过程。
使用 Hugo 构建
主题 StackJimmy 设计