Esegui il deployment di un gateway TLS passthrough

Questo documento mostra come eseguire il deployment di una risorsa Gateway Kubernetes configurata per il passthrough TLS per abilitare il routing basato su Server Name Indication (SNI) in Google Kubernetes Engine (GKE). Questo approccio preserva la crittografia end-to-end e il mutual TLS (mTLS) tra i client e i pod di backend, supporta i protocolli basati su TLS non HTTP e conserva gli indirizzi IP.

Questo documento è rivolto ad architetti cloud, specialisti di networking e sviluppatori che progettano, eseguono il deployment e gestiscono il networking criptato per i workload containerizzati. Per scoprire di più sui ruoli comuni e sulle attività di esempio, consulta Ruoli e attività comuni degli utenti GKE.

Panoramica

Oltre ai bilanciatori del carico delle applicazioni HTTP e HTTPS di livello 7, il controller GKE Gateway supporta i bilanciatori del carico di rete proxy di livello 4 (bilanciatori del carico del proxy TCP) configurati con passthrough TLS.

Con il passthrough TLS, il bilanciatore del carico non termina né decripta la sessione TLS. Invece, quando un client avvia un TLS handshake, il bilanciatore del carico esamina il messaggio ClientHello non criptato per leggere il nome host SNI (Server Name Indication). In base a questo nome host SNI, il bilanciatore del carico instrada il flusso TCP non elaborato e criptato al servizio Kubernetes di backend appropriato, dove i pod dell'applicazione terminano direttamente TLS.

Quando utilizzi il passthrough TLS con l'API Gateway, puoi:

  • Mantieni la crittografia end-to-end e supporta la conformità Zero Trust: mantieni il traffico completamente criptato dal client al pod di backend senza concedere al bilanciatore del carico l'accesso alle chiavi private o ai dati in testo non crittografato.
  • Utilizza l'autenticazione mutual TLS (mTLS): autentica i client direttamente a livello di applicazione di backend.
  • Risparmia indirizzi IPv4: esegui il multiplexing di più servizi TLS indipendenti su domini o sottodomini distinti utilizzando un unico indirizzo IP e una singola porta del gateway (ad esempio 443).
  • Supporto di protocolli basati su TLS non HTTP: instrada il traffico criptato per workload stateful, database, servizi gRPC personalizzati o protocolli proprietari in esecuzione su TLS.

GatewayClasses supportate

Le seguenti GatewayClass GKE supportano i listener TLS passthrough e le risorse TLSRoute:

  • 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

Per un confronto completo delle funzionalità di GatewayClass, consulta Funzionalità di GatewayClass.

Prima di iniziare

Prima di iniziare, assicurati di aver eseguito le seguenti attività:

  • Abilita l'API Google Kubernetes Engine.
  • Abilita l'API Google Kubernetes Engine
  • Per utilizzare Google Cloud CLI per questa attività, installala e poi inizializza gcloud CLI. Se hai già installato gcloud CLI, scarica l'ultima versione eseguendo il comando gcloud components update. Le versioni precedenti di gcloud CLI potrebbero non supportare l'esecuzione dei comandi in questo documento.
  • Verifica di avere un cluster Autopilot o Standard esistente che esegue GKE versione 1.35 o successive con l'API Gateway abilitata. Per creare un cluster, consulta Crea un cluster Autopilot. Per abilitare l'API Gateway su un cluster esistente, consulta Abilita l'API Gateway nel cluster.
  • Verifica di aver installato lo strumento a riga di comando OpenSSL. Utilizza questo strumento per generare certificati TLS autofirmati per le applicazioni di esempio.

Requisiti del GKE Gateway Controller

  • L'API Gateway è supportata solo sui cluster nativi di VPC.
  • Se utilizzi GatewayClass a livello di regione o tra regioni, devi attivare una subnet solo proxy.
  • Il cluster deve avere il componente aggiuntivo HttpLoadBalancing abilitato.
  • Se utilizzi Istio, devi eseguire l'upgrade a una delle seguenti versioni:
    • 1.15.2 o versioni successive
    • 1.14.5 o versioni successive
    • 1.13.9 o versioni successive.
  • Se utilizzi un VPC condiviso, nel progetto host devi assegnare il ruolo Compute Network User al service account GKE per il progetto di servizio.

