Verteilte Dienste auf privaten GKE-Clustern mit Cloud Service Mesh ausführen

In diesem Dokument erfahren Sie, wie Sie mit Cloud Service Mesh verteilte Dienste in mehreren Google Kubernetes Engine-Clustern (GKE) in Google Cloud ausführen. In diesem Dokument erfahren Sie außerdem, wie Sie einen verteilten Dienst mithilfe von Multi-Cluster-Ingress und Cloud Service Mesh verfügbar machen. Sie können mit diesem Dokument nicht private GKE-Cluster konfigurieren. In diesem Dokument wird die Konfiguration hervorgehoben, die ausschließlich für private Cluster vorgesehen ist.

Dieses Dokument richtet sich an Plattformadministratoren und Dienstoperatoren, die Grundkenntnisse in Kubernetes haben. Ein gewisses Maß an Wissen über Service Mesh ist vorteilhaft, aber nicht zwingend erforderlich. Cloud Service Mesh basiert auf der Istio-Open-Source-Technologie. Weitere Informationen zu Service Mesh und Istio finden Sie unter istio.io.

Ein verteilter Dienst ist ein Kubernetes-Service, der als einzelner logischer Dienst fungiert. Verteilte Dienste sind robuster als Kubernetes-Services, da sie in mehreren Kubernetes-Clustern im selben Namespace ausgeführt werden. Ein verteilter Dienst bleibt auch dann aktiv, wenn einer oder mehrere GKE-Cluster ausgefallen sind, solange die fehlerfreien Cluster die gewünschte Last verarbeiten können.

Kubernetes-Services sind nur dem Kubernetes API-Server des Clusters bekannt, in dem sie ausgeführt werden. Wenn der Kubernetes-Cluster ausfällt (z. B. während einer geplanten Wartung), fallen auch alle auf diesem Cluster ausgeführten Kubernetes-Services aus. Das Ausführen verteilter Dienste vereinfacht die Verwaltung des Clusterlebenszyklus, da Sie Cluster für Wartung oder Upgrades herunterfahren können, während anderer Clusterdiensttraffic ausgeführt wird. Zum Erstellen eines verteilten Dienstes werden die von Cloud Service Mesh bereitgestellten Service-Mesh-Funktionen verwendet, um Dienste, die in mehreren Clustern ausgeführt werden, zu einem einzigen logischen Dienst zu verknüpfen.

Mit privaten GKE-Clustern können Sie die Knoten und den API-Server als private Ressourcen konfigurieren, die nur im VPC-Netzwerk (Virtual Private Cloud) verfügbar sind. Das Ausführen verteilter Dienste in privaten GKE-Clustern bietet Unternehmen sowohl sichere als auch zuverlässige Dienste.

Architektur

In dieser Anleitung wird die im folgenden Diagramm dargestellte Architektur verwendet:

Architektur von verteilten Diensten auf privaten GKE-Clustern mit Cloud Service Mesh

Im obigen Diagramm umfasst die Architektur die folgenden Cluster:

  • Zwei Cluster (gke-central-priv und gke-west-priv) fungieren als identische private GKE-Cluster in zwei verschiedenen Regionen.
  • Ein separater Cluster (ingress-config) dient als Cluster auf Steuerungsebene, der Multi-Cluster-Ingress konfiguriert.

In dieser Anleitung stellen Sie die Beispielanwendung Bank of Anthos in zwei privaten GKE-Clustern (gke-central-priv und gke-west-priv) bereit. Bank of Anthos ist eine Beispiel-Mikrodienstanwendung, die aus mehreren Mikrodiensten und SQL-Datenbanken besteht, die eine Online-Banking-App simulieren. Die Anwendung besteht aus einem Webfrontend, auf das Kunden zugreifen können, und mehreren Backend-Diensten wie Kontostand, Hauptbuch und Kontodiensten, die eine Bank simulieren.

