Exécuter des services distribués sur des clusters privés GKE à l'aide de Cloud Service Mesh

Ce document explique comment exécuter des services distribués sur plusieurs clusters Google Kubernetes Engine (GKE) dans Google Cloud à l'aide de Cloud Service Mesh. Ce document explique également comment exposer un service distribué à l'aide d'Multi Cluster Ingress et de Cloud Service Mesh. Vous pouvez utiliser ce document pour configurer des clusters GKE non privés. Ce document met en évidence la configuration destinée exclusivement aux clusters privés.

Ce document est destiné aux administrateurs de plate-forme et aux opérateurs de service qui possèdent des connaissances de base sur Kubernetes. Certaines connaissances du maillage de services sont bénéfiques, même si cela n'est pas obligatoire. Cloud Service Mesh est basé sur la technologie Open Source Istio. Pour en savoir plus sur le maillage de services et Istio, consultez la page istio.io.

Un service distribué est un service Kubernetes qui agit en tant que service logique unique. Les services distribués sont plus résilients que les services Kubernetes, car ils s'exécutent sur plusieurs clusters Kubernetes dans le même espace de noms. Un service distribué reste actif même si un ou plusieurs clusters GKE sont en panne, tant que les clusters sains sont en mesure de diffuser la charge souhaitée.

