TLS-Passthrough-Gateway bereitstellen

In diesem Dokument wird beschrieben, wie Sie eine Kubernetes-Gateway-Ressource bereitstellen, die für TLS-Passthrough konfiguriert ist, um SNI-basiertes Routing (Server Name Indication) in Google Kubernetes Engine (GKE) zu aktivieren. Bei diesem Ansatz bleiben die Ende-zu-Ende-Verschlüsselung und das gegenseitige TLS (mTLS) zwischen Clients und Backend-Pods erhalten, nicht-HTTP-TLS-basierte Protokolle werden unterstützt und IP-Adressen werden eingespart.

Dieses Dokument richtet sich an Cloud-Architekten, Netzwerkexperten und Entwickler, die verschlüsselte Netzwerke für containerisierte Arbeitslasten entwerfen, bereitstellen und verwalten. Weitere Informationen zu gängigen Rollen und Beispielaufgaben finden Sie unter Häufig verwendete GKE-Nutzerrollen und -Aufgaben.

Übersicht

Zusätzlich zu den HTTP- und HTTPS-Application Load Balancern der Ebene 7 unterstützt der GKE-Gateway-Controller Proxy-Network Load Balancer der Ebene 4 (TCP-Proxy-Load-Balancer), die mit TLS-Passthrough konfiguriert sind.

Beim TLS-Passthrough wird die TLS-Sitzung vom Load Balancer nicht beendet oder entschlüsselt. Wenn ein Client einen TLS-Handshake initiiert, prüft der Load Balancer stattdessen die unverschlüsselte ClientHello-Nachricht, um den SNI-Hostnamen (Server Name Indication) zu lesen. Basierend auf diesem SNI-Hostnamen leitet der Load Balancer den unverschlüsselten, verschlüsselten TCP-Stream an den entsprechenden Kubernetes-Backend-Dienst weiter, wo Ihre Anwendungs-Pods TLS direkt beenden.

Wenn Sie TLS-Passthrough mit der Gateway API verwenden, können Sie Folgendes tun:

  • Ende-zu-Ende-Verschlüsselung beibehalten und Zero-Trust-Compliance unterstützen: Der Traffic wird vom Client zum Backend-Pod vollständig verschlüsselt, ohne dass der Load Balancer Zugriff auf private Schlüssel oder Klartextdaten hat.
  • Gegenseitige TLS-Authentifizierung (mTLS) verwenden: Authentifizieren Sie Clients direkt auf der Backend-Anwendungsebene.
  • IPv4-Adressen sparen: Multiplexen Sie mehrere unabhängige TLS-Dienste über verschiedene Domains oder Subdomains hinweg, indem Sie eine einzige Gateway-IP-Adresse und einen einzigen Port (z. B. 443) verwenden.
  • Unterstützung von TLS-basierten Nicht-HTTP-Protokollen: Verschlüsselten Traffic für zustandsorientierte Arbeitslasten, Datenbanken, benutzerdefinierte gRPC-Dienste oder proprietäre Protokolle, die über TLS ausgeführt werden, weiterleiten.

Unterstützte GatewayClasses

Die folgenden GKE-GatewayClasses unterstützen TLS-Passthrough-Listener und TLSRoute-Ressourcen:

  • gke-l7-regional-external-managed
  • gke-l7-regional-external-managed-mc
  • gke-l7-rilb
  • gke-l7-rilb-mc
  • gke-l7-cross-regional-internal-managed-mc

Einen vollständigen Vergleich der GatewayClass-Funktionen finden Sie unter GatewayClass-Funktionen.

Hinweis

Führen Sie die folgenden Aufgaben aus, bevor Sie beginnen:

  • Aktivieren Sie die Google Kubernetes Engine API.
  • Google Kubernetes Engine API aktivieren
  • Wenn Sie die Google Cloud CLI für diese Aufgabe verwenden möchten, müssen Sie die gcloud CLI installieren und dann initialisieren. Wenn Sie die gcloud CLI bereits installiert haben, rufen Sie die aktuelle Version mit dem Befehl gcloud components update ab. Ältere gcloud CLI-Versionen unterstützen möglicherweise nicht die Ausführung der Befehle in diesem Dokument.
  • Prüfen Sie, ob Sie einen Autopilot- oder Standardcluster mit GKE-Version 1.35 oder höher und aktivierter Gateway API haben. Informationen zum Erstellen eines neuen Clusters finden Sie unter Autopilot-Cluster erstellen. Informationen zum Aktivieren der Gateway API in einem vorhandenen Cluster finden Sie unter Gateway API im Cluster aktivieren.
  • Prüfen Sie, ob das OpenSSL-Befehlszeilentool installiert ist. Mit diesem Tool generieren Sie selbst signierte TLS-Zertifikate für die Beispielanwendungen.

