Deployment di gateway multi-cluster


Questa pagina descrive come eseguire il deployment delle risorse Kubernetes Gateway per il bilanciamento del carico del traffico in entrata su più cluster (o parchi risorse) Google Kubernetes Engine (GKE). Prima di eseguire il deployment di gateway multi-cluster, consulta Attivare i gateway multi-cluster per preparare l'ambiente.

Per eseguire il deployment di gateway per il bilanciamento del carico del traffico in entrata su un solo cluster GKE, consulta Eseguire il deployment dei gateway.

Gateway multi-cluster

Un gateway multi-cluster è una risorsa Gateway che bilancia il carico del traffico su più cluster Kubernetes. In GKE, le classi di gateway gke-l7-global-external-managed-mc, gke-l7-regional-external-managed-mc, gke-l7-rilb-mc e gke-l7-gxlb-mc dispiacciono gateway multi-cluster che forniscono routing HTTP, suddivisione del traffico, mirroring del traffico, failover basato sullo stato e altro ancora in diversi cluster GKE, spazi dei nomi Kubernetes e regioni. I gateway multi-cluster semplificano, rendono sicura e scalabile la gestione del networking delle applicazioni su molti cluster e team per gli amministratori dell'infrastruttura.

Un gateway multi-cluster è una risorsa gateway che bilancia il carico del traffico su più cluster Kubernetes.

Questa pagina illustra tre esempi per insegnarti a eseguire il deployment di gateway multi-cluster utilizzando il controller gateway GKE:

  • Esempio 1: un gateway multi-cluster esterno che fornisce il bilanciamento del carico su due cluster GKE per il traffico internet.
  • Esempio 2: distribuzione del traffico blue-green in base al peso e mirroring del traffico su due cluster GKE per il traffico VPC interno.
  • Esempio 3: un gateway basato sulla capacità per bilanciare il carico delle richieste su diversi backend in base alla loro capacità massima.

Ciascuno degli esempi utilizzerà le stesse applicazioni store e site per modellare un scenario reale in cui un servizio di shopping online e un servizio di siti web sono di proprietà e gestiti da team separati e di cui è stato eseguito il deployment in un parco di cluster GKE condivisi. Ciascuno degli esempi mette in evidenza diverse topologie e casi d'uso abilitati dai gateway multi-cluster.

I gateway multicluster richiedono una certa preparazione dell'ambiente prima di poter essere dipiamente. Prima di procedere, segui i passaggi descritti in Attivare i gateway multi-cluster:

  1. Esegui il deployment dei cluster GKE.

  2. Registra i cluster in un parco risorse.

  3. Abilita i controller di servizi e gateway multi-cluster.

Infine, esamina i limiti e i problemi noti del controller di gateway GKE prima di utilizzarlo nel tuo ambiente.

Gateway esterno multi-cluster e multi-regione

In questo tutorial, creerai un gateway multi-cluster esterno che gestisce il traffico esterno di un'applicazione in esecuzione in due cluster GKE.

store.example.com viene dispiegato su due cluster GKE ed esposto a internet utilizzando un gateway multi-cluster

Nei passaggi che seguono:

  1. Esegui il deployment dell'applicazione store di esempio nei cluster gke-west-1 e gke-east-1.
  2. Configura i servizi su ogni cluster da esportare nel tuo parco risorse (servizi multi-cluster).
  3. Esegui il deployment di un gateway multicluster esterno e di un percorso HTTP nel tuo cluster di configurazione (gke-west-1).

Dopo aver eseguito il deployment delle risorse dell'applicazione e del gateway, puoi controllare il traffico tra i due cluster GKE utilizzando il routing basato sui percorsi:

  • Le richieste a /west vengono instradate ai pod store nel cluster gke-west-1.
  • Le richieste a /east vengono instradate ai pod store nel cluster gke-east-1.
  • Le richieste a qualsiasi altro percorso vengono instradate a uno dei cluster, in base alla relativa integrità, alla capacità e alla vicinanza al client richiedente.

Esegui il deployment dell'applicazione demo

  1. Crea il deployment e lo spazio dei nomi store in tutti e tre i cluster che sono stati di cui è stato eseguito il deployment in Abilitazione di gateway multi-cluster:

    kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml
    kubectl apply --context gke-west-2 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml
    kubectl apply --context gke-east-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml
    

    In ogni cluster vengono implementate le seguenti risorse:

    namespace/store created
    deployment.apps/store created
    

    Tutti gli esempi in questa pagina utilizzano l'app di cui è stato eseguito il deployment in questo passaggio. Assicurati che l'app sia dipiattata su tutti e tre i cluster prima di provare uno dei passaggi rimanenti. Questo esempio utilizza solo i cluster gke-west-1 e gke-east-1 e gke-west-2 viene utilizzato in un altro esempio.

Servizi multi-cluster

I servizi sono il modo in cui i pod vengono esposti ai clienti. Poiché il controller di gateway GKE utilizza il bilanciamento del carico nativo del container, non utilizza il bilanciamento del carico ClusterIP o Kubernetes per raggiungere i pod. Il traffico viene inviato direttamente dal bilanciatore del carico agli indirizzi IP del pod. Tuttavia, i servizi continuano a svolgere un ruolo fondamentale come identificatore logico per il raggruppamento dei pod.

Multi-cluster Services (MCS) è uno standard API per i servizi che si estendono su più cluster e il relativo controller GKE fornisce Service Discovery nei cluster GKE. Il controller di gateway multi-cluster utilizza le risorse dell'API MCS per raggruppare i pod in un servizio indirizzabile su più cluster o che si estende su più cluster.

L'API Services multi-cluster definisce le seguenti risorse personalizzate:

  • ServiceExports si mappano a un servizio Kubernetes, esportando gli endpoint di quel servizio in tutti i cluster registrati nel parco risorse. Quando un servizio ha un ServiceExport corrispondente, significa che può essere indirizzato da un gateway multi-cluster.
  • ServiceImports vengono generati automaticamente dal controller dei servizi multi-cluster. ServiceExport e ServiceImport vengono forniti in coppia. Se nel parco risorse esiste un ServiceExport, viene creato un ServiceImport corrispondente per consentire l'accesso al servizio mappato a ServiceExport da tutti i cluster.

I servizi di esportazione funzionano nel seguente modo. In gke-west-1 esiste un servizio Store che seleziona un gruppo di pod in quel cluster. Nel cluster viene creato un ServiceExport che consente ai pod in gke-west-1 di diventare accessibili dagli altri cluster del parco risorse. ServiceExport verrà mappato ed esposto ai servizi che hanno lo stesso nome e spazio dei nomi della risorsa ServiceExport.

apiVersion: v1
kind: Service
metadata:
  name: store
  namespace: store
spec:
  selector:
    app: store
  ports:
  - port: 8080
    targetPort: 8080
---
kind: ServiceExport
apiVersion: net.gke.io/v1
metadata:
  name: store
  namespace: store