Restrizioni e limitazioni

Quando esegui il deployment di gateway TLS passthrough e risorse TLSRoute, tieni presente le seguenti limitazioni:

  • Quando configuri l'impostazione protocol: TLS su un listener, devi impostare esplicitamente il campo tls.mode sul valore Passthrough. GKE non supporta la modalità Terminate predefinita per i listener TLS.
  • Su un listener TLS, non impostare il campo certificateRefs. La convalida del certificato client a livello di gateway (il campo spec.tls.frontendValidation) non si applica ai listener TLS. Per utilizzare mTLS, convalida i certificati client nel backend.
  • Un listener TLS può condividere una porta solo con altri listener TLS. Non puoi configurare listener HTTP o HTTPS sulla stessa porta di un listener TLS.
  • Nel campo TLSRoute.spec.hostnames, devi specificare un elenco di nomi host SNI da 1 a 1024 (nome host esatto o prefisso con carattere jolly, ad esempio *.example.com). Ogni voce non può superare i 253 caratteri e non può essere un indirizzo IP.
  • Nel campo TLSRoute.spec.rules, puoi configurare al massimo una regola.
  • Ogni regola supporta esattamente una voce backendRef. I backend proxy di livello 4 non supportano la suddivisione del traffico ponderata tra più backend.
  • Le classi GatewayClass a cluster singolo supportano solo i backend Service, mentre le classi GatewayClass multi-cluster supportano solo i backend ServiceImport.
  • Nel campo TLSRoute.spec.rules.backendRefs, imposta il campo port su una porta dichiarata dalla risorsa Service o ServiceImport di destinazione, non sulla porta del container.
  • Il servizio Kubernetes di backend (inclusi i servizi esportati come ServiceImport) a cui fa riferimento una risorsa TLSRoute deve utilizzare il valore TCP per il protocollo della porta.
  • Non puoi collegare una risorsa BackendTLSPolicy, Identity-Aware Proxy o una policy di sicurezza Google Cloud Armor a un backend TLSRoute perché il controller rifiuta le configurazioni di questo tipo.
  • Quando colleghi una risorsa GCPBackendPolicy a un Service o ServiceImport a cui fa riferimento una risorsa TLSRoute, devi impostare il campo spec.protocol sul valore TCP (se ometti il campo spec.protocol, il valore predefinito è HTTP, che si applica solo ai backend HTTPRoute). A un servizio o a un ServiceImport possono essere associate contemporaneamente una policy HTTP e una policy TCP. Se più policy con lo stesso valore spec.protocol hanno come target lo stesso servizio o ServiceImport, la policy meno recente ha la precedenza e quelle più recenti non vengono associate.
  • Una risorsa GCPBackendPolicy con il campo spec.protocol impostato su TCP supporta solo i seguenti campi nel campo spec.default (quando il target è una risorsa ServiceImport, puoi impostare gli ultimi tre campi per cluster, zona o regione nel campo spec.default.scopes):

    • timeoutSec
    • connectionDraining
    • logging.enabled e logging.sampleRate
    • sessionAffinity.type (i valori validi sono CLIENT_IP o NONE)
    • capacityScalerPercent
    • balancingMode: CONNECTION
    • maxConnectionsPerEndpoint

    Non puoi creare una policy TCP che includa altri campi o una policy HTTP che includa campi solo per TCP (balancingMode: CONNECTION e maxConnectionsPerEndpoint); il server API Kubernetes rifiuta la policy al momento della creazione. Per saperne di più, consulta Configura le risorse Gateway utilizzando le policy.

  • Se sia una risorsa HTTPRoute che una risorsa TLSRoute fanno riferimento allo stesso Service o ServiceImport, il collegamento di una risorsa HealthCheckPolicy a quel target sostituisce i controlli di integrità predefiniti separati e applica la stessa configurazione del controllo di integrità ai backend di entrambe le route. Per configurare i controlli di integrità in modo indipendente (ad esempio i controlli di integrità HTTP per i backend HTTPRoute e i controlli di integrità SSL o TCP per i backend TLSRoute), crea un servizio separato per ogni route e collega una risorsa HealthCheckPolicy a ogni servizio. Entrambi i servizi possono selezionare gli stessi pod.

  • Le funzionalità di livello 7 (come le riscritture degli URL, il routing basato su percorso e le trasformazioni delle intestazioni HTTP) non si applicano ai bilanciatori del carico del proxy TCP di livello 4.

