Retour à l'accueil

Déployer des serveurs MCP dans Kubernetes : Architecture et JWT

L'article décrit la migration des serveurs MCP du lancement local vers une infrastructure centralisée dans Kubernetes. Il couvre les motifs de proxying sidecar, la configuration de l'authentification JWT via Envoy et la gestion des secrets à l'aide de Vault.

Comment déployer des serveurs MCP dans Kubernetes pour toute l'équipe
Advertisement 728x90

Déploiement centralisé des serveurs MCP dans Kubernetes : Architecture, authentification et gestion des secrets

L'exécution de serveurs MCP localement via des gestionnaires de paquets ou des conteneurs devient rapidement un goulot d'étranglement lors de la mise à l'échelle de l'infrastructure IA à travers une équipe. Des environnements d'exécution fragmentés, une propagation incontrôlée des identifiants et l'absence d'un point d'entrée unique entravent l'intégration sécurisée des modèles de langage dans l'environnement d'entreprise. Cet article décrit un chemin de migration pratique des instances isolées vers une architecture Kubernetes centralisée utilisant un proxy sidecar, la validation JWT et l'orchestration des secrets.

Évolution de l'architecture : Des processus locaux à la conteneurisation

Au stade initial d'adoption du Model Context Protocol, l'utilisation d'endpoints distants prêts à l'emploi fournis par les éditeurs suffit. La configuration se limite simplement à spécifier une URL dans l'application cliente, le fournisseur gérant l'authentification et la mise à l'échelle. Cependant, l'intégration de systèmes internes (Kubernetes, Grafana, bases de données) nécessite de lancer les serveurs de manière indépendante.

L'approche standard avec des appels npx, uvx locaux ou des binaires compilés crée des maux de tête en gestion de dépendances. Chaque intégration requiert son propre environnement d'exécution, entraînant des conflits de versions et compliquant l'intégration des nouveaux membres de l'équipe. Stocker les jetons d'accès à la production dans des fichiers de configuration locaux viole également les principes fondamentaux de la sécurité de l'information.

Google AdInline article slot

La conteneurisation résout l'isolation des environnements. Lancer chaque serveur MCP dans son propre conteneur avec transmission des variables d'environnement standardise le déploiement au niveau de la station de travail. Exemple de configuration pour un lancement isolé :

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

Malgré une meilleure isolation, Docker local ne permet pas un accès partagé. Les pipelines automatisés, les systèmes CI/CD et les utilisateurs non techniques ne peuvent pas travailler efficacement avec des conteneurs dispersés. Cela crée un besoin de migrer les serveurs MCP vers une infrastructure partagée avec une gestion centralisée du cycle de vie.

Orchestration dans Kubernetes : Proxying et déploiement universel

La migration des serveurs MCP vers un cluster nécessite de combler les incompatibilités architecturales : la plupart des serveurs utilisent stdio, tandis que le réseau Kubernetes repose sur HTTP/HTTPS. Le motif sidecar avec MCP Gateway comble cette lacune. Le conteneur proxy gère les requêtes HTTP entrantes (Streamable HTTP ou SSE), les transmet vers stdin du processus cible et relaie les réponses via le réseau.

Google AdInline article slot

Puisque les serveurs MCP en mode Streamable HTTP sont des services sans état, ils sont parfaits pour une mise à l'échelle horizontale via HPA. Pour éviter de dupliquer les manifestes par intégration, utilisez un chart Helm universel supportant deux modes :

  • proxy — lancement de conteneur sidecar pour la traduction HTTP vers stdio.
  • native — exposition directe des services supportant déjà le transport HTTP.

La configuration de déploiement via values.yaml offre un contrôle flexible sur le réseau, l'injection de secrets et le routage :

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"

L'intégration avec HashiCorp Vault ou External Secrets Operator maintient les identifiants hors du contrôle de version. Les contrôleurs Ingress ou Gateway API gèrent le routage, tandis que la désactivation du tamponnage et l'extension des délais d'attente assurent un support approprié pour les connexions longues et les données en streaming.

Google AdInline article slot

Sécurité et authentification : JWT, Envoy et gestion des accès

Le protocole MCP manque d'authentification intégrée, la protection doit donc être implémentée au niveau de la passerelle d'infrastructure. L'authentification basique est insuffisante pour la sécurité d'entreprise, rendant la validation JWT via Envoy Gateway la meilleure option. La passerelle vérifie la signature du jeton, l'émetteur et le public avant que les requêtes n'atteignent le pod du serveur MCP.

La génération de clés et de jetons utilise des outils crypto standards. La clé publique est packagée sous forme de JWKS dans un ConfigMap pour qu'Envoy la charge et la vérifie :

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

À ce stade de maturité du protocole, des limitations architecturales persistent. L'accès aux systèmes cibles utilise des comptes de service partagés — acceptable pour les lectures, risqué pour les écritures. L'absence de transmission de contexte utilisateur bloque l'autorisation par utilisateur et l'audit détaillé des appels d'outils. Les logs Envoy ne capturent que les métadonnées réseau, pas les paramètres spécifiques des méthodes MCP.

Points clés

  • Les lancements locaux de serveurs MCP ne s'étendent pas à l'échelle d'une équipe en raison des conflits d'environnements d'exécution et des risques de fuite d'identifiants.
  • Le motif sidecar avec MCP Gateway relie le transport stdio et les protocoles réseau Kubernetes.
  • L'architecture Streamable HTTP sans état supporte HPA standard pour une mise à l'échelle horizontale automatique.
  • Déléguez la validation JWT et le routage à une API Gateway, car le protocole n'a pas d'authentification native.
  • L'absence de contexte utilisateur dans MCP limite l'autorisation granulaire et l'audit de bout en bout pour l'instant.

— Editorial Team

Advertisement 728x90

Lire ensuite