使用 Core Profile 快速开始

本指南将带你完成 Kagenti Operator 的 core profile 上最小可行的端到端部署——这是默认的安装形态,支持 agent enrollment 和动态发现,但包含 identity sidecar、Keycloak 或 mesh mTLS。它是验证 operator 安装是否成功、并在逐步叠加 secure profile 之前熟悉 AgentRuntime 自定义资源的最快方式。

该场景是一个 weather agent:它通过调用用于获取实时数据的 weather MCP tool 和一个大语言模型来生成回复,回答类似 “What is the weather in New York?” 这样的问题。请求流程如下:

client ──A2A message/send──▶ weather-agent ──OpenAI chat API──▶ InferenceService (qwen36-27b-gguf)

                                  └──────────MCP──────────▶ weather-tool-mcp

在 core profile 下,没有认证或传输安全——下面的每一步都只是集群内的普通 HTTP 调用。关于安全版本(Bearer-token 请求、SPIRE mTLS、每个 agent 一个 AuthBridge sidecar),请在完成本指南后继续阅读 使用 Secure Profile 演示

前提条件

  • 已安装 Kagenti Operator,且其 Kagenti operand 已完成 reconciliation——请参见 安装

  • 具备目标集群的 kubectl 访问权限。

  • 一个演示命名空间。本指南使用 team1

    kubectl create namespace team1
  • 一个提供 OpenAI 兼容 chat API 的 InferenceService,且可在集群内访问。本指南使用名为 qwen36-27b-gguf 的 InferenceService。任何 chat 模型都可以;如果模型支持 tool calling,agent 效果会更好。

找到你的模型 endpoint 和名称

agent 通过三个环境变量连接模型——LLM_API_BASELLM_API_KEYLLM_MODEL。请从你的 InferenceService 中解析它们:

# The predictor Service exposes the OpenAI-compatible API in-cluster.
# Base URL pattern: http://<isvc-name>-predictor.<namespace>.svc.cluster.local/v1
kubectl get svc -n <model-namespace> | grep <isvc-name>-predictor

# The model id to send as "model" — list what the endpoint serves:
kubectl run modelq --rm -i --restart=Never -n <model-namespace> \
  --image=docker.io/alaudadockerhub/curl:8.1.2 --command -- \
  curl -sS http://<isvc-name>-predictor.<model-namespace>.svc.cluster.local/v1/models

对于部署在 models 命名空间中的 qwen36-27b-gguf InferenceService,解析结果如下:

变量
LLM_API_BASEhttp://qwen36-27b-gguf-predictor.models.svc.cluster.local/v1
LLM_MODELqwen36-27b-gguf
LLM_API_KEYdummy(任意非空值即可;集群内 endpoint 不需要 key)
INFO

在本指南的其余部分,请将示例中的 InferenceService 名称、命名空间和 model id 替换为你自己的值。如果模型是 reasoning 模型,响应的前几个 token 会是 reasoning 内容——请像下面这样保持 agent 的 token budget 不受限制,以免最终答案被截断。

步骤 1:部署 MCP tool server

MCP(Model Context Protocol)server 提供 agent 要调用的 get_weather tool。请部署它并通过 Service 暴露出来。在 core profile 下,tool 以普通 Deployment 方式运行(单容器、无 sidecar);在 secure profile 下也会继续沿用相同布局,因为 operand 默认值为 spec.featureGates.injectTools: false

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: weather-tool
  namespace: team1
  labels:
    app.kubernetes.io/name: weather-tool
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: weather-tool
  template:
    metadata:
      labels:
        app.kubernetes.io/name: weather-tool
    spec:
      containers:
      - name: mcp
        image: docker.io/alaudadockerhub/weather_tool:v0.1.0-rc.1
        imagePullPolicy: IfNotPresent
        env:
        - name: PORT
          value: "8000"
        - name: HOST
          value: 0.0.0.0
        - name: UV_CACHE_DIR
          value: /app/.cache/uv
        ports:
        - containerPort: 8000
        volumeMounts:
        - mountPath: /app/.cache
          name: cache
      volumes:
      - name: cache
        emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
  name: weather-tool-mcp
  namespace: team1
spec:
  selector:
    app.kubernetes.io/name: weather-tool
  ports:
  - name: http
    port: 8000
    targetPort: 8000
EOF
  1. MCP server 镜像已镜像到 docker.io/alaudadockerhub。在离线集群中,请使用重新分发到你平台 registry 中的副本。
  2. 该 Service 供 agent 访问,地址为 http://weather-tool-mcp.team1.svc.cluster.local:8000/mcp。operator 不会 自动为你创建这个 Service,因此需要你显式定义它,并选择 tool 的 pod。