Il seguente diagramma mostra cosa succede dopo il deployment di un ServiceExport. Se esiste una coppia ServiceExport e Service, il controller dei servizi multi-cluster esegue il deployment di un ServiceImport corrispondente in ogni cluster GKE del parco risorse. ServiceImport è la rappresentazione locale del servizio store in ogni cluster. In questo modo, il pod client in gke-east-1 può utilizzare i servizi ClusterIP o headless per raggiungere i pod store in gke-west-1. Se utilizzati in questo modo, i servizi multi-cluster forniscono il bilanciamento del carico est-ovest tra i cluster senza richiedere un servizio LoadBalancer interno. Per utilizzare i servizi multi-cluster per il bilanciamento del carico tra cluster, consulta Configurazione dei servizi multi-cluster.

I servizi multi-cluster esportano i servizi tra i cluster, il che consente la comunicazione tra cluster.

I gateway multi-cluster utilizzano anche ServiceImports, ma non per il bilanciamento del carico tra cluster. I gateway utilizzano invece ServiceImports come identificatori logici per un servizio esistente in un altro cluster o che si estende su più cluster. Il seguente parametro HTTPRoute fa riferimento a una risorsa ServiceImport anziché a una risorsa Servizio. Il riferimento a un'importazione di servizio indica che il traffico viene inoltrato a un gruppo di pod di backend che vengono eseguiti in uno o più cluster.

kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: store-route
  namespace: store
  labels:
    gateway: multi-cluster-gateway
spec:
  parentRefs:
  - kind: Gateway
    namespace: store
    name: external-http
  hostnames:
  - "store.example.com"
  rules:
  - backendRefs:
    - group: net.gke.io
      kind: ServiceImport
      name: store
      port: 8080

Il seguente diagramma mostra come HTTPRoute inoltra il traffico store.example.com ai pod store su gke-west-1 e gke-east-1. Il bilanciatore del carico li tratta come un unico pool di backend. Se i pod di uno dei cluster non sono operativi, non sono raggiungibili o non hanno capacità di traffico, il carico del traffico viene bilanciato tra i pod rimanenti dell'altro cluster. I nuovi cluster possono essere aggiunti o rimossi con il servizio store e ServiceExport. In questo modo, i pod di backend verranno aggiunti o rimossi in modo trasparente senza modifiche esplicite alla configurazione del routing.

Risorsa MCS

Servizi di esportazione

A questo punto, l'applicazione è in esecuzione su entrambi i cluster. Successivamente, esporrai ed esporterai le applicazioni eseguendo il deployment di Services e ServiceExports in ogni cluster.

  1. Applica il seguente manifest al cluster gke-west-1 per creare i servizi store e store-west-1 e i ServiceExport:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: store
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store
      namespace: store
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: store-west-1
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store-west-1
      namespace: store
    EOF
    
  2. Applica il seguente manifest al cluster gke-east-1 per creare i servizi store e store-east-1 e i ServiceExport:

    cat << EOF | kubectl apply --context gke-east-1 -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: store
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store
      namespace: store
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: store-east-1
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store-east-1
      namespace: store
    EOF
    
  3. Verifica che nei cluster siano stati creati i ServiceExport corretti.

    kubectl get serviceexports --context CLUSTER_NAME --namespace store
    

    Sostituisci CLUSTER_NAME con gke-west-1 e gke-east-1. L'output dovrebbe essere simile al seguente:

    # gke-west-1
    NAME           AGE
    store          2m40s
    store-west-1   2m40s
    
    # gke-east-1
    NAME           AGE
    store          2m25s
    store-east-1   2m25s
    

    Ciò dimostra che il servizio store contiene store pod in entrambi i cluster, mentre i servizi store-west-1 e store-east-1 contengono solo store pod nei rispettivi cluster. Questi servizi sovrapposti vengono utilizzati per scegliere come target i pod in più cluster o un sottoinsieme di pod in un singolo cluster.

  4. Dopo alcuni minuti, verifica che i ServiceImports aggiuntivi siano stati creati automaticamente dal controller dei servizi multi-cluster in tutti i cluster del parco risorse.

    kubectl get serviceimports --context CLUSTER_NAME --namespace store
    

    Sostituisci CLUSTER_NAME con gke-west-1 e gke-east-1. L'output dovrebbe essere simile al seguente:

    # gke-west-1
    NAME           TYPE           IP                  AGE
    store          ClusterSetIP   ["10.112.31.15"]    6m54s
    store-east-1   ClusterSetIP   ["10.112.26.235"]   5m49s
    store-west-1   ClusterSetIP   ["10.112.16.112"]   6m54s
    
    # gke-east-1
    NAME           TYPE           IP                  AGE
    store          ClusterSetIP   ["10.72.28.226"]    5d10h
    store-east-1   ClusterSetIP   ["10.72.19.177"]    5d10h
    store-west-1   ClusterSetIP   ["10.72.28.68"]     4h32m
    

    Ciò dimostra che tutti e tre i servizi sono accessibili da entrambi i cluster del parco risorse. Tuttavia, poiché esiste un solo cluster di configurazione attivo per ogni flotta, puoi implementare solo gateway e route HTTP che fanno riferimento a queste importazioni di servizi in gke-west-1. Quando un parametro HTTPRoute nel cluster di configurazione fa riferimento a queste importazioni di servizi come backend, il gateway può inoltrare il traffico a questi servizi indipendentemente dal cluster da cui vengono esportati.

Eseguire il deployment di Gateway e HTTPRoute