Anforderungen für GKE Gateway Controller

  • Die Gateway API wird nur in VPC-nativen Clustern unterstützt.
  • Wenn Sie die regionalen oder regionsübergreifenden GatewayClasses verwenden, müssen Sie ein Nur-Proxy-Subnetz aktivieren.
  • Für den Cluster muss das Add-on HttpLoadBalancing aktiviert sein.
  • Wenn Sie Istio verwenden, müssen Sie Istio auf eine der folgenden Versionen aktualisieren:
    • 1.15.2 oder höher
    • 1.14.5 oder höher
    • 1.13.9 oder höher
  • Wenn Sie eine gemeinsam genutzte VPC verwenden, müssen Sie dem GKE-Dienstkonto für das Dienstprojekt im Hostprojekt die Rolle Compute Network User zuweisen.

Limits und Einschränkungen

Beachten Sie beim Bereitstellen von TLS-Passthrough-Gateways und TLSRoute-Ressourcen die folgenden Einschränkungen:

  • Wenn Sie die Einstellung protocol: TLS für einen Listener konfigurieren, müssen Sie das Feld tls.mode explizit auf den Wert Passthrough festlegen. GKE unterstützt den Standardmodus Terminate für TLS-Listener nicht.
  • Legen Sie bei einem TLS-Listener das Feld certificateRefs nicht fest. Die Clientzertifikatsvalidierung auf Gateway-Ebene (Feld spec.tls.frontendValidation) gilt nicht für TLS-Listener. Wenn Sie mTLS verwenden möchten, müssen Sie Clientzertifikate in Ihrem Backend validieren.
  • Ein TLS-Listener kann einen Port nur mit anderen TLS-Listenern teilen. Sie können HTTP- oder HTTPS-Listener nicht auf demselben Port wie einen TLS-Listener konfigurieren.
  • Im Feld TLSRoute.spec.hostnames müssen Sie eine Liste mit 1 bis 1.024 SNI-Hostnamen (genauer Hostname oder Platzhalterpräfix, z. B. *.example.com) angeben. Jeder Eintrag darf maximal 253 Zeichen lang sein und darf keine IP-Adresse sein.
  • Im Feld TLSRoute.spec.rules können Sie maximal eine Regel konfigurieren.
  • Jede Regel unterstützt genau einen backendRef-Eintrag. Layer-4-Proxy-Backends unterstützen keine gewichtete Aufteilung des Traffics auf mehrere Backends.
  • Single-Cluster-GatewayClasses unterstützen nur Service-Backends und Multi-Cluster-GatewayClasses nur ServiceImport-Backends.
  • Legen Sie im Feld TLSRoute.spec.rules.backendRefs das Feld port auf einen Port fest, der von der Zielressource „Service“ oder „ServiceImport“ deklariert wurde, nicht auf den Containerport.
  • Der Kubernetes-Backend-Dienst (einschließlich als ServiceImport exportierter Dienste), auf den eine TLSRoute-Ressource verweist, muss den Wert TCP für sein Portprotokoll verwenden.
  • Sie können keine BackendTLSPolicy-Ressource, keinen Identity-Aware Proxy und keine Google Cloud Armor-Sicherheitsrichtlinie an ein TLSRoute-Backend anhängen, da der Controller Konfigurationen dieses Typs ablehnt.
  • Wenn Sie eine GCPBackendPolicy-Ressource an einen Service oder ServiceImport anhängen, auf den eine TLSRoute-Ressource verweist, müssen Sie das Feld spec.protocol auf den Wert TCP setzen. Wenn Sie das Feld spec.protocol weglassen, wird standardmäßig der Wert HTTP verwendet, der nur für HTTPRoute-Backends gilt. An einen Dienst oder ServiceImport können gleichzeitig eine HTTP-Richtlinie und eine TCP-Richtlinie angehängt werden. Wenn mehrere Richtlinien mit demselben spec.protocol-Wert auf denselben Dienst oder ServiceImport ausgerichtet sind, hat die älteste Richtlinie Vorrang und neuere Richtlinien werden nicht angehängt.
  • Eine GCPBackendPolicy-Ressource, bei der das Feld spec.protocol auf TCP festgelegt ist, unterstützt nur die folgenden Felder im Feld spec.default (wenn Sie eine ServiceImport-Ressource als Ziel verwenden, können Sie die letzten drei Felder stattdessen pro Cluster, Zone oder Region im Feld spec.default.scopes festlegen):

    • timeoutSec
    • connectionDraining
    • logging.enabled und logging.sampleRate
    • sessionAffinity.type (gültige Werte sind CLIENT_IP oder NONE)
    • capacityScalerPercent
    • balancingMode: CONNECTION
    • maxConnectionsPerEndpoint

    Sie können keine TCP-Richtlinie erstellen, die andere Felder enthält, oder eine HTTP-Richtlinie, die nur TCP-Felder (balancingMode: CONNECTION und maxConnectionsPerEndpoint) enthält. Der Kubernetes API-Server lehnt die Richtlinie bei der Erstellung ab. Weitere Informationen finden Sie unter Gateway-Ressourcen mithilfe von Richtlinien konfigurieren.

  • Wenn sowohl eine HTTPRoute- als auch eine TLSRoute-Ressource auf denselben Service oder ServiceImport verweisen, werden durch das Anhängen einer HealthCheckPolicy-Ressource an dieses Ziel die separaten Standard-Systemdiagnosen ersetzt und dieselbe Systemdiagnosekonfiguration auf die Backends beider Routen angewendet. Wenn Sie Systemdiagnosen unabhängig voneinander konfigurieren möchten (z. B. HTTP-Systemdiagnosen für HTTPRoute-Backends und SSL- oder TCP-Systemdiagnosen für TLSRoute-Backends), erstellen Sie für jede Route einen separaten Dienst und hängen Sie an jeden Dienst eine HealthCheckPolicy-Ressource an. Beide Dienste können dieselben Pods auswählen.

  • Layer-7-Features wie URL-Umschreibungen, pfadbasiertes Routing und HTTP-Header-Transformationen gelten nicht für Layer-4-TCP-Proxy-Load-Balancer.