Die Anwendung enthält zwei PostgreSQL-Datenbanken, die in Kubernetes als StatefulSets installiert sind. Eine Datenbank wird für Transaktionen und die andere für Nutzerkonten verwendet. Alle Dienste mit Ausnahme der beiden Datenbanken werden als verteilte Dienste ausgeführt. Das bedeutet, dass Pods für alle Dienste in beiden Anwendungsclustern (im selben Namespace) ausgeführt werden und Cloud Service Mesh so konfiguriert ist, dass jeder Dienst als einzelner logischer Dienst angezeigt wird.

Lernziele

  • Drei GKE-Cluster erstellen.
  • Zwei der GKE-Cluster als private Cluster (gke-central-priv und gke-west-priv) konfigurieren.
  • Einen GKE-Cluster (ingress-config) als zentralen Konfigurationscluster konfigurieren. Dieser Cluster fungiert als Konfigurationscluster für Multi-Cluster-Ingress.
  • Netzwerk (NAT-Gateways, Cloud Router und Firewallregeln) konfigurieren, um Inter-Cluster- und ausgehenden Traffic von den beiden privaten GKE-Clustern zuzulassen.
  • Autorisierte Netzwerke konfigurieren, um den API-Dienstzugriff aus Cloud Shell auf die beiden privaten GKE-Cluster zuzulassen.
  • Multi-Cluster-Cloud Service Mesh in den beiden privaten Clustern im Multi-Primär-Modus bereitstellen und konfigurieren. Im Multi-Primär-Modus wird eine Cloud Service Mesh-Steuerungsebene in beiden Clustern bereitgestellt.
  • Bank of Anthos-Anwendung in den beiden privaten Clustern bereitstellen. Alle Dienste mit Ausnahme der Datenbanken werden als verteilte Dienste bereitgestellt (Pods, die in beiden privaten Clustern ausgeführt werden).
  • Dienste mit Cloud Service Mesh überwachen.
  • Multi-Cluster-Ingress für die Bank of Anthos-frontend-Dienste konfigurieren. Dadurch können externe Clients (z. B. Ihr Webbrowser) auf einen verteilten Dienst zugreifen, der in einer Flotte privater GKE-Cluster ausgeführt wird.

Kosten

In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen. Neuen Google Cloud-Nutzern steht möglicherweise eine kostenlose Testversion zur Verfügung.

Hinweise

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

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

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

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

    Führen Sie alle Befehle in dieser Anleitung über Cloud Shell aus.

  4. Definieren Sie Umgebungsvariablen, die in dieser Anleitung verwendet werden. Die Variablen definieren Clusternamen, Regionen, Zonen, IP-Adressierung und Cloud Service Mesh-Versionen, die in dieser Anleitung verwendet werden.

    1. Ersetzen Sie YOUR_PROJECT_ID durch Ihre Projekt-ID:

      export PROJECT_ID=YOUR_PROJECT_ID
      gcloud config set project ${PROJECT_ID}
      
    2. Legen Sie die restlichen Umgebungsvariablen fest:

      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)
      

Umgebung vorbereiten

  1. Aktivieren Sie in Cloud Shell die APIs:

    gcloud services enable \
      --project=${PROJECT_ID} \
      container.googleapis.com \
      mesh.googleapis.com \
      gkehub.googleapis.com
    
  2. Aktivieren Sie die Cloud Service Mesh-Flotte für Ihr Projekt:

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

Netzwerk für private GKE-Cluster vorbereiten

In diesem Abschnitt bereiten Sie das Netzwerk für die privaten GKE-Cluster vor, die Sie zum Ausführen verteilter Dienste verwenden.