Les services Kubernetes ne sont connus que du serveur d'API Kubernetes du cluster sur lequel ils s'exécutent. Si le cluster Kubernetes est arrêté (par exemple, lors d'une maintenance planifiée), tous les services Kubernetes exécutés sur ce cluster sont également indisponibles. L'exécution de services distribués facilite la gestion du cycle de vie des clusters, car vous pouvez les arrêter pour des raisons de maintenance ou de mise à niveau, tandis que d'autres clusters gèrent le trafic. Pour créer un service distribué, la fonctionnalité de maillage de services fournie par Cloud Service Mesh permet de relier les services exécutés sur plusieurs clusters afin qu'ils agissent comme un seul service logique.

Les clusters privés GKE vous permettent de configurer les nœuds et le serveur d'API en tant que ressources privées disponibles seulement sur le réseau cloud privé virtuel (VPC). L'exécution de services distribués dans des clusters privés GKE offre aux entreprises des services sécurisés et fiables.

Architecture

Ce tutoriel utilise l'architecture illustrée dans le diagramme suivant :

Architecture des services distribués sur des clusters privés GKE à l'aide de Cloud Service Mesh

Dans le schéma précédent, l'architecture comprend les clusters suivants :

  • Deux clusters (gke-central-priv et gke-west-priv) agissent comme des clusters privés GKE identiques dans deux régions différentes.
  • Un cluster distinct (ingress-config) sert de cluster de plan de contrôle qui configure l'objet Ingress multicluster.

Dans ce tutoriel, vous allez déployer l'exemple d'application Bank of Anthos sur deux clusters privés GKE (gke-central-priv et gke-west-priv). Bank of Anthos est un exemple d'application de microservices qui consiste en plusieurs microservices et bases de données SQL qui simulent une application de banque en ligne. L'application se compose d'une interface Web à laquelle les clients peuvent accéder, ainsi que de plusieurs services de backend tels que des services de solde, de registre et de compte qui simulent une banque.

L'application comprend deux bases de données PostgreSQL installées dans Kubernetes en tant qu'objets StatefulSet. Une base de données est utilisée pour les transactions, tandis que l'autre est utilisée pour les comptes utilisateur. Tous les services, à l'exception des deux bases de données, s'exécutent en tant que services distribués. Cela signifie que les pods de tous les services s'exécutent dans les deux clusters d'application (dans le même espace de noms) et que Cloud Service Mesh est configuré de sorte que chaque service apparaisse comme un seul service logique.

Objectifs

  • Créer trois clusters GKE.
  • Configurer deux des clusters GKE en tant que clusters privés (gke-central-priv et gke-west-priv).
  • Configurer un cluster GKE (ingress-config) en tant que cluster de configuration central. Ce cluster agit comme un cluster de configuration pour l'objet Ingress multicluster.
  • Configurer la mise en réseau (passerelles NAT, Cloud Router et règles de pare-feu) pour autoriser le trafic intercluster et le trafic sortant des deux clusters GKE privés.
  • Configurer les réseaux autorisés pour qu'ils accordent l'accès au service API depuis Cloud Shell vers les deux clusters privés GKE.
  • Déployez et configurez Cloud Service Mesh multicluster sur les deux clusters privés en mode multiprimaire. Le mode multiprincipal déploie un plan de contrôle Cloud Service Mesh dans les deux clusters.
  • Déployer l'application Bank of Anthos sur les deux clusters privés. À l'exception des bases de données, tous les services sont déployés en tant que services distribués (pods s'exécutant sur les deux clusters privés).
  • Surveiller les services à l'aide de Cloud Service Mesh
  • Configurez l'objet Ingress multicluster sur les services frontend de Bank of Anthos. Cela permet aux clients externes (par exemple, votre navigateur Web) d'accéder à un service distribué s'exécutant sur un parc de clusters GKE privés.

Coûts

Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût. Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Avant de commencer

  1. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  2. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  3. Dans la console Google Cloud, activez Cloud Shell.

    Activer Cloud Shell

    En bas de la fenêtre de la console Google Cloud, une session Cloud Shell démarre et affiche une invite de ligne de commande. Cloud Shell est un environnement shell dans lequel Google Cloud CLI est déjà installé, et dans lequel des valeurs sont déjà définies pour votre projet actuel. L'initialisation de la session peut prendre quelques secondes.

    Vous exécuterez toutes les commandes de ce tutoriel depuis Cloud Shell.

  4. Définissez les variables d'environnement utilisées tout au long de ce tutoriel. Les variables définissent les noms des clusters, les régions, les zones, l'adressage IP et les versions de Cloud Service Mesh utilisées dans ce tutoriel.

    1. en remplaçant YOUR_PROJECT_ID par votre ID de projet :

      export PROJECT_ID=YOUR_PROJECT_ID
      gcloud config set project ${PROJECT_ID}
      
    2. Définissez les variables d'environnement restantes :

      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)
      

Préparer votre environnement

  1. Dans Cloud Shell, activez les API :

    gcloud services enable \
      --project=${PROJECT_ID} \
      container.googleapis.com \
      mesh.googleapis.com \
      gkehub.googleapis.com
    
  2. Activez le parc Cloud Service Mesh pour votre projet:

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

Préparer la mise en réseau pour les clusters GKE privés

Dans cette section, vous allez préparer la mise en réseau des clusters GKE privés que vous utilisez pour exécuter des services distribués.

Aucune adresse IP publique n'est attribuée aux nœuds de cluster GKE privés. Tous les nœuds d'un cluster GKE privé se voient attribuer une adresse IP VPC privée (dans l'espace d'adressage RFC 1918). Cela signifie que les pods qui ont besoin d'accéder à des ressources externes (en dehors du réseau VPC) requièrent une passerelle Cloud NAT. Les passerelles Cloud NAT sont des passerelles NAT régionales qui permettent aux pods avec des adresses IP internes de communiquer avec Internet. Dans ce tutoriel, vous allez configurer une passerelle Cloud NAT dans chacune des deux régions. Plusieurs clusters d'une région peuvent utiliser la même passerelle NAT.

  1. Dans Cloud Shell, créez deux adresses IP externes et réservez-les pour les deux passerelles 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. Stockez l'adresse IP et le nom des adresses IP dans des variables :

    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. Créez des passerelles Cloud NAT dans les deux régions des clusters GKE privés :

    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. Créez une règle de pare-feu qui autorise la communication entre pods et la communication entre pods et serveurs d'API. La communication entre les pods permet aux services distribués de communiquer entre eux sur les clusters GKE. La communication entre le pod et le serveur d'API permet au plan de contrôle Cloud Service Mesh d'interroger les clusters GKE pour la détection de services.

    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 mise en réseau est maintenant préparée. Dans ce tutoriel, vous utilisez l'intégralité de la plage d'adresses IP 10.0.0.0/8, qui inclut toutes les plages de pods. En production, nous vous recommandons de créer une règle de pare-feu plus stricte, en fonction de vos conditions et de vos exigences.

Créer des clusters GKE privés

Dans cette section, vous allez créer les deux clusters GKE privés dans lesquels l'exemple d'application est déployé. Dans ce tutoriel, les nœuds de cluster GKE privé ont des adresses IP privées, et le serveur d'API dispose d'un point de terminaison public. L'accès au serveur d'API est toutefois limité à l'aide de réseaux autorisés.

  1. Dans Cloud Shell, créez deux clusters privés disposant de réseaux autorisés. Configurez les clusters pour autoriser l'accès à partir de la plage CIDR d'adresses IP des pods (pour le plan de contrôle Cloud Service Mesh) et de Cloud Shell afin de pouvoir accéder aux clusters depuis votre terminal.

    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
    

    Les réseaux autorisés contiennent les adresses IP publiques sur les passerelles Cloud NAT. Étant donné que le point de terminaison du serveur d'API pour un cluster privé est un point de terminaison public, les pods exécutés dans un cluster privé doivent utiliser une passerelle Cloud NAT pour accéder aux points de terminaison du serveur d'API public.

    L'adresse IP de Cloud Shell fait également partie des réseaux autorisés, ce qui vous permet d'accéder aux clusters et de les gérer depuis votre terminal Cloud Shell. Les adresses IP publiques de Cloud Shell sont dynamiques. Par conséquent, chaque fois que vous démarrez Cloud Shell, vous pouvez obtenir une adresse IP publique différente. Lorsque vous obtenez une nouvelle adresse IP, vous perdez l'accès aux clusters, car la nouvelle adresse IP ne fait pas partie des réseaux autorisés pour les deux clusters.

    Si vous perdez l'accès aux clusters, mettez à jour les réseaux autorisés des clusters pour inclure la nouvelle adresse IP Cloud Shell :

    1. Obtenez l'adresse IP publique Cloud Shell mise à jour :

      export CLOUDSHELL_IP=$(dig +short myip.opendns.com @resolver1.opendns.com)
      
    2. Mettez à jour les réseaux autorisés pour les deux clusters :

      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. Vérifiez que tous les clusters sont en cours d'exécution :

    gcloud container clusters list
    

    La sortie ressemble à ceci :

    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. Connectez-vous aux deux clusters pour générer des entrées dans le fichier 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}
    

    Vous utilisez le fichier kubeconfig pour vous authentifier auprès des clusters en créant un utilisateur et un contexte pour chaque cluster. Une fois les entrées générées dans le fichier kubeconfig, vous pouvez rapidement basculer entre différents contextes pour les clusters.

  4. Renommez les contextes de cluster pour plus de commodité :

    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. Vérifiez que les deux contextes de cluster ont été correctement renommés et configurés :

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

    La sortie ressemble à ceci :

    gke-central-priv
    gke-west-priv
    
  6. Enregistrez vos clusters dans un parc :

    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
    

