Esegui il deployment di un gateway multi-cluster per il bilanciamento del carico basato sulla capacità

Questo documento ti guida nel deployment di un'applicazione di esempio su due cluster GKE in regioni diverse e mostra come il gateway multi-cluster instrada in modo intelligente il traffico quando supera i limiti di capacità del servizio.

Il bilanciamento del carico basato sulla capacità è una funzionalità dei gateway multi-cluster che ti aiuta a creare applicazioni altamente affidabili e resilienti. Definendo la capacità dei tuoi servizi, puoi proteggerli dal sovraccarico e contribuire a garantire un'esperienza coerente per i tuoi utenti. Quando un servizio in un cluster raggiunge la sua capacità, il bilanciatore del carico reindirizza automaticamente il traffico a un altro cluster con capacità disponibile. Per saperne di più sulla gestione del traffico, consulta la sezione Gestione del traffico GKE.

In questo tutorial utilizzerai un'applicazione store di esempio per simulare uno scenario reale in cui un servizio di shopping online è di proprietà e gestito da team separati e viene implementato in una flotta di cluster GKE condivisi.

Prima di iniziare

I gateway multicluster richiedono una preparazione dell'ambiente prima di poter essere implementati. Prima di procedere, segui i passaggi descritti in Prepara l'ambiente per i gateway multi-cluster:

  1. Esegui il deployment dei cluster GKE.

  2. Registra i cluster in un parco risorse (se non lo sono già).

  3. Abilita i controller del servizio multi-cluster e del gateway multi-cluster.

Infine, esamina le limitazioni e i problemi noti del controller GKE Gateway prima di utilizzarlo nel tuo ambiente.

Deployment del bilanciamento del carico basato sulla 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 viene bilanciato il carico del traffico tra cluster e regioni.

Il seguente diagramma mostra la topologia che verrà implementata e come il traffico si riversa tra cluster e regioni quando il traffico ha superato la capacità del servizio:

Traffico che si riversa da un cluster all'altro

prepara l'ambiente

  1. Segui le istruzioni riportate in Prepara l'ambiente per i gateway multicluster 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
    

Esegui il 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 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 due repliche per cluster, ogni servizio ha una capacità di 20 RPS per cluster.

    Per maggiori 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/v1
    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 esterno, globale e multicluster 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/v1
    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 HTTPRoute che configura il gateway con una regola di routing che indirizza tutto il traffico a ServiceImport store. store ServiceImport raggruppa i pod di servizio store in entrambi i cluster e consente al bilanciatore del carico di indirizzarli come un unico servizio.

    Puoi controllare gli eventi del gateway dopo qualche minuto per vedere 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 gateway è stato eseguito il deployment correttamente. Potrebbero essere necessari alcuni minuti prima che il traffico inizi a passare dopo il deployment del gateway. Prendi nota dell'indirizzo IP in questo output, poiché viene utilizzato in un passaggio successivo.

Conferma il traffico

Verifica che il traffico venga trasmesso 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 gestita la richiesta.

Verifica il traffico utilizzando i test di carico

Per verificare che il bilanciatore del carico funzioni, 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 seguenti passaggi mostrano tre livelli di carico:

  • 10 RPS, che rientra nella capacità del servizio di archiviazione in gke-west-1.
  • 30 RPS, che supera la capacità del servizio di negozio gke-west-1 e causa l'overflow del traffico a gke-east-1.
  • 60 RPS, che supera la capacità dei servizi in entrambi i cluster.

Configura dashboard

  1. Recupera il nome della mappa 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 del 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 URL del passaggio precedente.

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

Test con 10 RPS

  1. Esegui il deployment di un pod nel 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, il che indica che il generatore di traffico sta inviando 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 una nuova connessione TCP, il che significa che il traffico viene distribuito in modo più uniforme 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 linee che indicano la quantità di traffico bilanciato del carico in ciascun cluster:

    Grafico che mostra il traffico bilanciato del carico 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. Arresta il generatore di carico utilizzando Ctrl+C, quindi elimina il pod:

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

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 che supera la capacità di 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 è utilizzato completamente e sta trasferendo 10 RPS di traffico al servizio in gke-east-1.

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

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

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 mostrare che entrambi i cluster ricevono circa 30 RPS. Poiché tutti i servizi sono sovrautilizzati a livello globale, non si verifica un overflow del traffico e i servizi assorbono tutto il traffico possibile.

    Grafico che mostra i servizi sovrautilizzati

  3. Arresta 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 descritti in questo documento, segui questi passaggi per rimuovere le risorse ed evitare addebiti indesiderati sul tuo account:

  1. Elimina i cluster.

  2. Annulla 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. Disabilita le API:

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

Risoluzione dei problemi

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 il probe di controllo di integrità non riesce a trovare servizi di backend integri. È possibile che i servizi di backend siano integri, ma potrebbe essere necessario personalizzare i controlli di integrità.

Soluzione temporanea:

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

Passaggi successivi