Privaten GKE-Clusterknoten wird keine öffentliche IP-Adresse zugewiesen. Allen Knoten in einem privaten GKE-Cluster wird eine private VPC-IP-Adresse (im RFC 1918-Adressbereich) zugewiesen. Das bedeutet, dass Pods, die auf externe Ressourcen (außerhalb des VPC-Netzwerks) zugreifen müssen, ein Cloud NAT-Gateway benötigen. Cloud NAT-Gateways sind regionale NAT-Gateways, die es Pods mit internen IP-Adressen ermöglichen, mit dem Internet zu kommunizieren. In dieser Anleitung konfigurieren Sie in jeder der beiden Regionen ein Cloud NAT-Gateway. Mehrere Cluster innerhalb einer Region können dasselbe NAT-Gateway verwenden.

  1. Erstellen und reservieren Sie in Cloud Shell zwei externe IP-Adressen für die beiden NAT-Gateways:

    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. Speichern Sie die IP-Adresse und den Namen der IP-Adressen in Variablen:

    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. Erstellen Sie Cloud NAT-Gateways in den beiden Regionen der privaten GKE-Cluster:

    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. Erstellen Sie eine Firewallregel, die die Pod-zu-Pod-Kommunikation und die Pod-zu-API-Serverkommunikation zulässt. Die Pod-zu-Pod-Kommunikation ermöglicht die Kommunikation der verteilten Dienste über GKE-Cluster. Die Pod-zu-API-Serverkommunikation ermöglicht es der Cloud Service Mesh-Steuerungsebene, GKE-Cluster zur Diensterkennung abzufragen.

    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}
    

Das Netzwerk ist jetzt bereit. In dieser Anleitung verwenden Sie den gesamten IP-Adressbereich 10.0.0.0/8, der alle Pod-Bereiche enthält. Wir empfehlen Ihnen, in der Produktion anhand der Bedingungen und Anforderungen eine strengere Firewallregel zu erstellen.

Private GKE-Cluster erstellen

In diesem Abschnitt erstellen Sie die beiden privaten GKE-Cluster, in denen die Beispielanwendung bereitgestellt wird. In dieser Anleitung haben die privaten GKE-Clusterknoten private IP-Adressen und der API-Server hat einen öffentlichen Endpunkt. Der Zugriff auf den API-Server ist jedoch über autorisierte Netzwerke beschränkt.

  1. Erstellen Sie in Cloud Shell zwei private Cluster mit autorisierten Netzwerken. Konfigurieren Sie die Cluster so, dass der Zugriff über den Pod-IP-CIDR-Bereich (für die Cloud Service Mesh-Steuerungsebene) und über Cloud Shell möglich ist, damit Sie von Ihrem Terminal aus auf die Cluster zugreifen können.

    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
    

    Die autorisierten Netzwerke enthalten die öffentlichen IP-Adressen in den Cloud NAT-Gateways. Da der API-Serverendpunkt für einen privaten Cluster ein öffentlicher Endpunkt ist, müssen Pods, die in einem privaten Cluster ausgeführt werden, über ein Cloud NAT-Gateway auf die öffentlichen API-Serverendpunkte zugreifen.

    Die Cloud Shell-IP-Adresse ist auch Teil der autorisierten Netzwerke, mit denen Sie über Ihr Cloud Shell-Terminal auf Cluster zugreifen und diese verwalten können. Öffentliche IP-Adressen von Cloud Shell sind dynamisch. Daher wird bei jedem Start von Cloud Shell möglicherweise eine andere öffentliche IP-Adresse angezeigt. Wenn Sie eine neue IP-Adresse erhalten, verlieren Sie den Zugriff auf die Cluster, da die neue IP-Adresse nicht Teil der autorisierten Netzwerke für die beiden Cluster ist.

    Wenn Sie den Zugriff auf die Cluster verlieren, aktualisieren Sie die autorisierten Netzwerke der Cluster, um die neue Cloud Shell-IP-Adresse einzuschließen:

    1. Rufen Sie die aktualisierte öffentliche IP-Adresse von Cloud Shell ab:

      export CLOUDSHELL_IP=$(dig +short myip.opendns.com @resolver1.opendns.com)
      
    2. Aktualisieren Sie die autorisierten Netzwerke für die beiden 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. Prüfen Sie, ob alle Cluster ausgeführt werden:

    gcloud container clusters list
    

    Die Ausgabe sieht so aus:

    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. Greifen Sie auf die beiden Cluster zu, um Einträge in der kubeconfig-Datei zu generieren:

    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}
    

    Sie verwenden die kubeconfig-Datei, um sich bei Clustern zu authentifizieren, indem Sie für jeden Cluster einen Nutzer und einen Kontext erstellen. Nachdem Sie Einträge in der kubeconfig-Datei generiert haben, können Sie schnell zwischen Clustern wechseln.

  4. Benennen Sie die Clusterkontexte der Einfachheit halber um:

    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. Prüfen Sie, ob beide Clusterkontexte ordnungsgemäß umbenannt und konfiguriert wurden:

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

    Die Ausgabe sieht so aus:

    gke-central-priv
    gke-west-priv
    
  6. Registrieren Sie Ihre Cluster bei einer Flotte:

    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
    

