In diesem Dokument wird beschrieben, wie Sie die folgenden Aufgaben ausführen:
- Global verteilte Anwendungen, die über GKE Gateway und Cloud Service Mesh verfügbar gemacht werden, bereitstellen.
- Sie können eine Anwendung für mehrere Clients verfügbar machen, indem Sie Cloud Load Balancing mit Cloud Service Mesh kombinieren.
- Load Balancer in ein Service Mesh einbinden, das in mehreren Google Cloud-Regionen bereitgestellt wird.
Dieser Bereitstellungsleitfaden richtet sich an Plattformadministratoren. Sie richtet sich auch an fortgeschrittene Nutzer, die Cloud Service Mesh ausführen. Die Anleitung funktioniert auch für Istio on GKE.
Architektur
Das folgende Diagramm zeigt die Standard-Ingress-Topologie eines Service Mesh – einen externen TCP/UDP-Load Balancer, der die Ingress-Gateway-Proxys in einem einzelnen Cluster freigibt:
In diesem Bereitstellungsleitfaden werden GKE-Gateway-Ressourcen (Google Kubernetes Engine) verwendet. Dazu wird ein Multi-Cluster-Gateway verwendet, um das Multi-Region-Load Balancing vor mehreren Autopilot-Clustern zu konfigurieren, die auf zwei Regionen verteilt sind.
Das vorherige Diagramm zeigt, wie Daten bei Cloud-Ingress- und Mesh-Ingress-Szenarien fließen. Weitere Informationen finden Sie in der Erklärung des Architekturdiagramms im zugehörigen Dokument zur Referenzarchitektur.
Lernziele
- Sie stellen zwei GKE Autopilot-Cluster in Google Cloud in derselben Flotte bereit.
- Stellen Sie ein Istio-basiertes Cloud Service Mesh in derselben Flotte bereit.
- Konfigurieren Sie einen Load Balancer mit GKE Gateway, um öffentlichen HTTPS-Traffic zu beenden.
- Öffentlichen HTTPS-Traffic an von Cloud Service Mesh gehostete Anwendungen weiterleiten, die in mehreren Clustern und Regionen bereitgestellt werden.
- Stellen Sie die Beispielanwendung whereami in beiden Autopilot-Clustern bereit.
Kostenoptimierung
In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:
- Google Kubernetes Engine
- Cloud Load Balancing
- Cloud Service Mesh
- Multi Cluster Ingress
- Google Cloud Armor
- Certificate Manager
- Cloud Endpoints
Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen.
Nach Abschluss der in diesem Dokument beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.
Hinweise
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, activate Cloud Shell.
Alle Terminalbefehle für diese Bereitstellung werden in Cloud Shell ausgeführt.
Legen Sie Ihr Google Cloud-Standardprojekt fest:
export PROJECT=YOUR_PROJECT export PROJECT_NUMBER=$(gcloud projects describe PROJECT_ID --format="value(projectNumber)") gcloud config set project PROJECT_ID
Ersetzen Sie
PROJECT_ID
durch die ID des Projekts, das Sie für diese Bereitstellung verwenden möchten.Erstellen Sie ein Arbeitsverzeichnis:
mkdir -p ${HOME}/edge-to-mesh-multi-region cd ${HOME}/edge-to-mesh-multi-region export WORKDIR=`pwd`
GKE-Cluster erstellen
In diesem Abschnitt erstellen Sie GKE-Cluster zum Hosten der Anwendungen und der unterstützenden Infrastruktur, die Sie später in diesem Bereitstellungsleitfaden erstellen.
Erstellen Sie in Cloud Shell eine neue
kubeconfig
-Datei. Dieser Schritt gewährleistet, dass Sie keinen Konflikt mit Ihrer vorhandenen (Standard-)kubeconfig
-Datei schaffen.touch edge2mesh_mr_kubeconfig export KUBECONFIG=${WORKDIR}/edge2mesh_mr_kubeconfig
Definieren Sie die Umgebungsvariablen, die beim Erstellen der GKE-Cluster und der darin enthaltenen Ressourcen verwendet werden. Passen Sie die Standardregion an Ihre Anforderungen an.
export CLUSTER_1_NAME=edge-to-mesh-01 export CLUSTER_2_NAME=edge-to-mesh-02 export CLUSTER_1_REGION=us-central1 export CLUSTER_2_REGION=us-east4 export PUBLIC_ENDPOINT=frontend.endpoints.PROJECT_ID.cloud.goog
Aktivieren Sie die Google Cloud APIs, die in dieser Anleitung verwendet werden:
gcloud services enable \ container.googleapis.com \ mesh.googleapis.com \ gkehub.googleapis.com \ multiclusterservicediscovery.googleapis.com \ multiclusteringress.googleapis.com \ trafficdirector.googleapis.com \ certificatemanager.googleapis.com
Erstellen Sie in
CLUSTER_1_REGION
einen GKE Autopilot-Cluster mit privaten Knoten. Verwenden Sie das Flag--async
, um zu vermeiden, dass Sie auf die Bereitstellung und Registrierung des ersten Clusters in der Flotte warten müssen:gcloud container clusters create-auto --async \ ${CLUSTER_1_NAME} --region ${CLUSTER_1_REGION} \ --release-channel rapid --labels mesh_id=proj-${PROJECT_NUMBER} \ --enable-private-nodes --enable-fleet
Erstellen und registrieren Sie einen zweiten Autopilot-Cluster in
CLUSTER_2_REGION
:gcloud container clusters create-auto \ ${CLUSTER_2_NAME} --region ${CLUSTER_2_REGION} \ --release-channel rapid --labels mesh_id=proj-${PROJECT_NUMBER} \ --enable-private-nodes --enable-fleet
Prüfen Sie, ob die Cluster ausgeführt werden. Es kann bis zu 20 Minuten dauern, bis alle Cluster ausgeführt werden:
gcloud container clusters list
Die Ausgabe sieht in etwa so aus:
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS edge-to-mesh-01 us-central1 1.27.5-gke.200 34.27.171.241 e2-small 1.27.5-gke.200 RUNNING edge-to-mesh-02 us-east4 1.27.5-gke.200 35.236.204.156 e2-small 1.27.5-gke.200 RUNNING
Rufen Sie die Anmeldedaten für
CLUSTER_1_NAME
ab.Sie habenCLUSTER_1_NAME
asynchron erstellt, damit Sie während der Bereitstellung des Clusters zusätzliche Befehle ausführen konnten.gcloud container clusters get-credentials ${CLUSTER_1_NAME} \ --region ${CLUSTER_1_REGION}
Benennen Sie die Kubernetes-Kontexte in die Namen der Cluster um, um für Klarheit zu sorgen:
kubectl config rename-context gke_PROJECT_ID_${CLUSTER_1_REGION}_${CLUSTER_1_NAME} ${CLUSTER_1_NAME} kubectl config rename-context gke_PROJECT_ID_${CLUSTER_2_REGION}_${CLUSTER_2_NAME} ${CLUSTER_2_NAME}
Service Mesh installieren
In diesem Abschnitt konfigurieren Sie das verwaltete Cloud Service Mesh mit Fleet API. Wenn Sie Cloud Service Mesh mit der Fleet API aktivieren, können Sie ein Service Mesh deklarativ bereitstellen.
Aktivieren Sie in Cloud Shell Cloud Service Mesh in der Flotte:
gcloud container fleet mesh enable
Aktivieren Sie die automatische Verwaltung der Steuerungs- und Datenebene:
gcloud container fleet mesh update \ --management automatic \ --memberships ${CLUSTER_1_NAME},${CLUSTER_2_NAME}
Warten Sie etwa 20 Minuten. Prüfen Sie dann, ob der Status der Steuerungsebene
ACTIVE
lautet:gcloud container fleet mesh describe
Die Ausgabe sieht in etwa so aus:
createTime: '2023-11-30T19:23:21.713028916Z' membershipSpecs: projects/603904278888/locations/us-central1/memberships/edge-to-mesh-01: mesh: management: MANAGEMENT_AUTOMATIC projects/603904278888/locations/us-east4/memberships/edge-to-mesh-02: mesh: management: MANAGEMENT_AUTOMATIC membershipStates: projects/603904278888/locations/us-central1/memberships/edge-to-mesh-01: servicemesh: controlPlaneManagement: details: - code: REVISION_READY details: 'Ready: asm-managed-rapid' implementation: ISTIOD state: ACTIVE dataPlaneManagement: details: - code: OK details: Service is running. state: ACTIVE state: code: OK description: |- Revision ready for use: asm-managed-rapid. All Canonical Services have been reconciled successfully. updateTime: '2024-06-27T09:00:21.333579005Z' projects/603904278888/locations/us-east4/memberships/edge-to-mesh-02: servicemesh: controlPlaneManagement: details: - code: REVISION_READY details: 'Ready: asm-managed-rapid' implementation: ISTIOD state: ACTIVE dataPlaneManagement: details: - code: OK details: Service is running. state: ACTIVE state: code: OK description: |- Revision ready for use: asm-managed-rapid. All Canonical Services have been reconciled successfully. updateTime: '2024-06-27T09:00:24.674852751Z' name: projects/e2m-private-test-01/locations/global/features/servicemesh resourceState: state: ACTIVE spec: {} updateTime: '2024-06-04T17:16:28.730429993Z'
Externen Application Load Balancer bereitstellen und Ingress-Gateways erstellen
In diesem Abschnitt stellen Sie einen externen Application Load Balancer über den GKE-Gateway-Controller bereit und erstellen Ingress-Gateways für beide Cluster. Die Ressourcen gateway
und gatewayClass
automatisieren die Bereitstellung des Load Balancers und die Backend-Systemdiagnose. Wenn Sie TLS-Terminierung auf dem Load Balancer bereitstellen möchten, erstellen Sie Zertifikatmanager-Ressourcen und binden sie an den Load Balancer an. Außerdem verwenden Sie Endpoints, um automatisch einen öffentlichen DNS-Namen für die Anwendung bereitzustellen.
Ingress-Gateway in beiden Clustern installieren
Als Best Practice für die Sicherheit empfehlen wir, das Ingress-Gateway in einem anderen Namespace als die Mesh-Steuerungsebene bereitzustellen.
Erstellen Sie in Cloud Shell in jedem Cluster einen dedizierten
asm-ingress
-Namespace:kubectl --context=${CLUSTER_1_NAME} create namespace asm-ingress kubectl --context=${CLUSTER_2_NAME} create namespace asm-ingress
Fügen Sie den Namespaces
asm-ingress
ein Namespace-Label hinzu:kubectl --context=${CLUSTER_1_NAME} label namespace asm-ingress istio-injection=enabled kubectl --context=${CLUSTER_2_NAME} label namespace asm-ingress istio-injection=enabled
Die Ausgabe sieht in etwa so aus:
namespace/asm-ingress labeled
Das Hinzufügen des Labels
istio-injection=enabled
zum Namespaceasm-ingress
weist Cloud Service Mesh an, die Sidecar-Proxys von Envoy automatisch einzuschleusen, wenn ein Pod bereitgestellt wird.Generieren Sie ein selbst signiertes Zertifikat für die zukünftige Verwendung:
openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \ -subj "/CN=frontend.endpoints.PROJECT_ID.cloud.goog/O=Edge2Mesh Inc" \ -keyout ${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.key \ -out ${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.crt
Das Zertifikat bietet eine zusätzliche Verschlüsselungsebene zwischen dem Load Balancer und den Ingress-Gateways des Service Mesh. Außerdem wird die Unterstützung für HTTP/2-basierte Protokolle wie gRPC ermöglicht. Eine Anleitung zum Anhängen des selbst signierten Zertifikats an die Ingress-Gateways finden Sie weiter unten unter Externe IP-Adresse, DNS-Eintrag und TLS-Zertifikatsressourcen erstellen.
Weitere Informationen zu den Anforderungen des Ingress-Gateway-Zertifikats finden Sie unter Verschlüsselung vom Load Balancer zu Back-Ends.
Erstellen Sie in jedem Cluster ein Kubernetes-Secret zum Speichern des selbst signierten Zertifikats:
kubectl --context ${CLUSTER_1_NAME} -n asm-ingress create secret tls \ edge2mesh-credential \ --key=${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.key \ --cert=${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.crt kubectl --context ${CLUSTER_2_NAME} -n asm-ingress create secret tls \ edge2mesh-credential \ --key=${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.key \ --cert=${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.crt
Wenn Sie die Integration mit einem externen Application Load Balancer vornehmen möchten, erstellen Sie eine kustomize-Variante, um die Ingress-Gateway-Ressourcen zu konfigurieren:
mkdir -p ${WORKDIR}/asm-ig/base cat <<EOF > ${WORKDIR}/asm-ig/base/kustomization.yaml resources: - github.com/GoogleCloudPlatform/anthos-service-mesh-samples/docs/ingress-gateway-asm-manifests/base EOF mkdir ${WORKDIR}/asm-ig/variant cat <<EOF > ${WORKDIR}/asm-ig/variant/role.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: asm-ingressgateway namespace: asm-ingress rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "watch", "list"] EOF cat <<EOF > ${WORKDIR}/asm-ig/variant/rolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: asm-ingressgateway namespace: asm-ingress roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: asm-ingressgateway subjects: - kind: ServiceAccount name: asm-ingressgateway EOF cat <<EOF > ${WORKDIR}/asm-ig/variant/service-proto-type.yaml apiVersion: v1 kind: Service metadata: name: asm-ingressgateway namespace: asm-ingress spec: ports: - name: status-port port: 15021 protocol: TCP targetPort: 15021 - name: http port: 80 targetPort: 8080 appProtocol: HTTP - name: https port: 443 targetPort: 8443 appProtocol: HTTP2 type: ClusterIP EOF cat <<EOF > ${WORKDIR}/asm-ig/variant/gateway.yaml apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: asm-ingressgateway namespace: asm-ingress spec: servers: - port: number: 443 name: https protocol: HTTPS hosts: - "*" # IMPORTANT: Must use wildcard here when using SSL, as SNI isn't passed from GFE tls: mode: SIMPLE credentialName: edge2mesh-credential EOF cat <<EOF > ${WORKDIR}/asm-ig/variant/kustomization.yaml namespace: asm-ingress resources: - ../base - role.yaml - rolebinding.yaml patches: - path: service-proto-type.yaml target: kind: Service - path: gateway.yaml target: kind: Gateway EOF
Wenden Sie die Ingress-Gateway-Konfiguration auf beide Cluster an:
kubectl --context ${CLUSTER_1_NAME} apply -k ${WORKDIR}/asm-ig/variant kubectl --context ${CLUSTER_2_NAME} apply -k ${WORKDIR}/asm-ig/variant
Ingress-Gateway-Pods mithilfe eines Multi-Cluster-Dienstes für den Load Balancer verfügbar machen
In diesem Abschnitt exportieren Sie die Ingress-Gateway-Pods über eine ServiceExport
benutzerdefinierte Ressource. Sie müssen die Pods des Eingangsgateways aus folgenden Gründen über eine benutzerdefinierte ServiceExport
-Ressource exportieren:
- Ermöglicht es dem Load Balancer, die Ingress-Gateway-Pods über mehrere Cluster hinweg anzusprechen.
- Ermöglicht den Ingress-Gateway-Pods, Anfragen an Dienste weiterzuleiten, die im Service Mesh ausgeführt werden.
Aktivieren Sie in Cloud Shell Multi-Cluster-Dienste (MCS) für die Flotte:
gcloud container fleet multi-cluster-services enable
Gewähren Sie MCS die erforderlichen IAM-Berechtigungen für das Projekt oder die Flotte:
gcloud projects add-iam-policy-binding PROJECT_ID \ --member "serviceAccount:PROJECT_ID.svc.id.goog[gke-mcs/gke-mcs-importer]" \ --role "roles/compute.networkViewer"
Erstellen Sie die
ServiceExport
-YAML-Datei:cat <<EOF > ${WORKDIR}/svc_export.yaml kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: asm-ingressgateway namespace: asm-ingress EOF
Wenden Sie die
ServiceExport
-YAML-Datei auf beide Cluster an:kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/svc_export.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/svc_export.yaml
Wenn Sie die folgende Fehlermeldung erhalten, warten Sie einige Minuten, bis die benutzerdefinierten Ressourcendefinitionen (CRDs) für MCS installiert sind. Führen Sie dann die Befehle noch einmal aus, um die
ServiceExport
-YAML-Datei auf beide Cluster anzuwenden.error: resource mapping not found for name: "asm-ingressgateway" namespace: "asm-ingress" from "svc_export.yaml": no matches for kind "ServiceExport" in version "net.gke.io/v1" ensure CRDs are installed first
Ressourcen für externe IP-Adressen, DNS-Einträge und TLS-Zertifikate erstellen
In diesem Abschnitt erstellen Sie Netzwerkressourcen, die die Load Balancing-Ressourcen unterstützen, die Sie später in dieser Bereitstellung erstellen.
Reservieren Sie in Cloud Shell eine statische externe IP-Adresse:
gcloud compute addresses create mcg-ip --global
Die GKE-Gateway-Ressource verwendet eine statische IP-Adresse. So bleibt die IP-Adresse gleich, auch wenn der externe Load Balancer neu erstellt wird.
Rufen Sie die statische IP-Adresse ab und speichern Sie sie als Umgebungsvariable:
export MCG_IP=$(gcloud compute addresses describe mcg-ip --global --format "value(address)") echo ${MCG_IP}
Sie benötigen einen öffentlichen DNS-Eintrag, um eine stabile, nutzerfreundliche Zuordnung zu Ihrer Gateway-IP-Adresse zu erstellen.
Sie können einen beliebigen DNS-Anbieter und ein beliebiges Automatisierungsschema verwenden. In dieser Bereitstellung wird Endpoints verwendet, anstatt eine verwaltete DNS-Zone zu erstellen. Endpoints bietet einen kostenlosen von Google verwalteten DNS-Eintrag für eine externe IP-Adresse.
Führen Sie den folgenden Befehl aus, um eine YAML-Datei mit dem Namen
dns-spec.yaml
zu erstellen:cat <<EOF > ${WORKDIR}/dns-spec.yaml swagger: "2.0" info: description: "Cloud Endpoints DNS" title: "Cloud Endpoints DNS" version: "1.0.0" paths: {} host: "frontend.endpoints.PROJECT_ID.cloud.goog" x-google-endpoints: - name: "frontend.endpoints.PROJECT_ID.cloud.goog" target: "${MCG_IP}" EOF
In der Datei
dns-spec.yaml
wird der öffentliche DNS-Eintrag in Form vonfrontend.endpoints.PROJECT_ID.cloud.goog
definiert, wobeiPROJECT_ID
Ihre eindeutige Projekt-ID ist.Bereitstellen Sie die Datei
dns-spec.yaml
, um den DNS-Eintrag zu erstellen. Dieser Vorgang dauert einige Minuten.gcloud endpoints services deploy ${WORKDIR}/dns-spec.yaml
Erstellen Sie ein Zertifikat mit dem Zertifikatmanager für den Namen des DNS-Eintrags, den Sie im vorherigen Schritt erstellt haben:
gcloud certificate-manager certificates create mcg-cert \ --domains="frontend.endpoints.PROJECT_ID.cloud.goog"
Ein von Google verwaltetes TLS-Zertifikat wird verwendet, um eingehende Clientanfragen am Load Balancer zu beenden.
Erstellen Sie eine Zertifikatszuordnung:
gcloud certificate-manager maps create mcg-cert-map
Der Load Balancer verweist auf das Zertifikat über den Eintrag in der Zertifikatzuordnung, den Sie im nächsten Schritt erstellen.
Erstellen Sie einen Eintrag für die Zertifikatszuordnung für das Zertifikat, das Sie zuvor in diesem Abschnitt erstellt haben:
gcloud certificate-manager maps entries create mcg-cert-map-entry \ --map="mcg-cert-map" \ --certificates="mcg-cert" \ --hostname="frontend.endpoints.PROJECT_ID.cloud.goog"
Back-End-Dienstrichtlinien und Load Balancer-Ressourcen erstellen
In diesem Abschnitt führen Sie die folgenden Aufgaben aus:
- Erstellen Sie eine Google Cloud Armor-Sicherheitsrichtlinie mit Regeln.
- Erstellen Sie eine Richtlinie, mit der der Load Balancer die Reaktionsfähigkeit der Ingress-Gateway-Pods über die zuvor erstellte
ServiceExport
-YAML-Datei prüfen kann. - Verwenden Sie die GKE Gateway API, um eine Load Balancer-Ressource zu erstellen.
- Verwenden Sie die benutzerdefinierte Ressource
GatewayClass
, um den spezifischen Load Balancer-Typ festzulegen. - Aktivieren Sie das Multi-Cluster-Load Balancing für die Flotte und legen Sie einen der Cluster als Konfigurationscluster für die Flotte fest.
Erstellen Sie in Cloud Shell eine Google Cloud Armor-Sicherheitsrichtlinie:
gcloud compute security-policies create edge-fw-policy \ --description "Block XSS attacks"
Erstellen Sie eine Regel für die Sicherheitsrichtlinie:
gcloud compute security-policies rules create 1000 \ --security-policy edge-fw-policy \ --expression "evaluatePreconfiguredExpr('xss-stable')" \ --action "deny-403" \ --description "XSS attack filtering"
Erstellen Sie eine YAML-Datei für die Sicherheitsrichtlinie und verweisen Sie in einer entsprechenden YAML-Datei vom Typ
ServiceImport
auf die YAML-Datei vom TypServiceExport
:cat <<EOF > ${WORKDIR}/cloud-armor-backendpolicy.yaml apiVersion: networking.gke.io/v1 kind: GCPBackendPolicy metadata: name: cloud-armor-backendpolicy namespace: asm-ingress spec: default: securityPolicy: edge-fw-policy targetRef: group: net.gke.io kind: ServiceImport name: asm-ingressgateway EOF
Wenden Sie die Google Cloud Armor-Richtlinie auf beide Cluster an:
kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/cloud-armor-backendpolicy.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/cloud-armor-backendpolicy.yaml
Erstellen Sie eine benutzerdefinierte YAML-Datei, mit der der Load Balancer Systemdiagnosen am Envoy-Systemdiagnoseendpunkt (Port
15021
auf Pfad/healthz/ready
) der Ingress-Gateway-Pods in beiden Clustern durchführen kann:cat <<EOF > ${WORKDIR}/ingress-gateway-healthcheck.yaml apiVersion: networking.gke.io/v1 kind: HealthCheckPolicy metadata: name: ingress-gateway-healthcheck namespace: asm-ingress spec: default: config: httpHealthCheck: port: 15021 portSpecification: USE_FIXED_PORT requestPath: /healthz/ready type: HTTP targetRef: group: net.gke.io kind: ServiceImport name: asm-ingressgateway EOF
Wenden Sie die benutzerdefinierte YAML-Datei, die Sie im vorherigen Schritt erstellt haben, auf beide Cluster an:
kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/ingress-gateway-healthcheck.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/ingress-gateway-healthcheck.yaml
Aktivieren Sie das Multi-Cluster-Load Balancing für die Flotte und legen Sie
CLUSTER_1_NAME
als Konfigurationscluster fest:gcloud container fleet ingress enable \ --config-membership=${CLUSTER_1_NAME} \ --location=${CLUSTER_1_REGION}
Gewähren Sie IAM-Berechtigungen für den Gateway-Controller in der Flotte:
gcloud projects add-iam-policy-binding PROJECT_ID \ --member "serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-multiclusteringress.iam.gserviceaccount.com" \ --role "roles/container.admin"
Erstellen Sie die YAML-Datei des Load Balancers über eine benutzerdefinierte Gateway-Ressource, die auf die
gke-l7-global-external-managed-mc
gatewayClass
und die zuvor erstellte statische IP-Adresse verweist:cat <<EOF > ${WORKDIR}/frontend-gateway.yaml kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: external-http namespace: asm-ingress annotations: networking.gke.io/certmap: mcg-cert-map spec: gatewayClassName: gke-l7-global-external-managed-mc listeners: - name: http # list the port only so we can redirect any incoming http requests to https protocol: HTTP port: 80 - name: https protocol: HTTPS port: 443 allowedRoutes: kinds: - kind: HTTPRoute addresses: - type: NamedAddress value: mcg-ip EOF
Wenden Sie die YAML-Datei
frontend-gateway
auf beide Cluster an. Sofern Sie keinen anderen Konfigurationscluster als verbindlich festlegen, ist nurCLUSTER_1_NAME
verbindlich:kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/frontend-gateway.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/frontend-gateway.yaml
Erstellen Sie eine
HTTPRoute
-YAML-Datei namensdefault-httproute.yaml
, in der die Gateway-Ressource angewiesen wird, Anfragen an die Ingress-Gateways zu senden:cat << EOF > ${WORKDIR}/default-httproute.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: default-httproute namespace: asm-ingress spec: parentRefs: - name: external-http namespace: asm-ingress sectionName: https rules: - backendRefs: - group: net.gke.io kind: ServiceImport name: asm-ingressgateway port: 443 EOF
Wenden Sie die im vorherigen Schritt erstellte YAML-Datei
HTTPRoute
auf beide Cluster an:kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/default-httproute.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/default-httproute.yaml
Wenn Sie HTTP-zu-HTTP(S)-Weiterleitungen ausführen möchten, erstellen Sie eine zusätzliche
HTTPRoute
-YAML-Datei mit dem Namendefault-httproute-redirect.yaml
:cat << EOF > ${WORKDIR}/default-httproute-redirect.yaml kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: http-to-https-redirect-httproute namespace: asm-ingress spec: parentRefs: - name: external-http namespace: asm-ingress sectionName: http rules: - filters: - type: RequestRedirect requestRedirect: scheme: https statusCode: 301 EOF
Wenden Sie die YAML-Datei für die Weiterleitung
HTTPRoute
auf beide Cluster an:kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/default-httproute-redirect.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/default-httproute-redirect.yaml
Prüfen Sie die Gateway-Ressource, um den Fortschritt der Bereitstellung des Load Balancers zu prüfen:
kubectl --context=${CLUSTER_1_NAME} describe gateway external-http -n asm-ingress
In der Ausgabe werden die Informationen angezeigt, die Sie in diesem Abschnitt eingegeben haben.
Beispielanwendung „whereami“ bereitstellen
In dieser Anleitung wird whereami als Beispielanwendung verwendet, um direktes Feedback dazu zu erhalten, welche Cluster auf Anfragen antworten. Im folgenden Abschnitt werden zwei separate Bereitstellungen von whereami in beiden Clustern eingerichtet: eine frontend
-Bereitstellung und eine backend
-Bereitstellung.
Die frontend
-Bereitstellung ist die erste Arbeitslast, die die Anfrage empfängt. Anschließend wird die backend
-Bereitstellung aufgerufen.
Dieses Modell wird verwendet, um eine Multi-Service-Anwendungsarchitektur zu veranschaulichen.
Sowohl der frontend
- als auch der backend
-Dienst werden in beiden Clustern bereitgestellt.
Erstellen Sie in Cloud Shell die Namespaces für „whereami“
frontend
und „whereami“backend
in beiden Clustern und aktivieren Sie die Namespace-Injection:kubectl --context=${CLUSTER_1_NAME} create ns frontend kubectl --context=${CLUSTER_1_NAME} label namespace frontend istio-injection=enabled kubectl --context=${CLUSTER_1_NAME} create ns backend kubectl --context=${CLUSTER_1_NAME} label namespace backend istio-injection=enabled kubectl --context=${CLUSTER_2_NAME} create ns frontend kubectl --context=${CLUSTER_2_NAME} label namespace frontend istio-injection=enabled kubectl --context=${CLUSTER_2_NAME} create ns backend kubectl --context=${CLUSTER_2_NAME} label namespace backend istio-injection=enabled
Erstellen Sie eine Kustomize-Variante für den Befehl „whereami“
backend
:mkdir -p ${WORKDIR}/whereami-backend/base cat <<EOF > ${WORKDIR}/whereami-backend/base/kustomization.yaml resources: - github.com/GoogleCloudPlatform/kubernetes-engine-samples/quickstarts/whereami/k8s EOF mkdir ${WORKDIR}/whereami-backend/variant cat <<EOF > ${WORKDIR}/whereami-backend/variant/cm-flag.yaml apiVersion: v1 kind: ConfigMap metadata: name: whereami data: BACKEND_ENABLED: "False" # assuming you don't want a chain of backend calls METADATA: "backend" EOF cat <<EOF > ${WORKDIR}/whereami-backend/variant/service-type.yaml apiVersion: "v1" kind: "Service" metadata: name: "whereami" spec: type: ClusterIP EOF cat <<EOF > ${WORKDIR}/whereami-backend/variant/kustomization.yaml nameSuffix: "-backend" namespace: backend commonLabels: app: whereami-backend resources: - ../base patches: - path: cm-flag.yaml target: kind: ConfigMap - path: service-type.yaml target: kind: Service EOF
Wenden Sie die Variante „whereami“
backend
auf beide Cluster an:kubectl --context=${CLUSTER_1_NAME} apply -k ${WORKDIR}/whereami-backend/variant kubectl --context=${CLUSTER_2_NAME} apply -k ${WORKDIR}/whereami-backend/variant
Erstellen Sie eine Kustomize-Variante für den Befehl „whereami“
frontend
:mkdir -p ${WORKDIR}/whereami-frontend/base cat <<EOF > ${WORKDIR}/whereami-frontend/base/kustomization.yaml resources: - github.com/GoogleCloudPlatform/kubernetes-engine-samples/quickstarts/whereami/k8s EOF mkdir whereami-frontend/variant cat <<EOF > ${WORKDIR}/whereami-frontend/variant/cm-flag.yaml apiVersion: v1 kind: ConfigMap metadata: name: whereami data: BACKEND_ENABLED: "True" BACKEND_SERVICE: "http://whereami-backend.backend.svc.cluster.local" EOF cat <<EOF > ${WORKDIR}/whereami-frontend/variant/service-type.yaml apiVersion: "v1" kind: "Service" metadata: name: "whereami" spec: type: ClusterIP EOF cat <<EOF > ${WORKDIR}/whereami-frontend/variant/kustomization.yaml nameSuffix: "-frontend" namespace: frontend commonLabels: app: whereami-frontend resources: - ../base patches: - path: cm-flag.yaml target: kind: ConfigMap - path: service-type.yaml target: kind: Service EOF
Wenden Sie die Variante „whereami“
frontend
auf beide Cluster an:kubectl --context=${CLUSTER_1_NAME} apply -k ${WORKDIR}/whereami-frontend/variant kubectl --context=${CLUSTER_2_NAME} apply -k ${WORKDIR}/whereami-frontend/variant
Erstellen Sie eine
VirtualService
-YAML-Datei, um Anfragen an den whereami-frontend
weiterzuleiten:cat << EOF > ${WORKDIR}/frontend-vs.yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: whereami-vs namespace: frontend spec: gateways: - asm-ingress/asm-ingressgateway hosts: - 'frontend.endpoints.PROJECT_ID.cloud.goog' http: - route: - destination: host: whereami-frontend port: number: 80 EOF
Wenden Sie die
frontend-vs
-YAML-Datei auf beide Cluster an:kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/frontend-vs.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/frontend-vs.yaml
Nachdem Sie
frontend-vs.yaml
in beiden Clustern bereitgestellt haben, versuchen Sie, den öffentlichen Endpunkt für Ihre Cluster aufzurufen:curl -s https://frontend.endpoints.PROJECT_ID.cloud.goog | jq
Die Ausgabe sieht in etwa so aus:
{ "backend_result": { "cluster_name": "edge-to-mesh-02", "gce_instance_id": "8396338201253702608", "gce_service_account": "e2m-mcg-01.svc.id.goog", "host_header": "whereami-backend.backend.svc.cluster.local", "metadata": "backend", "node_name": "gk3-edge-to-mesh-02-pool-2-675f6abf-645h", "pod_ip": "10.124.0.199", "pod_name": "whereami-backend-7cbdfd788-8mmnq", "pod_name_emoji": "📸", "pod_namespace": "backend", "pod_service_account": "whereami-backend", "project_id": "e2m-mcg-01", "timestamp": "2023-12-01T03:46:24", "zone": "us-east4-b" }, "cluster_name": "edge-to-mesh-01", "gce_instance_id": "1047264075324910451", "gce_service_account": "e2m-mcg-01.svc.id.goog", "host_header": "frontend.endpoints.e2m-mcg-01.cloud.goog", "metadata": "frontend", "node_name": "gk3-edge-to-mesh-01-pool-2-d687e3c0-5kf2", "pod_ip": "10.54.1.71", "pod_name": "whereami-frontend-69c4c867cb-dgg8t", "pod_name_emoji": "🪴", "pod_namespace": "frontend", "pod_service_account": "whereami-frontend", "project_id": "e2m-mcg-01", "timestamp": "2023-12-01T03:46:24", "zone": "us-central1-c" }
Wenn Sie den Befehl curl
einige Male ausführen, sehen Sie, dass die Antworten (sowohl von frontend
als auch von backend
) aus verschiedenen Regionen stammen. In seiner Antwort bietet der Load Balancer Geo-Routing. Das bedeutet, dass der Load Balancer Anfragen vom Client an den nächstgelegenen aktiven Cluster weiterleitet, die Anfragen aber trotzdem nach dem Zufallsprinzip landen. Wenn Anfragen gelegentlich von einer Region in eine andere gehen, erhöhen sich Latenz und Kosten.
Im nächsten Abschnitt implementieren Sie das Load Balancing nach Standort im Service Mesh, um Anfragen lokal zu halten.
Ort-Load Balancing für „whereami“ aktivieren und testen
In diesem Abschnitt implementieren Sie das Load Balancing nach Standort im Service Mesh, um Anfragen lokal zu halten. Außerdem führen Sie einige Tests durch, um zu sehen, wie whereami mit verschiedenen Fehlerszenarien umgeht.
Wenn Sie eine Anfrage an den whereami frontend
-Dienst senden, sendet der Load Balancer die Anfrage an den Cluster mit der niedrigsten Latenz im Verhältnis zum Client. Das bedeutet, dass die Ingress-Gateway-Pods innerhalb des Mesh Anfragen an Whereami frontend
-Pods in beiden Clustern ausbalancieren. In diesem Abschnitt wird dieses Problem behoben, indem das Load Balancing auf Ortsebene innerhalb des Mesh aktiviert wird.
Erstellen Sie in Cloud Shell eine YAML-Datei vom Typ
DestinationRule
, die das regionale Failover für das Load Balancing nach Standort für den Dienstfrontend
aktiviert:cat << EOF > ${WORKDIR}/frontend-dr.yaml apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: frontend namespace: frontend spec: host: whereami-frontend.frontend.svc.cluster.local trafficPolicy: connectionPool: http: maxRequestsPerConnection: 0 loadBalancer: simple: LEAST_REQUEST localityLbSetting: enabled: true outlierDetection: consecutive5xxErrors: 1 interval: 1s baseEjectionTime: 1m EOF
Im vorherigen Codebeispiel wird nur das lokale Routing für den
frontend
-Dienst aktiviert. Außerdem ist eine zusätzliche Konfiguration erforderlich, die das Backend verwaltet.Wenden Sie die
frontend-dr
-YAML-Datei auf beide Cluster an:kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/frontend-dr.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/frontend-dr.yaml
Erstellen Sie eine
DestinationRule
-YAML-Datei, die das Load Balancing auf Ortsebene und den regionalen Failover für denbackend
-Dienst ermöglicht:cat << EOF > ${WORKDIR}/backend-dr.yaml apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: n ame: backend namespace: backend spec: host: whereami-backend.backend.svc.cluster.local trafficPolicy: connectionPool: http: maxRequestsPerConnection: 0 loadBalancer: simple: LEAST_REQUEST localityLbSetting: enabled: true outlierDetection: consecutive5xxErrors: 1 interval: 1s baseEjectionTime: 1m EOF
Wenden Sie die
backend-dr
-YAML-Datei auf beide Cluster an:kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/backend-dr.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/backend-dr.yaml
Wenn beide
DestinationRule
-YAML-Dateien auf beide Cluster angewendet werden, bleiben Anfragen lokal für den Cluster, an den sie weitergeleitet werden.Wenn Sie den Failover für den
frontend
-Dienst testen möchten, verringern Sie die Anzahl der Replikate für das Ingress-Gateway in Ihrem primären Cluster.Aus Sicht des multiregionalen Load Balancers simuliert diese Aktion einen Clusterausfall. Dies führt dazu, dass der Cluster die Load Balancer-Systemdiagnosen nicht besteht. In diesem Beispiel wird der Cluster in
CLUSTER_1_REGION
verwendet. Sie sollten nur Antworten vom Cluster inCLUSTER_2_REGION
sehen.Reduzieren Sie die Anzahl der Replikate für das Ingress-Gateway in Ihrem primären Cluster auf null und rufen Sie den öffentlichen Endpunkt auf, um zu prüfen, ob Anfragen an den anderen Cluster umgeleitet wurden:
kubectl --context=${CLUSTER_1_NAME} -n asm-ingress scale --replicas=0 deployment/asm-ingressgateway
Die Ausgabe sollte in etwa so aussehen:
$ curl -s https://frontend.endpoints.PROJECT_ID.cloud.goog | jq { "backend_result": { "cluster_name": "edge-to-mesh-02", "gce_instance_id": "2717459599837162415", "gce_service_account": "e2m-mcg-01.svc.id.goog", "host_header": "whereami-backend.backend.svc.cluster.local", "metadata": "backend", "node_name": "gk3-edge-to-mesh-02-pool-2-675f6abf-dxs2", "pod_ip": "10.124.1.7", "pod_name": "whereami-backend-7cbdfd788-mp8zv", "pod_name_emoji": "🏌🏽♀", "pod_namespace": "backend", "pod_service_account": "whereami-backend", "project_id": "e2m-mcg-01", "timestamp": "2023-12-01T05:41:18", "zone": "us-east4-b" }, "cluster_name": "edge-to-mesh-02", "gce_instance_id": "6983018919754001204", "gce_service_account": "e2m-mcg-01.svc.id.goog", "host_header": "frontend.endpoints.e2m-mcg-01.cloud.goog", "metadata": "frontend", "node_name": "gk3-edge-to-mesh-02-pool-3-d42ddfbf-qmkn", "pod_ip": "10.124.1.142", "pod_name": "whereami-frontend-69c4c867cb-xf8db", "pod_name_emoji": "🏴", "pod_namespace": "frontend", "pod_service_account": "whereami-frontend", "project_id": "e2m-mcg-01", "timestamp": "2023-12-01T05:41:18", "zone": "us-east4-b" }
Wenn Sie das normale Traffic-Routing fortsetzen möchten, stellen Sie die Ingress-Gateway-Replikate im Cluster auf den ursprünglichen Wert zurück:
kubectl --context=${CLUSTER_1_NAME} -n asm-ingress scale --replicas=3 deployment/asm-ingressgateway
Simulieren Sie einen Fehler für den
backend
-Dienst, indem Sie die Anzahl der Repliken in der primären Region auf 0 reduzieren:kubectl --context=${CLUSTER_1_NAME} -n backend scale --replicas=0 deployment/whereami-backend
Prüfen Sie, ob die Antworten vom
frontend
-Dienst aus der primären Regionus-central1
über den Load Balancer und die Antworten vombackend
-Dienst aus der sekundären Regionus-east4
stammen.Die Ausgabe sollte auch eine Antwort für den Dienst
frontend
aus der primären Region (us-central1
) und eine Antwort für den Dienstbackend
aus der sekundären Region (us-east4
) enthalten.Stellen Sie die Back-End-Dienstrepliken auf den ursprünglichen Wert zurück, um das normale Traffic-Routing fortzusetzen:
kubectl --context=${CLUSTER_1_NAME} -n backend scale --replicas=3 deployment/whereami-backend
Sie haben jetzt einen globalen HTTP(S)-Load Balancer, der als Front-End für Ihre von einem Dienst gehostete, mehrstufige Anwendung dient.
Bereinigen
Damit Ihrem Google Cloud-Konto die in dieser Bereitstellung verwendeten Ressourcen nicht in Rechnung gestellt werden, löschen Sie entweder das Projekt, das die Ressourcen enthält, oder behalten Sie das Projekt bei und löschen Sie die einzelnen Ressourcen.
Projekt löschen
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Einzelne Ressourcen löschen
Wenn Sie das in dieser Bereitstellung verwendete Google Cloud-Projekt beibehalten möchten, löschen Sie die einzelnen Ressourcen:
Löschen Sie in Cloud Shell die
HTTPRoute
-Ressourcen:kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/default-httproute-redirect.yaml kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/default-httproute-redirect.yaml kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/default-httproute.yaml kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/default-httproute.yaml
Löschen Sie die GKE-Gateway-Ressourcen:
kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/frontend-gateway.yaml kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/frontend-gateway.yaml
So löschen Sie die Richtlinien:
kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/ingress-gateway-healthcheck.yaml kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/ingress-gateway-healthcheck.yaml kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/cloud-armor-backendpolicy.yaml kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/cloud-armor-backendpolicy.yaml
Löschen Sie die Dienstexporte:
kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/svc_export.yaml kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/svc_export.yaml
Löschen Sie die Google Cloud Armor-Ressourcen:
gcloud --project=PROJECT_ID compute security-policies rules delete 1000 --security-policy edge-fw-policy --quiet gcloud --project=PROJECT_ID compute security-policies delete edge-fw-policy --quiet
Löschen Sie die Certificate Manager-Ressourcen:
gcloud --project=PROJECT_ID certificate-manager maps entries delete mcg-cert-map-entry --map="mcg-cert-map" --quiet gcloud --project=PROJECT_ID certificate-manager maps delete mcg-cert-map --quiet gcloud --project=PROJECT_ID certificate-manager certificates delete mcg-cert --quiet
Endpoints-DNS-Eintrag löschen:
gcloud --project=PROJECT_ID endpoints services delete "frontend.endpoints.PROJECT_ID.cloud.goog" --quiet
Löschen Sie die statische IP-Adresse:
gcloud --project=PROJECT_ID compute addresses delete mcg-ip --global --quiet
Löschen Sie die GKE Autopilot-Cluster. Dieser Schritt dauert einige Minuten.
gcloud --project=PROJECT_ID container clusters delete ${CLUSTER_1_NAME} --region ${CLUSTER_1_REGION} --quiet gcloud --project=PROJECT_ID container clusters delete ${CLUSTER_2_NAME} --region ${CLUSTER_2_REGION} --quiet
Nächste Schritte
- Weitere Informationen zu Funktionen von GKE Gateway, die Sie mit Ihrem Service Mesh verwenden können
- Weitere Informationen zu den verschiedenen Arten von Cloud Load Balancing für GKE.
- Weitere Informationen zu Features und Funktionen von Cloud Service Mesh.
- Weitere Referenzarchitekturen, Diagramme und Best Practices finden Sie im Cloud-Architekturcenter.
Beitragende
Autoren:
- Alex Mattson | Application Specialist Engineer
- Mark Chilvers | Application Specialist Engineer
Weitere Beitragende:
- Abdelfettah Sghiouar | Cloud Developer Advocate
- Greg Bray | Customer Engineer
- Paul Revello | Cloud Solutions Architect
- Valavan Rajakumar | Key Enterprise Architect