Nur-Proxy-Subnetz konfigurieren

Ein regionales Gateway erfordert ein Nur-Proxy-Subnetz (purpose=REGIONAL_MANAGED_PROXY) in jeder Region, in der Sie es bereitstellen. Ein Nur-Proxy-Subnetz bedient alle regionalen Envoy-basierten Load Balancer in dieser Region. Wenn Ihre Region noch kein Nur-Proxy-Subnetz hat, finden Sie weitere Informationen unter Nur-Proxy-Subnetz konfigurieren.

Statische IP-Adresse reservieren

Reservieren Sie vor der Bereitstellung des Gateways eine regionale statische IP-Adresse, damit sich die Gateway-Adresse nicht ändert und Sie Ihre Beispiel-Hostnamen in diese auflösen können. Eine Anleitung zum Erstellen einer statischen IP-Adresse finden Sie unter Regionales externes HTTP(S)-Gateway erstellen.

Gateway mit TLS-Passthrough-Listenern bereitstellen

Das Gateway in diesem Abschnitt konfiguriert zwei TLS-Listener, die den Port 443 gemeinsam nutzen. Jeder Listener entspricht einem anderen SNI-Hostnamen und leitet Verbindungen im Passthrough-Modus an angehängte TLSRoute-Ressourcen weiter.

  1. Speichern Sie das folgende Manifest als store-gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-tls
    spec:
      gatewayClassName: gke-l7-regional-external-managed
      listeners:
      # Accept TLS connections for store.example.com without decrypting them.
      - name: store
        protocol: TLS
        port: 443
        hostname: "store.example.com"
        tls:
          mode: Passthrough
        allowedRoutes:
          kinds:
          - kind: TLSRoute
      # A second listener on the same port, selected by a different SNI name.
      - name: store-german
        protocol: TLS
        port: 443
        hostname: "store-de.example.com"
        tls:
          mode: Passthrough
        allowedRoutes:
          kinds:
          - kind: TLSRoute
      addresses:
      - type: NamedAddress
        value: IP_ADDRESS_NAME
    

    Ersetzen Sie IP_ADDRESS_NAME durch den Namen der statischen IP-Adresse, die Sie reserviert haben.

    Beachten Sie, dass der Block tls kein Feld certificateRefs hat. Im Passthrough-Modus befindet sich das TLS-Zertifikat in Ihren Backend-Pods und nicht auf dem Load Balancer.

  2. Wenden Sie das Gateway-Manifest an:

    kubectl apply -f store-gateway.yaml
    
  3. Prüfen Sie, ob das Gateway programmiert ist:

    kubectl get gateway store-tls
    

    Die Bereitstellung des Load Balancers dauert einige Minuten. Die Ausgabe sieht in etwa so aus:

    NAME        CLASS                              ADDRESS         PROGRAMMED   AGE
    store-tls   gke-l7-regional-external-managed   35.118.32.224   True         53s
    

Internes Gateway verwenden

Wenn Sie den Traffic in Ihrem VPC-Netzwerk belassen möchten, ändern Sie den Wert des Felds gatewayClassName in gke-l7-rilb und entfernen Sie das Feld addresses aus dem Gateway-Manifest. GKE erstellt dann einen regionalen internen Proxy-Network-Load-Balancer und weist eine interne IP-Adresse aus Ihrem Cluster-Subnetz zu. Die verbleibenden Schritte auf dieser Seite sind unverändert. Senden Sie Ihre Testanfragen von einer Compute Engine-Instanz im selben VPC-Netzwerk, da die interne IP-Adresse nicht über das Internet erreichbar ist.