Configura una subnet solo proxy

Un gateway a livello di regione richiede una subnet solo proxy (purpose=REGIONAL_MANAGED_PROXY) in ogni regione in cui ne esegui il deployment. Una subnet solo proxy gestisce tutti i bilanciatori del carico basati su Envoy a livello di regione in quella regione. Se la tua regione non ne ha già una, consulta Configura una subnet solo proxy.

Prenota un indirizzo IP statico

Prima di eseguire il deployment del gateway, prenota un indirizzo IP statico regionale in modo che l'indirizzo del gateway non cambi e tu possa risolvere i nomi host di esempio in questo indirizzo. Per istruzioni su come creare un indirizzo IP statico, consulta Crea un gateway HTTP(S) esterno regionale.

Esegui il deployment di un gateway con listener TLS passthrough

Il gateway in questa sezione configura due listener TLS che condividono la porta 443. Ogni listener corrisponde a un nome host SNI diverso e inoltra le connessioni in modalità passthrough alle risorse TLSRoute collegate.

  1. Salva il seguente manifest come 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
    

    Sostituisci IP_ADDRESS_NAME con il nome dell'indirizzo IP statico che hai prenotato.

    Tieni presente che il blocco tls non ha un campo certificateRefs. In modalità Passthrough, il certificato TLS si trova nei pod di backend anziché nel bilanciatore del carico.

  2. Applica il manifest del gateway:

    kubectl apply -f store-gateway.yaml
    
  3. Verifica che il gateway sia programmato:

    kubectl get gateway store-tls
    

    Il provisioning del bilanciatore del carico richiede alcuni minuti. L'output è simile al seguente:

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

Utilizza un gateway interno

Per mantenere il traffico all'interno della rete VPC, modifica il valore del campo gatewayClassName in gke-l7-rilb e rimuovi il campo addresses dal manifest del gateway. GKE crea quindi un bilanciatore del carico di rete proxy interno regionale e assegna un indirizzo IP interno dalla subnet del cluster. I passaggi rimanenti in questa pagina rimangono invariati. Invia le richieste di test da un'istanza Compute Engine nella stessa rete VPC, perché l'indirizzo IP interno non è raggiungibile da internet.

Esegui il deployment di applicazioni TLS di esempio

In questa sezione, creerai due deployment NGINX (store-v1 e store-german) che terminano TLS sulla porta 8443. Ogni deployment fornisce un certificato TLS diverso e segnala il nome host SNI ricevuto, il che ti consente di verificare che il routing sia avvenuto in base a SNI.

  1. Genera un certificato TLS autofirmato e una chiave privata per ogni nome host:

    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'
    

    Utilizza i certificati della tua autorità di certificazione in produzione. I certificati autofirmati mantengono questo esempio autonomo.

  2. Archivia ogni certificato e chiave in un secret Kubernetes eseguendo i seguenti comandi:

    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. Salva il seguente manifest come 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
    

    I Servizi non richiedono un campo appProtocol. GKE inoltra il traffico TLSRoute al backend come TCP, quindi il campo non ha alcun effetto.

  4. Applica il manifest al tuo cluster:

    kubectl apply -f store-tls-app.yaml
    
  5. Verifica che i pod siano in esecuzione:

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

    L'output è simile al seguente:

    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
    