Una volta eseguiti i deployment delle applicazioni, puoi configurare un gateway utilizzando gke-l7-global-external-managed-mc GatewayClass. Questo gateway crea un bilanciatore del carico delle applicazioni esterno configurato per distribuire il traffico tra i cluster di destinazione.

  1. Applica il seguente manifest Gateway al cluster di configurazione gke-west-1 in questo esempio:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: external-http
      namespace: store
    spec:
      gatewayClassName: gke-l7-global-external-managed-mc
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          kinds:
          - kind: HTTPRoute
    EOF
    

    Questa configurazione del gateway esegue il deployment delle risorse del bilanciatore del carico delle applicazioni esterno con la seguente convenzione di denominazione: gkemcg1-NAMESPACE-GATEWAY_NAME-HASH.

    Le risorse predefinite create con questa configurazione sono:

    • 1 bilanciatore del carico: gkemcg1-store-external-http-HASH
    • 1 indirizzo IP pubblico: gkemcg1-store-external-http-HASH
    • 1 regola di forwarding: gkemcg1-store-external-http-HASH
    • 2 servizi di backend:
      • Servizio di backend 404 predefinito: gkemcg1-store-gw-serve404-HASH
      • Servizio di backend predefinito di 500: gkemcg1-store-gw-serve500-HASH
    • 1 controllo di integrità:
      • Controllo di integrità 404 predefinito: gkemcg1-store-gw-serve404-HASH
    • 0 regole di routing (la mappa URL è vuota)

    A questo punto, qualsiasi richiesta all'indirizzo GATEWAY_IP:80 porterà a una pagina predefinita che mostra il seguente messaggio: fault filter abort.

  2. Applica il seguente manifest HTTPRoute al cluster di configurazione gke-west-1 in questo esempio:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: public-store-route
      namespace: store
      labels:
        gateway: external-http
    spec:
      hostnames:
      - "store.example.com"
      parentRefs:
      - name: external-http
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /west
        backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          name: store-west-1
          port: 8080
      - matches:
        - path:
            type: PathPrefix
            value: /east
        backendRefs:
          - group: net.gke.io
            kind: ServiceImport
            name: store-east-1
            port: 8080
      - backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          name: store
          port: 8080
    EOF
    

    A questo punto, qualsiasi richiesta all'indirizzo GATEWAY_IP:80 porterà a una pagina predefinita che mostra il seguente messaggio: fault filter abort.

    Una volta implementato, questo percorso HTTP configurerà il seguente comportamento di routing:

    • Le richieste a /west vengono instradate ai pod store nel cluster gke-west-1, perché i pod selezionati da store-west-1 ServiceExport esistono solo nel cluster gke-west-1.
    • Le richieste a /east vengono instradate ai pod store nel clustergke-east-1, perché i pod selezionati da store-east-1 ServiceExport esistono solo nel clustergke-east-1.
    • Le richieste a qualsiasi altro percorso vengono instradate ai pod store in entrambi i cluster, in base alla loro integrità, alla loro capacità e alla loro vicinanza al client richiedente.
    • Le richieste all'indirizzo GATEWAY_IP:80 mostreranno una pagina predefinita con il seguente messaggio: fault filter abort.

    HTTPRoute consente il routing verso diversi sottoinsiemi di cluster utilizzando servizi sovrapposti

    Tieni presente che se tutti i pod di un determinato cluster non sono operativi (o non esistono), il traffico verso il servizio store verrà inviato solo ai cluster che hanno effettivamente pod store. L'esistenza di ServiceExport e Service in un determinato cluster non garantisce che il traffico verrà inviato a quel cluster. I pod devono essere esistenti e rispondere in modo affermativo al controllo di integrità del bilanciatore del carico, altrimenti il bilanciatore del carico invierà il traffico solo ai pod store integri in altri cluster.

    Con questa configurazione vengono create nuove risorse:

    • 3 servizi di backend:
      • Il servizio di backend store: gkemcg1-store-store-8080-HASH
      • Il servizio di backend store-east-1: gkemcg1-store-store-east-1-8080-HASH
      • Il servizio di backend store-west-1: gkemcg1-store-store-west-1-8080-HASH
    • 3 controlli di integrità:
      • Il controllo di integrità di store: gkemcg1-store-store-8080-HASH
      • Il controllo di integrità di store-east-1: gkemcg1-store-store-east-1-8080-HASH
      • Il controllo di integrità di store-west-1: gkemcg1-store-store-west-1-8080-HASH
    • 1 regola di routing in URLmap:
      • La regola di routing store.example.com:
      • 1 host: store.example.com
      • Più matchRules per il routing ai nuovi servizi di backend

Il seguente diagramma mostra le risorse di cui hai eseguito il deployment in entrambi i cluster. Poiché gke-west-1 è il cluster di configurazione di Gateway, è il cluster in cui Gateway, HTTPRoutes e ServiceImports vengono monitorati dal controller di Gateway. Ogni cluster ha un store ServiceImport e un altro ServiceImport specifico per quel cluster. Entrambi rimandano agli stessi pod. In questo modo, l'HTTPRoute può specificare esattamente dove deve andare il traffico: ai pod store su un cluster specifico o ai pod store su tutti i cluster.

Questo è il modello di risorse Gateway e Multi-cluster Service in entrambi i cluster

Tieni presente che si tratta di un modello di risorse logiche, non di una rappresentazione del flussi di traffico. Il percorso del traffico va direttamente dal bilanciatore del carico ai pod di backend e non ha alcuna relazione diretta con il cluster di configurazione.

Convalida del deployment