Sie haben jetzt Ihre privaten GKE-Cluster erstellt und umbenannt.

Cloud Service Mesh installieren.

In diesem Abschnitt installieren Sie Cloud Service Mesh in den beiden GKE-Clustern und konfigurieren die Cluster für die clusterübergreifende Diensterkennung.

  1. Installieren Sie in Cloud Shell mit der fleet API Cloud Service Mesh in beiden Clustern:

    gcloud container fleet mesh update --management automatic --memberships ${CLUSTER_1},${CLUSTER_2}
    
  2. Nachdem das verwaltete Cloud Service Mesh in den Clustern aktiviert wurde, legen Sie eine Installation für das zu installierende Mesh-Netzwerk fest:

    watch -g "gcloud container fleet mesh describe | grep 'code: REVISION_READY'"
    
  3. Installieren Sie Cloud Service Mesh-Ingress-Gateways für beide 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. Prüfen Sie, ob die Cloud Service Mesh-Ingress-Gateways bereitgestellt wurden:

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

    Die Ausgabe für beide Cluster sieht so aus:

    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
    

    Nachdem die Cloud Service Mesh-Steuerungsebene und die Ingress-Gateways für beide Cluster installiert wurden, ist die clusterübergreifende Service Discovery mit der Flotten-API aktiviert. Mit der clusterübergreifenden Diensterkennung können die beiden Cluster Dienstendpunkte vom Remote-Cluster erkennen. Verteilte Dienste werden in mehreren Clustern im selben Namespace ausgeführt.

    Damit beide Cloud Service Mesh-Steuerungsebenen alle Endpunkte eines verteilten Dienstes erkennen können, muss Cloud Service Mesh Zugriff auf alle Cluster haben, auf denen der verteilte Dienst ausgeführt wird. In diesem Beispiel werden zwei Cluster verwendet, sodass beide Cluster den Remote-Cluster nach Dienstendpunkten abfragen können müssen. Wenn das verwaltete Cloud Service Mesh mit der Fleet API aktiviert ist, wird die Endpunkterkennung automatisch konfiguriert.

Die Cluster und Cloud Service Mesh sind jetzt konfiguriert.