TLS-Beispielanwendungen bereitstellen

In diesem Abschnitt stellen Sie zwei NGINX-Deployments (store-v1 und store-german) bereit, die TLS auf Port 8443 beenden. Jedes Deployment stellt ein anderes TLS-Zertifikat bereit und meldet den empfangenen SNI-Hostnamen. So können Sie prüfen, ob das Routing auf der Grundlage von SNI erfolgt ist.

  1. Generieren Sie für jeden Hostnamen ein selbst signiertes TLS-Zertifikat und einen privaten Schlüssel:

    openssl req -x509 -newkey rsa:2048 -nodes -sha256 -days 365 \
        -keyout store.key -out store.crt \
        -subj '/CN=store.example.com' \
        -addext 'subjectAltName=DNS:store.example.com'
    openssl req -x509 -newkey rsa:2048 -nodes -sha256 -days 365 \
        -keyout store-de.key -out store-de.crt \
        -subj '/CN=store-de.example.com' \
        -addext 'subjectAltName=DNS:store-de.example.com'
    

    Verwenden Sie in der Produktion Zertifikate Ihrer Zertifizierungsstelle. Selbst signierte Zertifikate sorgen dafür, dass dieses Beispiel eigenständig bleibt.

  2. Speichern Sie jedes Zertifikat und jeden Schlüssel in einem Kubernetes-Secret, indem Sie die folgenden Befehle ausführen:

    kubectl create secret tls store-cert \
        --cert=store.crt --key=store.key
    kubectl create secret tls store-de-cert \
        --cert=store-de.crt --key=store-de.key
    
  3. Speichern Sie das folgende Manifest als store-tls-app.yaml:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: store-nginx
    data:
      default.conf: |
        server {
          listen 8443 ssl;
          ssl_certificate     /etc/nginx/ssl/tls.crt;
          ssl_certificate_key /etc/nginx/ssl/tls.key;
          default_type text/plain;
          # Report which Pod answered and which SNI name it received.
          return 200 "backend: $hostname\nsni: $ssl_server_name\n";
        }
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: store-v1
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: store-v1
      template:
        metadata:
          labels:
            app: store-v1
        spec:
          containers:
          - name: nginx
            image: nginx:1.27
            ports:
            - containerPort: 8443
            volumeMounts:
            - name: config
              mountPath: /etc/nginx/conf.d
            - name: cert
              mountPath: /etc/nginx/ssl
              readOnly: true
          volumes:
          - name: config
            configMap:
              name: store-nginx
          - name: cert
            secret:
              secretName: store-cert
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: store-v1
    spec:
      selector:
        app: store-v1
      ports:
      - port: 443
        targetPort: 8443
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: store-german
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: store-german
      template:
        metadata:
          labels:
            app: store-german
        spec:
          containers:
          - name: nginx
            image: nginx:1.27
            ports:
            - containerPort: 8443
            volumeMounts:
            - name: config
              mountPath: /etc/nginx/conf.d
            - name: cert
              mountPath: /etc/nginx/ssl
              readOnly: true
          volumes:
          - name: config
            configMap:
              name: store-nginx
          - name: cert
            secret:
              secretName: store-de-cert
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: store-german
    spec:
      selector:
        app: store-german
      ports:
      - port: 443
        targetPort: 8443
    

    Die Dienste benötigen kein appProtocol-Feld. GKE leitet TLSRoute-Traffic als TCP an das Backend weiter, sodass das Feld keine Auswirkungen hat.

  4. Wenden Sie das Manifest auf Ihren Cluster an:

    kubectl apply -f store-tls-app.yaml
    
  5. Prüfen Sie, ob die Pods ausgeführt werden:

    kubectl get pods -l 'app in (store-v1,store-german)'
    

    Die Ausgabe sieht etwa so aus:

    NAME                            READY   STATUS    RESTARTS   AGE
    store-german-7d9f8c5b47-2xqkd   1/1     Running   0          41s
    store-german-7d9f8c5b47-h6tzn   1/1     Running   0          41s
    store-v1-6c4b9d8f65-kp8vr       1/1     Running   0          41s
    store-v1-6c4b9d8f65-wm2ls       1/1     Running   0          41s
    

TLSRoute-Ressourcen für SNI-basiertes Routing bereitstellen