Vous avez maintenant créé et renommé vos clusters GKE privés.

Installer Cloud Service Mesh

Dans cette section, vous allez installer Cloud Service Mesh sur les deux clusters GKE et configurer les clusters pour la détection de services interclusters.

  1. Dans Cloud Shell, installez Cloud Service Mesh sur les deux clusters à l'aide de l'fleet API:

    gcloud container fleet mesh update --management automatic --memberships ${CLUSTER_1},${CLUSTER_2}
    
  2. Une fois que le service Cloud Service Mesh géré est activé sur les clusters, définissez une surveillance pour l'installation du maillage:

    watch -g "gcloud container fleet mesh describe | grep 'code: REVISION_READY'"
    
  3. Installez des passerelles d'entrée Cloud Service Mesh pour les deux clusters:

    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. Vérifiez que les passerelles d'entrée Cloud Service Mesh sont déployées:

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

    Le résultat des deux clusters ressemble à ce qui suit :

    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
    

    Une fois que le plan de contrôle et les passerelles d'entrée Cloud Service Mesh sont installés pour les deux clusters, la détection de services entre clusters est activée avec l'API du parc. La détection de services entre clusters permet aux deux clusters de découvrir les points de terminaison de service du cluster distant. Les services distribués s'exécutent sur plusieurs clusters dans le même espace de noms.

    Pour que les deux plans de contrôle Cloud Service Mesh puissent découvrir tous les points de terminaison d'un service distribué, Cloud Service Mesh doit avoir accès à tous les clusters qui exécutent le service distribué. Cet exemple utilise deux clusters. Par conséquent, les deux clusters doivent pouvoir interroger le cluster distant pour y rechercher des points de terminaison de service. Lorsque le service géré Cloud Service Mesh est activé avec l'API du parc, la détection des points de terminaison est automatiquement configurée.

