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-managedgke-l7-regional-external-managed-mcgke-l7-rilbgke-l7-rilb-mcgke-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 updateab. Ä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
HttpLoadBalancingaktiviert 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 Userzuweisen.
Limits und Einschränkungen
Beachten Sie beim Bereitstellen von TLS-Passthrough-Gateways und TLSRoute-Ressourcen die folgenden Einschränkungen:
- Wenn Sie die Einstellung
protocol: TLSfür einen Listener konfigurieren, müssen Sie das Feldtls.modeexplizit auf den WertPassthroughfestlegen. GKE unterstützt den StandardmodusTerminatefürTLS-Listener nicht. - Legen Sie bei einem
TLS-Listener das FeldcertificateRefsnicht fest. Die Clientzertifikatsvalidierung auf Gateway-Ebene (Feldspec.tls.frontendValidation) gilt nicht fürTLS-Listener. Wenn Sie mTLS verwenden möchten, müssen Sie Clientzertifikate in Ihrem Backend validieren. - Ein
TLS-Listener kann einen Port nur mit anderenTLS-Listenern teilen. Sie könnenHTTP- oderHTTPS-Listener nicht auf demselben Port wie einenTLS-Listener konfigurieren. - Im Feld
TLSRoute.spec.hostnamesmü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.ruleskö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.backendRefsdas Feldportauf 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
TCPfü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.protocolauf den WertTCPsetzen. Wenn Sie das Feldspec.protocolweglassen, wird standardmäßig der WertHTTPverwendet, der nur für HTTPRoute-Backends gilt. An einen Dienst oder ServiceImport können gleichzeitig eineHTTP-Richtlinie und eineTCP-Richtlinie angehängt werden. Wenn mehrere Richtlinien mit demselbenspec.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.protocolaufTCPfestgelegt ist, unterstützt nur die folgenden Felder im Feldspec.default(wenn Sie eine ServiceImport-Ressource als Ziel verwenden, können Sie die letzten drei Felder stattdessen pro Cluster, Zone oder Region im Feldspec.default.scopesfestlegen):timeoutSecconnectionDraininglogging.enabledundlogging.sampleRatesessionAffinity.type(gültige Werte sindCLIENT_IPoderNONE)capacityScalerPercentbalancingMode: CONNECTIONmaxConnectionsPerEndpoint
Sie können keine
TCP-Richtlinie erstellen, die andere Felder enthält, oder eineHTTP-Richtlinie, die nurTCP-Felder (balancingMode: CONNECTIONundmaxConnectionsPerEndpoint) 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 undSSL- oderTCP-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.
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_NAMEErsetzen Sie IP_ADDRESS_NAME durch den Namen der statischen IP-Adresse, die Sie reserviert haben.
Beachten Sie, dass der Block
tlskein FeldcertificateRefshat. ImPassthrough-Modus befindet sich das TLS-Zertifikat in Ihren Backend-Pods und nicht auf dem Load Balancer.Wenden Sie das Gateway-Manifest an:
kubectl apply -f store-gateway.yamlPrüfen Sie, ob das Gateway programmiert ist:
kubectl get gateway store-tlsDie 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.
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.
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.keySpeichern 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: 8443Die Dienste benötigen kein
appProtocol-Feld. GKE leitet TLSRoute-Traffic als TCP an das Backend weiter, sodass das Feld keine Auswirkungen hat.Wenden Sie das Manifest auf Ihren Cluster an:
kubectl apply -f store-tls-app.yamlPrü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.
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: 443Mit dem Feld
sectionNamewird der Ziel-Listener auf dem Gateway ausgewählt. Im Feldportwird der Dienstport (443) und nicht der Containerport angegeben.Wenden Sie das TLSRoute-Manifest an:
kubectl apply -f store-tls-routes.yamlPrüfen Sie, ob der Gateway-Controller die Route akzeptiert hat:
kubectl get tlsroute store -o yamlDas Feld
statussieht 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: ReconciliationSucceededDie Bedingung
Reconciledist eine GKE-spezifische Statusbedingung, die angibt, ob der Gateway-Controller die zugrunde liegendenGoogle Cloud -Ressourcen erstellt hat.Prüfen Sie, ob der Gateway-Listener die Route akzeptiert hat:
kubectl get gateway store-tls -o yamlJeder Eintrag im Feld
status.listenerssieht 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.
Rufen Sie die Gateway-IP-Adresse ab:
kubectl get gateway store-tls -o jsonpath='{.status.addresses[0].value}'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.comIn 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.comDa 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.
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 -subjectIn der Ausgabe wird das Zertifikat des Back-Ends
store-germanangezeigt:subject=CN=store-de.example.comWenn 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.Senden Sie eine Anfrage mit einem SNI-Hostnamen, der mit keinem Listener übereinstimmt:
curl --resolve other.example.com:443:GATEWAY_IP \ https://other.example.comDie Verbindung wird geschlossen, weil kein Listener auf Port
443mit dem SNI-Hostnamenother.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-Einstellungenworker_processes * worker_connections, das Tomcat-AttributmaxConnectionsoder 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:
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-v1Wenden 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.typeaufTCPgesetzt) 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:
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-serviceWenden 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 eineAccepted: False-Bedingung mit dem GrundConflictedmelden.
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.
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: TLSRouteErstellen Sie im Anwendungs-Namespace (
store-ns) eine ReferenceGrant-Ressource, die es dem Gateway im Namespacegateway-infraermö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: ServiceErstellen 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:
- Verwenden Sie eine unterstützte Multi-Cluster-GatewayClass (
gke-l7-regional-external-managed-mc,gke-l7-rilb-mcodergke-l7-cross-regional-internal-managed-mc). - Exportieren Sie Ihren Backend-Dienst mit einer ServiceExport-Ressource in die Flotte.
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.comoder 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(oderHost) geprüft wird. Wenn der angeforderte Host nicht mit der erwarteten Domain des Servers übereinstimmt, wird der StatuscodeHTTP 421 Misdirected Requestzurü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:
Löschen Sie die TLSRoute-Ressourcen:
kubectl delete tlsroute store store-germanLöschen Sie die Gateway-Ressource:
kubectl delete gateway store-tlsLö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
- GatewayClass-Funktionen
- Weitere Informationen zur Gateway-Sicherheit.
- Gateway-Ressourcen mithilfe von Richtlinien konfigurieren