Eine TLSRoute-Ressource wird an einen Gateway-Listener angehängt und leitet Verbindungen, die mit ihren Hostnamen übereinstimmen, an einen einzelnen Backend-Dienst weiter.

  1. Speichern Sie das folgende Manifest als store-tls-routes.yaml:

    kind: TLSRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store
    spec:
      parentRefs:
      - kind: Gateway
        name: store-tls
        sectionName: store
      hostnames:
      - "store.example.com"
      rules:
      - backendRefs:
        - name: store-v1
          port: 443
    ---
    kind: TLSRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-german
    spec:
      parentRefs:
      - kind: Gateway
        name: store-tls
        sectionName: store-german
      hostnames:
      - "store-de.example.com"
      rules:
      - backendRefs:
        - name: store-german
          port: 443
    

    Mit dem Feld sectionName wird der Ziel-Listener auf dem Gateway ausgewählt. Im Feld port wird der Dienstport (443) und nicht der Containerport angegeben.

  2. Wenden Sie das TLSRoute-Manifest an:

    kubectl apply -f store-tls-routes.yaml
    
  3. Prüfen Sie, ob der Gateway-Controller die Route akzeptiert hat:

    kubectl get tlsroute store -o yaml
    

    Das Feld status sieht in etwa so aus:

    status:
      parents:
      - controllerName: networking.gke.io/gateway
        parentRef:
          name: store-tls
          sectionName: store
        conditions:
        - type: ResolvedRefs
          status: "True"
          reason: ResolvedRefs
        - type: Accepted
          status: "True"
          reason: Accepted
        - type: Reconciled
          status: "True"
          reason: ReconciliationSucceeded
    

    Die Bedingung Reconciled ist eine GKE-spezifische Statusbedingung, die angibt, ob der Gateway-Controller die zugrunde liegendenGoogle Cloud -Ressourcen erstellt hat.

  4. Prüfen Sie, ob der Gateway-Listener die Route akzeptiert hat:

    kubectl get gateway store-tls -o yaml
    

    Jeder Eintrag im Feld status.listeners sieht in etwa so aus:

    - name: store
      supportedKinds:
      - group: gateway.networking.k8s.io
        kind: TLSRoute
      attachedRoutes: 1
      conditions:
      - type: ResolvedRefs
        status: "True"
        reason: ResolvedRefs
      - type: Accepted
        status: "True"
        reason: Accepted
      - type: Programmed
        status: "True"
        reason: Programmed
    

Traffic-Routing prüfen

GKE führt eine Systemdiagnose für ein TLS-Passthrough-Backend durch, indem ein TLS-Handshake mit ihm abgeschlossen wird. Es kann einige Minuten dauern, bis Ihre Pods die erste Systemdiagnose bestehen.

  1. Rufen Sie die Gateway-IP-Adresse ab:

    kubectl get gateway store-tls -o jsonpath='{.status.addresses[0].value}'
    
  2. Senden Sie eine Anfrage an jeden Hostnamen und ersetzen Sie dabei GATEWAY_IP durch die IP-Adresse aus dem vorherigen Schritt:

    curl --resolve store.example.com:443:GATEWAY_IP \
        --cacert store.crt https://store.example.com
    curl --resolve store-de.example.com:443:GATEWAY_IP \
        --cacert store-de.crt https://store-de.example.com
    

    In jeder Antwort wird der Pod genannt, der geantwortet hat, und der SNI-Hostname, der ihn erreicht hat:

    backend: store-v1-6c4b9d8f65-kp8vr
    sni: store.example.com
    backend: store-german-7d9f8c5b47-2xqkd
    sni: store-de.example.com
    

    Da für jede Anfrage eine andere Zertifizierungsstellendatei verwendet wurde und beide erfolgreich waren, hat jedes Backend sein eigenes Zertifikat bereitgestellt. Der Load Balancer hat die verschlüsselte Verbindung weitergeleitet, ohne sie zu beenden.

  3. Prüfen Sie, ob das Routing während des TLS-Handshakes erfolgt, bevor der Client eine HTTP-Anfrage sendet:

    openssl s_client -connect GATEWAY_IP:443 \
        -servername store-de.example.com </dev/null 2>/dev/null \
        | openssl x509 -noout -subject
    

    In der Ausgabe wird das Zertifikat des Back-Ends store-german angezeigt:

    subject=CN=store-de.example.com
    

    Wenn Sie nur den Wert des Flags -servername ändern, wird das zurückgegebene Zertifikat geändert. Dadurch wird bestätigt, dass der Load Balancer das Backend nur anhand von SNI ausgewählt hat.

  4. Senden Sie eine Anfrage mit einem SNI-Hostnamen, der mit keinem Listener übereinstimmt:

    curl --resolve other.example.com:443:GATEWAY_IP \
        https://other.example.com
    

    Die Verbindung wird geschlossen, weil kein Listener auf Port 443 mit dem SNI-Hostnamen other.example.com übereinstimmt.

Backend-Verbindungskapazität konfigurieren

Für GKE-Dienste, auf die von TLSRoute-Ressourcen verwiesen wird, konfiguriert der GKE-Gateway-Controller einen TCP-Backend-Dienst mit dem Balancing-Modus CONNECTION und legt den Standardwert des Felds maxConnectionsPerEndpoint auf 100,000,000 (1e8) fest.

