Volver al inicio

Desplegar servidores MCP en Kubernetes: Arquitectura y JWT

El artículo describe la migración de servidores MCP desde el lanzamiento local a la infraestructura centralizada en Kubernetes. Cubre patrones de proxying sidecar, configuración de autenticación JWT vía Envoy y gestión de secretos usando Vault.

Cómo desplegar servidores MCP en Kubernetes para todo el equipo
Advertisement 728x90

Despliegue centralizado de servidores MCP en Kubernetes: Arquitectura, autenticación y gestión de secretos

Ejecutar servidores MCP localmente mediante gestores de paquetes o contenedores se convierte rápidamente en un cuello de botella al escalar la infraestructura de IA en un equipo. Entornos de ejecución fragmentados, la dispersión incontrolada de credenciales y la falta de un único punto de entrada obstaculizan la integración segura de modelos de lenguaje en el entorno empresarial. Este artículo describe un camino práctico de migración desde instancias aisladas hasta una arquitectura centralizada en Kubernetes utilizando proxy de sidecar, validación JWT y orquestación de secretos.

Evolución de la arquitectura: De procesos locales a contenedorización

En la etapa inicial de adopción del Protocolo de Contexto de Modelo, usar endpoints remotos listos de los proveedores es suficiente. La configuración simplemente implica especificar una URL en la app del cliente, con el proveedor manejando la autenticación y el escalado. Sin embargo, integrar sistemas internos (Kubernetes, Grafana, bases de datos) requiere ejecutar servidores de forma independiente.

El enfoque estándar con llamadas locales a npx, uvx o binarios compilados genera dolores de cabeza en la gestión de dependencias. Cada integración necesita su propio entorno de ejecución, lo que lleva a conflictos de versiones y complica la incorporación de nuevos miembros del equipo. Almacenar tokens de acceso de producción en archivos de configuración locales también viola los principios básicos de seguridad de la información.

Google AdInline article slot

La contenedorización resuelve el aislamiento de entornos. Ejecutar cada servidor MCP en su propio contenedor con paso de variables de entorno estandariza el despliegue a nivel de estación de trabajo. Ejemplo de configuración para lanzamiento aislado:

{
  "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>"
      }
    }
  }
}

A pesar de un mejor aislamiento, Docker local no permite acceso compartido. Pipelines automatizados, sistemas CI/CD y usuarios no técnicos no pueden trabajar de forma efectiva con contenedores dispersos. Esto crea la necesidad de migrar servidores MCP a infraestructura compartida con gestión centralizada del ciclo de vida.

Orquestación en Kubernetes: Proxying y despliegue universal

Migrar servidores MCP a un clúster requiere puente entre desajustes arquitectónicos: la mayoría de servidores usan stdio, mientras que la red de Kubernetes se basa en HTTP/HTTPS. El patrón sidecar con MCP Gateway llena este vacío. El contenedor proxy maneja solicitudes HTTP entrantes (Streamable HTTP o SSE), las reenvía al stdin del proceso objetivo y retransmite las respuestas por la red.

Google AdInline article slot

Dado que los servidores MCP en modo Streamable HTTP son servicios sin estado, son perfectos para escalado horizontal mediante HPA. Para evitar duplicar manifiestos por integración, usa un chart Helm universal que soporta dos modos:

  • proxy — lanzamiento de contenedor sidecar para traducción HTTP-to-stdio.
  • native — exposición directa de servicios que ya soportan transporte HTTP.

La configuración de despliegue vía values.yaml ofrece control flexible sobre red, inyección de secretos y enrutamiento:

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"

La integración con HashiCorp Vault o External Secrets Operator mantiene las credenciales fuera del control de versiones. Controladores Ingress o Gateway API gestionan el enrutamiento, mientras que desactivar el buffering y extender los tiempos de espera aseguran soporte adecuado para conexiones de larga duración y datos en streaming.

Google AdInline article slot

Seguridad y autenticación: JWT, Envoy y gestión de acceso

El protocolo MCP carece de autenticación integrada, por lo que la protección debe implementarse en la puerta de entrada de la infraestructura. La autenticación básica se queda corta para la seguridad empresarial, haciendo de la validación JWT vía Envoy Gateway la mejor opción. La puerta de entrada verifica la firma del token, emisor y audiencia antes de que las solicitudes lleguen al pod del servidor MCP.

La generación de claves y tokens usa herramientas crypto estándar. La clave pública se empaqueta como JWKS en un ConfigMap para que Envoy la cargue y verifique:

# Generate RSA keys and form 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}"

En esta etapa de madurez del protocolo, persisten limitaciones arquitectónicas. El acceso a sistemas objetivo usa cuentas de servicio compartidas —bien para lecturas, riesgoso para escrituras. La falta de transmisión de contexto de usuario final bloquea autorización por usuario y auditoría detallada de llamadas a herramientas. El logging de Envoy captura solo metadatos de red, no parámetros específicos de métodos MCP.

Lecciones clave

  • Los lanzamientos locales de servidores MCP no escalan a nivel de equipo debido a conflictos de entornos de ejecución y riesgos de fugas de credenciales.
  • El patrón sidecar con MCP Gateway puentea el transporte stdio y los protocolos de red de Kubernetes.
  • La arquitectura Streamable HTTP sin estado soporta HPA estándar para escalado horizontal automático.
  • Delega la validación JWT y enrutamiento a API Gateway, ya que el protocolo no tiene autenticación nativa.
  • La falta de contexto de usuario en MCP limita la autorización granular y la auditoría de extremo a extremo por ahora.

— Editorial Team

Advertisement 728x90

Leer después