Bank of Anthos-Anwendung bereitstellen

  1. Klonen Sie in Cloud Shell das GitHub-Repository von Bank of Anthos:

    git clone https://github.com/GoogleCloudPlatform/bank-of-anthos.git ${HOME}/bank-of-anthos
    
  2. Einen bank-of-anthos-Namespace in beiden Clustern erstellen und mit einem Label versehen. Das Label ermöglicht die automatische Einfügung der Sidecar-Envoy-Proxys in jedem Pod innerhalb des mit einem Label versehenen Namespace.

    # 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. Stellen Sie die Bank of Anthos-Anwendung in beiden Clustern im Namespace bank-of-anthos bereit.

    # 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
    

    Die Kubernetes-Services müssen für die Diensterkennung in beiden Clustern vorhanden sein. Wenn ein Service in einem der Cluster versucht, eine Anfrage zu stellen, führt er zuerst einen DNS-Lookup nach dem Hostnamen durch, um die IP-Adresse abzurufen. In GKE verarbeitet der im Cluster ausgeführte kube-dns-Server diese Suche, sodass eine konfigurierte Service-Definition erforderlich ist.

  4. Löschen Sie die StatefulSets aus einem Cluster, damit die beiden PostgreSQL-Datenbanken nur in einem der Cluster vorhanden sind:

    # 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. Prüfen Sie, ob alle Pods in beiden Clustern ausgeführt werden:

    1. Pods aus cluster_1 abrufen:

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

      Die Ausgabe sieht so aus:

      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. Pods aus cluster_2 abrufen:

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

      Die Ausgabe sieht so aus:

      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. Stellen Sie die Cloud Service Mesh-Konfigurationen in beiden Clustern bereit. Dadurch wird ein Gateway im asm-ingress-Namespace und ein VirtualService in den bank-of-anthos-Namespaces für den frontend-Dienst erstellt, wodurch eingehender Traffic an den frontend-Dienst ermöglicht wird.

    Gateways gehören im Allgemeinen dem Plattformadministrator- oder dem Netzwerkadministrator-Team. Daher wird die Gateway-Ressource im Ingress-Gateway-Namespace erstellt, der dem Plattformadministrator gehört, und kann in anderen Namespaces über dessen eigene VirtualService-Einträge verwendet werden. Dies ist ein Modell für ein freigegebenes 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
    

Sie haben die Bank of Anthos-Anwendung jetzt in zwei privaten GKE-Clustern bereitgestellt. Mit Ausnahme der Datenbank werden alle Dienste als verteilte Dienste ausgeführt.

Verteilte Dienste prüfen

In diesem Abschnitt verwenden Sie das istioctl-Tool, um die Proxykonfiguration eines der Proxys zu prüfen. Dadurch können Sie sehen, dass die Sidecar-Proxys zwei Pods für jeden Dienst sehen, wobei in jedem Cluster ein Pod ausgeführt wird.

  1. Prüfen Sie in Cloud Shell die Endpunktliste der Proxykonfiguration für den frontend-Pod 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
    

    Die Ausgabe sieht so aus:

    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
    

    In der vorherigen Ausgabe hat jeder verteilte Dienst zwei Endpunkt-IP-Adressen. Dies sind die Pod-IP-Adressen (eine für jeden Cluster).

Auf Bank of Anthos zugreifen

Für den Zugriff auf die Bank of Anthos-Anwendung können Sie die öffentliche IP-Adresse des asm-ingressgateway-Dienstes aus einem der Cluster verwenden.

  1. Rufen Sie asm-ingressgateway-IP-Adressen von beiden Clustern ab:

    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"
    
    

    Die Ausgabe sieht wie folgt aus:

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

    Kopieren Sie eine der IP-Adressen, um sie im nächsten Schritt zu verwenden.

  2. Öffnen Sie einen neuen Tab in einem Webbrowser und rufen Sie eine der IP-Adressen aus der vorherigen Ausgabe auf. Das Frontend von Bank of Anthos sollte angezeigt werden. Dort können Sie sich anmelden, Geld auf Ihr Konto einzahlen oder auf andere Konten überweisen. Die Anwendung sollte voll funktionsfähig sein.

Verteilte Dienste visualisieren