Da der Gateway-Controller das Limit für gleichzeitige Verbindungen eines Containers nicht automatisch ermitteln kann, können Sie mit einer GCPBackendPolicy-Ressource den Standardwert des Felds maxConnectionsPerEndpoint (von 1 auf 1,000,000,000) überschreiben. Berücksichtigen Sie Folgendes, um das optimale Verbindungslimit für Ihre Backend-Pods zu ermitteln:

  • Softwarelimits: Prüfen Sie die Server- oder Anwendungskonfiguration, z. B. die Apache-Anweisung MaxRequestWorkers, die NGINX-Einstellungen worker_processes * worker_connections, das Tomcat-Attribut maxConnections oder die Limits für den Datenbankverbindungspool.
  • Lasttests: Erhöhen Sie schrittweise die Anzahl gleichzeitiger Verbindungen zu einem isolierten Pod, während Sie CPU, Arbeitsspeicher, Latenz und Socket- oder Dateideskriptorlimits überwachen.

Benutzerdefinierte GCPBackendPolicy anwenden

Wenn Sie den Standardwert des Felds maxConnectionsPerEndpoint für einen TLSRoute-Backend-Dienst überschreiben möchten, hängen Sie eine GCPBackendPolicy-Ressource an, wobei das Feld spec.protocol auf TCP und das Feld balancingMode auf CONNECTION gesetzt ist:

  1. Speichern Sie das folgende Manifest als backend-policy.yaml:

    apiVersion: networking.gke.io/v1
    kind: GCPBackendPolicy
    metadata:
      name: store-v1-backend-policy
    spec:
      protocol: TCP
      default:
        balancingMode: CONNECTION
        maxConnectionsPerEndpoint: 1000
      targetRef:
        group: ""
        kind: Service
        name: store-v1
    
  2. Wenden Sie die Richtlinie an:

    kubectl apply -f backend-policy.yaml
    

Weitere Informationen zum Konfigurieren von Backend-Richtlinien finden Sie unter Gateway-Ressourcen mithilfe von Richtlinien konfigurieren.

Systemdiagnosen für TLS-Passthrough konfigurieren

Standardmäßig stellt der GKE-Gateway-Controller für Backend-Dienste, die mit TLS-Passthrough-TLSRoute-Ressourcen verknüpft sind, automatisch eine Systemdiagnose vom Typ SSL bereit.

Fehlen von SNI-Erweiterungen von Probern verarbeiten

Wenn Sie Systemdiagnosen für TLS-Passthrough-Back-Ends konfigurieren, müssen Sie berücksichtigen, wie die Google Cloud -Systemdiagnose-Prober mit TLS-Endpunkten interagieren.

Wenn Ihre Backend-Anwendungen einen gültigen SNI-Hostnamen benötigen, um einen TLS-Handshake abzuschließen, schlagen die Standard-SSL-Systemdiagnosen fehl. Verwenden Sie einen der folgenden Ansätze, um dieses Problem zu beheben:

  • Fallback-Zertifikate konfigurieren: Konfigurieren Sie Ihren Backend-Server oder Pod so, dass ein Standard-Fallback-TLS-Zertifikat bereitgestellt wird, wenn eine TLS-Verbindung ohne SNI-Erweiterung eingeht.
  • TCP-Systemdiagnosen mit HealthCheckPolicy verwenden: Hängen Sie eine HealthCheckPolicy-Ressource (mit dem Feld config.type auf TCP gesetzt) an Ihren Dienst an, um die TCP-Port-Konnektivität zu prüfen und den TLS-Handshake zu vermeiden.

Benutzerdefinierte HealthCheckPolicy anwenden

Wenn Sie benutzerdefinierte Systemdiagnoseparameter konfigurieren oder zur TCP-Systemdiagnose wechseln möchten, verwenden Sie eine HealthCheckPolicy-Ressource:

  1. Speichern Sie das folgende Manifest als health-check-policy.yaml:

    apiVersion: networking.gke.io/v1
    kind: HealthCheckPolicy
    metadata:
      name: store-health-check
    spec:
      default:
        checkIntervalSec: 10
        timeoutSec: 5
        healthyThreshold: 2
        unhealthyThreshold: 3
        config:
          type: TCP
          tcpHealthCheck:
            port: 8443
      targetRef:
        group: ""
        kind: Service
        name: store-service
    
  2. Wenden Sie die Richtlinie an:

    kubectl apply -f health-check-policy.yaml
    

Weitere Informationen zum Konfigurieren von Systemdiagnosen finden Sie unter Gateway-Ressourcen mithilfe von Richtlinien konfigurieren.

Erweiterte Konfigurationen

In diesem Abschnitt werden erweiterte Routingmuster, mehrmandantenfähige Konfigurationen und Multi-Cluster-Bereitstellungen beschrieben, die mit TLS-Passthrough-Gateways und TLSRoute-Ressourcen unterstützt werden.

Platzhalterbasierter Hostnamenabgleich