Esegui il deployment delle risorse TLSRoute per il routing basato su SNI

Una risorsa TLSRoute si collega a un listener Gateway e instrada le connessioni che corrispondono ai suoi nomi host a un singolo servizio di backend.

  1. Salva il seguente manifest come 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
    

    Il campo sectionName seleziona il listener di destinazione sul gateway. Il campo port specifica la porta del servizio (443), non la porta del container.

  2. Applica il manifest TLSRoute:

    kubectl apply -f store-tls-routes.yaml
    
  3. Verifica che il controller del gateway abbia accettato la route:

    kubectl get tlsroute store -o yaml
    

    Il campo status è simile al seguente:

    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
    

    La condizione Reconciled è una condizione di stato specifica di GKE che indica se il controller Gateway ha creato le risorseGoogle Cloud sottostanti.

  4. Verifica che il listener del gateway abbia accettato la route:

    kubectl get gateway store-tls -o yaml
    

    Ogni voce nel campo status.listeners è simile alla seguente:

    - 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
    

Verifica il routing del traffico

GKE esegue il controllo di integrità di un backend TLS passthrough completando un TLS handshake con il backend. I pod potrebbero impiegare alcuni minuti per superare il controllo di integrità iniziale.

  1. Recupera l'indirizzo IP del gateway:

    kubectl get gateway store-tls -o jsonpath='{.status.addresses[0].value}'
    
  2. Invia una richiesta a ogni nome host, sostituendo GATEWAY_IP con l'indirizzo IP del passaggio precedente:

    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
    

    Ogni risposta indica il pod che ha risposto e restituisce il nome host SNI che lo ha raggiunto:

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

    Poiché ogni richiesta ha utilizzato un file dell'autorità di certificazione diverso ed entrambe sono andate a buon fine, ogni backend ha fornito il proprio certificato. Il bilanciatore del carico ha inoltrato la connessione criptata senza terminarla.

  3. Verifica che il routing avvenga durante il TLS handshake, prima che il client invii qualsiasi richiesta HTTP:

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

    L'output mostra il certificato del backend store-german:

    subject=CN=store-de.example.com
    

    La modifica del solo valore del flag -servername cambia il certificato restituito, confermando che il bilanciatore del carico ha selezionato il backend in base al solo SNI.

  4. Invia una richiesta con un nome host SNI che non corrisponde a nessun listener:

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

    La connessione viene chiusa perché nessun listener sulla porta 443 corrisponde al nome host SNI other.example.com.

Configura la capacità di connessione del backend

Per i servizi GKE a cui fanno riferimento le risorse TLSRoute, il controller GKE Gateway configura un servizio di backend TCP utilizzando la modalità di bilanciamento CONNECTION e imposta il valore predefinito del campo maxConnectionsPerEndpoint su 100,000,000 (1e8).

Poiché il controller Gateway non può determinare automaticamente il limite di connessioni simultanee di un container, puoi utilizzare una risorsa GCPBackendPolicy per eseguire l'override del valore predefinito del campo maxConnectionsPerEndpoint (da 1 a 1,000,000,000). Per determinare il limite di connessioni ottimale per i pod di backend, valuta quanto segue:

  • Limiti del software: controlla la configurazione del server o dell'applicazione, ad esempio la direttiva MaxRequestWorkers di Apache, le impostazioni worker_processes * worker_connections di NGINX, l'attributo maxConnections di Tomcat o i limiti del pool di connessioni al database.
  • Test di carico: aumenta gradualmente le connessioni simultanee a un pod isolato monitorando i limiti di CPU, memoria, latenza e socket o descrittore del file.

Applica una risorsa GCPBackendPolicy personalizzata

Per eseguire l'override del valore predefinito del campo maxConnectionsPerEndpoint su un servizio di backend TLSRoute, collega una risorsa GCPBackendPolicy con il campo spec.protocol impostato su TCP e il campo balancingMode impostato su CONNECTION:

  1. Salva il seguente manifest come 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. Applica la policy:

    kubectl apply -f backend-policy.yaml
    

