返回首页

在 Kubernetes 中部署 MCP 服务器:架构和 JWT

本文描述了将 MCP 服务器从本地启动迁移到 Kubernetes 中的集中基础设施。它涵盖了 sidecar 代理模式、通过 Envoy 设置 JWT 认证以及使用 Vault 的 secrets 管理。

如何为整个团队在 Kubernetes 中部署 MCP 服务器
Advertisement 728x90

# Kubernetes 中 MCP 服务器的集中部署:架构、认证与密钥管理

在团队扩展 AI 基础设施时,通过包管理器或容器在本地运行 MCP 服务器很快就会成为瓶颈。运行时碎片化、凭证无控扩散以及缺少单一入口点,这些问题阻碍了将语言模型安全集成到企业环境。本文概述了从孤立实例向使用 sidecar 代理、JWT 验证和密钥编排的集中式 Kubernetes 架构的实际迁移路径。

架构演进:从本地进程到容器化

在采用 Model Context Protocol 的初始阶段,使用供应商提供的现成远程端点就足够了。配置只需在客户端应用中指定 URL,由提供商处理认证和扩展。然而,集成内部系统(Kubernetes、Grafana、数据库)则需要独立运行服务器。

使用本地 npx、uvx 调用或编译二进制文件的方式会导致依赖管理难题。每个集成都需要自己的运行时,容易引发版本冲突,并使新团队成员的入职变得复杂。将生产访问令牌存储在本地配置文件中也违反了核心信息安全原则。

Google AdInline article slot

容器化解决了环境隔离问题。在工作站层面,将每个 MCP 服务器运行在自己的容器中,并通过环境变量透传来标准化部署。孤立启动的示例配置:

{
  "mcpServers": {
    "grafana": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "-e", "GRAFANA_URL",
        "-e", "GRAFANA_SERVICE_ACCOUNT_TOKEN",
        "grafana/mcp-grafana",
        "-t", "stdio"
      ],
      "env": {
        "GRAFANA_URL": "https://grafana.example.com",
        "GRAFANA_SERVICE_ACCOUNT_TOKEN": "<token>"
      }
    }
  }
}

尽管隔离性更好,但本地 Docker 无法实现共享访问。自动化流水线、CI/CD 系统和非技术用户无法有效处理分散的容器。这就需要将 MCP 服务器迁移到具有集中生命周期管理的共享基础设施。

Kubernetes 中的编排:代理与通用部署

将 MCP 服务器迁移到集群需要桥接架构差异:大多数服务器使用 stdio,而 Kubernetes 网络依赖 HTTP/HTTPS。使用 MCP Gateway 的 sidecar 模式填补了这一空白。代理容器处理传入的 HTTP 请求(Streamable HTTP 或 SSE),将它们转发到目标进程的 stdin,并通过网络中继响应。

Google AdInline article slot

由于 Streamable HTTP 模式的 MCP 服务器是无状态服务,它们非常适合通过 HPA 进行水平扩展。为了避免为每个集成重复编写清单,使用支持两种模式的通用 Helm chart:

  • proxy — sidecar 容器启动,用于 HTTP 到 stdio 的转换。
  • native — 直接暴露已支持 HTTP 传输的服务。

通过 values.yaml 的部署配置,可以灵活控制网络、密钥注入和路由:

mode: proxy
proxy:
  image:
    repository: node
    tag: "20-bookworm"
    pullPolicy: IfNotPresent
  gateway:
    package: "@michlyn/mcpgateway"
    stdioCommand: "npx -y @digitalocean/mcp --services apps,droplets,doks,networking"
    outputTransport: streamable-http
    port: 8080
    httpPath: /mcp
vault:
  enabled: true
  role: "mcp"
  path: "kubernetes_dev-fra1-01"
env:
  - name: DIGITALOCEAN_API_TOKEN
    value: vault:devops/data/ai/mcp/digitalocean#token
ingress:
  enabled: true
  className: "internal"
  annotations:
    nginx.ingress.kubernetes.io/proxy-buffering: "off"
    nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"

与 HashiCorp Vault 或 External Secrets Operator 的集成可将凭证排除在版本控制之外。Ingress 控制器或 Gateway API 管理路由,同时禁用缓冲并延长超时时间,确保对长连接和流式数据的正确支持。

Google AdInline article slot

安全与认证:JWT、Envoy 和访问管理

MCP 协议缺少内置认证,因此保护措施必须在基础设施网关层面实现。基本认证无法满足企业安全需求,通过 Envoy Gateway 进行 JWT 验证是最佳选择。网关在请求到达 MCP 服务器 Pod 之前检查令牌签名、颁发者和受众。

密钥和令牌生成使用标准加密工具。公钥以 JWKS 形式打包到 ConfigMap 中,供 Envoy 加载和验证:

# 生成 RSA 密钥并形成 JWT
openssl genrsa -out mcp-jwt-private.pem 4096
openssl rsa -in mcp-jwt-private.pem -pubout -out mcp-jwt-public.pem
KID=$(openssl rand -hex 16)
HEADER=$(echo -n '{"alg":"RS256","typ":"JWT","kid":"${KID}"}' | base64 -w0 | tr '+/' '-_' | tr -d '=')
PAYLOAD=$(echo -n '{"sub":"claude-desktop","aud":"mcp-servers","iss":"https://your-domain.com","iat":$(date +%s),"exp":$(( $(date +%s) + 31536000 ))}' | base64 -w0 | tr '+/' '-_' | tr -d '=')
SIGNATURE=$(echo -n "${HEADER}.${PAYLOAD}" | openssl dgst -sha256 -sign mcp-jwt-private.pem | base64 -w0 | tr '+/' '-_' | tr -d '=')
echo "${HEADER}.${PAYLOAD}.${SIGNATURE}"

在协议当前成熟度下,架构限制依然存在。目标系统访问使用共享服务账户——读操作无妨,写操作风险较高。没有终端用户上下文传输,阻塞了按用户授权和详细工具调用审计。Envoy 日志仅捕获网络元数据,而非具体的 MCP 方法参数。

关键要点

  • 本地 MCP 服务器启动无法在团队范围内扩展,因为存在运行时冲突和凭证泄露风险。
  • 使用 MCP Gateway 的 sidecar 模式桥接了 stdio 传输与 Kubernetes 网络协议。
  • 无状态 Streamable HTTP 架构支持标准的 HPA 自动水平扩展。
  • 将 JWT 验证和路由卸载到 API Gateway,因为协议本身无内置认证。
  • MCP 中缺少用户上下文,目前限制了细粒度授权和端到端审计。

— Editorial Team

Advertisement 728x90

继续阅读