等待 tool 就绪:

kubectl rollout status deploy/weather-tool -n team1
kubectl get pod -n team1 -l app.kubernetes.io/name=weather-tool
# NAME                            READY   STATUS    RESTARTS   AGE
# weather-tool-XXXXXXXXXX-YYYYY   1/1     Running   0          1m

READY 1/1 表示该 tool 正在以单容器方式运行。

步骤 2:部署 agent

agent 只需要在其 Deployment 上添加一个 protocol.kagenti.io/a2a 标签——controller 会应用 kagenti.io/type,计算 config hash,并在启用 identity stack 时触发 sidecar 注入。protocol 标签还会告诉 AgentCard sync controller 该 agent 使用哪种 protocol,从而启用自动发现。

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: weather-agent
  namespace: team1
  labels:
    app.kubernetes.io/name: weather-agent
    protocol.kagenti.io/a2a: ""
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: weather-agent
  template:
    metadata:
      labels:
        app.kubernetes.io/name: weather-agent
    spec:
      containers:
      - name: agent
        image: docker.io/alaudadockerhub/weather_service:v0.1.0-rc.1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8000
        env:
        - name: PORT
          value: "8000"
        - name: UV_CACHE_DIR
          value: /app/.cache/uv
        - name: MCP_URL
          value: http://weather-tool-mcp.team1.svc.cluster.local:8000/mcp
        - name: LLM_API_BASE
          value: http://qwen36-27b-gguf-predictor.models.svc.cluster.local/v1
        - name: LLM_API_KEY
          value: dummy
        - name: LLM_MODEL
          value: qwen36-27b-gguf
---
apiVersion: v1
kind: Service
metadata:
  name: weather-agent
  namespace: team1
spec:
  selector:
    app.kubernetes.io/name: weather-agent
  ports:
  - name: http
    port: 8000
    targetPort: 8000
---
apiVersion: agent.kagenti.dev/v1alpha1
kind: AgentRuntime
metadata:
  name: weather-agent-runtime
  namespace: team1
spec:
  type: agent
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: weather-agent
EOF
  1. protocol.kagenti.io/a2a: "" 将该 Deployment 标记为 A2A agent。它会启用 AgentCard 的自动创建;ValidatingAdmissionPolicy 会禁止直接设置 kagenti.io/type,因此 enrollment 必须通过 AgentRuntime 进行。
  2. agent 镜像已镜像到 docker.io/alaudadockerhub。请使用 v0.1.0 或更高版本——这些版本会从环境变量中读取 HOST/PORT,这在 secure profile 下是必需的(AuthBridge sidecar 会重映射应用端口)。
  3. MCP_URL —— 步骤 1 中的 MCP tool endpoint(Service 名称加上 /mcp 路径)。
  4. LLM_API_BASE —— 你的 InferenceService predictor 的 OpenAI 兼容 base URL(.../v1)。
  5. LLM_MODEL —— 由 InferenceService 提供的 model id。

agent 的 Service 以 Deployment 名称命名(weather-agent);AgentRuntime controller 会解析它,以便获取用于发现的 Agent Card。

创建 AgentRuntime 后,controller 将执行以下操作:

  1. 解析 targetRef 并验证 Deployment 是否存在。
  2. 应用 kagenti.io/type: agentapp.kubernetes.io/managed-by: kagenti-operator 标签。
  3. 计算 config hash,并将其作为 kagenti.io/config-hash 注解设置到 pod template 上,从而触发 rolling update。

步骤 3:检查状态

# AgentRuntime status — only the agent has one in this pattern
kubectl get agentruntime -n team1
# NAME                    TYPE    TARGET          READY   AGE
# weather-agent-runtime   agent   weather-agent   True    1m

# Conditions (core profile: MTLSReady is False with reason SPIREUnavailable — expected)
kubectl get agentruntime weather-agent-runtime -n team1 \
  -o jsonpath='{range .status.conditions[*]}{.type}={.status}{"\n"}{end}'
# TargetResolved=True
# IstioMeshEnrolled=True
# MTLSReady=False
# ConfigResolved=True
# Ready=True

# Labels applied by the operator
kubectl get deployment weather-agent -n team1 --show-labels

# Pods: agent 1/1, tool 1/1 — no sidecars in the core profile
kubectl get pods -n team1
# NAME                             READY   STATUS    RESTARTS   AGE
# weather-agent-XXXXXXXXX-YYYYY    1/1     Running   0          1m
# weather-tool-XXXXXXXXX-YYYYY     1/1     Running   0          6m

