本页面适用于 Apigee 和 Apigee Hybrid。
查看 Apigee Edge 文档。
本页面介绍了如何在运行版本 1.17.0 或更高版本的现有 Apigee Hybrid 集群中启用 Model Context Protocol (MCP)。完成此过程后,您的集群将运行新的集群内 MCP 数据平面,并且您的消息处理器已准备好将 MCP 工具调用路由到该数据平面。然后,您可以按照共享的 MCP 快速入门部署第一个 MCP Discovery Proxy。
如需了解 Apigee 和 Apigee Hybrid 之间共用的 MCP 概念、架构和功能详情,请参阅 Apigee 中的 MCP 概览。
此程序的作用
在 Apigee Hybrid 集群上启用 MCP 会带来以下变化:
- 向
apigee-watcher身份授予对 Apigee 控制平面上 MCP 配置的访问权限。您需要将apigee-watcher服务账号添加到 Apigee 组织的controlPlaneAccess资源中的watcher_identities列表中,以便 MCP 边车可以从 Apigee 控制平面拉取 MCP 配置软件包。这是一项控制平面变更,范围限定为 Apigee 组织,并且每个组织只需执行一次,无论有多少个集群为该组织提供服务。 - 添加新的集群内 MCP 数据平面。在安装 Apigee Hybrid 的同一 Kubernetes 命名空间(默认
apigee)中创建一组新的 MCP pod,以及运行这些 pod 所需的支持性 Kubernetes 资源(服务、Pod 横向自动扩缩器和 RBAC)。MCP 工具调用由这些 pod 处理。 - 配置消息处理器以访问 MCP 数据平面。Apigee 运算符会更新消息处理器 Pod 规范,以便 MP 将 MCP 工具调用路由到新的集群内 MCP 数据平面。应用此更改会触发消息处理器(由
ApigeeDeployment控制器管理)的阶段性 Canary 发布;在新的 pod 变为Ready之前,之前的 pod 会继续处理流量。该版本仅在启用和停用转换时触发,不会在持续的 MCP 活动或稳态 MCP 流量时触发。在批准的维护窗口中运行此过程,并等待版本发布完成,然后再继续。
第 1 步:修改 overrides.yaml
打开您用于 Apigee Hybrid Helm 图表的 overrides.yaml 文件。在文件顶层,添加:
enableMcpServer: true
这是启用 MCP 所需的最低配置。它使用 apigee-org 图表中的内置默认值:两个 MCP 数据平面副本,在 CPU 利用率为 70% 时自动扩缩到 10 个,资源请求为 500m CPU 和 512Mi 内存,MCP 数据平面容器的限制为 2000m CPU 和 1Gi 内存。如需自定义副本数量、资源请求或 MCP 服务账号,请参阅本页面后面的参考:overrides.yaml 中的 MCP 字段。
下面是合并 overrides.yaml 的完整示例,每种身份验证样式各一个。请使用与现有基本安装配置相符的示例;MCP 特定的行会以注释突出显示,并且在所有三种变体中都相同。
选择与基本安装如何向 Google Cloud 验证 Apigee 组件相符的标签页。此选择适用于此页面上所有具有变体范围的代码块。
Workload Identity (GKE)
如果您的基本安装通过 GKE Workload Identity 将 Apigee 组件向 Google Cloud 进行身份验证(磁盘上没有服务账号密钥文件),请使用此变体。
instanceID: "my-hybrid-instance" namespace: APIGEE_NAMESPACE gcp: region: us-central1 projectID: my-hybrid-project workloadIdentity: enabled: true gsa: apigee-non-prod@my-hybrid-project.iam.gserviceaccount.com k8sCluster: name: my-cluster region: us-central1 org: my-org envs: - name: my-env # ---- MCP: minimum required ------------------------------------------------- enableMcpServer: true # ---- MCP: optional customization (all fields default when omitted) --------- # mcpServer: # replicaCountMin: 2 # replicaCountMax: 10 # targetCPUUtilizationPercentage: 70 # resources: # requests: { cpu: 500m, memory: 512Mi } # limits: { cpu: 2000m, memory: 1Gi } # sidecar: # resources: # requests: { cpu: 200m, memory: 128Mi } # limits: { cpu: 500m, memory: 512Mi } # annotations: {} # ----------------------------------------------------------------------------
基于文件的服务账号密钥
如果您的基本安装通过您分发给每个集群的服务账号密钥文件向 Google Cloud 验证 Apigee 组件的身份,请使用此变体。
instanceID: "my-hybrid-instance" namespace: APIGEE_NAMESPACE gcp: region: us-central1 projectID: my-hybrid-project k8sCluster: name: my-cluster region: us-central1 org: my-org guardrails: serviceAccountPath: ./service-accounts/apigee-non-prod.json mart: serviceAccountPath: ./service-accounts/apigee-non-prod.json connectAgent: serviceAccountPath: ./service-accounts/apigee-non-prod.json watcher: serviceAccountPath: ./service-accounts/apigee-non-prod.json # MCP also uses this key file envs: - name: my-env serviceAccountPaths: synchronizer: ./service-accounts/apigee-non-prod.json runtime: ./service-accounts/apigee-non-prod.json # ---- MCP: minimum required ------------------------------------------------- enableMcpServer: true # ---- MCP: optional customization (all fields default when omitted) --------- # mcpServer: # replicaCountMin: 2 # replicaCountMax: 10 # targetCPUUtilizationPercentage: 70 # resources: # requests: { cpu: 500m, memory: 512Mi } # limits: { cpu: 2000m, memory: 1Gi } # sidecar: # resources: # requests: { cpu: 200m, memory: 128Mi } # limits: { cpu: 500m, memory: 512Mi } # annotations: {} # ----------------------------------------------------------------------------
工作负载身份联合 (AKS/EKS)
如果您的基本安装在 AKS 或 EKS 上,并通过工作负载身份联合向 Google Cloud 进行身份验证,请使用此变体。MCP 使用 apigee-watcher 已使用的凭据配置文件(来自 watcher.serviceAccountPath),因此您无需添加任何 MCP 特定的身份配置。如果您改为将凭据配置存储在 Kubernetes Secret 中,请参阅其他身份验证机制。
将 MCP 顶级密钥添加到现有 WIF overrides.yaml:
# ---- MCP: minimum required ------------------------------------------------- enableMcpServer: true # ---- MCP: optional customization (all fields default when omitted) --------- # mcpServer: # replicaCountMin: 2 # replicaCountMax: 10 # targetCPUUtilizationPercentage: 70 # resources: # requests: { cpu: 500m, memory: 512Mi } # limits: { cpu: 2000m, memory: 1Gi } # sidecar: # resources: # requests: { cpu: 200m, memory: 128Mi } # limits: { cpu: 500m, memory: 512Mi } # annotations: {} # ----------------------------------------------------------------------------
不设置 mcpServer.gsa 和 mcpServer.serviceAccountPath。 MCP 边车使用与 apigee-watcher 相同的凭据配置文件,该文件位于 watcher.serviceAccountPath 中。
第 2 步:向观看者身份授予对控制平面上 MCP 配置的访问权限
MCP Sidecar 使用 apigee-watcher 组件的 Google Cloud 服务账号(您在第 1 步中选择的身份)从 Apigee 控制平面提取其配置软件包。在 MCP pod 启动之前,将该服务账号添加到 Apigee 组织的 controlPlaneAccess 资源的 watcher_identities 列表中。如果没有此授权,MCP Sidecar 对 apigee.googleapis.com 的调用(用于检索 MCP 配置引用)会返回 404 Not Found,并且 MCP 数据平面永远不会准备好为工具流量提供服务。
此步骤只需每个组织执行一次(而不是每个集群执行一次)。如果您已在同一 Apigee 组织中为之前的集群授予访问权限,请跳过此步骤。
- 设置用于 API 调用的 shell 变量。重复使用安装中的值:
export ORG_NAME=YOUR_ORG_NAME export PROJECT_ID=YOUR_GCP_PROJECT_ID export WATCHER_SA=apigee-watcher@${PROJECT_ID}.iam.gserviceaccount.com export TOKEN=$(gcloud auth print-access-token)
其中:
YOUR_ORG_NAME是您的 Apigee Hybrid 组织的名称。YOUR_GCP_PROJECT_ID是托管 Apigee Hybrid 组织的 Google Cloud 项目。WATCHER_SA是apigee-watcher服务账号的电子邮件地址。如果您在overrides.yaml中替换了watcher.gsa,请使用该值而不是默认值apigee-watcher@${PROJECT_ID}.iam.gserviceaccount.com。
- 调用 updateControlPlaneAccess API 以将 watcher 服务账号添加到
watcher_identities列表:无数据驻留
curl -X PATCH -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ "https://apigee.googleapis.com/v1/organizations/${ORG_NAME}/controlPlaneAccess?update_mask=watcher_identities" \ -d "{\"watcher_identities\": [\"serviceAccount:${WATCHER_SA}\"]}"数据驻留
curl -X PATCH -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ "https://${CONTROL_PLANE_LOCATION}-apigee.googleapis.com/v1/organizations/${ORG_NAME}/controlPlaneAccess?update_mask=watcher_identities" \ -d "{\"watcher_identities\": [\"serviceAccount:${WATCHER_SA}\"]}"其中,如果您的 Apigee Hybrid 安装启用了数据驻留,
CONTROL_PLANE_LOCATION用于指定控制平面数据的位置。如需查看可用位置的列表,请参阅可用的 Apigee API 控制平面区域。该调用会返回一个长时间运行的操作。等待其完成,然后再运行下方的验证步骤。
- 验证授权是否已生效。调用 getControlPlaneAccess 并确认监控服务账号显示在响应的
watcherIdentities字段中:无数据驻留
curl -X GET -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ "https://apigee.googleapis.com/v1/organizations/${ORG_NAME}/controlPlaneAccess"数据驻留
curl -X GET -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ "https://${CONTROL_PLANE_LOCATION}-apigee.googleapis.com/v1/organizations/${ORG_NAME}/controlPlaneAccess"响应应包含一个
watcherIdentities数组,其中包含您的监控服务账号。例如:{ "synchronizerIdentities": [ ... ], "analyticsPublisherIdentities": [ ... ], "watcherIdentities": [ "serviceAccount:apigee-watcher@YOUR_GCP_PROJECT_ID.iam.gserviceaccount.com" ] }
如果响应中缺少
watcherIdentities或不包含您的 watcher 服务账号,请重新运行 PATCH 命令并检查操作状态是否存在错误,然后再继续。
第 3 步:升级 apigee-operator 图表
首先升级 operator 图表。运算符图表拥有新 MCP 资源的架构;组织图表引用这些资源。以错误的顺序升级会导致 helm upgrade 成功,但不会创建 MCP pod。
helm upgrade APIGEE_OPERATOR_RELEASE_NAME apigee-operator/ \ --namespace APIGEE_NAMESPACE \ --atomic \ -f overrides.yaml
该命令会在不到一分钟的时间内完成。确认 operator Deployment 已完全推出新映像(apigee-controller-manager
Deployment 是普通的 Kubernetes 资源,而不是 ApigeeDeployment,因此 kubectl rollout status deploy 是此处的正确命令):
kubectl rollout status deploy -n APIGEE_NAMESPACE apigee-controller-manager --timeout=2m
预期输出:
deployment "apigee-controller-manager" successfully rolled out
第 4 步:升级 apigee-org 图表
helm upgrade APIGEE_ORG_RELEASE_NAME apigee-org/ \ --namespace APIGEE_NAMESPACE \ --atomic \ -f overrides.yaml
现在有两个协调循环并行运行:
- Apigee 运算符会创建 MCP Deployment、Service、HPA、ServiceAccount、Role 和 RoleBinding。MCP Pod 一次启动两个(取决于 Kubernetes 调度);每个 Pod 中的边车容器在启动后不久便会从 Apigee 控制平面执行首次配置提取。
- Apigee 运算符将
hostAliases条目注入到消息处理器 pod 规范中,这会触发apigee-runtimeApigeeDeployment的发布。
第 5 步:验证安装
验证 MCP 数据平面是否正在运行
检查操作员创建的 4 个与 MCP 相关的资源。资源名称包含组织派生的后缀;以下示例使用 ORG_CR_SUFFIX 作为该后缀的占位符,并且 Pod 后缀和服务 ClusterIP 在您的环境中会有所不同。
MCP pod(默认情况下为 2 个;在负载下自动扩缩到 10 个):
kubectl get pod -n APIGEE_NAMESPACE -l app=apigee-mcp-server
NAME READY STATUS RESTARTS AGE apigee-mcp-server-default-ORG_CR_SUFFIX-6d4c8-abc12 2/2 Running 0 2m apigee-mcp-server-default-ORG_CR_SUFFIX-6d4c8-def34 2/2 Running 0 2m
每个 pod 都必须在 READY 列中显示 2/2。每个 pod 中的两个容器分别是:
apigee-mcp-server- MP pod 连接到的 MCP 数据平面容器。apigee-mcp-server-config- 配置边车(apigee-watcher二进制文件的一种模式),用于从 Apigee 控制平面提取配置软件包,并将其写入 MCP 数据平面容器读取的共享卷。
MCP ApigeeDeployment(一种 Kubernetes 自定义资源,而非普通的 Deployment):
kubectl get apigeedeployment -n APIGEE_NAMESPACE -l app=apigee-mcp-server
NAME STATE NESTEDSTATE AGE apigee-mcp-server-default-ORG_CR_SUFFIX running 2m
预期状态为 running。另请验证底层 pod 是否处于 2/2
Running 状态:
kubectl get pod -n APIGEE_NAMESPACE -l app=apigee-mcp-server
NAME READY STATUS RESTARTS AGE apigee-mcp-server-default-ORG_CR_SUFFIX-REV-POD_HASH 2/2 Running 0 2m
MCP 服务:
kubectl get svc -n APIGEE_NAMESPACE -l app=apigee-mcp-server
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE apigee-mcp-server-default-ORG_CR_SUFFIX ClusterIP 10.96.42.17 <none> 80/TCP,443/TCP,15021/TCP,15000/TCP 2m
MCP HorizontalPodAutoscaler:
kubectl get hpa -n APIGEE_NAMESPACE | grep apigee-mcp-server
确认 MINPODS 与 overrides.yaml 中的 mcpServer.replicaCountMin(默认值为 2)一致,且 MAXPODS 与 mcpServer.replicaCountMax(默认值为 10)一致。TARGETS、REPLICAS 和 AGE 列取决于实时指标和集群状态。
验证消息处理器 pod 是否收到了 hostAliases 条目
每个 MP pod 都必须显示注入的条目,如果缺少任何一个 pod,该 pod 就无法路由 MCP 工具调用。列出所有 MP pod 及其 hostAliases:
kubectl get pods -n APIGEE_NAMESPACE -l app=apigee-runtime \ -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.hostAliases}{"\n"}{end}'
预期输出:每个 MP pod 列出一个 hostAliases 数组,其中包含一个条目,该条目具有两个指向上一步中 MCP 服务 ClusterIP 的主机名(第二个主机名使用您的小写组织名称)。消息处理器 pod 名称遵循 apigee-runtime-TRUNCATED_ORG-ENV_GROUP_HASH-REV-POD_HASH 模板,其中 TRUNCATED_ORG 是您的组织名称(如果组织名称较长,则会截断以符合 Kubernetes 63 个字符的名称限制),ENV_GROUP_HASH 是每个环境的部署组哈希,REV 是当前发布版本号(四位数,例如 1170),POD_HASH 是每个 pod 的随机后缀。例如:
apigee-runtime-myorg-env1-abc12-1170-def34 [map[hostnames:[mcp.apigee.internal myorg.mcp.apigee.internal] ip:10.96.42.17]] apigee-runtime-myorg-env1-abc12-1170-ghi56 [map[hostnames:[mcp.apigee.internal myorg.mcp.apigee.internal] ip:10.96.42.17]]
如果任何 pod 显示空的 hostAliases 值,则表示消息处理器 ApigeeDeployment 未完全获取更新后的 pod 规范。通过删除当前的消息处理器 pod 来强制执行新的分阶段 Canary 版本;ApigeeDeployment 控制器将根据当前规范(现在包含 hostAliases 条目)重新呈现这些 pod:
kubectl delete pod -n APIGEE_NAMESPACE -l app=apigee-runtime
ApigeeDeployment 控制器会在一分钟内重新创建 pod。请注意,kubectl rollout restart deploy(常规 Kubernetes 命令)不适用于消息处理器,因为消息处理器是作为 ApigeeDeployment 自定义资源(而非 Deployment)部署的。
安装完毕
上述三项检查共同确认您的 MCP 数据平面正在运行且可寻址 MP:
- 每个 MCP pod 都是
2/2 Running。如果操作员颁发的 TLS 证书未加载,并且边车尚未加载其初始 MCP 配置,则 MCP 数据平面容器会在端口15021上未能通过其 Kubernetes 就绪状态探测,因此Readypod 同时满足这两个前提条件。 - 每个 MP pod 的规范都包含
hostAliases条目,用于将mcp.apigee.internal和ORG_NAME.mcp.apigee.internal固定到 MCP 服务 ClusterIP。因此,MP pod 可以将 MCP 代理目标端点解析为集群内 MCP 数据平面。 - MP pod 通过注入的
hostAliases条目将mcp.apigee.internal解析为 MCP 服务 ClusterIP。
在部署第一个 MCP Discovery Proxy 后,您可以按照共享的 MCP 快速入门中的步骤验证端到端 MCP 工具流量(通过 Apigee 入口的实际 MCP initialize 或 tools/list 调用)。
如果上述三项检查中的任何一项失败,请先参阅排查 MCP 部署问题,然后再继续快速入门。
第 6 步:在其余集群上启用 MCP
针对给定主机名的 MCP 请求可以路由到提供相应 Apigee 环境组服务的任何集群。如果 MCP 在同一环境组中的某些集群上已启用,而在其他集群上未启用,则路由到未启用 MCP 的集群的 MCP 请求会失败(通常会以 503 Service Unavailable 的形式返回给客户端)。
在为同一环境组提供服务的每个集群上统一启用 MCP。 对于每个额外的集群,重复执行第 1 步、第 3 步、第 4 步和第 5 步。您无需重复执行第 2 步(授予观看者身份访问权限):该授权的范围限定为 Apigee 组织,适用于同一组织中的所有集群。
回滚
如需在集群上停用 MCP,请在 overrides.yaml 中设置 enableMcpServer: false(或完全移除该字段),然后升级 apigee-org 图表:
helm upgrade APIGEE_ORG_RELEASE_NAME apigee-org/ \ --namespace APIGEE_NAMESPACE --atomic -f overrides.yaml
enableMcpServer 字段仅供 apigee-org 图表使用,因此在停用期间无需升级运营商图表。Apigee 运算符(未更改)从 ApigeeOrganization 自定义资源中获取配置更改,删除 MCP 资源,并从消息处理器 Pod 规范中移除 hostAliases 条目,从而触发 apigee-runtime ApigeeDeployment 的发布。在获批的维护窗口中回滚。
回滚后,您部署到 Apigee 环境的 MCP Discovery 代理仍然存在于 Apigee 控制平面中,但该环境组中没有任何集群提供 MCP 流量。取消部署 MCP Discovery Proxy 以完全撤消该功能,或者让它们保持部署状态,稍后在集群上重新启用 MCP。
参考:overrides.yaml 中的 MCP 字段
下表列出了每个 Apigee Hybrid overrides.yaml 字段,这些字段用于控制版本 1.17.0 中的 MCP 行为。只有 enableMcpServer 是必需的;所有其他字段都有适合大多数安装的安全默认值。
字段定义与混合 1.17.0 的 apigee-org Helm 图表默认值相匹配。
| 字段 | 类型 | 默认 | 推荐的调整 |
|---|---|---|---|
enableMcpServer |
布尔值 | false |
必需。设置为 true 可在此集群上启用 MCP。切换此字段会触发消息处理器的分阶段 Canary 版本发布。仅在维护窗口中切换,并等待版本发布完成,然后再继续。 |
mcpServer.replicaCountMin |
整数 | 2 |
将 2 保持为 HA。只有在 MCP 流量基准较高的情况下才增加;HPA 会在 CPU 压力下自动向上扩缩。信号:HPA 持续处于 replicaCountMax,且 CPU 高于目标值。 |
mcpServer.replicaCountMax |
整数 | 10 |
如果发现 HPA 在高峰时段达到上限值 10,则应增加该值。信号:
kubectl top pods -l app=apigee-mcp-server 表示所有 Pod 在峰值时接近其 CPU 限制。如果未安装 metrics-server,请使用 kubectl get hpa -n APIGEE_NAMESPACE | grep apigee-mcp-server 并检查 REPLICAS 列是否位于 MAXPODS 上限。 |
mcpServer.targetCPUUtilizationPercentage |
整数 | 70 |
对于延迟敏感型工作负载,可将该值调低至 50-60(更早进行扩缩)。将该值提高到 80–85,以减少对费用敏感的集群中的副本数量。信号:第 95 百分位请求延迟时间与每个 pod 的 CPU 相关。 |
mcpServer.resources.requests |
资源列表 | cpu: 500m, memory: 512Mi |
如果 pod 在稳定状态下经常被 OOMKilled 或 CPU 受到限制,请增加请求。信号:kubectl describe pod 显示 OOMKilled 或节流条件。 |
mcpServer.resources.limits |
资源列表 | cpu: 2000m, memory: 1Gi |
如果 p95 延迟时间较长,但总体 QPS 较低(请求数量少但费用高),请先提高 CPU 限制,然后再提高副本数。仅当您看到 OOMKill 时才提高内存限制。 |
mcpServer.sidecar.resources.requests |
资源列表 | cpu: 200m, memory: 128Mi |
很少需要调整。边车容器会定期创建并写入配置软件包;稳态 CPU 使用率非常低。 |
mcpServer.sidecar.resources.limits |
资源列表 | cpu: 500m, memory: 512Mi |
很少需要调整。仅当您在单个 Discovery 代理中部署了数量异常多的 MCP 工具时,才需要增加内存。 |
mcpServer.terminationGracePeriodSeconds |
整数 | 30 |
很少需要调整。如果长时间运行的 MCP 在 pod 排空期间需要更多时间才能完成,则增加此值。 |
mcpServer.annotations |
地图 | {} |
如果您的集群需要,请添加额外的 pod 注释。 |
mcpServer.serviceAccountPath |
字符串 | unset | 除非您需要按组件进行身份分离,否则请保持未设置状态。如果未设置,MCP 会使用 watcher.serviceAccountPath。MCP 不使用 envs[].serviceAccountPaths.runtime。apigee-watcher 身份已拥有 MCP Sidecar 所需的权限。如果您替换此字段,请指定 Google Cloud 服务账号密钥 JSON 文件的路径。与 mcpServer.gsa 互斥。
如果未启用 Workload Identity,并且您既未设置 mcpServer.serviceAccountRef 也未设置 serviceAccountSecretProviderClass,则必须设置 mcpServer.serviceAccountPath 或 watcher.serviceAccountPath。如果您未设置任何一个,helm upgrade 将失败并显示错误 mcpServer.serviceAccountPath or watcher.serviceAccountPath is
required!!。
尽可能首选 Workload Identity (GKE) 或工作负载身份联合 (AKS/EKS)。基于文件的服务账号密钥必须轮替、安全存储、分发到每个集群,并且是最常见的支持工件泄露源(请参阅支持服务工单)。 |
mcpServer.gsa |
字符串 | unset | 除非您需要按组件进行身份分离,否则请保持未设置状态。如果未设置,MCP 会回退到 watcher.gsa,然后回退到 gcp.workloadIdentity.gsa。apigee-watcher 身份已拥有 MCP Sidecar 所需的权限,因此建议重用该身份。仅当您的组织出于审核原因而要求 MCP Sidecar 具有不同的身份时,才使用专用 Google Cloud 服务账号电子邮件地址进行替换。 |
mcpServer.serviceAccountRef |
字符串 | unset | 高级。Apigee 命名空间中现有 Kubernetes Secret 的名称,该 Secret 包含 MCP Sidecar 的 Google Cloud 服务账号密钥。仅当您在 Apigee Helm 图表之外管理服务账号密钥 Secret 时,才使用此参数。与 mcpServer.serviceAccountPath 和 mcpServer.gsa 相互排斥。
MCP 不使用 watcher.serviceAccountRef。如果您的基本安装将 apigee-watcher 密钥存储在具有 watcher.serviceAccountRef 的 Kubernetes Secret 中,请将此属性设置为相同的 Secret 名称。 |
mcpServer.podDisruptionBudget |
地图 | unset | MCP pod 的可选 PodDisruptionBudget。接受 minAvailable 或 maxUnavailable(整数或百分比字符串)。设置其中一个,而不是同时设置两者。除非您的集群具有需要明确预算的严格自愿中断政策,否则请保持未设置状态。 |
mcpServer.tolerations |
list | 未设置(回退到顶级 tolerations) |
MCP Pod 的标准 Kubernetes 容忍。仅当 MCP pod 必须容忍其他 Apigee 组件不容忍的污点时才设置。 |
mcpServer.image.pullPolicy |
字符串 | IfNotPresent |
MCP 服务器容器的映像拉取政策。很少更改。 |
mcpServer.sidecar.image.pullPolicy |
字符串 | IfNotPresent |
MCP 边车容器的映像拉取政策。很少更改。 |
估算 MCP 工具容量
Apigee Hybrid 不会强制规定每个组织的最大 MCP 工具数量。相反,工具容量受在部署或请求时强制执行的四项硬性大小限制的约束。特定数量的工具是否适合取决于每个工具的大小,而每个工具的大小源自定义该工具的 OpenAPI 规范。
常规电池容量
对于大多数 OpenAPI 规范(包含各种参数数量、请求正文大小和说明长度的工具,其中大多数工具属于小到中等大小范围),在默认的 tools/list 响应大小限制下,您通常可以预期每个组织最多可容纳 10,000 个 MCP 工具。
实际容量因 OpenAPI 规范的具体形状而异。如果组织的规范主要由具有许多参数、大型请求正文或长描述的工具组成,那么在达到以下四个硬性限制之一之前,其适合的工具数量会相对较少。如需验证特定规格的容量,请按照下文中的估算规格的容量操作。
硬性限额
Apigee Hybrid 版本 1.17.0 中有四种大小限制。以最低的适用限额为准;提高其中一个限额不会提高其他限额。
| 限制 | 值 | 范围 | 故障模式 |
|---|---|---|---|
| OpenAPI 规范文件大小 | 3 MiB | 每个 .yaml 文件 |
400 在代理验证时 |
| MCP 代理软件包大小(解压缩后) | 50 MiB | 每个 MCP 发现代理 | 400 在代理验证时 |
tools/list 响应大小 |
10 MiB(默认) | 按主机名 | 502 - TooBigBody |
| 每个环境组的主机名 | 100 | 每个环境组 | 400 在环境组更新时 |
影响每个工具大小的因素
每个工具的大小几乎完全由工具的 inputSchema 组成,而 inputSchema 是根据操作的 OpenAPI 规范的 parameters 和 requestBody 得出的。
有三个属性最为重要:
- 参数数量。每个参数条目大约会使
tools/list响应中的工具大小增加 100 字节。 - 请求正文属性的数量。每个请求正文属性大约占用 100 字节。因此,具有请求正文(通常为
POST和PUT)的操作比没有请求正文(通常为GET和DELETE)的操作大得多。 - 说明长度。操作说明几乎会原封不动地复制到工具中,因此较长的说明会直接增加工具的大小。
响应架构不会占用大小预算。只有 parameters 和 requestBody 会到达 MCP 配置。因此,仅根据 OpenAPI 文件大小来确定容量往往会高估费用,因为大多数实际的 OpenAPI 规范都包含不影响工具大小的响应架构定义。
估算规范的容量
估算 OpenAPI 规范的工具容量最可靠的方法是测量具有代表性的子集:
- 部署 MCP 发现代理,该代理引用您计划发布的一小部分具有代表性的工具(例如,50 到 100 个工具,这些工具应能反映完整规范中参数数量、请求正文大小和说明长度的组合)。
- 针对已部署的代理调用
tools/list,并记录响应大小(以字节为单位)和返回的工具数量。 - 将响应大小除以工具数量,即可得出规范中每个工具的平均大小。
- 将适用的
tools/list响应大小限制(默认值为 10 MiB)除以该平均值,即可估算出对于这种形状的规范,一个主机名最多可容纳多少个工具。
提高容量
有两种机制可将工具容量提升到超出默认值:
- 跨主机名分片工具。
tools/list回答上限是按主机名计算的。在同一环境组内跨多个主机名拆分工具可增加每个主机名的余量(但不得超过每个环境组 100 个主机名的限制)。分片不会提高每个代理软件包的限制;50 MiB 的软件包上限仍适用于单个 MCP 发现代理上的所有主机名。 - 提高
tools/list回答的大小限制。默认限制为每个主机名 10 MiB。您可以将其提高到 30 MiB。至少,这需要您在overrides.yaml中设置envs.components.runtime.resources.limits.memory、envs.components.runtime.resources.requests.memory和envs.components.runtime.cwcAppend.bin_setenv_max_mem,然后在apigee-org图表上运行helm upgrade。如需了解完整流程,包括按环境配置与按整个安装配置的变体、消息处理器堆大小调整指南和完整的overrides.yaml示例,请参阅在 Apigee Hybrid 中配置大型消息载荷支持。提高响应限制不会影响 50 MiB MCP 代理软件包大小限制;如果您的容量受该限制的约束,则此更改不会有帮助。
安全
信任边界
MCP 数据平面在您自己的 Kubernetes 集群内运行。Google 在运行时无权访问数据平面。Apigee 控制平面会根据您的 OpenAPI 规范为您提供 MCP 配置,但不会监控 MCP 请求流量。静态配置数据存储在由 Apigee 管理的 Cloud Storage 存储桶中,该存储桶的范围限定为您的 Apigee 租户项目,并由 MCP 边车使用其环境 Google Cloud 服务账号进行提取。
Apigee 运算符会在您的 Apigee 命名空间 (APIGEE_NAMESPACE) 中为 MCP 数据平面 ServiceAccount 配置 MCP 范围的 Kubernetes Role 和 RoleBinding。该角色授予只读权限:
get、list、watch(位于核心 API 组中)的services。get、list、watch(位于apigee.cloud.google.comAPI 群组中的apigeeroutes上)。
该角色不授予任何写入动词,也不授予对 Secrets、ConfigMaps 或 Pod 状态的访问权限。审核员可以直接通过以下命令从集群中验证确切的规则:
APIGEE_ORG_CR=$(kubectl get apigeeorganization -n APIGEE_NAMESPACE \ -o jsonpath='{.items[0].metadata.name}') kubectl get role,rolebinding -n APIGEE_NAMESPACE \ --field-selector metadata.name=apigee-mcp-server-$APIGEE_ORG_CR -o yaml
apigee-mcp-server-APIGEE_ORG_CR Role 和 RoleBinding 是 MCP 范围的 RBAC 资源;它们的名称包含 ApigeeOrganization 自定义资源的全名(该名称源自您的 Apigee 组织名称和一个短哈希)。它们在资源级别没有 app=apigee-mcp-server 标签(只有 pod 有),因此基于标签的查找不会返回任何结果。如果上述 field-selector 命令未返回任何内容,请使用以下命令列出命名空间中与 MCP 相关的所有 RBAC 资源:
kubectl get role,rolebinding -n APIGEE_NAMESPACE | grep apigee-mcp-server
消息处理器与 MCP 数据平面之间的 TLS
消息处理器 pod 在 https://mcp.apigee.internal/ 或 https://ORG_NAME.mcp.apigee.internal/ 拨打 MCP 数据平面。这些主机名通过注入的 hostAliases 条目解析为 MCP 服务 ClusterIP。MCP 数据平面容器会提供由 Apigee 操作器预配的签发者(名为 apigee-ca-issuer 的 ClusterIssuer)签名的 TLS 证书。该证书的主题备用名称同时包含这两个主机名。
限制对 MCP 服务的入站访问权限
在 Apigee Hybrid 1.17.0 中,MCP 数据平面不会独立对其调用方进行身份验证。它信任到达它的请求已由在消息处理器中运行的 Apigee MCP 代理进行身份验证。MCP 服务的唯一预期调用方是消息处理器。任何其他可以通过 TCP 443 访问 MCP 服务 ClusterIP 的集群内工作负载都可以调用 MCP 工具,而无需进行身份验证检查。
使用平台集群的入站流量政策引擎(Kubernetes NetworkPolicy、Cilium、Calico、Istio AuthorizationPolicy 或同等引擎),将 MCP Pod 的入站流量访问权限限制为仅限消息处理器 Pod。限制:
- 仅允许从同一命名空间中带有标签
app=apigee-runtime的 pod 向命名空间APIGEE_NAMESPACE中带有标签app=apigee-mcp-server的 pod 在 TCP443上发送入站流量。 - 拒绝所有其他在 TCP
443上流向具有标签app=apigee-mcp-server的 pod 的入站流量。 - 拒绝集群中所有通过 TCP
15021流向具有标签app=apigee-mcp-server的 Pod 的入站流量。端口15021提供未经身份验证的纯 HTTP/healthz/ready端点,供 kubelet 用于就绪状态探测;kubelet 直接通过 pod IP 访问该端口,因此集群中的任何其他工作负载都不应通过15021访问 MCP pod。
在完成 MCP 快速入门并在非开发环境中部署第一个 MCP 发现代理之前,请应用此限制。
配置新鲜度合约
当 MCP 边车成功完成配置拉取时,MCP 数据平面容器会加载提取的软件包,并继续提供服务,直到下一次成功拉取。如果后续拉取失败(Apigee 控制平面无法访问、Cloud Storage 无法访问、监控服务账号的 IAM 权限被移除,或者拉取流水线的任何其他阶段出现错误),边车会无限期地继续提供上次已知良好的软件包。1.17.0 中没有内置的陈旧性上限:Pod 保持 Ready 状态,并且 MCP 工具流量继续针对陈旧的软件包提供服务。配置停止刷新的信号是 ERROR 级别的边车日志行,其中包含 consecutive_failures 计数器(有关边车在每个失败阶段发出的具体消息,请参阅排查 MCP 部署问题)。
对于受监管的生产环境,请参阅有关此计数器重复递增的页面。最低可行性提醒是指:当任何 MCP 边车容器发出 ERROR 级日志行且 consecutive_failures 达到您根据陈旧容忍度设置的阈值时,系统会发出提醒。值升高表示边车已停止刷新配置;与此同时,边车会继续提供上次成功的软件包。
如果边车已停止刷新配置,请从边车日志中调查故障模式;请参阅排查 MCP 部署问题。弹跳 MCP pod 无法解决潜在的提取问题,因为新创建的 pod 会命中相同的提取路径。
出站网络要求
MCP 边车(每个 MCP pod 内的配置容器)需要通过 TCP 443 对以下端点进行出站网络访问。选择与您的 Apigee 组织是否使用数据驻留相符的标签页;所需的端点会有所不同。
无数据驻留
| 端点 | 用于: |
|---|---|
apigee.googleapis.com |
在每次配置刷新时,从 Apigee 控制平面检索组织的当前 MCP 配置参考。 |
storage.googleapis.com |
从 Google Cloud Storage 下载组织的 MCP 配置。 |
数据驻留
如果您的 Apigee 组织使用数据驻留,MCP 边车会命中区域性 Apigee 控制平面端点(与您的其他 Apigee 混合组件使用的端点相同,通过 overrides.yaml 中的 contractProvider 图表值进行配置)。将 CONTROL_PLANE_LOCATION 替换为组织的控制平面位置(例如 us、eu)。
| 端点 | 用于: |
|---|---|
CONTROL_PLANE_LOCATION-apigee.googleapis.com |
在每次配置刷新时,从组织所在区域的 Apigee 控制平面端点检索当前 MCP 配置参考。 |
storage.googleapis.com |
从 Google Cloud Storage 下载组织的 MCP 配置。存储桶位于您组织的区域中;Cloud Storage 会自动将请求路由到该存储桶。 |
此外,边车必须能够为 pod 运行的环境凭据(通过 Workload Identity 或基于文件的服务账号密钥)获取 Google Cloud 访问令牌。具体的令牌交换端点取决于您的身份验证路径,并且与集群中其他 Apigee Hybrid 组件已使用的端点相同。如果从该命名空间到 Google Cloud API 的现有 Apigee Hybrid 流量成功,则 MCP 边车的令牌交换也会成功。
此外,边车需要集群内访问 Kubernetes API 服务器(通过标准集群内服务地址)来发布其活跃度和就绪状态。此流量绝不会离开您的集群。
问题排查
如需查看完整的诊断检查清单,请参阅排查 MCP 部署问题,其中包含适用于 Apigee Hybrid 的 集群端诊断检查清单。
常见的安装失败情况
| 症状 | 原因和修复 |
|---|---|
helm upgrade 已完成,但未显示任何 MCP 资源。 |
组织结构图在操作员图之前升级。先运行 helm upgrade APIGEE_OPERATOR_RELEASE_NAME apigee-operator/,然后重新运行 helm upgrade APIGEE_ORG_RELEASE_NAME apigee-org/。 |
MCP pod 卡在 ContainerCreating 或 1/2 Ready 状态。 |
两个常见原因:MCP 的 cert-manager Certificate 尚未颁发,或者容器映像拉取失败。在受影响的 pod 上运行 kubectl describe pod,以了解确切原因。 |
边车 (apigee-mcp-server-config) 日志报告
no MCP config from CP yet; skipping tick, pod stays Ready via seed
在每次轮询时。 |
尚未为组织部署任何 MCP 发现代理时的预期稳定状态。Apigee 控制平面返回一个空的配置引用,而 MCP 数据平面仅在端口 15021 上加载了 Kubernetes 就绪状态监听器;MCP 请求端口 8443 尚无监听器,并且对 https://mcp.apigee.internal/mcp 的请求会收到连接拒绝。如需转换为提供服务状态,请按照 MCP 快速入门中的说明将 MCP Discovery Proxy 部署到此集群所服务的环境组中的某个环境。 |
边车日志报告 CP fetch failed,其中嵌入了 HTTP 403 或 PermissionDenied。 |
Apigee 监控器 Google Cloud 服务账号在您的 Apigee 租户项目中失去了 roles/apigee.runtimeAgent 角色(该角色授予边车所需的 apigee.runtimeconfigs.get 权限)。基本 Apigee Hybrid 安装会自动授予此角色;如果此角色已被 IAM 自动化扫描移除,请在 apigee-watcher Google Cloud 服务账号上重新应用此角色。 |
Sidecar 日志报告 CP fetch failed,并显示 context deadline exceeded、DNS 错误或 TLS 错误。 |
边车无法从集群内部访问 apigee.googleapis.com 或 storage.googleapis.com。根据上文出站网络要求中列出的三个端点验证出站流量。 |
消息处理器 Pod 在 helm upgrade 后未重启。 |
验证每个 MP pod 上是否存在 hostAliases 条目:
kubectl get pods -n APIGEE_NAMESPACE -l app=apigee-runtime -o
jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.hostAliases}{"\n"}{end}'。
如果任何 pod 显示为空,请通过删除 pod (kubectl delete pod -n APIGEE_NAMESPACE -l app=apigee-runtime) 强制执行全新渲染。
ApigeeDeployment 控制器将根据当前规范(包括 hostAliases 条目)重新创建该 pod。请勿使用 kubectl rollout restart deploy;它不适用于 ApigeeDeployment。 |
MP pod 日志显示,在 MCP 工具流量开始通过快速入门流动后,拨打 https://mcp.apigee.internal/ 或 https://ORG_NAME.mcp.apigee.internal/ 时出现 TLS 握手错误。 |
MCP 数据平面容器正在提供一个证书,该证书的主题备用名称 (SAN) 不包含 MP 拨号的主机名。验证证书:
依次选择 kubectl get cert -n APIGEE_NAMESPACE | grep apigee-mcp-server 和 kubectl get cert -n APIGEE_NAMESPACE CERT_NAME -o yaml。证书的 dnsNames 必须同时包含 mcp.apigee.internal 和小写形式的 ORG_NAME.mcp.apigee.internal。如果未更新,请删除 MCP Certificate 资源,并让 cert-manager 重新签发。 |
后续步骤
- 按照 MCP 快速入门指南部署您的第一个 MCP Discovery Proxy,并从 MCP 客户端调用 MCP 工具。
- 了解如何使用 API 产品管理 MCP 工具访问权限。
- 了解如何监控和分析 MCP 流量。
- 如需进行高级诊断,请参阅 MCP 问题排查指南。