Les clusters et Cloud Service Mesh sont maintenant configurés.

Déployer l'application Bank of Anthos

  1. Dans Cloud Shell, clonez le dépôt GitHub de Bank of Anthos :

    git clone https://github.com/GoogleCloudPlatform/bank-of-anthos.git ${HOME}/bank-of-anthos
    
  2. Créez et attribuez un libellé à un espace de noms bank-of-anthos dans les deux clusters. Le libellé permet l'injection automatique des proxys side-car Envoy dans chaque pod de l'espace de noms auquel un libellé a été attribué.

    # 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. Déployez l'application Bank of Anthos sur les deux clusters de l'espace de noms 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
    

    Les services Kubernetes doivent se trouver dans les deux clusters pour la découverte de services. Lorsqu'un service de l'un des clusters tente d'envoyer une requête, il effectue d'abord une résolution DNS pour le nom d'hôte afin d'obtenir l'adresse IP. Dans GKE, le serveur kube-dns exécuté dans le cluster gère cette recherche. Une définition de service configurée est donc requise.

  4. Supprimez les objets StatefulSets d'un cluster afin que les deux bases de données PostgreSQL n'existent que dans l'un des clusters :

    # 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. Assurez-vous que tous les pods s'exécutent dans les deux clusters :

    1. Obtenez les pods depuis cluster_1 :

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

      La sortie ressemble à ceci :

      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. Obtenez les pods depuis cluster_2 :

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

      La sortie ressemble à ceci :

      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. Déployez les configurations Cloud Service Mesh sur les deux clusters. Cela crée une passerelle dans l'espace de noms asm-ingress et une passerelle VirtualService dans les espaces de noms bank-of-anthos pour le service frontend, ce qui vous permet d'entrer du trafic vers le service frontend.

    Les Gateways appartiennent généralement aux administrateurs de la plate-forme ou à l'équipe des administrateurs réseau. Par conséquent, la ressource Gateway est créée dans l'espace de noms de la passerelle d'entrée appartenant à l'administrateur de la plate-forme et peut être utilisée dans d'autres espaces de noms via leurs propres entrées VirtualService. Il s'agit d'un modèle de "passerelle partagée".

    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
    

Vous avez maintenant déployé l'application Bank of Anthos sur deux clusters GKE privés. Tous les services s'exécutent en tant que services distribués, à l'exception de la base de données.

Inspecter les services distribués

Dans cette section, vous utilisez l'outil istioctl pour inspecter la configuration proxy de l'un des proxys. Cela vous permet de voir que les proxys side-car voient deux pods pour chaque service, avec un pod en cours d'exécution dans chaque cluster.

  1. Dans Cloud Shell, examinez la liste des points de terminaison de configuration proxy du pod frontend dans 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
    

    La sortie ressemble à ceci :

    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
    

    Dans le résultat précédent, chaque service distribué possède deux adresses IP de point de terminaison. Il s'agit des adresses IP des pods, une pour chaque cluster.

