Esecuzione di servizi distribuiti su cluster privati GKE utilizzando Cloud Service Mesh

Questo documento mostra come eseguire servizi distribuiti su più cluster Google Kubernetes Engine (GKE) in Google Cloud utilizzando Cloud Service Mesh. Questo documento mostra anche come esporre un servizio distribuito utilizzando Ingress multi-clusters e Cloud Service Mesh. Puoi utilizzare questo documento per configurare cluster GKE non privati; il documento evidenzia la configurazione destinata esclusivamente ai cluster privati.

Questo documento è destinato agli amministratori delle piattaforme e agli operatori di servizio che hanno conoscenze di base di Kubernetes. Una conoscenza del mesh di servizi è utile, anche se non obbligatoria. Cloud Service Mesh si basa sulla tecnologia open source Istio. Per ulteriori informazioni sul mesh di servizi e su Istio, visita il sito istio.io.

Un servizio distribuito è un servizio Kubernetes che funge da singolo servizio logico. I servizi distribuiti sono più resilienti dei servizi Kubernetes perché vengono eseguiti su più cluster Kubernetes nello stesso spazio dei nomi. Un servizio distribuito rimane attivo anche se uno o più cluster GKE non funzionano, a condizione che i cluster integri siano in grado di gestire il carico desiderato.

I servizi Kubernetes sono noti solo al server API Kubernetes del cluster su cui vengono eseguiti. Se il cluster Kubernetes non è attivo (ad esempio durante una manutenzione pianificata), anche tutti i servizi Kubernetes in esecuzione su quel cluster non sono attivi. L'esecuzione di servizi distribuiti semplifica la gestione del ciclo di vita del cluster perché puoi disattivare i cluster per la manutenzione o gli upgrade mentre altri cluster gestiscono il traffico di servizio. Per creare un servizio distribuito, la funzionalità di mesh di servizi fornita da Cloud Service Mesh viene utilizzata per collegare i servizi in esecuzione su più cluster in modo che agiscano come un unico servizio logico.

I cluster privati GKE consentono di configurare i nodi e il server API come risorse private disponibili solo sulla rete Virtual Private Cloud (VPC). L'esecuzione di servizi distribuiti nei cluster privati GKE offre alle aziende servizi sicuri e affidabili.

Architettura

Questo tutorial utilizza l'architettura mostrata nel seguente diagramma:

Architettura dei servizi distribuiti sui cluster privati GKE utilizzando Cloud Service Mesh

Nel diagramma precedente, l'architettura include i seguenti cluster:

  • Due cluster (gke-central-priv e gke-west-priv) fungono da cluster privati GKE identici in due regioni diverse.
  • Un cluster separato (ingress-config) funge da cluster del control plane che configura Ingress multi-cluster.

In questo tutorial, esegui il deployment dell'applicazione di esempio Bank of Anthos su due cluster privati GKE (gke-central-priv e gke-west-priv). Bank of Anthos è un'applicazione di esempio di microservizi costituita da più microservizi e database SQL che simulano un'app di online banking. L'applicazione è costituita da un frontend web a cui i client possono accedere e da diversi servizi di backend come i servizi di saldo, contabilità e conto che simulano una banca.

L'applicazione include due database PostgreSQL installati in Kubernetes come StatefulSet. Un database viene utilizzato per le transazioni, mentre l'altro per gli account utente. Tutti i servizi, ad eccezione dei due database, vengono eseguiti come servizi distribuiti. Ciò significa che i pod per tutti i servizi vengono eseguiti in entrambi i cluster di applicazioni (nello stesso spazio dei nomi) e Cloud Service Mesh è configurato in modo che ogni servizio venga visualizzato come un unico servizio logico.

Obiettivi

  • Crea tre cluster GKE.
  • Configura due dei cluster GKE come cluster privati (gke-central-priv e gke-west-priv).
  • Configura un cluster GKE (ingress-config) come cluster di configurazione centrale. Questo cluster funge da cluster di configurazione per Ingress multi-cluster.
  • Configura il networking (gateway NAT, router Cloud e regole firewall) per consentire il traffico in uscita e tra cluster dai due cluster GKE privati.
  • Configura le reti autorizzate per consentire l'accesso al servizio API da Cloud Shell ai due cluster GKE privati.
  • Esegui il deployment e configura Cloud Service Mesh multi-cluster nei due cluster privati in modalità multi-primaria. La modalità multi-primary esegue il deployment di un control plane Cloud Service Mesh in entrambi i cluster.
  • Esegui il deployment dell'applicazione Bank of Anthos sui due cluster privati. Tutti i servizi, ad eccezione dei database, vengono implementati come servizi distribuiti (pod in esecuzione su entrambi i cluster privati).
  • Monitora i servizi utilizzando Cloud Service Mesh.
  • Configura Ingress multi-cluster sui servizi frontend di Bank of Anthos. In questo modo, i client esterni (ad esempio il browser web) possono accedere a un servizio distribuito in esecuzione su una flotta di cluster GKE privati.

Costi

In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il calcolatore prezzi.

I nuovi utenti di Google Cloud potrebbero avere diritto a una prova senza costi.