TLSRoute-Ressourcen unterstützen den Platzhalter-Präfixabgleich für Hostnamen und folgen deterministischen Rangfolgeregeln, wenn mehrere Routen mit demselben eingehenden Traffic übereinstimmen.

Speichern Sie das folgende Manifest, um eine Platzhalter-TLSRoute zu definieren:

apiVersion: gateway.networking.k8s.io/v1
kind: TLSRoute
metadata:
  name: wildcard-tls-route
spec:
  parentRefs:
  - name: store-tls
    sectionName: store
  hostnames:
  - "*.example.com"
  rules:
  - backendRefs:
    - name: store-v1
      port: 443

Regeln für Rangfolge und Konfliktlösung

Wenn mehrere TLSRoute-Ressourcen an denselben Gateway-Listener angehängt sind und sich überschneidende oder identische Hostnamen beanspruchen, löst der GKE-Gateway-Controller Konflikte mit denselben Hostnamenspezifitäts- und Erstellungszeitstempelregeln wie andere Gateway-Routen:

  • Genaue Hostnamenübereinstimmungen (z. B. store.example.com) haben Vorrang vor Platzhalterübereinstimmungen (z. B. *.example.com) und längere Platzhalterübereinstimmungen haben Vorrang vor allgemeineren Platzhalterübereinstimmungen (z. B. *.com).
  • Wenn zwei oder mehr TLSRoute-Ressourcen genau denselben Hostnamen deklarieren, hat die Route mit dem ältesten Erstellungszeitstempel (metadata.creationTimestamp) Vorrang. Wenn die Zeitstempel der Erstellung übereinstimmen, wird die lexikografisch kleinere <namespace>/<name>-ID verwendet. Der Gateway-Controller akzeptiert keine in Konflikt stehenden Routen, die eine Accepted: False-Bedingung mit dem Grund Conflicted melden.

Weitere Informationen zur Routenpriorität finden Sie unter Zusammenführung, Priorisierung und Validierung von Routen.

Namespace-übergreifendes Routing mit ReferenceGrant

In Mehrmandanten-Umgebungen kann ein zentrales Plattformteam das Gateway in einem Infrastruktur-Namespace (z. B. gateway-infra) verwalten, während Anwendungsteams TLSRoute- und Service-Ressourcen in Entwickler-Namespaces (z. B. store-ns) verwalten.

  1. Lassen Sie im Gateway-Listener Routen aus allen Namespaces (oder ausgewählten Namespaces) zu:

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: shared-tls-gateway
      namespace: gateway-infra
    spec:
      gatewayClassName: gke-l7-regional-external-managed
      listeners:
      - name: tls-passthrough
        protocol: TLS
        port: 443
        tls:
          mode: Passthrough
        allowedRoutes:
          namespaces:
            from: All
          kinds:
          - kind: TLSRoute
    
  2. Erstellen Sie im Anwendungs-Namespace (store-ns) eine ReferenceGrant-Ressource, die es dem Gateway im Namespace gateway-infra ermöglicht, auf die TLSRoute- oder Service-Ressource zu verweisen:

    apiVersion: gateway.networking.k8s.io/v1beta1
    kind: ReferenceGrant
    metadata:
      name: allow-gateway-infra
      namespace: store-ns
    spec:
      from:
      - group: gateway.networking.k8s.io
        kind: Gateway
        namespace: gateway-infra
      to:
      - group: ""
        kind: Service
    
  3. Erstellen Sie im Anwendungs-Namespace (store-ns) die TLSRoute-Ressource, die auf das freigegebene Gateway verweist:

    apiVersion: gateway.networking.k8s.io/v1
    kind: TLSRoute
    metadata:
      name: store-tls-route
      namespace: store-ns
    spec:
      parentRefs:
      - name: shared-tls-gateway
        namespace: gateway-infra
        sectionName: tls-passthrough
      hostnames:
      - "store.example.com"
      rules:
      - backendRefs:
        - name: store-service
          port: 443
    

Multi-Cluster-TLS-Passthrough-Gateway

Sie können Multi-Cluster-Gateways mit TLS-Passthrough in mehreren GKE-Clustern in einer Flotte bereitstellen:

  1. Verwenden Sie eine unterstützte Multi-Cluster-GatewayClass (gke-l7-regional-external-managed-mc, gke-l7-rilb-mc oder gke-l7-cross-regional-internal-managed-mc).
  2. Exportieren Sie Ihren Backend-Dienst mit einer ServiceExport-Ressource in die Flotte.
  3. Verweisen Sie in Ihrer TLSRoute-Ressource mit einer ServiceImport-Ressource auf das Multi-Cluster-Backend:

    apiVersion: gateway.networking.k8s.io/v1
    kind: TLSRoute
    metadata:
      name: mc-store-tls-route
    spec:
      parentRefs:
      - name: mc-tls-gateway
        sectionName: tls-passthrough
      hostnames:
      - "store.example.com"
      rules:
      - backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          name: store-service
          port: 443
    