Access Bank of Anthos

Pour accéder à l'application Bank of Anthos, vous pouvez utiliser l'adresse IP publique du service asm-ingressgateway de l'un des clusters.

  1. Obtenez les adresses IP asm-ingressgateway des deux clusters :

    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"
    
    

    Le résultat est semblable à ce qui suit.

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

    Copiez l'une des adresses IP à utiliser à l'étape suivante.

  2. Ouvrez un nouvel onglet dans un navigateur Web et accédez à l'une des adresses IP du résultat précédent. L'interface de Bank of Anthos doit s'afficher. Elle vous permet de vous connecter, de déposer des fonds sur votre compte et de transférer des fonds vers d'autres comptes. L'application doit être totalement fonctionnelle.

Visualiser les services distribués

Vous pouvez visualiser des services distribués dans Cloud Service Mesh.

  1. Pour afficher vos services, accédez à la page Anthos > Service Mesh dans la console Google Cloud.

    Accéder à Service Mesh

    Vous pouvez afficher les services dans une vue Tableau ou dans une vue Topologie. La vue par défaut est la vue Tableau, qui affiche tous les services distribués s'exécutant sous forme de tableau. Pour changer de vue, cliquez sur la vue que vous souhaitez afficher.

  2. Dans la vue Tableaux, cliquez sur frontend distributed service. Lorsque vous cliquez sur un service individuel, vous obtenez une vue détaillée du service et des services connectés.

    Dans la vue "Détails du service", vous pouvez créer des SLO et afficher une chronologie historique du service en cliquant sur Afficher la chronologie.

  3. Pour afficher les signaux clés, cliquez sur Métriques dans le panneau latéral.

  4. Dans le graphique Requêtes par seconde, cliquez sur Répartition par, puis sélectionnez Emplacement.

    Les résultats affichent les requêtes par seconde des deux clusters dans les deux régions. Le service distribué est opérationnel et les deux points de terminaison diffusent le trafic.

  5. Pour afficher la topologie de votre maillage de services, cliquez sur Anthos Service Mesh dans le panneau latéral, puis sur Vue Topologie.

  6. Pour afficher des données supplémentaires, maintenez le pointeur de la souris sur le service frontend. Cela permet d'afficher des informations telles que le nombre de requêtes par seconde entrant et sortant de l'interface depuis et vers d'autres services.

  7. Pour afficher plus de détails, cliquez sur Développer sur le service frontend. Un service et une charge de travail s'affichent. Vous pouvez étendre davantage la charge de travail à deux déploiements, étendre les déploiements en ReplicaSets et étendre les ReplicaSets en pods. Lorsque vous développez tous les éléments, vous pouvez voir le service distribué frontend, qui est essentiellement un service et deux pods.

Configurer un objet Ingress multicluster

Dans cette section, vous allez créer une Multi Cluster Ingress qui envoie du trafic aux services frontend de la Bank of GKE Enterprise s'exécutant dans les deux clusters. Vous utilisez Cloud Load Balancing pour créer un équilibreur de charge qui utilise les services asm-ingressgateway dans les deux clusters en tant que backends. Un cluster ingress-config est utilisé pour orchestrer la configuration de l'objet Ingress multi-cluster.