Prima di iniziare

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Verify that billing is enabled for your Google Cloud project.

  3. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    Esegui tutti i comandi di questo tutorial da Cloud Shell.

  4. Definisci le variabili di ambiente utilizzate in questo tutorial. Le variabili definiscono i nomi dei cluster, le regioni, le zone, l'indirizzamento IP e le versioni di Cloud Service Mesh utilizzate in questo tutorial.

    1. Sostituisci YOUR_PROJECT_ID con l'ID progetto:

      export PROJECT_ID=YOUR_PROJECT_ID
      gcloud config set project ${PROJECT_ID}
      
    2. Imposta le variabili di ambiente rimanenti:

      export CLUSTER_1=gke-west-priv
      export CLUSTER_2=gke-central-priv
      export CLUSTER_1_ZONE=us-west2-a
      export CLUSTER_1_REGION=us-west2
      export CLUSTER_1_MASTER_IPV4_CIDR=172.16.0.0/28
      export CLUSTER_2_ZONE=us-central1-a
      export CLUSTER_2_REGION=us-central1
      export CLUSTER_2_MASTER_IPV4_CIDR=172.16.1.0/28
      export CLUSTER_INGRESS=gke-ingress
      export CLUSTER_INGRESS_ZONE=us-west1-a
      export CLUSTER_INGRESS_REGION=us-west1
      export CLUSTER_INGRESS_MASTER_IPV4_CIDR=172.16.2.0/28
      export WORKLOAD_POOL=${PROJECT_ID}.svc.id.goog
      export ASM_VERSION=1.10
      export CLOUDSHELL_IP=$(dig +short myip.opendns.com @resolver1.opendns.com)
      
  5. prepara l'ambiente

    1. In Cloud Shell, abilita le API:

      gcloud services enable \
        --project=${PROJECT_ID} \
        container.googleapis.com \
        mesh.googleapis.com \
        gkehub.googleapis.com
      
    2. Abilita la flotta Cloud Service Mesh per il tuo progetto:

      gcloud container fleet mesh enable --project=${PROJECT_ID}
      

    Prepara il networking per i cluster GKE privati

    In questa sezione, preparerai il networking per i cluster GKE privati che utilizzi per eseguire i servizi distribuiti.

    Ai nodi cluster GKE privati non viene assegnato un indirizzo IP pubblico. A tutti i nodi di un cluster GKE privato viene assegnato un indirizzo IP VPC privato (nello spazio di indirizzi RFC 1918). Ciò significa che i pod che devono accedere a risorse esterne (al di fuori della rete VPC) richiedono un gateway Cloud NAT. I gateway Cloud NAT sono gateway NAT regionali che consentono ai pod con indirizzi IP interni di comunicare con internet. In questo tutorial, configurerai un gateway Cloud NAT in ognuna delle due regioni. Più cluster all'interno di una regione possono utilizzare lo stesso gateway NAT.

    1. In Cloud Shell, crea e riserva due indirizzi IP esterni per i due gateway NAT:

      gcloud compute addresses create ${CLUSTER_1_REGION}-nat-ip \
        --project=${PROJECT_ID} \
        --region=${CLUSTER_1_REGION}
      
      gcloud compute addresses create ${CLUSTER_2_REGION}-nat-ip \
        --project=${PROJECT_ID} \
        --region=${CLUSTER_2_REGION}
      
    2. Memorizza l'indirizzo IP e il nome degli indirizzi IP nelle variabili:

      export NAT_REGION_1_IP_ADDR=$(gcloud compute addresses describe ${CLUSTER_1_REGION}-nat-ip \
        --project=${PROJECT_ID} \
        --region=${CLUSTER_1_REGION} \
        --format='value(address)')
      
      export NAT_REGION_1_IP_NAME=$(gcloud compute addresses describe ${CLUSTER_1_REGION}-nat-ip \
        --project=${PROJECT_ID} \
        --region=${CLUSTER_1_REGION} \
        --format='value(name)')
      
      export NAT_REGION_2_IP_ADDR=$(gcloud compute addresses describe ${CLUSTER_2_REGION}-nat-ip \
        --project=${PROJECT_ID} \
        --region=${CLUSTER_2_REGION} \
        --format='value(address)')
      
      export NAT_REGION_2_IP_NAME=$(gcloud compute addresses describe ${CLUSTER_2_REGION}-nat-ip \
        --project=${PROJECT_ID} \
        --region=${CLUSTER_2_REGION} \
        --format='value(name)')
      
    3. Crea gateway Cloud NAT nelle due regioni dei cluster GKE privati:

      gcloud compute routers create rtr-${CLUSTER_1_REGION} \
        --network=default \
        --region ${CLUSTER_1_REGION}
      
      gcloud compute routers nats create nat-gw-${CLUSTER_1_REGION} \
        --router=rtr-${CLUSTER_1_REGION} \
        --region ${CLUSTER_1_REGION} \
        --nat-external-ip-pool=${NAT_REGION_1_IP_NAME} \
        --nat-all-subnet-ip-ranges \
        --enable-logging
      
      gcloud compute routers create rtr-${CLUSTER_2_REGION} \
        --network=default \
        --region ${CLUSTER_2_REGION}
      
      gcloud compute routers nats create nat-gw-${CLUSTER_2_REGION} \
        --router=rtr-${CLUSTER_2_REGION} \
        --region ${CLUSTER_2_REGION} \
        --nat-external-ip-pool=${NAT_REGION_2_IP_NAME} \
        --nat-all-subnet-ip-ranges \
        --enable-logging
      
    4. Crea una regola firewall che consenta la comunicazione tra pod e tra pod e server API. La comunicazione tra pod consente ai servizi distribuiti di comunicare tra loro nei cluster GKE. La comunicazione da pod a server API consente al piano di controllo di Cloud Service Mesh di eseguire query sui cluster GKE per Service Discovery.

      gcloud compute firewall-rules create all-pods-and-master-ipv4-cidrs \
        --project ${PROJECT_ID} \
        --network default \
        --allow all \
        --direction INGRESS \
        --source-ranges 10.0.0.0/8,${CLUSTER_1_MASTER_IPV4_CIDR},${CLUSTER_2_MASTER_IPV4_CIDR},${CLUSTER_INGRESS_MASTER_IPV4_CIDR}
      

    La rete è ora preparata. In questo tutorial, utilizzi l'intero intervallo di indirizzi IP 10.0.0.0/8, che include tutti gli intervalli di pod. Ti consigliamo di creare una regola firewall più restrittiva in produzione, in base alle tue condizioni e ai tuoi requisiti.

    Crea cluster GKE privati

    In questa sezione, crei i due cluster GKE privati in cui viene eseguito il deployment dell'app di esempio. In questo tutorial, i nodi cluster GKE privati hanno indirizzi IP privati e il server API ha un endpoint pubblico. Tuttavia, l'accesso al server API è limitato tramite le reti autorizzate.

    1. In Cloud Shell, crea due cluster privati con reti autorizzate. Configura i cluster per consentire l'accesso dall'intervallo CIDR IP pod (per il control plane di Cloud Service Mesh) e da Cloud Shell, in modo da poter accedere ai cluster dal terminale.

      gcloud container clusters create ${CLUSTER_1} \
        --project ${PROJECT_ID} \
        --zone=${CLUSTER_1_ZONE} \
        --machine-type "e2-standard-4" \
        --num-nodes "3" --min-nodes "3" --max-nodes "5" \
        --enable-ip-alias --enable-autoscaling \
        --workload-pool=${WORKLOAD_POOL} \
        --enable-private-nodes \
        --master-ipv4-cidr=${CLUSTER_1_MASTER_IPV4_CIDR} \
        --enable-master-authorized-networks \
        --master-authorized-networks $NAT_REGION_1_IP_ADDR/32,$NAT_REGION_2_IP_ADDR/32,$CLOUDSHELL_IP/32
      
      gcloud container clusters create ${CLUSTER_2} \
        --project ${PROJECT_ID} \
        --zone=${CLUSTER_2_ZONE} \
        --machine-type "e2-standard-4" \
        --num-nodes "3" --min-nodes "3" --max-nodes "5" \
        --enable-ip-alias --enable-autoscaling \
        --workload-pool=${WORKLOAD_POOL} \
        --enable-private-nodes \
        --master-ipv4-cidr=${CLUSTER_2_MASTER_IPV4_CIDR} \
        --enable-master-authorized-networks \
        --master-authorized-networks $NAT_REGION_1_IP_ADDR/32,$NAT_REGION_2_IP_ADDR/32,$CLOUDSHELL_IP/32
      

      Le reti autorizzate contengono gli indirizzi IP pubblici sui gateway Cloud NAT. Poiché l'endpoint del server API per un cluster privato è un endpoint pubblico, i pod eseguiti in un cluster privato devono utilizzare un gateway Cloud NAT per accedere agli endpoint del server API pubblici.

      L'indirizzo IP di Cloud Shell fa parte anche delle reti autorizzate, il che ti consente di accedere ai cluster e gestirli dal terminale Cloud Shell. Gli indirizzi IP pubblici di Cloud Shell sono dinamici, quindi ogni volta che avvii Cloud Shell, potresti ottenere un indirizzo IP pubblico diverso. Quando ottieni un nuovo indirizzo IP, perdi l'accesso ai cluster perché il nuovo indirizzo IP non fa parte delle reti autorizzate per i due cluster.

      Se perdi l'accesso ai cluster, aggiorna le reti autorizzate dei cluster in modo da includere il nuovo indirizzo IP di Cloud Shell:

      1. Recupera l'indirizzo IP pubblico aggiornato di Cloud Shell:

        export CLOUDSHELL_IP=$(dig +short myip.opendns.com @resolver1.opendns.com)
        
      2. Aggiorna le reti autorizzate per i due cluster:

        gcloud container clusters update ${CLUSTER_1} \
          --zone=${CLUSTER_1_ZONE} \
          --enable-master-authorized-networks \
          --master-authorized-networks $NAT_REGION_1_IP_ADDR/32,$NAT_REGION_2_IP_ADDR/32,$CLOUDSHELL_IP/32
        
        gcloud container clusters update ${CLUSTER_2} \
          --zone=${CLUSTER_2_ZONE} \
          --enable-master-authorized-networks \
          --master-authorized-networks $NAT_REGION_1_IP_ADDR/32,$NAT_REGION_2_IP_ADDR/32,$CLOUDSHELL_IP/32
        
    2. Verifica che tutti i cluster siano in esecuzione:

      gcloud container clusters list
      

      L'output è simile al seguente:

      NAME              LOCATION       MASTER_VERSION    MASTER_IP      MACHINE_TYPE   NODE_VERSION      NUM_NODES  STATUS
      gke-central-priv  us-central1-a  1.16.15-gke.6000  35.238.99.104  e2-standard-4  1.16.15-gke.6000  3          RUNNING
      gke-west-priv     us-west2-a     1.16.15-gke.6000  34.94.188.180  e2-standard-4  1.16.15-gke.6000  3          RUNNING
      
    3. Connettiti a entrambi i cluster per generare voci nel file kubeconfig:

      touch ~/asm-kubeconfig && export KUBECONFIG=~/asm-kubeconfig
      gcloud container clusters get-credentials ${CLUSTER_1} --zone ${CLUSTER_1_ZONE}
      gcloud container clusters get-credentials ${CLUSTER_2} --zone ${CLUSTER_2_ZONE}
      

      Utilizzi il file kubeconfig per eseguire l'autenticazione ai cluster creando un utente e un contesto per ogni cluster. Dopo aver generato le voci nel file kubeconfig, puoi cambiare rapidamente contesto tra i cluster.

    4. Rinomina i contesti del cluster per comodità:

      kubectl config rename-context \
      gke_${PROJECT_ID}_${CLUSTER_1_ZONE}_${CLUSTER_1} ${CLUSTER_1}
      
      kubectl config rename-context \
      gke_${PROJECT_ID}_${CLUSTER_2_ZONE}_${CLUSTER_2} ${CLUSTER_2}
      
    5. Verifica che entrambi i contesti del cluster siano stati rinominati e configurati correttamente:

      kubectl config get-contexts --output="name"
      

      L'output è simile al seguente:

      gke-central-priv
      gke-west-priv
      
    6. Registra i cluster in un parco risorse:

      gcloud container fleet memberships register ${CLUSTER_1} --gke-cluster=${CLUSTER_1_ZONE}/${CLUSTER_1} --enable-workload-identity
      gcloud container fleet memberships register ${CLUSTER_2} --gke-cluster=${CLUSTER_2_ZONE}/${CLUSTER_2} --enable-workload-identity
      

    Ora hai creato e rinominato i tuoi cluster GKE privati.

    Installa Cloud Service Mesh

    In questa sezione, installa Cloud Service Mesh sui due cluster GKE e configura i cluster per Service Discovery multi-cluster.

    1. In Cloud Shell, installa Cloud Service Mesh su entrambi i cluster utilizzando fleet API:

      gcloud container fleet mesh update --management automatic --memberships ${CLUSTER_1},${CLUSTER_2}
      
    2. Dopo aver abilitato Cloud Service Mesh gestito sui cluster, imposta un monitoraggio per l'installazione del mesh:

      watch -g "gcloud container fleet mesh describe | grep 'code: REVISION_READY'"
      
    3. Installa i gateway in entrata di Cloud Service Mesh per entrambi i cluster:

      kubectl --context=${CLUSTER_1} create namespace asm-ingress
      kubectl --context=${CLUSTER_1} label namespace asm-ingress istio-injection=enabled --overwrite
      kubectl --context=${CLUSTER_2} create namespace asm-ingress
      kubectl --context=${CLUSTER_2} label namespace asm-ingress istio-injection=enabled --overwrite
      
      cat <<'EOF' > asm-ingress.yaml
      apiVersion: v1
      kind: Service
      metadata:
        name: asm-ingressgateway
        namespace: asm-ingress
      spec:
        type: LoadBalancer
        selector:
          asm: ingressgateway
        ports:
        - port: 80
          name: http
        - port: 443
          name: https
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: asm-ingressgateway
        namespace: asm-ingress
      spec:
        selector:
          matchLabels:
            asm: ingressgateway
        template:
          metadata:
            annotations:
              # This is required to tell Anthos Service Mesh to inject the gateway with the
              # required configuration.
              inject.istio.io/templates: gateway
            labels:
              asm: ingressgateway
          spec:
            containers:
            - name: istio-proxy
              image: auto # The image will automatically update each time the pod starts.
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: Role
      metadata:
        name: asm-ingressgateway-sds
        namespace: asm-ingress
      rules:
      - apiGroups: [""]
        resources: ["secrets"]
        verbs: ["get", "watch", "list"]
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: RoleBinding
      metadata:
        name: asm-ingressgateway-sds
        namespace: asm-ingress
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: Role
        name: asm-ingressgateway-sds
      subjects:
      - kind: ServiceAccount
        name: default
      EOF
      
      kubectl --context=${CLUSTER_1} apply -f asm-ingress.yaml
      kubectl --context=${CLUSTER_2} apply -f asm-ingress.yaml
      
    4. Verifica che i gateway in entrata Cloud Service Mesh siano stati sottoposti a deployment:

      kubectl --context=${CLUSTER_1} get pod,service -n asm-ingress
      kubectl --context=${CLUSTER_2} get pod,service -n asm-ingress
      

      L'output per entrambi i cluster è simile al seguente:

      NAME                                        READY   STATUS    RESTARTS   AGE
      pod/asm-ingressgateway-5894744dbd-zxlgc   1/1     Running   0          84s
      
      NAME                           TYPE           CLUSTER-IP    EXTERNAL-IP      PORT(S)                      AGE
      service/asm-ingressgateway   LoadBalancer   10.16.2.131   34.102.100.138   80:30432/TCP,443:30537/TCP   92s
      

      Dopo l'installazione del control plane Cloud Service Mesh e dei gateway in entrata per entrambi i cluster, la service discovery cross-cluster viene abilitata con l'API Fleet. Il rilevamento del servizio tra cluster consente ai due cluster di rilevare gli endpoint di servizio del cluster remoto. I servizi distribuiti vengono eseguiti su più cluster nello stesso spazio dei nomi.

      Affinché entrambi i piani di controllo di Cloud Service Mesh rilevino tutti gli endpoint di un servizio distribuito, Cloud Service Mesh deve avere accesso a tutti i cluster che eseguono il servizio distribuito. Questo esempio utilizza due cluster, quindi entrambi i cluster devono essere in grado di eseguire query sul cluster remoto per gli endpoint di servizio. Con Cloud Service Mesh gestito abilitato con l'API Fleet, l'individuazione degli endpoint viene configurata automaticamente.

    I cluster e Cloud Service Mesh sono ora configurati.

    Esegui il deployment dell'applicazione Bank of Anthos

    1. In Cloud Shell, clona il repository GitHub di Bank of Anthos:

      git clone https://github.com/GoogleCloudPlatform/bank-of-anthos.git ${HOME}/bank-of-anthos
      
    2. Crea ed etichetta uno spazio dei nomi bank-of-anthos in entrambi i cluster. L'etichetta consente l'injection automatica dei proxy sidecar Envoy in ogni pod all'interno dello spazio dei nomi etichettato.

      # cluster_1
      kubectl create --context=${CLUSTER_1} namespace bank-of-anthos
      kubectl label --context=${CLUSTER_1} namespace bank-of-anthos istio-injection=enabled
      
      # cluster_2
      kubectl create --context=${CLUSTER_2} namespace bank-of-anthos
      kubectl label --context=${CLUSTER_2} namespace bank-of-anthos istio-injection=enabled
      
    3. Esegui il deployment dell'applicazione Bank of Anthos in entrambi i cluster nello spazio dei nomi bank-of-anthos.

      # The following secret is used for user account creation and authentication
      kubectl --context=$CLUSTER_1 -n bank-of-anthos apply -f ${HOME}/bank-of-anthos/extras/jwt/jwt-secret.yaml
      kubectl --context=$CLUSTER_2 -n bank-of-anthos apply -f ${HOME}/bank-of-anthos/extras/jwt/jwt-secret.yaml
      
      # Deploy all manifests to both clusters
      kubectl --context=$CLUSTER_1 -n bank-of-anthos apply -f ${HOME}/bank-of-anthos/kubernetes-manifests
      kubectl --context=$CLUSTER_2 -n bank-of-anthos apply -f ${HOME}/bank-of-anthos/kubernetes-manifests
      

      I servizi Kubernetes devono essere presenti in entrambi i cluster per il rilevamento dei servizi. Quando un servizio in uno dei cluster tenta di effettuare una richiesta, esegue prima una ricerca DNS per il nome host per ottenere l'indirizzo IP. In GKE, il server kube-dns in esecuzione nel cluster gestisce questa ricerca, pertanto è necessaria una definizione del servizio configurata.

    4. Elimina StatefulSets da un cluster in modo che i due database PostgreSQL esistano in uno solo dei cluster:

      # Delete the two DB statefulSets from Cluster2
      kubectl --context=$CLUSTER_2 -n bank-of-anthos delete statefulset accounts-db
      kubectl --context=$CLUSTER_2 -n bank-of-anthos delete statefulset ledger-db
      
    5. Assicurati che tutti i pod siano in esecuzione in entrambi i cluster:

      1. Ottieni i pod da cluster_1:

        kubectl --context=${CLUSTER_1} -n bank-of-anthos get pod
        

        L'output è simile al seguente:

        NAME                                  READY   STATUS    RESTARTS   AGE
        accounts-db-0                         2/2     Running   0          9m54s
        balancereader-c5d664b4c-xmkrr         2/2     Running   0          9m54s
        contacts-7fd8c5fb6-wg9xn              2/2     Running   1          9m53s
        frontend-7b7fb9b665-m7cw7             2/2     Running   1          9m53s
        ledger-db-0                           2/2     Running   0          9m53s
        ledgerwriter-7b5b6db66f-xhbp4         2/2     Running   0          9m53s
        loadgenerator-7fb54d57f8-g5lz5        2/2     Running   0          9m52s
        transactionhistory-7fdb998c5f-vqh5w   2/2     Running   1          9m52s
        userservice-76996974f5-4wlpf          2/2     Running   1          9m52s
        
      2. Ottieni i pod da cluster_2:

        kubectl --context=${CLUSTER_2} -n bank-of-anthos get pod
        

        L'output è simile al seguente:

        NAME                                  READY   STATUS    RESTARTS   AGE
        balancereader-c5d664b4c-bn2pl         2/2     Running   0          9m54s
        contacts-7fd8c5fb6-kv8cp              2/2     Running   0          9m53s
        frontend-7b7fb9b665-bdpp4             2/2     Running   0          9m53s
        ledgerwriter-7b5b6db66f-297c2         2/2     Running   0          9m52s
        loadgenerator-7fb54d57f8-tj44v        2/2     Running   0          9m52s
        transactionhistory-7fdb998c5f-xvmtn   2/2     Running   0          9m52s
        userservice-76996974f5-mg7t6          2/2     Running   0          9m51s
        
    6. Esegui il deployment delle configurazioni di Cloud Service Mesh su entrambi i cluster. Vengono creati un gateway nello spazio dei nomi asm-ingress e un VirtualService negli spazi dei nomi bank-of-anthos per il servizio frontend, che consente di ricevere il traffico in entrata nel servizio frontend.

      Gateways sono generalmente di proprietà degli amministratori della piattaforma o del team di amministratori di rete. Pertanto, la risorsa Gateway viene creata nello spazio dei nomi Ingress Gateway di proprietà dell'amministratore della piattaforma e può essere utilizzata in altri spazi dei nomi tramite le proprie voci VirtualService. Questo è un modello "Shared Gateway".

      cat <<'EOF' > asm-vs-gateway.yaml
      apiVersion: networking.istio.io/v1alpha3
      kind: Gateway
      metadata:
        name: asm-ingressgateway
        namespace: asm-ingress
      spec:
        selector:
          asm: ingressgateway
        servers:
          - port:
              number: 80
              name: http
              protocol: HTTP
            hosts:
              - "*"
      ---
      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: frontend
        namespace: bank-of-anthos
      spec:
        hosts:
        - "*"
        gateways:
        - asm-ingress/asm-ingressgateway
        http:
        - route:
          - destination:
              host: frontend
              port:
                number: 80
      EOF
      
      kubectl --context=$CLUSTER_1 apply -f asm-vs-gateway.yaml
      
      kubectl --context=$CLUSTER_2 apply -f asm-vs-gateway.yaml
      

    Ora hai eseguito il deployment dell'applicazione Bank of Anthos su due cluster GKE privati. Tutti i servizi vengono eseguiti come servizi distribuiti, ad eccezione del database.

    Ispeziona i servizi distribuiti

    In questa sezione utilizzerai lo strumento istioctl per ispezionare la configurazione del proxy di uno qualsiasi dei proxy. In questo modo puoi vedere che i proxy sidecar vedono due pod per ogni servizio, con un pod in esecuzione in ogni cluster.

    1. In Cloud Shell, controlla l'elenco di proxy-config Endpoints nel pod frontend in cluster_1:

      export FRONTEND1=$(kubectl get pod -n bank-of-anthos -l app=frontend \
        --context=${CLUSTER_1} -o jsonpath='{.items[0].metadata.name}')
      istioctl proxy-config endpoints \
      --context $CLUSTER_1 -n bank-of-anthos $FRONTEND1 | grep bank-of-anthos
      

      L'output è simile al seguente:

      10.12.0.6:5432                   HEALTHY     OK                outbound|5432||accounts-db.bank-of-anthos.svc.cluster.local
      10.12.0.7:8080                   HEALTHY     OK                outbound|8080||balancereader.bank-of-anthos.svc.cluster.local
      10.12.0.8:8080                   HEALTHY     OK                outbound|8080||transactionhistory.bank-of-anthos.svc.cluster.local
      10.12.0.9:8080                   HEALTHY     OK                outbound|8080||userservice.bank-of-anthos.svc.cluster.local
      10.12.1.10:8080                  HEALTHY     OK                outbound|8080||ledgerwriter.bank-of-anthos.svc.cluster.local
      10.12.1.9:8080                   HEALTHY     OK                outbound|8080||contacts.bank-of-anthos.svc.cluster.local
      10.12.2.11:5432                  HEALTHY     OK                outbound|5432||ledger-db.bank-of-anthos.svc.cluster.local
      10.12.2.13:8080                  HEALTHY     OK                outbound|80||frontend.bank-of-anthos.svc.cluster.local
      10.76.1.10:8080                  HEALTHY     OK                outbound|8080||transactionhistory.bank-of-anthos.svc.cluster.local
      10.76.1.8:8080                   HEALTHY     OK                outbound|8080||balancereader.bank-of-anthos.svc.cluster.local
      10.76.1.9:8080                   HEALTHY     OK                outbound|80||frontend.bank-of-anthos.svc.cluster.local
      10.76.2.10:8080                  HEALTHY     OK                outbound|8080||userservice.bank-of-anthos.svc.cluster.local
      10.76.2.8:8080                   HEALTHY     OK                outbound|8080||contacts.bank-of-anthos.svc.cluster.local
      10.76.2.9:8080                   HEALTHY     OK                outbound|8080||ledgerwriter.bank-of-anthos.svc.cluster.local
      

      Nell'output precedente, ogni servizio distribuito ha due indirizzi IP endpoint. Questi sono gli indirizzi IP dei pod, uno per ogni cluster.

    Accedi a Bank of Anthos

    Per accedere all'applicazione Bank of Anthos, puoi utilizzare l'indirizzo IP pubblico del servizio asm-ingressgateway da uno dei due cluster.

    1. Recupera gli indirizzi IP di asm-ingressgateway da entrambi i cluster:

      kubectl --context ${CLUSTER_1} \
      --namespace asm-ingress get svc asm-ingressgateway -o jsonpath='{.status.loadBalancer}' | grep "ingress"
      
      kubectl --context ${CLUSTER_2} \
      --namespace asm-ingress get svc asm-ingressgateway -o jsonpath='{.status.loadBalancer}' | grep "ingress"
      
      

      L'output è simile al seguente.

      {"ingress":[{"ip":"35.236.4.18"}]}
      {"ingress":[{"ip":"34.68.94.81"}]}
      

      Copia uno degli indirizzi IP da utilizzare nel passaggio successivo.

    2. Apri una nuova scheda in un browser web e vai a uno dei due indirizzi IP dell'output precedente. Dovrebbe essere visualizzato il frontend di Bank of Anthos, che ti consente di accedere, depositare fondi sul tuo account e trasferirli ad altri account. L'applicazione dovrebbe essere completamente funzionale.

    Visualizzare i servizi distribuiti

    Puoi visualizzare i servizi distribuiti in Cloud Service Mesh.

    1. Per visualizzare i tuoi servizi, vai alla pagina Service Mesh nella console Google Cloud .

      Vai a Service Mesh

      Puoi visualizzare i servizi nella visualizzazione Tabella o nella visualizzazione Topologia. La visualizzazione predefinita è la visualizzazione tabella, che mostra tutti i servizi distribuiti in esecuzione in un formato tabellare. Per cambiare visualizzazione, fai clic su quella che vuoi visualizzare.

    2. Nella visualizzazione Tabelle, fai clic su frontend distributed service. Quando fai clic su un singolo servizio, viene visualizzata una visualizzazione dettagliata del servizio insieme ai servizi connessi.

      Nella visualizzazione dei dettagli del servizio, puoi creare SLO e visualizzare una cronologia del servizio facendo clic su Mostra cronologia.

    3. Per visualizzare i segnali d'oro, fai clic su Metriche nel riquadro laterale.

    4. Nel grafico Richieste al secondo, fai clic su Distribuzione per e poi seleziona Località.

      I risultati mostrano le richieste al secondo di entrambi i cluster nelle due regioni. Il servizio distribuito è integro ed entrambi gli endpoint gestiscono il traffico.

    5. Per visualizzare la topologia del mesh di servizi, nel riquadro laterale fai clic su Anthos Service Mesh e poi su Visualizzazione topologia.

    6. Per visualizzare dati aggiuntivi, tieni il puntatore del mouse sopra il servizio frontend. Vengono visualizzate informazioni come le richieste al secondo da e verso il frontend ad altri servizi.

    7. Per visualizzare ulteriori dettagli, fai clic su Espandi nel servizio frontend. Vengono visualizzati un servizio e un workload. Puoi espandere ulteriormente il workload in due deployment, espandere i deployment in ReplicaSet ed espandere i ReplicaSet in pod. Quando espandi tutti gli elementi, puoi vedere il servizio frontend distribuito, che è essenzialmente un servizio e due pod.

    Configura Ingress multi-cluster

    In questa sezione, creerai un Ingress multi-cluster che invia il traffico ai servizi Bank of GKE Enterprise frontend in esecuzione in entrambi i cluster. Utilizzi Cloud Load Balancing per creare un bilanciatore del carico che utilizzi i servizi asm-ingressgateway in entrambi i cluster come backend. Un cluster ingress-config viene utilizzato per orchestrare la configurazione di Ingress multi-cluster.

    Per creare il bilanciatore del carico, utilizzi un MultiClusterIngress e uno o più MultiClusterServices. Gli oggetti MultiClusterIngress e MultiClusterService sono analoghi multi-cluster delle risorse Kubernetes Ingress e Service esistenti utilizzate nel contesto di un singolo cluster.

    1. Abilita le API GKE Enterprise, GKE Fleet e Multi Cluster Ingress richieste:

      gcloud services enable \
        anthos.googleapis.com \
        multiclusterservicediscovery.googleapis.com \
        multiclusteringress.googleapis.com
      
    2. Crea il cluster ingress-config. Puoi utilizzare qualsiasi cluster, ma ti consigliamo di crearne uno separato per questo scopo.

      gcloud container clusters create ${CLUSTER_INGRESS} \
        --zone ${CLUSTER_INGRESS_ZONE} \
        --num-nodes=1 \
        --enable-ip-alias \
        --workload-pool=${WORKLOAD_POOL}
      
    3. Recupera le credenziali del cluster e rinomina il contesto per comodità:

      gcloud container clusters get-credentials ${CLUSTER_INGRESS} \
        --zone ${CLUSTER_INGRESS_ZONE} --project ${PROJECT_ID}
      
      kubectl config rename-context \
        gke_${PROJECT_ID}_${CLUSTER_INGRESS_ZONE}_${CLUSTER_INGRESS} ${CLUSTER_INGRESS}
      
    4. Per utilizzare Ingress multi-cluster, registra tutti i cluster partecipanti in GKE Enterprise Fleet, incluso il cluster di configurazione:

    5. Registra il cluster di configurazione:

      gcloud container fleet memberships register ${CLUSTER_INGRESS} \
        --project=${PROJECT_ID} \
        --gke-cluster=${CLUSTER_INGRESS_ZONE}/${CLUSTER_INGRESS} \
        --enable-workload-identity
      
    6. Verifica che tutti i cluster siano registrati in GKE Enterprise Fleet:

      gcloud container fleet memberships list
      

      L'output è simile al seguente:

      NAME            EXTERNAL_ID
      gke-west        7fe5b7ce-50d0-4e64-a9af-55d37b3dd3fa
      gke-central     6f1f6bb2-a3f6-4e9c-be52-6907d9d258cd
      gke-ingress     3574ee0f-b7e6-11ea-9787-42010a8a019c
      
    7. Abilita le funzionalità di Ingress multi-cluster sul cluster ingress-config. Vengono create le CustomResourceDefinitions (CRD) MulticlusterService e MulticlusterIngress sul cluster.

      gcloud container fleet ingress enable \
        --config-membership=projects/${PROJECT_ID}/locations/global/memberships/${CLUSTER_INGRESS}
      
    8. Verifica che Ingress multi-cluster sia abilitato sul cluster ingress-config:

      gcloud container fleet ingress describe
      

      L'output è simile al seguente:

      membershipStates:
        projects/986443280307/locations/global/memberships/gke-central-priv:
          state:
            code: OK
            updateTime: '2022-09-29T13:57:02.972748202Z'
        projects/986443280307/locations/global/memberships/gke-ingress:
          state:
            code: OK
            updateTime: '2022-09-29T13:57:02.972744692Z'
        projects/986443280307/locations/global/memberships/gke-west-priv:
          state:
            code: OK
            updateTime: '2022-09-29T13:57:02.972746497Z'
      
    9. Verifica che le due CRD siano state implementate nel cluster ingress-config:

      kubectl --context=${CLUSTER_INGRESS} get crd | grep multicluster
      

      L'output è simile al seguente.

      multiclusteringresses.networking.gke.io     2020-10-29T17:32:50Z
      multiclusterservices.networking.gke.io      2020-10-29T17:32:50Z
      
    10. Crea lo spazio dei nomi asm-ingress nel cluster ingress-config:

      kubectl --context ${CLUSTER_INGRESS} create namespace asm-ingress
      
    11. Crea la risorsa MultiClusterIngress:

      cat <<EOF > ${HOME}/mci.yaml
      apiVersion: networking.gke.io/v1beta1
      kind: MultiClusterIngress
      metadata:
        name: asm-ingressgateway-multicluster-ingress
      spec:
        template:
          spec:
            backend:
             serviceName: asm-ingressgateway-multicluster-svc
             servicePort: 80
      EOF
      
    12. Crea la risorsa MultiClusterService:

      cat <<'EOF' > $HOME/mcs.yaml
      apiVersion: networking.gke.io/v1beta1
      kind: MultiClusterService
      metadata:
        name: asm-ingressgateway-multicluster-svc
        annotations:
          beta.cloud.google.com/backend-config: '{"ports": {"80":"gke-ingress-config"}}'
      spec:
        template:
          spec:
            selector:
              asm: ingressgateway
            ports:
            - name: frontend
              protocol: TCP
              port: 80 # servicePort defined in Multi Cluster Ingress
        clusters:
        - link: "us-west2-a/gke-west-priv"
        - link: "us-central1-a/gke-central-priv"
      EOF
      
    13. Crea la risorsa BackendConfig per i controlli di integrità:

      cat <<EOF > $HOME/backendconfig.yaml
      apiVersion: cloud.google.com/v1beta1
      kind: BackendConfig
      metadata:
        name: gke-ingress-config
      spec:
        healthCheck:
          type: HTTP
          port: 15021
          requestPath: /healthz/ready
      EOF
      
    14. Applica i manifest BackendConfig, MultiClusterService e MultiClusterIngress:

      kubectl --context ${CLUSTER_INGRESS} -n asm-ingress apply -f ${HOME}/backendconfig.yaml
      kubectl --context ${CLUSTER_INGRESS} -n asm-ingress apply -f ${HOME}/mci.yaml
      kubectl --context ${CLUSTER_INGRESS} -n asm-ingress apply -f ${HOME}/mcs.yaml
      
    15. Il MultiClusterService che hai eseguito il deployment nel cluster Ingress creerà un Service "headless" nel cluster 1 e nel cluster 2. Verifica che siano stati creati i Services "headless":

      kubectl --context=${CLUSTER_1} -n asm-ingress \
        get services | grep multicluster-svc
      kubectl --context=${CLUSTER_2} -n asm-ingress \
        get services | grep multicluster-svc
      

      L'output è simile al seguente:

      mci-frontend-multi-cluster-service-svc-f7rcyqry22iq8nmw   ClusterIP      None          <none>          80/TCP         77s
      mci-frontend-multi-cluster-service-svc-f7rcyqry22iq8nmw   ClusterIP      None          <none>          80/TCP         78s
      
    16. Esegui questo comando e attendi fino a quando non ricevi un indirizzo IP di bilanciamento del carico Cloud:

      watch kubectl --context ${CLUSTER_INGRESS} -n asm-ingress get multiclusteringress \
        -o jsonpath="{.items[].status.VIP}"
      

      L'output è simile al seguente:

      35.35.23.11
      

      Per uscire dal comando watch, premi Ctrl+C.

    17. Vai all'indirizzo IP di bilanciamento del carico cloud in un browser web per accedere al frontend di Bank of Anthos:

      kubectl --context ${CLUSTER_INGRESS} \
        -n asm-ingress get multiclusteringress \
        -o jsonpath="{.items[].status.VIP}"
      

      Se ricevi un errore 404 (o 502), attendi qualche minuto e poi aggiorna la pagina nel browser web.

    Esegui la pulizia

    Per evitare che al tuo account vengano addebitati costi, elimina il progetto o i cluster.

    Elimina il progetto

    Il modo più semplice per eliminare la fatturazione è eliminare il progetto creato per il tutorial.

    1. In the Google Cloud console, go to the Manage resources page.

      Go to Manage resources

    2. In the project list, select the project that you want to delete, and then click Delete.
    3. In the dialog, type the project ID, and then click Shut down to delete the project.

    Elimina i cluster

    1. In Cloud Shell, annulla la registrazione ed elimina i cluster blue e green:

      gcloud container fleet memberships unregister ${CLUSTER_1} \
        --project=${PROJECT} \
        --gke-uri=${CLUSTER_1_URI}
      gcloud container clusters delete ${CLUSTER_1} \
        --zone ${CLUSTER_1_ZONE} \
        --quiet
      
      gcloud container fleet memberships unregister ${CLUSTER_2} \
        --project=${PROJECT} \
        --gke-uri=${CLUSTER_2_URI}
      gcloud container clusters delete ${CLUSTER_2} \
        --zone ${CLUSTER_2_ZONE} \
        --quiet
      
    2. Elimina la risorsa MuticlusterIngress dal cluster ingress-config:

      kubectl --context ${CLUSTER_INGRESS} -n istio-system delete -f $HOME/mci.yaml
      

      In questo modo, le risorse Cloud Load Balancing vengono eliminate dal progetto.

    3. Annulla la registrazione ed elimina il cluster ingress-config:

      gcloud container fleet memberships unregister ${CLUSTER_INGRESS} \
        --project=${PROJECT} \
        --gke-uri=${CLUSTER_INGRESS_URI}
      gcloud container clusters delete ${CLUSTER_INGRESS} \
        --zone ${CLUSTER_INGRESS_ZONE} \
        --quiet
      
    4. Verifica che tutti i cluster siano eliminati:

      gcloud container clusters list
      

      L'output è il seguente:

      <null>
    5. Reimposta il file kubeconfig:

      unset KUBECONFIG
      

    Passaggi successivi