Ora puoi inviare richieste al nostro gateway multi-cluster e distribuire il traffico tra i due cluster GKE.

  1. Verifica che il gateway e HTTPRoute siano stati dipartiti correttamente controllando lo stato e gli eventi del gateway.

    kubectl describe gateways.gateway.networking.k8s.io external-http --context gke-west-1 --namespace store
    

    Dovresti vedere un output simile al seguente:

    Name:         external-http
    Namespace:    store
    Labels:       <none>
    Annotations:  networking.gke.io/addresses: /projects/PROJECT_NUMBER/global/addresses/gkemcg1-store-external-http-laup24msshu4
                  networking.gke.io/backend-services:
                    /projects/PROJECT_NUMBER/global/backendServices/gkemcg1-store-gw-serve404-80-n65xmts4xvw2, /projects/PROJECT_NUMBER/global/backendServices/gke...
                  networking.gke.io/firewalls: /projects/PROJECT_NUMBER/global/firewalls/gkemcg1-l7-default-global
                  networking.gke.io/forwarding-rules: /projects/PROJECT_NUMBER/global/forwardingRules/gkemcg1-store-external-http-a5et3e3itxsv
                  networking.gke.io/health-checks:
                    /projects/PROJECT_NUMBER/global/healthChecks/gkemcg1-store-gw-serve404-80-n65xmts4xvw2, /projects/PROJECT_NUMBER/global/healthChecks/gkemcg1-s...
                  networking.gke.io/last-reconcile-time: 2023-10-12T17:54:24Z
                  networking.gke.io/ssl-certificates: 
                  networking.gke.io/target-http-proxies: /projects/PROJECT_NUMBER/global/targetHttpProxies/gkemcg1-store-external-http-94oqhkftu5yz
                  networking.gke.io/target-https-proxies: 
                  networking.gke.io/url-maps: /projects/PROJECT_NUMBER/global/urlMaps/gkemcg1-store-external-http-94oqhkftu5yz
    API Version:  gateway.networking.k8s.io/v1beta1
    Kind:         Gateway
    Metadata:
      Creation Timestamp:  2023-10-12T06:59:32Z
      Finalizers:
        gateway.finalizer.networking.gke.io
      Generation:        1
      Resource Version:  467057
      UID:               1dcb188e-2917-404f-9945-5f3c2e907b4c
    Spec:
      Gateway Class Name:  gke-l7-global-external-managed-mc
      Listeners:
        Allowed Routes:
          Kinds:
            Group:  gateway.networking.k8s.io
            Kind:   HTTPRoute
          Namespaces:
            From:  Same
        Name:      http
        Port:      80
        Protocol:  HTTP
    Status:
      Addresses:
        Type:   IPAddress
        Value:  34.36.127.249
      Conditions:
        Last Transition Time:  2023-10-12T07:00:41Z
        Message:               The OSS Gateway API has deprecated this condition, do not depend on it.
        Observed Generation:   1
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
        Last Transition Time:  2023-10-12T07:00:41Z
        Message:               
        Observed Generation:   1
        Reason:                Accepted
        Status:                True
        Type:                  Accepted
        Last Transition Time:  2023-10-12T07:00:41Z
        Message:               
        Observed Generation:   1
        Reason:                Programmed
        Status:                True
        Type:                  Programmed
        Last Transition Time:  2023-10-12T07:00:41Z
        Message:               The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use.  GKE Gateway will stop emitting it in a future update, use "Programmed" instead.
        Observed Generation:   1
        Reason:                Ready
        Status:                True
        Type:                  Ready
      Listeners:
        Attached Routes:  1
        Conditions:
          Last Transition Time:  2023-10-12T07:00:41Z
          Message:               
          Observed Generation:   1
          Reason:                Programmed
          Status:                True
          Type:                  Programmed
          Last Transition Time:  2023-10-12T07:00:41Z
          Message:               The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use.  GKE Gateway will stop emitting it in a future update, use "Programmed" instead.
          Observed Generation:   1
          Reason:                Ready
          Status:                True
          Type:                  Ready
        Name:                    http
        Supported Kinds:
          Group:  gateway.networking.k8s.io
          Kind:   HTTPRoute
    Events:
      Type    Reason  Age                    From                   Message
      ----    ------  ----                   ----                   -------
      Normal  UPDATE  35m (x4 over 10h)      mc-gateway-controller  store/external-http
      Normal  SYNC    4m22s (x216 over 10h)  mc-gateway-controller  SYNC on store/external-http was a success
    
  2. Una volta completato il deployment del gateway, recupera l'indirizzo IP esterno da external-http Gateway.

    kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}" --context gke-west-1 --namespace store
    

    Sostituisci VIP nei passaggi seguenti con l'indirizzo IP ricevuto come output.

  3. Invia il traffico al percorso principale del dominio. Questo bilancia il traffico in store ServiceImport, che si trova nei cluster gke-west-1 e gke-east-1. Il bilanciatore del carico invia il traffico alla regione più vicina a te e potresti non visualizzare le risposte dall'altra regione.

    curl -H "host: store.example.com" http://VIP
    

    L'output conferma che la richiesta è stata eseguita dal pod del cluster gke-east-1:

    {
      "cluster_name": "gke-east-1",
      "zone": "us-east1-b",
      "host_header": "store.example.com",
      "node_name": "gke-gke-east-1-default-pool-7aa30992-t2lp.c.agmsb-k8s.internal",
      "pod_name": "store-5f5b954888-dg22z",
      "pod_name_emoji": "⏭",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-06-01T17:32:51"
    }
    
  4. Invia il traffico al percorso /west. In questo modo, il traffico viene instradato a store-west-1 ServiceImport, che ha solo pod in esecuzione sul cluster gke-west-1. Un'importazione di servizi specifica per il cluster, come store-west-1, consente a un proprietario dell'applicazione di inviare esplicitamente il traffico a un cluster specifico, anziché lasciare che sia il bilanciatore del carico a prendere la decisione.

    curl -H "host: store.example.com" http://VIP/west
    

    L'output conferma che la richiesta è stata eseguita dal pod del cluster gke-west-1:

    {
      "cluster_name": "gke-west-1", 
      "zone": "us-west1-a", 
      "host_header": "store.example.com",
      "node_name": "gke-gke-west-1-default-pool-65059399-2f41.c.agmsb-k8s.internal",
      "pod_name": "store-5f5b954888-d25m5",
      "pod_name_emoji": "🍾",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-06-01T17:39:15",
    }
    
  5. Infine, invia il traffico al percorso /east.

    curl -H "host: store.example.com" http://VIP/east
    

    L'output conferma che la richiesta è stata eseguita dal pod del cluster gke-east-1:

    {
      "cluster_name": "gke-east-1",
      "zone": "us-east1-b",
      "host_header": "store.example.com",
      "node_name": "gke-gke-east-1-default-pool-7aa30992-7j7z.c.agmsb-k8s.internal",
      "pod_name": "store-5f5b954888-hz6mw",
      "pod_name_emoji": "🧜🏾",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-06-01T17:40:48"
    }
    

Routing blu-verde multi-cluster con Gateway

I GatewayClass gke-l7-global-external-managed-*, gke-l7-regional-external-managed-* e gke-l7-rilb-* hanno molte funzionalità avanzate di routing del traffico, tra cui suddivisione del traffico, corrispondenza delle intestazioni, manipolazione delle intestazioni, mirroring del traffico e altro ancora. In questo esempio viene mostrato come utilizzare la suddivisione del traffico in base al peso per controllare esplicitamente la proporzione del traffico tra due cluster GKE.

Questo esempio illustra alcuni passaggi realistici che un proprietario di servizio dovrebbe seguire per spostare o espandere la propria applicazione in un nuovo cluster GKE. Lo scopo dei deployment blu/verdi è ridurre i rischi tramite più passaggi di convalida che confermano il corretto funzionamento del nuovo cluster. Questo esempio illustra quattro fasi di deployment:

  1. 100% -Canary basato su intestazioni: Utilizza il routing delle intestazioni HTTP per inviare solo traffico di test o sintetico al nuovo cluster.
  2. 100%-Copia il traffico: Copia il traffico utente nel cluster canary. In questo modo viene testata la capacità del cluster canary copiando il 100% del traffico utente in questo cluster.
  3. 90%-10%: esegui una suddivisione del traffico del 10% per esporre gradualmente il nuovo cluster al traffico in tempo reale.
  4. 0%-100%: Esegui il passaggio completo al nuovo cluster con la possibilità di tornare al cluster precedente se vengono rilevati errori.

Suddivisione del traffico blu/verde in due cluster GKE

Questo esempio è simile a quello precedente, ma viene implementato un gateway interno multi-cluster. Viene implementato un bilanciatore del carico delle applicazioni interno accessibile solo privatamente dall'interno della VPC. Utilizzerai i cluster e la stessa applicazione di cui hai eseguito il deployment nei passaggi precedenti, ma li eseguirai tramite un gateway diverso.

Prerequisiti

L'esempio seguente si basa su alcuni passaggi descritti in Eseguire il deployment di un gateway multi-cluster esterno. Prima di procedere con questo esempio, assicurati di aver svolto i seguenti passaggi:

  1. Attivare i gateway multi-cluster

  2. Deployment di un'applicazione di demo

    Questo esempio utilizza i cluster gke-west-1 e gke-west-2 che hai già configurato. Questi cluster si trovano nella stessa regione perché gke-l7-rilb-mc GatewayClass è regionale e supporta solo i backend dei cluster nella stessa regione.

  3. Esegui il deployment del servizio e dei ServiceExport necessari su ogni cluster. Se hai eseguito il deployment di Services e ServiceExports dall'esempio precedente, hai già eseguito il deployment di alcuni di questi.

    kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store-west-1-service.yaml
    kubectl apply --context gke-west-2 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store-west-2-service.yaml
    

    Esegue il deployment di un insieme di risorse simile in ogni cluster:

    service/store created
    serviceexport.net.gke.io/store created
    service/store-west-2 created
    serviceexport.net.gke.io/store-west-2 created
    

Configurazione di una subnet solo proxy

Se non lo hai già fatto, configura una sottorete solo proxy per ogni regione in cui stai implementando i gateway interni. Questa subnet viene utilizzata per fornire indirizzi IP interni ai proxy del bilanciatore del carico e deve essere configurata con un --purpose impostato solo su REGIONAL_MANAGED_PROXY.

Devi creare una subnet solo proxy prima di creare gateway che gestiscono i bilanciatori del carico delle applicazioni interni. Ogni regione di una rete Virtual Private Cloud (VPC) in cui utilizzi bilanciatori del carico delle applicazioni interni deve avere una subnet solo proxy.