Mehrere IP-Adressen in Multi-Cluster-Gateways

Wenn Sie regionenübergreifende Multi-Cluster-Gateways bereitstellen (z. B. bei Verwendung der GatewayClass gke-l7-cross-regional-internal-managed-mc), können Sie im Feld spec.addresses mehrere IP-Adressen definieren, um eine interne VIP in verschiedenen Regionen bereitzustellen.

Wenn Sie mehrere IP-Adressen in einem einzelnen Gateway konfigurieren, übersetzt der GKE-Gateway-Controller jede IP-Adresse in eine separate Weiterleitungsregel. Gleichzeitig verweist der Controller auf einen freigegebenen Ziel-Proxy und verwendet dieselbe zugrunde liegende Routingkonfiguration wieder. Der Controller multipliziert die zugrunde liegenden TLSRoute-Ressourcen nicht mit der Anzahl der IP-Adressen. Dadurch werden Routenduplizierungen und die Erschöpfung von Kontingenten verhindert.

Das folgende Beispiel zeigt ein Multi-Cluster-Gateway, das mit sitzungsspezifischen IP-Adressen in zwei Regionen konfiguriert ist:

kind: Gateway
apiVersion: gateway.networking.k8s.io/v1
metadata:
  name: internal-cross-region-tls-gateway
spec:
  gatewayClassName: gke-l7-cross-regional-internal-managed-mc
  addresses:
  - type: networking.gke.io/ephemeral-ipv4-address/us-west1
    value: "us-west1"
  - type: networking.gke.io/ephemeral-ipv4-address/us-east1
    value: "us-east1"
  listeners:
  - name: tls-passthrough
    protocol: TLS
    port: 443
    tls:
      mode: Passthrough
    allowedRoutes:
      kinds:
      - kind: TLSRoute

Weitere Informationen zum Bereitstellen interner Multi-Cluster-Gateways finden Sie unter Internes Multi-Cluster-Gateway bereitstellen.

HTTP-Verbindungszusammenführung

Gemäß RFC 7540 (Abschnitt 9.1.1) können Webbrowser und HTTP/2-Clients eine hergestellte TLS-Verbindung für mehrere Anfragen wiederverwenden, wenn beide der folgenden Bedingungen erfüllt sind:

  • Die Zielhostnamen werden in dieselbe IP-Adresse aufgelöst.
  • Das vom Server bereitgestellte TLS-Zertifikat ist für beide Hostnamen maßgeblich. Ein Zertifikat kann beispielsweise mehrere Hostnamen abdecken, wenn Sie Platzhalterzertifikate wie *.example.com oder SANs (Subject Alternative Names) für mehrere Domains verwenden.

Da ein Layer-4-TCP-Proxy-Load-Balancer HTTP-Anfrageheader nach dem ersten TLS-Handshake nicht prüft, leitet der Load-Balancer zusammengeführte Anfragen über die vorhandene Verbindung an den ursprünglich übereinstimmenden Backend-Pod weiter.

So vermeiden Sie Probleme mit der Verbindungszusammenführung:

  • Verwenden Sie eindeutige, sich nicht überschneidende TLS-Zertifikate: Teilen Sie keine Platzhalterzertifikate oder gemeinsamen SAN-Identitäten über verschiedene Backend-Dienste, die hinter derselben Gateway-IP-Adresse gemultiplext werden.
  • HTTP 421 Misdirected Request zurückgeben: Konfigurieren Sie Ihre Backend-HTTPS-Server so, dass der HTTP-Header :authority (oder Host) geprüft wird. Wenn der angeforderte Host nicht mit der erwarteten Domain des Servers übereinstimmt, wird der Statuscode HTTP 421 Misdirected Request zurückgegeben, der den Client auffordert, eine neue Verbindung zu öffnen.
  • HTTP/2-ORIGIN-Frame aktivieren: Übernehmen Sie die RFC 8336-ORIGIN-Frame-Unterstützung auf Ihren Ursprungsservern und deklarieren Sie explizit, welche Hostnamen für die Wiederverwendung von Verbindungen gültig sind.

Bereinigen

Löschen Sie die Ressourcen, damit Ihrem Google Cloud -Konto die auf dieser Seite verwendeten Ressourcen nicht in Rechnung gestellt werden:

  1. Löschen Sie die TLSRoute-Ressourcen:

    kubectl delete tlsroute store store-german
    
  2. Löschen Sie die Gateway-Ressource:

    kubectl delete gateway store-tls
    
  3. Löschen Sie die Beispielressourcen für Deployment, Service und Secret:

    kubectl delete -f store-tls-app.yaml
    kubectl delete secret store-cert store-de-cert
    

Nächste Schritte