Sie können verteilte Dienste in Cloud Service Mesh visualisieren.

  1. Rufen Sie in der Google Cloud Console die Seite Anthos > Service Mesh auf, um sich Ihre Dienste anzusehen.

    Zur Seite "Service Mesh"

    Sie können Dienste in der Ansicht Tabelle oder Topologie aufrufen. Die Standardansicht ist die Tabellenansicht, in der alle verteilten Dienste in einem Tabellenformat angezeigt werden. Zum Ändern der Ansichten klicken Sie auf die gewünschte Ansicht.

  2. Klicken Sie in der Ansicht Tabellen auf frontend distributed service. Wenn Sie auf einen einzelnen Dienst klicken, wird eine detaillierte Ansicht des Dienstes zusammen mit verbundenen Diensten angezeigt.

    In der detaillierten Ansicht des Dienstes können Sie SLOs erstellen und einen zeitlichen Verlauf des Dienstes aufrufen. Klicken Sie dazu auf Zeitachse aufrufen.

  3. Wenn Sie goldene Signale sehen möchten, klicken Sie in der Seitenleiste auf Messwerte.

  4. Klicken Sie im Diagramm Anfragen pro Sekunde auf Aufschlüsselung nach und wählen Sie dann Standort aus.

    Die Ergebnisse zeigen die Anfragen pro Sekunde von beiden Clustern in den beiden Regionen an. Der verteilte Dienst ist fehlerfrei und beide Endpunkte stellen Traffic bereit.

  5. Zum Aufrufen der Topologie Ihres Service Mesh klicken Sie in der Seitenleiste auf Anthos Service Mesh und dann auf Topologieansicht.

  6. Wenn Sie weitere Daten sehen möchten, bewegen Sie den Mauszeiger über den frontend-Dienst. Dadurch werden Informationen wie Anfragen pro Sekunde an das Frontend und von dort an andere Dienste angezeigt.

  7. Klicken Sie beim frontend-Dienst auf Maximieren, um weitere Details aufzurufen. Ein Service und eine Arbeitslast werden angezeigt. Sie können die Arbeitslast weiter in zwei Deployments erweitern, die Deployments in ReplicaSets und die ReplicaSets in Pods. Wenn Sie alle Elemente maximieren, sehen Sie den verteilten frontend-Dienst, der im Wesentlichen ein Service und zwei Pods ist.

Multi-Cluster-Ingress konfigurieren

In diesem Abschnitt erstellen Sie einen Multi-Cluster-Ingress, der Traffic an die in beiden Clustern ausgeführten frontend-Dienste von Bank of GKE Enterprise sendet. Sie verwenden Cloud Load Balancing, um einen Load Balancer zu erstellen, der die asm-ingressgateway-Dienste in beiden Clustern als Back-Ends verwendet. Ein ingress-config-Cluster wird zur Orchestrierung der Multi-Cluster-Ingress-Konfiguration verwendet.