Il comando gcloud compute networks subnets create crea una subnet solo proxy.

gcloud compute networks subnets create SUBNET_NAME \
    --purpose=REGIONAL_MANAGED_PROXY \
    --role=ACTIVE \
    --region=REGION \
    --network=VPC_NETWORK_NAME \
    --range=CIDR_RANGE

Sostituisci quanto segue:

  • SUBNET_NAME: il nome della subnet solo proxy.
  • REGION: la regione della subnet solo proxy.
  • VPC_NETWORK_NAME: il nome della rete VPC che contiene la subnet.
  • CIDR_RANGE: l'intervallo di indirizzi IP principale della subnet. Devi utilizzare una subnet mask non superiore a /26 in modo che siano disponibili almeno 64 indirizzi IP per i proxy nella regione. La subnet mask consigliata è /23.

Deployment del gateway

Il seguente gateway viene creato dalla classe GatewayClass gke-l7-rilb-mc. Si tratta di un gateway interno regionale che può avere come target solo i cluster GKE nella stessa regione.

  1. Applica il seguente manifest Gateway al cluster di configurazione gke-west-1 in questo esempio:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: internal-http
      namespace: store
    spec:
      gatewayClassName: gke-l7-rilb-mc
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          kinds:
          - kind: HTTPRoute
    EOF
    
  2. Verifica che il gateway sia stato avviato correttamente. Puoi filtrare solo gli eventi di questo gateway con il seguente comando:

    kubectl get events --field-selector involvedObject.kind=Gateway,involvedObject.name=internal-http --context=gke-west-1 --namespace store
    

    Il deployment di Gateway è andato a buon fine se l'output è simile al seguente:

    LAST SEEN   TYPE     REASON   OBJECT                  MESSAGE
    5m18s       Normal   ADD      gateway/internal-http   store/internal-http
    3m44s       Normal   UPDATE   gateway/internal-http   store/internal-http
    3m9s        Normal   SYNC     gateway/internal-http   SYNC on store/internal-http was a success
    

Canary basato su intestazione

Il canarying basato sugli intestazioni consente al proprietario del servizio di associare il traffico di test sintetico che non proviene da utenti reali. Si tratta di un modo semplice per verificare che la rete di base dell'applicazione funzioni senza esporre direttamente gli utenti.

  1. Applica il seguente manifest HTTPRoute al cluster di configurazione gke-west-1 in questo esempio:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: internal-store-route
      namespace: store
      labels:
        gateway: internal-http
    spec:
      parentRefs:
      - kind: Gateway
        namespace: store
        name: internal-http
      hostnames:
      - "store.example.internal"
      rules:
      # Matches for env=canary and sends it to store-west-2 ServiceImport
      - matches:
        - headers:
          - name: env
            value: canary
        backendRefs:
          - group: net.gke.io
            kind: ServiceImport
            name: store-west-2
            port: 8080
      # All other traffic goes to store-west-1 ServiceImport
      - backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          name: store-west-1
          port: 8080
    EOF
    

    Una volta implementato, questo HTTPRoute configura il seguente comportamento di routing:

    • Le richieste interne a store.example.internal senza l'env: canary intestazione HTTP vengono inoltrate ai pod store nel cluster gke-west-1
    • Le richieste interne a store.example.internal con l'intestazione HTTP env: canary vengono indirizzate ai pod store nel cluster gke-west-2

    HTTPRoute consente il routing verso cluster diversi in base alle intestazioni HTTP

    Verifica che HTTPRoute funzioni correttamente inviando traffico all'indirizzo IP del gateway.

  2. Recupera l'indirizzo IP interno da internal-http.

    kubectl get gateways.gateway.networking.k8s.io internal-http -o=jsonpath="{.status.addresses[0].value}" --context gke-west-1 --namespace store
    

    Sostituisci VIP nei passaggi seguenti con l'indirizzo IP ricevuto come output.

  3. Invia una richiesta al gateway utilizzando l'intestazione HTTP env: canary. In questo modo, confirmi che il traffico viene indirizzato a gke-west-2. Utilizza un client privato nella stessa VPC dei cluster GKE per verificare che le richieste vengano instradate correttamente. Il seguente comando deve essere eseguito su una macchina che abbia accesso privato all'indirizzo IP del gateway, altrimenti non funzionerà.

    curl -H "host: store.example.internal" -H "env: canary" http://VIP
    

    L'output conferma che la richiesta è stata eseguita da un pod del cluster gke-west-2:

    {
        "cluster_name": "gke-west-2", 
        "host_header": "store.example.internal",
        "node_name": "gke-gke-west-2-default-pool-4cde1f72-m82p.c.agmsb-k8s.internal",
        "pod_name": "store-5f5b954888-9kdb5",
        "pod_name_emoji": "😂",
        "project_id": "agmsb-k8s",
        "timestamp": "2021-05-31T01:21:55",
        "zone": "us-west1-a"
    }
    

Specchio retrovisore

Questa fase invia il traffico al cluster previsto, ma lo esegue anche nel cluster canary.

L'utilizzo del mirroring è utile per determinare in che modo il carico del traffico influirà sul rendimento dell'applicazione senza influire in alcun modo sulle risposte ai clienti. Potrebbe non essere necessario per tutti i tipi di implementazioni, ma può essere utile per implementare modifiche sostanziali che potrebbero influire sul rendimento o sul carico.

  1. Applica il seguente manifest HTTPRoute al cluster di configurazione gke-west-1 in questo esempio:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: internal-store-route
      namespace: store
      labels:
        gateway: internal-http
    spec:
      parentRefs:
      - kind: Gateway
        namespace: store
        name: internal-http
      hostnames:
      - "store.example.internal"
      rules:
      # Sends all traffic to store-west-1 ServiceImport
      - backendRefs:
        - name: store-west-1
          group: net.gke.io
          kind: ServiceImport
          port: 8080
        # Also mirrors all traffic to store-west-2 ServiceImport
        filters:
        - type: RequestMirror
          requestMirror:
            backendRef:
              group: net.gke.io
              kind: ServiceImport
              name: store-west-2
              port: 8080
    EOF
    
  2. Utilizzando il tuo client privato, invia una richiesta al gateway internal-http. Utilizza il percorso /mirror per identificare in modo univoco questa richiesta nei log dell'applicazione in un passaggio successivo.

    curl -H "host: store.example.internal" http://VIP/mirror
    
  3. L'output conferma che il client ha ricevuto una risposta da un pod nel gke-west-1 cluster:

    {
        "cluster_name": "gke-west-1", 
        "host_header": "store.example.internal",
        "node_name": "gke-gke-west-1-default-pool-65059399-ssfq.c.agmsb-k8s.internal",
        "pod_name": "store-5f5b954888-brg5w",
        "pod_name_emoji": "🎖",
        "project_id": "agmsb-k8s",
        "timestamp": "2021-05-31T01:24:51",
        "zone": "us-west1-a"
    }
    

    Ciò conferma che il cluster principale risponde al traffico. Devi comunque confermare che il cluster di destinazione della migrazione stia ricevendo il traffico sottoposto a mirroring.

  4. Controlla i log dell'applicazione di un pod store nel cluster gke-west-2. I log dovrebbero confermare che il pod ha ricevuto traffico sottoposto a mirroring dal bilanciatore del carico.

    kubectl logs deployment/store --context gke-west-2 -n store | grep /mirror
    
  5. Questo output conferma che anche i pod del cluster gke-west-2 ricevono le stesse richieste, ma le loro risposte a queste richieste non vengono inviate al client. Gli indirizzi IP visualizzati nei log sono quelli degli indirizzi IP interni del bilanciatore del carico che comunicano con i tuoi pod.

    Found 2 pods, using pod/store-5c65bdf74f-vpqbs
    [2023-10-12 21:05:20,805] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:20] "GET /mirror HTTP/1.1" 200 -
    [2023-10-12 21:05:27,158] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:27] "GET /mirror HTTP/1.1" 200 -
    [2023-10-12 21:05:27,805] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:27] "GET /mirror HTTP/1.1" 200 -
    