Per saperne di più sulla configurazione delle policy di backend, consulta Configura le risorse Gateway utilizzando le policy.

Configura i controlli di integrità per il passthrough TLS

Per impostazione predefinita, per i servizi di backend associati alle risorse TLSRoute di passthrough TLS, il controller GKE Gateway esegue automaticamente il provisioning di un controllo di integrità di tipo SSL.

Gestisci l'assenza di estensioni SNI dai prober

Quando configuri i controlli di integrità per i backend TLS passthrough, devi tenere conto di come i prober dei controlli di integrità di Google Cloud interagiscono con gli endpoint TLS.

Se le tue applicazioni di backend richiedono un nome host SNI valido per completare un TLS handshake, i controlli di integrità SSL predefiniti non riusciranno. Per risolvere il problema, utilizza uno dei seguenti approcci:

  • Configura i certificati di riserva: configura il server di backend o il pod in modo che fornisca un certificato TLS di riserva predefinito quando arriva una connessione TLS senza un'estensione SNI.
  • Utilizza i controlli di integrità TCP con HealthCheckPolicy: collega una risorsa HealthCheckPolicy (con il campo config.type impostato su TCP) al tuo servizio per controllare la connettività della porta TCP non elaborata ed evitare il TLS handshake.

Applica una risorsa HealthCheckPolicy personalizzata

Per configurare parametri di controllo di integrità personalizzati o passare al controllo di integrità TCP, utilizza una risorsa HealthCheckPolicy:

  1. Salva il seguente manifest come 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. Applica la policy:

    kubectl apply -f health-check-policy.yaml
    

Per saperne di più sulla configurazione dei controlli di integrità, consulta Configura le risorse Gateway utilizzando le policy.

Configurazioni avanzate

Questa sezione descrive i pattern di routing avanzati, le configurazioni multi-tenant e i deployment multi-cluster supportati con i gateway di passthrough TLS e le risorse TLSRoute.

Corrispondenza del nome host con caratteri jolly

Le risorse TLSRoute supportano la corrispondenza dei prefissi con caratteri jolly per i nomi host e seguono regole di precedenza deterministiche quando più route corrispondono allo stesso traffico in entrata.

Salva il seguente manifest per definire una risorsa TLSRoute con caratteri jolly:

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

Regole di precedenza e risoluzione dei conflitti

Quando più risorse TLSRoute si collegano allo stesso listener Gateway e rivendicano nomi host sovrapposti o identici, il controller GKE Gateway risolve i conflitti utilizzando la stessa specificità del nome host e le stesse regole di timestamp di creazione di altre route Gateway:

  • Le corrispondenze esatte dei nomi host (ad esempio store.example.com) hanno la precedenza sulle corrispondenze con caratteri jolly (ad esempio *.example.com) e le corrispondenze con caratteri jolly più lunghe hanno la precedenza sulle corrispondenze con caratteri jolly più ampie (ad esempio *.com).
  • Se due o più risorse TLSRoute dichiarano esattamente lo stesso nome host, la route con il timestamp di creazione meno recente (metadata.creationTimestamp) ha la precedenza. Se i timestamp di creazione corrispondono, l'identificatore <namespace>/<name> più piccolo in ordine lessicografico risolve la parità. Il controller Gateway non accetta route in conflitto, che segnalano una condizione Accepted: False con il motivo Conflicted.

Per saperne di più sulla precedenza delle route, consulta Unione, precedenza e convalida delle route.

Routing tra spazi dei nomi con ReferenceGrant

In ambienti multi-tenant, un team della piattaforma centralizzato può gestire il gateway in uno spazio dei nomi dell'infrastruttura (ad esempio gateway-infra), mentre i team delle applicazioni gestiscono le risorse TLSRoute e Service negli spazi dei nomi degli sviluppatori (ad esempio store-ns).

  1. Nel listener del gateway, consenti le route da tutti gli spazi dei nomi (o dagli spazi dei nomi selezionati):

    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. Nello spazio dei nomi dell'applicazione (store-ns), crea una risorsa ReferenceGrant che consenta al gateway nello spazio dei nomi gateway-infra di fare riferimento alla risorsa TLSRoute o Service:

    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. Nello spazio dei nomi dell'applicazione (store-ns), crea la risorsa TLSRoute che fa riferimento al gateway condiviso:

    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
    