Pour créer l'équilibreur de charge, vous devez utiliser un MultiClusterIngress et un ou plusieurs MultiClusterServices. Les objets MultiClusterIngress et MultiClusterService sont des ressources multicluster correspondant aux ressources Kubernetes "Ingress" et "Service" qui sont utilisées dans le cadre d'un cluster unique.

  1. Activez les API GKE Enterprise, GKE Fleet et Multi Cluster Ingress requises:

    gcloud services enable \
      anthos.googleapis.com \
      multiclusterservicediscovery.googleapis.com \
      multiclusteringress.googleapis.com
    
  2. Créez le cluster ingress-config. Vous pouvez utiliser n'importe quel cluster, mais nous vous recommandons de créer un cluster distinct à cette fin.

    gcloud container clusters create ${CLUSTER_INGRESS} \
      --zone ${CLUSTER_INGRESS_ZONE} \
      --num-nodes=1 \
      --enable-ip-alias \
      --workload-pool=${WORKLOAD_POOL}
    
  3. Obtenez les identifiants du cluster et renommez le contexte pour plus de commodité :

    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. Pour utiliser Multi Cluster Ingress, enregistrez tous les clusters participants dans le parc GKE Enterprise, y compris le cluster de configuration:

  5. Enregistrez le cluster de configuration :

    gcloud container fleet memberships register ${CLUSTER_INGRESS} \
      --project=${PROJECT_ID} \
      --gke-cluster=${CLUSTER_INGRESS_ZONE}/${CLUSTER_INGRESS} \
      --enable-workload-identity
    
  6. Vérifiez que tous les clusters sont enregistrés dans le parc GKE Enterprise:

    gcloud container fleet memberships list
    

    La sortie ressemble à ceci :

    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. Activez les fonctionnalités de l'objet Ingress multi-cluster sur le cluster ingress-config. Cela crée les définitions de ressources personnalisées (CRD, CustomResourceDefinitions) MulticlusterService et MulticlusterIngress sur le cluster.

    gcloud container fleet ingress enable \
      --config-membership=projects/${PROJECT_ID}/locations/global/memberships/${CLUSTER_INGRESS}
    
  8. Vérifiez que l'objet Ingress multicluster est activé sur le cluster ingress-config :

    gcloud container fleet ingress describe
    

    La sortie ressemble à ceci :

    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. Vérifiez que les deux CRD sont déployées dans le cluster ingress-config :

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

    Le résultat est semblable à ce qui suit.

    multiclusteringresses.networking.gke.io     2020-10-29T17:32:50Z
    multiclusterservices.networking.gke.io      2020-10-29T17:32:50Z
    
  10. Créez l'espace de noms asm-ingress dans le cluster ingress-config :

    kubectl --context ${CLUSTER_INGRESS} create namespace asm-ingress
    
  11. Créez la ressource 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. Créez la ressource 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. Créez la ressource BackendConfig pour les vérifications d'état :

    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. Appliquez les fichiers manifestes BackendConfig, MultiClusterService et 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. Le service MultiClusterService que vous avez déployé dans le cluster Ingress va créer un service Service sans interface graphique dans les clusters 1 et 2. Vérifiez que les services Services sans interface graphique ont été créés :

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

    Le résultat est semblable à :

    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. Exécutez la commande suivante et attendez d'obtenir une adresse IP Cloud Load Balancing :

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

    La sortie ressemble à ceci :

    35.35.23.11
    

    Pour quitter la commande watch, appuyez sur Ctrl+C.

  17. Accédez à l'adresse IP de Cloud Load Balancing dans un navigateur Web pour accéder à l'interface de Bank of Anthos :

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

    Si vous obtenez une erreur 404 (ou une erreur 502), attendez quelques minutes, puis actualisez la page dans votre navigateur Web.

Effectuer un nettoyage

Pour éviter que des frais ne soient facturés sur votre compte, supprimez le projet ou les clusters.

Supprimer le projet

Le moyen le plus simple d'empêcher la facturation est de supprimer le projet que vous avez créé pour ce tutoriel.

  1. Dans la console Google Cloud, accédez à la page Gérer les ressources.

    Accéder à la page Gérer les ressources

  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.

Supprimer les clusters

  1. Dans Cloud Shell, annulez l'enregistrement et supprimez les clusters blue et 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. Supprimez la ressource MuticlusterIngress du cluster de configuration d'entrée :

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

    Cela supprime les ressources Cloud Load Balancing du projet.

  3. Annuler l'enregistrement et supprimer le 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. Vérifiez que tous les clusters sont supprimés :

    gcloud container clusters list
    

    Le résultat est le suivant :

    <null>
  5. Réinitialisez le fichier kubeconfig :

    unset KUBECONFIG
    

Étapes suivantes