Suddivisione traffico

La suddivisione del traffico è uno dei metodi più comuni per implementare nuovo codice o eseguire il deployment in nuovi ambienti in modo sicuro. Il proprietario del servizio imposta una percentuale esplicita del traffico inviato ai backend canary, che in genere corrisponde a una quantità molto piccola del traffico complessivo, in modo che il successo dell'implementazione possa essere determinato con un livello di rischio accettabile per le richieste degli utenti reali.

Eseguire una suddivisione del traffico con una minoranza del traffico consente al proprietario del servizio di controllare l'integrità dell'applicazione e delle risposte. Se tutti gli indicatori sembrano essere in regola, è possibile procedere con il passaggio completo.

  1. Applica il seguente manifest HTTPRoute al cluster di configurazione gke-west-1 in questo esempio:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: internal-store-route
      namespace: store
      labels:
        gateway: internal-http
    spec:
      parentRefs:
      - kind: Gateway
        namespace: store
        name: internal-http
      hostnames:
      - "store.example.internal"
      rules:
      - backendRefs:
        # 90% of traffic to store-west-1 ServiceImport
        - name: store-west-1
          group: net.gke.io
          kind: ServiceImport
          port: 8080
          weight: 90
        # 10% of traffic to store-west-2 ServiceImport
        - name: store-west-2
          group: net.gke.io
          kind: ServiceImport
          port: 8080
          weight: 10
    EOF
    
  2. Utilizzando il tuo client privato, invia una richiesta curl continua al gateway internal- http.

    while true; do curl -H "host: store.example.internal" -s VIP | grep "cluster_name"; sleep 1; done
    

    L'output sarà simile a questo, a indicare che si sta verificando una suddivisione del traffico 90/10.

    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-2",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    ...
    

Passaggio del traffico

L'ultima fase della migrazione blue-green consiste nel passare completamente al nuovo cluster e rimuovere il vecchio cluster. Se il proprietario del servizio stava eseguendo l'onboarding di un secondo cluster in un cluster esistente, questo ultimo passaggio sarebbe diverso, in quanto il traffico verrebbe indirizzato a entrambi i cluster. In questo caso, è consigliabile un singolo store ServiceImport con pod di entrambi i cluster gke-west-1 e gke-west-2. In questo modo, il bilanciatore del carico può decidere dove indirizzare il traffico per un'applicazione active-active in base a prossimità, integrità e capacità.

  1. Applica il seguente manifest HTTPRoute al cluster di configurazione gke-west-1 in questo esempio:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: internal-store-route
      namespace: store
      labels:
        gateway: internal-http
    spec:
      parentRefs:
      - kind: Gateway
        namespace: store
        name: internal-http
      hostnames:
      - "store.example.internal"
      rules:
        - backendRefs:
          # No traffic to the store-west-1 ServiceImport
          - name: store-west-1
            group: net.gke.io
            kind: ServiceImport
            port: 8080
            weight: 0
          # All traffic to the store-west-2 ServiceImport
          - name: store-west-2
            group: net.gke.io
            kind: ServiceImport
            port: 8080
            weight: 100
    EOF
    
  2. Utilizzando il tuo client privato, invia una richiesta curl continua al gateway internal- http.

    while true; do curl -H "host: store.example.internal" -s VIP | grep "cluster_name"; sleep 1; done
    

    L'output sarà simile a questo, a indicare che tutto il traffico ora viene indirizzato a gke-west-2.

    "cluster_name": "gke-west-2",
    "cluster_name": "gke-west-2",
    "cluster_name": "gke-west-2",
    "cluster_name": "gke-west-2",
    ...
    

Questo passaggio finale completa una migrazione completa delle applicazioni blue-green da un cluster GKE a un altro cluster GKE.

Esegui il deployment del bilanciamento del carico in base alla capacità

L'esercizio in questa sezione illustra i concetti di bilanciamento del carico globale e capacità del servizio eseguendo il deployment di un'applicazione in due cluster GKE in regioni diverse. Il traffico generato viene inviato a vari livelli di richieste al secondo (RPS) per mostrare come il traffico viene bilanciato in base al carico tra cluster e regioni.

Il seguente diagramma mostra la topologia che verrà implementata e il modo in cui il traffico viene trasferito tra cluster e regioni quando ha superato la capacità del servizio:

Trafico in eccesso da un cluster all&#39;altro

Per scoprire di più sulla gestione del traffico, consulta Gestione del traffico GKE.

prepara l'ambiente

  1. Segui la sezione Attivare i gateway multi-cluster per preparare l'ambiente.

  2. Verifica che le risorse GatewayClass siano installate sul cluster di configurazione:

    kubectl get gatewayclasses --context=gke-west-1
    

    L'output è simile al seguente:

    NAME                                  CONTROLLER                  ACCEPTED   AGE
    gke-l7-global-external-managed        networking.gke.io/gateway   True       16h
    gke-l7-global-external-managed-mc     networking.gke.io/gateway   True       14h
    gke-l7-gxlb                           networking.gke.io/gateway   True       16h
    gke-l7-gxlb-mc                        networking.gke.io/gateway   True       14h
    gke-l7-regional-external-managed      networking.gke.io/gateway   True       16h
    gke-l7-regional-external-managed-mc   networking.gke.io/gateway   True       14h
    gke-l7-rilb                           networking.gke.io/gateway   True       16h
    gke-l7-rilb-mc                        networking.gke.io/gateway   True       14h
    

Deployment di un'applicazione

Esegui il deployment del server dell'applicazione web di esempio in entrambi i cluster:

kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/store-traffic-deploy.yaml
kubectl apply --context gke-east-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/store-traffic-deploy.yaml

L'output è simile al seguente:

namespace/store created
deployment.apps/store created