# The AgentCard is created and synced automatically
kubectl get agentcards -n team1
# NAME                            PROTOCOL   KIND         TARGET          AGENT               SYNCED   AGE
# weather-agent-deployment-card   a2a        Deployment   weather-agent   Weather Assistant   True     1m

SYNCED=TrueAGENT 列已填充(此处为 Weather Assistant)表示 sync controller 已获取到该 agent 的 A2A card——动态发现已正常工作。

步骤 4:发送查询(端到端测试)

从一个临时的集群内 pod 向 agent 发送 A2A message/send 请求,使用 agent 的内部 Service DNS 名称:

kubectl run curl-wq --rm -i --restart=Never -n team1 \
  --image=docker.io/alaudadockerhub/curl:8.1.2 --command -- \
  curl -sS -X POST http://weather-agent.team1.svc.cluster.local:8000/ \
    -H "Content-Type: application/json" \
    -d '{"jsonrpc":"2.0","id":"76CD6BA3-16AA-4CED-8E0E-19156B8C5886","method":"message/send","params":{"message":{"role":"user","parts":[{"kind":"text","text":"What is the weather in NY?"}],"messageId":"DF05857B-98B7-4414-BD63-19E16E684E39"}}}'

agent 会调用模型,模型再调用 weather MCP tool,最终 agent 返回一个已完成的 A2A task:

{
  "id": "76CD6BA3-16AA-4CED-8E0E-19156B8C5886",
  "jsonrpc": "2.0",
  "result": {
    "artifacts": [
      {
        "parts": [
          {
            "kind": "text",
            "text": "The current weather in New York is 66.4°F with clear skies. The wind speed is 4.4."
          }
        ]
      }
    ],
    "kind": "task",
    "status": { "state": "completed" }
  }
}

完整响应中的 history 数组展示了 tool-calling 流程(assistanttoolsassistant),其中包含由 weather MCP server 返回的 ToolMessage

INFO

reasoning 模型会先用前几个 token “思考”,再给出最终答案,因此第一次请求可能会明显慢于非 reasoning 模型。后续请求会更快。

你可以在日志中观察交互过程:

# Agent logs
kubectl logs -f -l app.kubernetes.io/name=weather-agent -n team1

# MCP tool logs (in another terminal)
kubectl logs -f -l app.kubernetes.io/name=weather-tool -n team1

更新和删除 AgentRuntime

平台配置变更(集群级或命名空间级 ConfigMap)会触发 rolling update,以便 pod 获取新设置。直接编辑 AgentRuntime 的 spec 本身不会强制重启——新值只会在创建 pod 时生效。

删除 AgentRuntime 会执行优雅清理:controller 会移除 kagenti.io/type 标签和 kagenti.io/config-hash 注解(从而触发 rolling update,使任何已注入的 pod 被替换),并移除 app.kubernetes.io/managed-by 标签。

kubectl delete agentruntime weather-agent-runtime -n team1

清理

kubectl delete namespace team1

下一步

你刚刚体验的 core profile 不包含认证或传输安全。要逐步加入这些能力:

  1. 安装 Secure-Profile Dependencies — SPIRE、Keycloak、Istio ambient。
  2. 启用 Secure Profile — 切换 operand feature gate。
  3. 使用 Secure Profile 演示 — 用同样的 weather 场景重新演示,在 agent 上加上 AuthBridge sidecar、每个 workload 一个 SPIRE SVID,以及 Bearer-token 认证请求。
  4. 高级演示:在 tool 上使用 AuthBridge 和 Token Exchange — 也为 tool 添加 AuthBridge,在 agent 和 tool 之间使用 RFC 8693 token exchange。

故障排查

症状检查项
AgentRuntime 不是 Readykubectl describe agentruntime <name> -n team1 —— 确认 TargetResolved。常见原因是目标 Deployment 或其 Service هنوز 还不存在。
agent 无响应 / 超时检查 agent 是否能访问模型:LLM_API_BASE 是否可解析,且 /v1/models 是否列出了 LLM_MODEL。查看 kubectl logs -l app.kubernetes.io/name=weather-agent -n team1 中的 LLM 连接错误。
agent 回答中没有实时数据确认 MCP_URL 指向 weather-tool-mcp Service,且 tool pod 处于 Runningkubectl logs -l app.kubernetes.io/name=weather-tool -n team1
ImagePullBackOff在没有 docker.io 出站访问权限的集群上,请将镜像重新分发到你的平台 registry(例如通过 violet),并引用该副本。
MTLSReady=False在 core profile 中这是预期行为(原因是 SPIREUnavailable);它不会影响 agent 或 tool 的功能。