Zum Erstellen des Load-Balancers verwenden Sie einen MultiClusterIngress und einen oder mehrere MultiClusterServices. MultiClusterIngress- und MultiClusterService-Objekte sind Multi-Cluster-Analoge für die vorhandenen Kubernetes Ingress- und Dienstressourcen, die im einzelnen Clusterkontext verwendet werden.

  1. Aktivieren Sie die erforderlichen GKE Enterprise, GKE Fleet und Multi-Cluster-Ingress APIs:

    gcloud services enable \
      anthos.googleapis.com \
      multiclusterservicediscovery.googleapis.com \
      multiclusteringress.googleapis.com
    
  2. Erstellen Sie den ingress-config-Cluster. Sie können einen beliebigen Cluster verwenden. Wir empfehlen jedoch, für diesen Zweck einen separaten Cluster zu erstellen.

    gcloud container clusters create ${CLUSTER_INGRESS} \
      --zone ${CLUSTER_INGRESS_ZONE} \
      --num-nodes=1 \
      --enable-ip-alias \
      --workload-pool=${WORKLOAD_POOL}
    
  3. Rufen Sie die Anmeldedaten für den Cluster ab und benennen Sie den Kontext der Einfachheit halber um:

    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. Wenn Sie Multi-Cluster-Ingress verwenden möchten, registrieren Sie alle teilnehmenden Cluster, einschließlich des Konfigurationsclusters, bei GKE Enterprise Fleet:

  5. Registrieren Sie den Konfigurationscluster:

    gcloud container fleet memberships register ${CLUSTER_INGRESS} \
      --project=${PROJECT_ID} \
      --gke-cluster=${CLUSTER_INGRESS_ZONE}/${CLUSTER_INGRESS} \
      --enable-workload-identity
    
  6. Prüfen Sie, ob alle Cluster bei der GKE Enterprise-Flotte registriert sind:

    gcloud container fleet memberships list
    

    Die Ausgabe sieht so aus:

    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. Aktivieren Sie Multi-Cluster-Ingress-Features im Cluster ingress-config. Dadurch werden die CustomResourceDefinitions (CRDs) MulticlusterService und MulticlusterIngress im Cluster erstellt.

    gcloud container fleet ingress enable \
      --config-membership=projects/${PROJECT_ID}/locations/global/memberships/${CLUSTER_INGRESS}
    
  8. Prüfen Sie, ob Multi-Cluster-Ingress für den Cluster ingress-config aktiviert ist:

    gcloud container fleet ingress describe
    

    Die Ausgabe sieht so aus:

    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. Prüfen Sie, ob die beiden CRDs im Cluster ingress-config bereitgestellt werden:

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

    Die Ausgabe sieht wie folgt aus:

    multiclusteringresses.networking.gke.io     2020-10-29T17:32:50Z
    multiclusterservices.networking.gke.io      2020-10-29T17:32:50Z
    
  10. Erstellen Sie den Namespace asm-ingress im Cluster ingress-config:

    kubectl --context ${CLUSTER_INGRESS} create namespace asm-ingress
    
  11. Erstellen Sie die 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. Erstellen Sie die 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. Erstellen Sie die Ressource BackendConfig für Systemdiagnosen:

    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. Wenden Sie die Manifeste BackendConfig, MultiClusterService und MultiClusterIngress an:

    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. Der MultiClusterService, den Sie im Ingress-Cluster bereitgestellt haben, erstellt in Cluster 1 und Cluster 2 einen monitorlosen Service. Prüfen Sie, ob die monitorlosen Services erstellt wurden:

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

    Die Ausgabe sieht etwa so aus:

    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. Führen Sie den folgenden Befehl aus und warten Sie, bis Sie eine Cloud Load Balancing-IP-Adresse erhalten:

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

    Die Ausgabe sieht so aus:

    35.35.23.11
    

    Drücken Sie Strg+C, um den watch-Befehl zu beenden.

  17. Rufen Sie in einem Webbrowser die IP-Adresse von Cloud Load Balancing auf, um das Frontend von Bank of Anthos aufzurufen:

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

    Wenn Sie einen 404-Fehler (oder einen 502-Fehler) erhalten, warten Sie einige Minuten und aktualisieren Sie dann die Seite in Ihrem Webbrowser.

Bereinigen

Löschen Sie das Projekt oder die Cluster, damit Ihrem Konto keine Gebühren in Rechnung gestellt werden.

Projekt löschen

Am einfachsten vermeiden Sie weitere Kosten, wenn Sie das für die Anleitung erstellte Projekt löschen.

  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.

Cluster löschen

  1. Heben Sie in Cloud Shell die Registrierung der Cluster blue und green auf und löschen Sie sie:

    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. Löschen Sie die Ressource MuticlusterIngress aus dem Cluster "ingress-config":

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

    Dadurch werden die Cloud Load Balancing-Ressourcen aus dem Projekt gelöscht.

  3. Haben Sie die Registrierung des Clusters ingress-config auf und löschen Sie ihn:

    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. Prüfen Sie, ob alle Cluster gelöscht wurden:

    gcloud container clusters list
    

    Die Ausgabe sieht so aus:

    <null>
  5. Setzen Sie die Datei kubeconfig zurück:

    unset KUBECONFIG
    

Nächste Schritte