Esegui il deployment di un servizio, un gateway e un parametro HTTPRoute

  1. Applica il seguente manifest Service ai cluster gke-west-1 e gke-east-1:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: store
      namespace: traffic-test
      annotations:
        networking.gke.io/max-rate-per-endpoint: "10"
    spec:
      ports:
      - port: 8080
        targetPort: 8080
        name: http
      selector:
        app: store
      type: ClusterIP
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store
      namespace: traffic-test
    EOF
    
    cat << EOF | kubectl apply --context gke-east-1 -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: store
      namespace: traffic-test
      annotations:
        networking.gke.io/max-rate-per-endpoint: "10"
    spec:
      ports:
      - port: 8080
        targetPort: 8080
        name: http
      selector:
        app: store
      type: ClusterIP
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store
      namespace: traffic-test
    EOF
    

    Il servizio è annotato con max-rate-per-endpoint impostato su 10 richieste al secondo. Con 2 repliche per cluster, ogni servizio ha una capacità di 20 RPS per cluster.

    Per ulteriori informazioni su come scegliere un livello di capacità del servizio per il tuo servizio, consulta Determinare la capacità del servizio.

  2. Applica il seguente manifest Gateway al cluster di configurazione gke-west-1 in questo esempio:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: store
      namespace: traffic-test
    spec:
      gatewayClassName: gke-l7-global-external-managed-mc
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          kinds:
          - kind: HTTPRoute
    EOF
    

    Il manifest descrive un gateway multicluster esterno e globale che esegue il deployment di un bilanciatore del carico delle applicazioni esterno con un indirizzo IP accessibile pubblicamente.

  3. Applica il seguente manifest HTTPRoute al cluster di configurazione gke-west-1 in questo esempio:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: store
      namespace: traffic-test
      labels:
        gateway: store
    spec:
      parentRefs:
      - kind: Gateway
        namespace: traffic-test
        name: store
      rules:
      - backendRefs:
        - name: store
          group: net.gke.io
          kind: ServiceImport
          port: 8080
    EOF
    

    Il manifest descrive un parametro HTTPRoute che configura il gateway con una regola di routing che indirizza tutto il traffico a ServiceImport del negozio. store ServiceImport raggruppa i pod di servizio store in entrambi i cluster e consente loro di essere indirizzati dal bilanciatore del carico come un singolo servizio.

    Puoi controllare gli eventi del gateway dopo alcuni minuti per verificare se il deployment è stato completato:

    kubectl describe gateway store -n traffic-test --context gke-west-1
    

    L'output è simile al seguente:

    ...
    Status:
      Addresses:
        Type:   IPAddress
        Value:  34.102.159.147
      Conditions:
        Last Transition Time:  2023-10-12T21:40:59Z
        Message:               The OSS Gateway API has deprecated this condition, do not depend on it.
        Observed Generation:   1
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
        Last Transition Time:  2023-10-12T21:40:59Z
        Message:               
        Observed Generation:   1
        Reason:                Accepted
        Status:                True
        Type:                  Accepted
        Last Transition Time:  2023-10-12T21:40:59Z
        Message:               
        Observed Generation:   1
        Reason:                Programmed
        Status:                True
        Type:                  Programmed
        Last Transition Time:  2023-10-12T21:40:59Z
        Message:               The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use.  GKE Gateway will stop emitting it in a future update, use "Programmed" instead.
        Observed Generation:   1
        Reason:                Ready
        Status:                True
        Type:                  Ready
      Listeners:
        Attached Routes:  1
        Conditions:
          Last Transition Time:  2023-10-12T21:40:59Z
          Message:               
          Observed Generation:   1
          Reason:                Programmed
          Status:                True
          Type:                  Programmed
          Last Transition Time:  2023-10-12T21:40:59Z
          Message:               The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use.  GKE Gateway will stop emitting it in a future update, use "Programmed" instead.
          Observed Generation:   1
          Reason:                Ready
          Status:                True
          Type:                  Ready
        Name:                    http
        Supported Kinds:
          Group:  gateway.networking.k8s.io
          Kind:   HTTPRoute
    Events:
      Type    Reason  Age                  From                   Message
      ----    ------  ----                 ----                   -------
      Normal  ADD     12m                  mc-gateway-controller  traffic-test/store
      Normal  SYNC    6m43s                mc-gateway-controller  traffic-test/store
      Normal  UPDATE  5m40s (x4 over 12m)  mc-gateway-controller  traffic-test/store
      Normal  SYNC    118s (x6 over 10m)   mc-gateway-controller  SYNC on traffic-test/store was a success
    

    Questo output mostra che il deployment del gateway è stato eseguito correttamente. Potrebbero essere necessari ancora alcuni minuti prima che il traffico inizi a passare dopo il deployment del gateway. Prendi nota dell'indirizzo IP in questo output, poiché verrà utilizzato in un passaggio successivo.

Conferma traffico

Verifica che il traffico venga inoltrato all'applicazione testando l'indirizzo IP del gateway con un comando curl:

curl GATEWAY_IP_ADDRESS

L'output è simile al seguente:

{
  "cluster_name": "gke-west-1",
  "host_header": "34.117.182.69",
  "pod_name": "store-54785664b5-mxstv",
  "pod_name_emoji": "👳🏿",
  "project_id": "project",
  "timestamp": "2021-11-01T14:06:38",
  "zone": "us-west1-a"
}

Questo output mostra i metadati del pod, che indicano la regione da cui è stata eseguita la richiesta.

Verificare il traffico utilizzando i test di carico

Per verificare il funzionamento del bilanciatore del carico, puoi eseguire il deployment di un generatore di traffico nel tuo cluster gke-west-1. Il generatore di traffico genera traffico a diversi livelli di carico per dimostrare la capacità e le funzionalità di overflow del bilanciatore del carico. I passaggi che seguono mostrano tre livelli di carico:

  • 10 RPS, che è inferiore alla capacità del servizio dello Store in gke-west-1.
  • 30 RPS, che supera la capacità del servizio del negozio gke-west-1 e causa un overflow del traffico verso gke-east-1.
  • 60 RPS, che supera la capacità dei servizi in entrambi i cluster.

Configura dashboard

  1. Ottieni il nome della mappatura URL sottostante per il tuo gateway:

    kubectl get gateway store -n traffic-test --context=gke-west-1 -o=jsonpath="{.metadata.annotations.networking\.gke\.io/url-maps}"
    

    L'output è simile al seguente:

    /projects/PROJECT_NUMBER/global/urlMaps/gkemcg1-traffic-test-store-armvfyupay1t
    
  2. Nella console Google Cloud, vai alla pagina Esplora metriche.

    Vai a Esplora metriche

  3. In Seleziona una metrica, fai clic su CODICE: MQL.

  4. Inserisci la seguente query per osservare le metriche sul traffico per il servizio Store nei due cluster:

    fetch https_lb_rule
    | metric 'loadbalancing.googleapis.com/https/backend_request_count'
    | filter (resource.url_map_name == 'GATEWAY_URL_MAP')
    | align rate(1m)
    | every 1m
    | group_by [resource.backend_scope],
        [value_backend_request_count_aggregate:
            aggregate(value.backend_request_count)]
    

    Sostituisci GATEWAY_URL_MAP con il nome della mappa di URL del passaggio precedente.

  5. Fai clic su Esegui query. Attendi almeno 5 minuti dopo aver eseguito il deployment del generatore di carica nella sezione successiva affinché le metriche vengano visualizzate nel grafico.