Gateway passthrough TLS multi-cluster

Puoi eseguire il deployment di gateway multi-cluster con passthrough TLS in più cluster GKE di un parco risorse:

  1. Utilizza una GatewayClass multi-cluster supportata (gke-l7-regional-external-managed-mc, gke-l7-rilb-mc o gke-l7-cross-regional-internal-managed-mc).
  2. Esporta il servizio di backend nel parco risorse utilizzando una risorsa ServiceExport.
  3. Nella risorsa TLSRoute, fai riferimento al backend multi-cluster utilizzando una risorsa ServiceImport:

    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
    

Più indirizzi IP nei gateway multi-cluster

Quando esegui il deployment di gateway multi-cluster tra regioni (ad esempio quando utilizzi la GatewayClass gke-l7-cross-regional-internal-managed-mc), puoi definire più indirizzi IP nel campo spec.addresses per esporre un VIP interno in regioni diverse.

Quando configuri più indirizzi IP in un singolo gateway, il controller GKE Gateway traduce ogni indirizzo IP in una regola di forwarding separata. Allo stesso tempo, il controller fa riferimento a un proxy di destinazione condiviso e riutilizza la stessa configurazione di routing sottostante. Il controller non moltiplica le risorse TLSRoute sottostanti per il numero di indirizzi IP, il che aiuta a prevenire la duplicazione delle route e l'esaurimento della quota.

L'esempio seguente mostra un gateway multi-cluster configurato con indirizzi IP temporanei in due regioni:

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

Per ulteriori informazioni sul deployment di gateway multi-cluster interni, consulta Esegui il deployment di un gateway multi-cluster interno.

Coalescenza delle connessioni HTTP

In base alla sezione 9.1.1 del documento RFC 7540, i browser web e i client HTTP/2 possono riutilizzare una connessione TLS stabilita per più richieste se sono soddisfatte entrambe le seguenti condizioni:

  • I nomi host di destinazione vengono risolti nello stesso indirizzo IP.
  • Il certificato TLS presentato dal server è autoritativo per entrambi i nomi host. Ad esempio, un certificato può coprire più nomi host quando utilizzi certificati con caratteri jolly come *.example.com o nomi alternativi del soggetto (SAN) multidominio.

Poiché un bilanciatore del carico proxy TCP di livello 4 non ispeziona le intestazioni delle richieste HTTP dopo il TLS handshake iniziale, il bilanciatore del carico inoltra le richieste raggruppate tramite la connessione esistente al pod di backend corrispondente inizialmente.

Per evitare problemi di coalescenza delle connessioni:

  • Utilizza certificati TLS distinti e non sovrapposti: non condividere certificati con caratteri jolly o identità SAN comuni tra diversi servizi di backend multiplexati dietro lo stesso indirizzo IP del gateway.
  • Restituisci l'errore HTTP 421 Misdirected Request: configura i server HTTPS di backend in modo che controllino l'intestazione HTTP :authority (o Host). Se l'host richiesto non corrisponde al dominio previsto del server, restituisci un codice di stato HTTP 421 Misdirected Request, che richiede al client di aprire una nuova connessione.
  • Attiva il frame HTTP/2 ORIGIN: adotta il supporto del frame RFC 8336 ORIGIN sui server di origine e dichiara esplicitamente quali nomi host sono validi per il riutilizzo della connessione.

Esegui la pulizia

Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questa pagina, elimina le risorse:

  1. Elimina le risorse TLSRoute:

    kubectl delete tlsroute store store-german
    
  2. Elimina la risorsa Gateway:

    kubectl delete gateway store-tls
    
  3. Elimina le risorse Deployment, Service e Secret di esempio:

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

Passaggi successivi