Zurück zur Startseite

MCP-Server in Kubernetes bereitstellen: Architektur und JWT

Der Artikel beschreibt die Migration von MCP-Servern von lokalem Start zu zentralisierter Infrastruktur in Kubernetes. Er behandelt Sidecar-Proxying-Muster, JWT-Authentifizierungseinrichtung via Envoy und Secrets-Management mit Vault.

MCP-Server in Kubernetes für das gesamte Team bereitstellen
Advertisement 728x90

Zentrale Bereitstellung von MCP-Servern in Kubernetes: Architektur, Authentifizierung und Secret-Management

Das lokale Ausführen von MCP-Servern über Paketmanager oder Container wird schnell zu einem Engpass, wenn KI-Infrastruktur teamweit skaliert wird. Fragmentierte Laufzeiten, unkontrollierte Ausbreitung von Anmeldeinformationen und das Fehlen eines einheitlichen Einstiegspunkts erschweren die sichere Integration von Sprachmodellen in die Unternehmensumgebung. Dieser Artikel beschreibt einen praktischen Migrationsweg von isolierten Instanzen zu einer zentralisierten Kubernetes-Architektur mit Sidecar-Proxying, JWT-Validierung und Secret-Orchestrierung.

Architekturentwicklung: Von lokalen Prozessen zur Containerisierung

In der anfänglichen Phase der Einführung des Model Context Protocol reichen fertige Remote-Endpunkte von Anbietern aus. Die Konfiguration beschränkt sich darauf, eine URL in der Client-App anzugeben, wobei der Anbieter Authentifizierung und Skalierung übernimmt. Die Integration interner Systeme (Kubernetes, Grafana, Datenbanken) erfordert jedoch eigenständig laufende Server.

Der Standardansatz mit lokalen npx- oder uvx-Aufrufen oder kompilierten Binaries führt zu Kopfschmerzen bei der Abhängigkeitsverwaltung. Jede Integration benötigt eine eigene Laufzeitumgebung, was zu Versionskonflikten führt und das Onboarding neuer Teammitglieder erschwert. Die Speicherung von Produktionszugangstokens in lokalen Konfigurationsdateien verstößt zudem gegen grundlegende Prinzipien der Informationssicherheit.

Google AdInline article slot

Die Containerisierung löst Umgebungsisolierung. Das Ausführen jedes MCP-Servers in einem eigenen Container mit Durchreichen von Umgebungsvariablen standardisiert die Bereitstellung auf Workstation-Ebene. Beispielkonfiguration für isolierten Start:

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

Trotz besserer Isolierung ermöglicht lokales Docker keinen geteilten Zugriff. Automatisierte Pipelines, CI/CD-Systeme und nicht-technische Nutzer können nicht effektiv mit verteilten Containern arbeiten. Dies schafft den Bedarf, MCP-Server auf gemeinsame Infrastruktur mit zentraler Lebenszyklusverwaltung zu migrieren.

Orchestrierung in Kubernetes: Proxying und universelle Bereitstellung

Die Migration von MCP-Servern in einen Cluster erfordert die Überbrückung architektureller Unterschiede: Die meisten Server nutzen stdio, während Kubernetes-Netzwerk auf HTTP/HTTPS basiert. Das Sidecar-Muster mit MCP Gateway schließt diese Lücke. Der Proxy-Container bearbeitet eingehende HTTP-Anfragen (Streamable HTTP oder SSE), leitet sie an den stdin des Zielprozesses weiter und gibt Antworten über das Netzwerk zurück.

Google AdInline article slot

Da MCP-Server im Streamable-HTTP-Modus stateless sind, eignen sie sich ideal für horizontale Skalierung via HPA. Um Manifeste pro Integration nicht zu duplizieren, verwendet man ein universelles Helm-Chart mit zwei Modi:

  • proxy — Sidecar-Container-Start für HTTP-to-stdio-Übersetzung.
  • native — Direkte Freigabe von Diensten, die HTTP-Transport unterstützen.

Die Bereitstellungskonfiguration via values.yaml bietet flexible Kontrolle über Netzwerk, Secret-Injection und Routing:

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"

Die Integration mit HashiCorp Vault oder External Secrets Operator hält Anmeldeinformationen außerhalb der Versionskontrolle. Ingress-Controller oder Gateway API verwalten das Routing, während das Deaktivieren des Buffering und das Verlängern der Timeouts eine ordnungsgemäße Unterstützung für langlebige Verbindungen und Streaming-Daten gewährleisten.

Google AdInline article slot

Sicherheit und Authentifizierung: JWT, Envoy und Zugriffsverwaltung

Das MCP-Protokoll verfügt über keine integrierte Authentifizierung, daher muss der Schutz auf Gateway-Ebene der Infrastruktur implementiert werden. Basic Auth reicht für Unternehmenssicherheit nicht aus, weshalb JWT-Validierung via Envoy Gateway die beste Option ist. Das Gateway prüft Token-Signatur, Issuer und Audience, bevor Anfragen den MCP-Server-Pod erreichen.

Schlüssel- und Token-Generierung erfolgt mit Standard-Crypto-Tools. Der öffentliche Schlüssel wird als JWKS in einem ConfigMap für Envoy gepackt, um ihn zu laden und zu verifizieren:

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

In dieser Reifegradstufe des Protokolls bestehen architekturelle Einschränkungen. Der Zugriff auf Zielsyteme erfolgt über geteilte Service Accounts – gut für Lesezugriffe, riskant für Schreibzugriffe. Die fehlende Übertragung von Endnutzerkontext verhindert nutzergranulare Autorisierung und detaillierte Audits von Tool-Aufrufen. Envoy-Logging erfasst nur Netzwerkmetadaten, keine spezifischen MCP-Methodenparameter.

Wichtige Erkenntnisse

  • Lokale MCP-Server-Starts skalieren nicht teamweit aufgrund von Laufzeitkonflikten und Risiken der Credential-Lecks.
  • Sidecar-Muster mit MCP Gateway überbrückt stdio-Transport und Kubernetes-Netzwerkprotokolle.
  • Stateless Streamable-HTTP-Architektur unterstützt standardmäßiges HPA für automatische horizontale Skalierung.
  • JWT-Validierung und Routing an API Gateway auslagern, da das Protokoll keine native Auth hat.
  • Fehlender Nutzerkontext in MCP begrenzt derzeit granulare Autorisierung und End-to-End-Audits.

— Editorial Team

Advertisement 728x90

Weiterlesen