Esegui il test con 10 RPS

  1. Esegui il deployment di un pod nel tuo cluster gke-west-1:

    kubectl run --context gke-west-1 -i --tty --rm loadgen  \
        --image=cyrilbkr/httperf  \
        --restart=Never  \
        -- /bin/sh -c 'httperf  \
        --server=GATEWAY_IP_ADDRESS  \
        --hog --uri="/zone" --port 80  --wsess=100000,1,1 --rate 10'
    

    Sostituisci GATEWAY_IP_ADDRESS con l'indirizzo IP del gateway del passaggio precedente.

    L'output è simile al seguente, a indicare che il generatore di traffico invia traffico:

    If you don't see a command prompt, try pressing enter.
    

    Il generatore di carico invia continuamente 10 RPS al gateway. Anche se il traffico proviene dall'interno di una regione Google Cloud, il bilanciatore del carico lo tratta come traffico client proveniente dalla costa occidentale degli Stati Uniti. Per simulare una diversità realistica dei client, il generatore di carico invia ogni richiesta HTTP come nuova connessione TCP, il che significa che il traffico viene distribuito più uniformemente tra i pod di backend.

    Il generatore impiega fino a 5 minuti per generare traffico per la dashboard.

  2. Visualizza la dashboard di Esplora metriche. Vengono visualizzate due righe che indicano la quantità di traffico bilanciato in base al carico su ciascun cluster:

    Grafico che mostra il bilanciamento del carico del traffico nei cluster

    Dovresti vedere che us-west1-a riceve circa 10 RPS di traffico mentre us-east1-b non riceve traffico. Poiché il generatore di traffico è in esecuzione in us-west1, tutto il traffico viene inviato al servizio nel cluster gke-west-1.

  3. Interrompi il generatore di carico utilizzando Ctrl+C, quindi elimina il pod:

    kubectl delete pod loadgen --context gke-west-1
    

Esegui il test con 30 RPS

  1. Esegui di nuovo il deployment del generatore di carico, ma configurato per inviare 30 RPS:

    kubectl run --context gke-west-1 -i --tty --rm loadgen  \
        --image=cyrilbkr/httperf  \
        --restart=Never  \
        -- /bin/sh -c 'httperf  \
        --server=GATEWAY_IP_ADDRESS  \
        --hog --uri="/zone" --port 80  --wsess=100000,1,1 --rate 30'
    

    Il generatore impiega fino a 5 minuti per generare traffico per la dashboard.

  2. Visualizza la dashboard di Cloud Ops.

    Grafico che mostra il traffico in eccesso in gke-east-1

    Dovresti vedere che vengono inviati circa 20 RPS a us-west1-a e 10 RPS a us-east1-b. Ciò indica che il servizio in gke-west-1 è completamente utilizzato e supera 10 RPS di traffico verso il servizio in gke-east-1.

  3. Interrompi il generatore di carico utilizzando Ctrl+C, quindi elimina il pod:

    kubectl delete pod loadgen --context gke-west-1
    

Esegui il test con 60 RPS

  1. Esegui il deployment del generatore di carico configurato per inviare 60 RPS:

    kubectl run --context gke-west-1 -i --tty --rm loadgen  \
        --image=cyrilbkr/httperf  \
        --restart=Never  \
        -- /bin/sh -c 'httperf  \
        --server=GATEWAY_IP_ADDRESS  \
        --hog --uri="/zone" --port 80  --wsess=100000,1,1 --rate 60'
    
  2. Attendi 5 minuti e visualizza la dashboard di Cloud Ops. Ora dovrebbe essere visualizzato che entrambi i cluster ricevono circa 30 RPS. Poiché tutti i servizi sono sovrautilizzati a livello globale, non si verificano sbordamenti di traffico e i servizi assorbono tutto il traffico possibile.

    Grafico che mostra i servizi sovrautilizzati

  3. Interrompi il generatore di carico utilizzando Ctrl+C, quindi elimina il pod:

    kubectl delete pod loadgen --context gke-west-1
    

Esegui la pulizia

Dopo aver completato gli esercizi in questa pagina, segui questi passaggi per rimuovere le risorse ed evitare addebiti indesiderati sul tuo account:

  1. Elimina i cluster.

  2. Annullare la registrazione dei cluster dal parco risorse se non devono essere registrati per un altro scopo.

  3. Disattiva la funzionalità multiclusterservicediscovery:

    gcloud container fleet multi-cluster-services disable
    
  4. Disabilita Ingress multi-cluster:

    gcloud container fleet ingress disable
    
  5. Disattiva le API:

    gcloud services disable \
        multiclusterservicediscovery.googleapis.com \
        multiclusteringress.googleapis.com \
        trafficdirector.googleapis.com \
        --project=PROJECT_ID
    

Utilizzare il gateway multi-cluster con VPC condiviso

Un gateway multi-cluster può essere implementato anche in un ambiente VPC condiviso, con topologie diverse a seconda del caso d'uso.

La tabella seguente descrive le topologie di gateway multi-cluster supportate in un ambiente VPC condiviso:

Scenario Progetto host del parco risorse Config cluster Cluster di carichi di lavoro
1 Progetto host VPC condiviso Progetto host VPC condiviso Progetto host VPC condiviso
2 Progetto di servizio VPC condiviso Progetto di servizio VPC condiviso
(uguale a progetto di servizio del parco risorse)
Progetto di servizio VPC condiviso
(uguale a progetto di servizio del parco risorse)

Per creare gateway multi-cluster in un ambiente VPC condiviso, segui i passaggi riportati di seguito:

  1. Segui la procedura per configurare i servizi multi-cluster con VPC condiviso

  2. Crea i servizi ed esportali nel cluster di configurazione

  3. Se prevedi di utilizzare un gateway interno multi-cluster, crea una subnet solo proxy

  4. Crea Gateway e HTTPRoutes esterni o interni multi-cluster

Al termine di questi passaggi, puoi convalidare il deployment, a seconda della tua topologia.

Risoluzione dei problemi

La subnet solo proxy per il gateway interno non esiste

Se nel gateway interno viene visualizzato il seguente evento, significa che per la regione in questione non esiste una subnet solo proxy. Per risolvere il problema, esegui il deployment di una sottorete solo proxy.

generic::invalid_argument: error ensuring load balancer: Insert: Invalid value for field 'resource.target': 'regions/us-west1/targetHttpProxies/gkegw-x5vt-default-internal-http-2jzr7e3xclhj'. A reserved and active subnetwork is required in the same region and VPC as the forwarding rule.

Nessun upstream integro

Sintomo:

Quando crei un gateway, ma non riesci ad accedere ai servizi di backend (codice di risposta 503), potrebbe verificarsi il seguente problema:

no healthy upstream

Motivo:

Questo messaggio di errore indica che lo strumento di controllo di integrità non riesce a trovare servizi di backend sani. È possibile che i servizi di backend siano integri, ma potrebbe essere necessario personalizzare i controlli di integrità.

Soluzione:

Per risolvere il problema, personalizza il controllo di integrità in base ai requisiti della tua applicazione (ad esempio /health) utilizzando un HealthCheckPolicy.

Passaggi successivi