Auf dieser Seite wird beschrieben, wie Sie Kubernetes-Gateway-Ressourcen bereitstellen, um Load Balancing auf eingehenden Traffic über mehrere GKE-Cluster (oder Flotten) von Google Kubernetes Engine hinweg anzuwenden. Lesen Sie die Informationen zum Vorbereiten Ihrer Umgebung unter Multi-Cluster-Gateways aktivieren, bevor Sie Multi-Cluster-Gateways bereitstellen.
Informationen zum Bereitstellen von Gateways für das Load Balancing von eingehendem Traffic auf nur einen GKE-Cluster finden Sie unter Gateways bereitstellen.
Multi-Cluster-Gateways
Ein Multi-Cluster-Gateway ist eine Gateway-Ressource, bei der der Traffic auf mehrere Kubernetes-Cluster verteilt wird. In GKE stellen die GatewayClasses gke-l7-global-external-managed-mc
, gke-l7-regional-external-managed-mc
, gke-l7-rilb-mc
und gke-l7-gxlb-mc
Multi-Cluster-Gateways bereit, die HTTP-Routing, Trafficaufteilung, Trafficspiegelung, Systemdiagnose-Failover und mehr über verschiedene GKE-Cluster, Kubernetes Namespaces und verschiedene Regionen hinweg bieten.
Multi-Cluster-Gateways machen die Verwaltung von Anwendungsnetzwerken über viele Cluster und Teams hinweg für Infrastrukturadministratoren einfach, sicher und skalierbar.
Auf dieser Seite werden drei Beispiele vorgestellt, die zeigen, wie Sie Multi-Cluster-Gateways mit dem GKE-Gateway-Controller bereitstellen:
- Beispiel 1: Ein externes Multi-Cluster-Gateway, das Load Balancing auf zwei GKE-Clustern für den Internet-Traffic anwendet.
- Beispiel 2: Blau-grüne, gewichtete Trafficaufteilung und Trafficspiegelung für zwei GKE-Cluster für internen VPC-Traffic.
- Beispiel 3: Ein kapazitätsbasiertes Gateway zum Load Balancing von Anfragen an verschiedene Back-Ends basierend auf ihrer maximalen Kapazität.
Beide Beispiele nutzen dieselben Speicher- und Website-Anwendungen, um ein reales Szenario zu modellieren, in dem ein Online-Shopping-Dienst und ein Website-Dienst von separaten Teams betrieben und über eine Flotte freigegebener GKE-Cluster bereitgestellt werden. Die Beispiele heben verschiedene Topologien und Anwendungsfälle hervor, die Multi-Cluster-Gateways nutzen.
Multi-Cluster-Gateways erfordern eine gewisse Umgebungsvorbereitung, bevor sie bereitgestellt werden können. Bevor Sie fortfahren, führen Sie die Schritte unter Multi-Cluster-Gateways aktivieren aus:
GKE-Cluster bereitstellen.
Registrieren Sie Ihre Cluster bei einer Flotte.
Aktivieren Sie den Multi-Cluster-Service und die Multi-Cluster-Gateway-Controller.
Prüfen Sie dann vor der Verwendung in der Umgebung die Einschränkungen und bekannten Probleme des GKE-Gateway-Controllers.
Externes Multi-Cluster-/Multi-Region-Gateway
In dieser Anleitung erstellen Sie ein externes Multi-Cluster-Gateway, das externen Traffic für eine Anwendung bereitstellt, die in zwei GKE-Clustern ausgeführt wird.
In den nächsten Schritten führen Sie die folgenden Aufgaben aus:
- Stellen Sie die
store
-Beispielanwendung in den Clusterngke-west-1
undgke-east-1
bereit. - Konfigurieren Sie die Dienste auf jedem Cluster, damit sie in Ihre Flotte exportiert werden (Multi-Cluster-Dienste).
- Stellen Sie ein externes Multi-Cluster-Gateway und eine HTTPRoute in Ihrem Konfigurationscluster (
gke-west-1
) bereit.
Nachdem die Anwendungs- und Gateway-Ressourcen bereitgestellt wurden, können Sie den Traffic zwischen den beiden GKE-Clustern über pfadbasierte Routings steuern:
- Anfragen an
/west
werden anstore
-Pods imgke-west-1
-Cluster weitergeleitet. - Anfragen an
/east
werden anstore
-Pods imgke-east-1
-Cluster weitergeleitet. - Anfragen an jeden anderen Pfad werden abhängig von ihrem Zustand, ihrer Kapazität und der Nähe zum anfragenden Client an einen der Cluster weitergeleitet.
Demoanwendung bereitstellen
Erstellen Sie das
store
-Deployment und den Namespace in allen drei Clustern, die unter Multi-Cluster-Gateways aktivieren bereitgestellt wurden:kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml kubectl apply --context gke-west-2 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml kubectl apply --context gke-east-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml
In jedem Cluster werden folgende Ressourcen bereitgestellt:
namespace/store created deployment.apps/store created
Für alle Beispiele auf dieser Seite wird die in diesem Schritt bereitgestellte Anwendung verwendet. Prüfen Sie, ob die Anwendung in allen drei Clustern bereitgestellt wird, bevor Sie einen der verbleibenden Schritte ausführen. In diesem Beispiel werden nur die Cluster
gke-west-1
undgke-east-1
verwendet. In einem anderen Beispiel wirdgke-west-2
verwendet.
Multi-Cluster-Dienste
Services werden wie Pods für Clients verfügbar gemacht. Da der GKE-Gateway-Controller containernatives Load Balancing verwendet, wird nicht das ClusterIP- oder Kubernetes-Load-Balancing verwendet, um Pods zu erreichen. Der Traffic wird direkt vom Load Balancer an die Pod-IP-Adressen gesendet. Services spielen jedoch weiterhin eine wichtige Rolle als logische Kennzeichnung für die Pod-Gruppierung.
Multi-Cluster-Service (MCS) ist ein API-Standard für Services, die Cluster umfassen. Der zugehörige GKE-Controller stellt Service Discovery in GKE-Clustern bereit. Der Multi-Cluster-Gateway-Controller verwendet MCS-API-Ressourcen, um Pods in einem Service zu gruppieren, der über mehrere Cluster adressierbar ist oder sich über mehrere Cluster erstreckt.
Die Multi-Cluster Services API definiert folgende benutzerdefinierte Ressourcen:
- ServiceExports werden einem Kubernetes-Dienst zugeordnet und exportieren die Endpunkte dieses Dienstes auf alle Cluster, die für die Flotte registriert sind. Wenn ein Service einen entsprechenden ServiceExport hat, kann er von einem Multi-Cluster-Gateway adressiert werden.
- ServiceImports werden vom Multi-Cluster-Service-Controller automatisch generiert. ServiceExport und ServiceImport sind paarweise verfügbar. Wenn ein ServiceExport in der Flotte vorhanden ist, wird ein entsprechender ServiceImport erstellt, damit der Service, der dem ServiceExport zugeordnet ist, über alle Cluster zugänglich ist.
Der Export von Services funktioniert auf folgende Weise. In gke-west-1
befindet sich ein Speicher-Service, der eine Gruppe von Pods in diesem Cluster auswählt. Im Cluster wird ein ServiceExport erstellt, durch den die Pods in gke-west-1
von den anderen Clustern in der Flotte zugänglich sind. Der ServiceExport wird Services zugeordnet, die denselben Namen und Namespace wie die ServiceExport-Ressource haben, und macht sie verfügbar.
apiVersion: v1
kind: Service
metadata:
name: store
namespace: store
spec:
selector:
app: store
ports:
- port: 8080
targetPort: 8080
---
kind: ServiceExport
apiVersion: net.gke.io/v1
metadata:
name: store
namespace: store
Das folgende Diagramm zeigt, was nach der Bereitstellung eines ServiceExport geschieht. Wenn ein ServiceExport/Service-Paar vorhanden ist, stellt der Multi-Cluster-Service-Controller einen entsprechenden ServiceImport in jedem GKE-Cluster in der Flotte bereit. Der ServiceImport ist die lokale Darstellung des store
-Service in jedem Cluster. Dadurch kann der client
-Pod in gke-east-1
ClusterIP- oder monitorlose Services verwenden, um die store
-Pods in gke-west-1
zu erreichen. Bei dieser Verwendungsart bieten Multi-Cluster-Services ein Ost-West-Load-Balancing zwischen Clustern, ohne einen internen LoadBalancer-Service zu erfordern.
Informationen zum Verwenden von Multi-Cluster-Services für Cluster-zu-Cluster-Load-Balancing finden Sie unter Multi-Cluster-Services konfigurieren.
Multi-Cluster-Gateways verwenden auch ServiceImports, jedoch nicht für das Cluster-zu-Cluster-Load-Balancing. Stattdessen verwenden Gateways ServiceImports als logische Kennzeichnungen für einen Service, der in einem anderen Cluster vorhanden ist oder sich über mehrere Cluster erstreckt. Die folgende HTTPRoute verweist auf eine ServiceImport-Ressource statt auf eine Service-Ressource. Durch Verweisen auf einen ServiceImport wird angegeben, dass der Traffic an eine Gruppe von Backend-Pods weitergeleitet wird, die in einem oder mehreren Clustern ausgeführt werden.
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
name: store-route
namespace: store
labels:
gateway: multi-cluster-gateway
spec:
parentRefs:
- kind: Gateway
namespace: store
name: external-http
hostnames:
- "store.example.com"
rules:
- backendRefs:
- group: net.gke.io
kind: ServiceImport
name: store
port: 8080
Das folgende Diagramm zeigt, wie die HTTPRoute store.example.com
-Traffic zu store
-Pods in gke-west-1
und gke-east-1
weiterleitet. Der Load-Balancer behandelt sie als einen einzigen Pool von Back-Ends. Wenn die Pods aus einem der Cluster fehlerhaft werden, nicht mehr erreichbar sind oder keine Traffic-Kapazität haben, wird die Traffic-Last auf die verbleibenden Pods im anderen Cluster verteilt. Neue Cluster können mit dem store
-Service und -ServiceExport hinzugefügt oder entfernt werden. Dadurch werden Backend-Pods transparent ohne explizite Routingkonfigurationsänderungen hinzugefügt oder entfernt.
Services exportieren
An diesem Punkt wird die Anwendung in beiden Clustern ausgeführt. Als Nächstes machen Sie die Anwendungen verfügbar und exportieren sie, wozu Sie Services und ServiceExports in jedem Cluster bereitstellen.
Wenden Sie das folgende Manifest auf den Cluster
gke-west-1
an, um die Services und ServiceExportsstore
undstore-west-1
zu erstellen.cat << EOF | kubectl apply --context gke-west-1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: store --- apiVersion: v1 kind: Service metadata: name: store-west-1 namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store-west-1 namespace: store EOF
Wenden Sie das folgende Manifest auf den Cluster
gke-east-1
an, um die Services und ServiceExportsstore
undstore-east-1
zu erstellen.cat << EOF | kubectl apply --context gke-east-1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: store --- apiVersion: v1 kind: Service metadata: name: store-east-1 namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store-east-1 namespace: store EOF
Prüfen Sie, ob im Cluster die richtigen ServiceExports erstellt wurden.
kubectl get serviceexports --context CLUSTER_NAME --namespace store
Ersetzen Sie CLUSTER_NAME durch
gke-west-1
undgke-east-1
. Die Ausgabe sollte in etwa so aussehen:# gke-west-1 NAME AGE store 2m40s store-west-1 2m40s # gke-east-1 NAME AGE store 2m25s store-east-1 2m25s
Dies zeigt, dass der
store
-Service in beiden Clusternstore
-Pods enthält, während diestore-west-1
- undstore-east-1
-Services in den jeweiligen Clustern nurstore
-Pods enthalten. Diese sich überschneidenden Services werden verwendet, um die Pods auf mehrere Cluster oder eine Teilmenge von Pods in einem einzelnen Cluster auszurichten.Prüfen Sie nach einigen Minuten, ob die zugehörigen
ServiceImports
vom Multi-Cluster-Services-Controller automatisch in allen Clustern der Flotte erstellt wurden.kubectl get serviceimports --context CLUSTER_NAME --namespace store
Ersetzen Sie CLUSTER_NAME durch
gke-west-1
undgke-east-1
. Die Ausgabe sollte in etwa so aussehen:# gke-west-1 NAME TYPE IP AGE store ClusterSetIP ["10.112.31.15"] 6m54s store-east-1 ClusterSetIP ["10.112.26.235"] 5m49s store-west-1 ClusterSetIP ["10.112.16.112"] 6m54s # gke-east-1 NAME TYPE IP AGE store ClusterSetIP ["10.72.28.226"] 5d10h store-east-1 ClusterSetIP ["10.72.19.177"] 5d10h store-west-1 ClusterSetIP ["10.72.28.68"] 4h32m
Dies zeigt, dass auf alle drei Services von beiden Clustern in der Flotte aus zugegriffen werden kann. Da es jedoch nur einen aktiven Konfigurationscluster pro Flotte gibt, können Sie nur Gateways und HTTPRoutes bereitstellen, die in
gke-west-1
auf diese ServiceImports verweisen. Wenn eine HTTPRoute im Konfigurationscluster auf diese ServiceImports als Back-Ends verweist, kann das Gateway Traffic an diese Services weiterleiten, unabhängig davon, aus welchem Cluster sie exportiert wurden.
Gateway und HTTPRoute bereitstellen
Wenn die Anwendungen bereitgestellt wurden, können Sie ein Gateway mithilfe der GatewayClass gke-l7-global-external-managed-mc
konfigurieren. Dieses Gateway erstellt einen externen Application Load Balancer, der so konfiguriert ist, dass der Traffic auf Ihre Zielcluster verteilt wird.
Wenden Sie das folgende
Gateway
-Manifest auf den Konfigurationsclustergke-west-1
in diesem Beispiel an:cat << EOF | kubectl apply --context gke-west-1 -f - kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: external-http namespace: store spec: gatewayClassName: gke-l7-global-external-managed-mc listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute EOF
Diese Gateway-Konfiguration stellt externe Application-Load-Balancer-Ressourcen mit der folgenden Namenskonvention bereit:
gkemcg1-NAMESPACE-GATEWAY_NAME-HASH
.Die bei dieser Konfiguration erstellten Standardressourcen:
- 1 Load Balancer:
gkemcg1-store-external-http-HASH
- 1 öffentliche IP-Adresse:
gkemcg1-store-external-http-HASH
- 1 Weiterleitungsregel:
gkemcg1-store-external-http-HASH
- 2 backend services:
- Standard-Backend-Dienst 404:
gkemcg1-store-gw-serve404-HASH
- Standard-Backend-Dienst 500:
gkemcg1-store-gw-serve500-HASH
- Standard-Backend-Dienst 404:
- 1 Systemdiagnose:
- Standard-Systemdiagnose 404:
gkemcg1-store-gw-serve404-HASH
- Standard-Systemdiagnose 404:
- 0 Weiterleitungsregeln (URLmap ist leer)
In dieser Phase führt jede Anfrage an GATEWAY_IP:80 zu einer Standardseite mit der folgenden Meldung:
fault filter abort
.- 1 Load Balancer:
Wenden Sie das folgende
HTTPRoute
-Manifest auf den Konfigurationsclustergke-west-1
in diesem Beispiel an:cat << EOF | kubectl apply --context gke-west-1 -f - kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: public-store-route namespace: store labels: gateway: external-http spec: hostnames: - "store.example.com" parentRefs: - name: external-http rules: - matches: - path: type: PathPrefix value: /west backendRefs: - group: net.gke.io kind: ServiceImport name: store-west-1 port: 8080 - matches: - path: type: PathPrefix value: /east backendRefs: - group: net.gke.io kind: ServiceImport name: store-east-1 port: 8080 - backendRefs: - group: net.gke.io kind: ServiceImport name: store port: 8080 EOF
In dieser Phase führt jede Anfrage an GATEWAY_IP:80 zu einer Standardseite mit der folgenden Meldung:
fault filter abort
.Nach der Bereitstellung konfiguriert diese HTTPRoute das folgende Routingverhalten:
- Anfragen an
/west
werden anstore
-Pods imgke-west-1
-Cluster weitergeleitet, da Pods, die vom ServiceExportstore-west-1
ausgewählt wurden, nur imgke-west-1
-Cluster vorhanden sind. - Anfragen an
/east
werden anstore
-Pods imgke-east-1
-Cluster weitergeleitet, da Pods, die vom ServiceExportstore-east-1
ausgewählt wurden, nur imgke-east-1
-Cluster vorhanden sind. - Anfragen an jeden anderen Pfad werden abhängig von ihrem Zustand, ihrer Kapazität und der Nähe zum anfragenden Client an
store
-Pods in einem der Cluster weitergeleitet. - Anfragen an GATEWAY_IP:80 führen zu einer Standardseite mit der folgenden Meldung:
fault filter abort
.
Wenn alle Pods in einem bestimmten Cluster fehlerhaft oder nicht vorhanden sind, wird der Traffic zum
store
-Service nur an Cluster gesendet, die tatsächlichstore
-Pods haben. Wenn ein ServiceExport und Service in einem bestimmten Cluster vorhanden sind, wird dadurch nicht garantiert, dass Traffic an diesen Cluster gesendet wird. Pods müssen vorhanden sein und positiv auf die Systemdiagnose des Load-Balancers reagieren. Andernfalls sendet der Load-Balancer Traffic an fehlerfreiestore
-Pods in anderen Clustern.Mit dieser Konfiguration werden neue Ressourcen erstellt:
- 3 backend services:
- Der
store
-Backend-Dienst:gkemcg1-store-store-8080-HASH
- Der
store-east-1
-Backend-Dienst:gkemcg1-store-store-east-1-8080-HASH
- Der
store-west-1
-Backend-Dienst:gkemcg1-store-store-west-1-8080-HASH
- Der
- 3 Systemdiagnosen:
- Die
store
-Systemdiagnose:gkemcg1-store-store-8080-HASH
- Die
store-east-1
-Systemdiagnose:gkemcg1-store-store-east-1-8080-HASH
- Die
store-west-1
-Systemdiagnose:gkemcg1-store-store-west-1-8080-HASH
- Die
- 1 Routingregel in der URLmap:
- Die
store.example.com
-Routingregel: - 1 Host:
store.example.com
- Mehrere
matchRules
zur Weiterleitung an die neuen Backend-Dienste
- Die
- Anfragen an
Das folgende Diagramm zeigt die Ressourcen, die Sie in beiden Clustern bereitgestellt haben.
Da gke-west-1
der Gateway-Konfigurationscluster ist, ist er der Cluster, in dem unser Gateway, die HTTPRoutes und die ServiceImports vom Gateway-Controller überwacht werden. Jeder Cluster hat einen store
-ServiceImport und einen weiteren ServiceImport, der für diesen Cluster spezifisch ist. Beide verweisen auf dieselben Pods. Damit kann mit der HTTPRoute genau angegeben werden, wohin der Traffic geht – zu den store
-Pods in einem bestimmten Cluster oder zu den store
-Pods in allen Clustern.
Beachten Sie, dass dies ein logisches Ressourcenmodell und keine Darstellung des Trafficflusses ist. Der Trafficpfad führt direkt vom Load-Balancer zu den Back-End-Pods und hat keine direkte Beziehung zu dem Cluster, der der Konfigurationscluster ist.
Bereitstellung prüfen
Sie können nun Anfragen an unser Multi-Cluster-Gateway senden und den Traffic auf beide GKE-Cluster verteilen.
Rufen Sie den Gateway-Status und die Ereignisse auf, um zu prüfen, ob das Gateway und die HTTPRoute erfolgreich bereitgestellt wurden.
kubectl describe gateways.gateway.networking.k8s.io external-http --context gke-west-1 --namespace store
Die Ausgabe sollte in etwa so aussehen:
Name: external-http Namespace: store Labels: <none> Annotations: networking.gke.io/addresses: /projects/PROJECT_NUMBER/global/addresses/gkemcg1-store-external-http-laup24msshu4 networking.gke.io/backend-services: /projects/PROJECT_NUMBER/global/backendServices/gkemcg1-store-gw-serve404-80-n65xmts4xvw2, /projects/PROJECT_NUMBER/global/backendServices/gke... networking.gke.io/firewalls: /projects/PROJECT_NUMBER/global/firewalls/gkemcg1-l7-default-global networking.gke.io/forwarding-rules: /projects/PROJECT_NUMBER/global/forwardingRules/gkemcg1-store-external-http-a5et3e3itxsv networking.gke.io/health-checks: /projects/PROJECT_NUMBER/global/healthChecks/gkemcg1-store-gw-serve404-80-n65xmts4xvw2, /projects/PROJECT_NUMBER/global/healthChecks/gkemcg1-s... networking.gke.io/last-reconcile-time: 2023-10-12T17:54:24Z networking.gke.io/ssl-certificates: networking.gke.io/target-http-proxies: /projects/PROJECT_NUMBER/global/targetHttpProxies/gkemcg1-store-external-http-94oqhkftu5yz networking.gke.io/target-https-proxies: networking.gke.io/url-maps: /projects/PROJECT_NUMBER/global/urlMaps/gkemcg1-store-external-http-94oqhkftu5yz API Version: gateway.networking.k8s.io/v1beta1 Kind: Gateway Metadata: Creation Timestamp: 2023-10-12T06:59:32Z Finalizers: gateway.finalizer.networking.gke.io Generation: 1 Resource Version: 467057 UID: 1dcb188e-2917-404f-9945-5f3c2e907b4c Spec: Gateway Class Name: gke-l7-global-external-managed-mc Listeners: Allowed Routes: Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute Namespaces: From: Same Name: http Port: 80 Protocol: HTTP Status: Addresses: Type: IPAddress Value: 34.36.127.249 Conditions: Last Transition Time: 2023-10-12T07:00:41Z Message: The OSS Gateway API has deprecated this condition, do not depend on it. Observed Generation: 1 Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2023-10-12T07:00:41Z Message: Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2023-10-12T07:00:41Z Message: Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Last Transition Time: 2023-10-12T07:00:41Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Listeners: Attached Routes: 1 Conditions: Last Transition Time: 2023-10-12T07:00:41Z Message: Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Last Transition Time: 2023-10-12T07:00:41Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Name: http Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal UPDATE 35m (x4 over 10h) mc-gateway-controller store/external-http Normal SYNC 4m22s (x216 over 10h) mc-gateway-controller SYNC on store/external-http was a success
Sobald das Gateway bereitgestellt wurde, rufen Sie die externe IP-Adresse vom
external-http
-Gateway ab.kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}" --context gke-west-1 --namespace store
Ersetzen Sie
VIP
in den folgenden Schritten durch die IP-Adresse, die Sie als Ausgabe erhalten.Senden Sie Traffic an den Stammpfad der Domain. Dadurch wird der Traffic auf den
store
-ServiceImport verteilt, der sich in den Clusterngke-west-1
undgke-east-1
befindet. Der Load-Balancer sendet den Traffic an die nächstgelegene Region und Sie sehen möglicherweise keine Antworten aus der anderen Region.curl -H "host: store.example.com" http://VIP
Die Ausgabe bestätigt, dass die Anfrage vom Pod aus dem Cluster
gke-east-1
bereitgestellt wurde:{ "cluster_name": "gke-east-1", "zone": "us-east1-b", "host_header": "store.example.com", "node_name": "gke-gke-east-1-default-pool-7aa30992-t2lp.c.agmsb-k8s.internal", "pod_name": "store-5f5b954888-dg22z", "pod_name_emoji": "⏭", "project_id": "agmsb-k8s", "timestamp": "2021-06-01T17:32:51" }
Als Nächstes senden Sie Traffic an den Pfad
/west
. Dadurch wird der Traffic an den ServiceImportstore-west-1
weitergeleitet, der nur Pods im Clustergke-west-1
ausführt. Ein clusterspezifischer ServiceImport wiestore-west-1
ermöglicht einem Anwendungsinhaber, Traffic explizit an einen bestimmten Cluster zu senden, statt die Entscheidung dem Load Balancer zu überlassen.curl -H "host: store.example.com" http://VIP/west
Die Ausgabe bestätigt, dass die Anfrage vom Pod aus dem Cluster
gke-west-1
bereitgestellt wurde:{ "cluster_name": "gke-west-1", "zone": "us-west1-a", "host_header": "store.example.com", "node_name": "gke-gke-west-1-default-pool-65059399-2f41.c.agmsb-k8s.internal", "pod_name": "store-5f5b954888-d25m5", "pod_name_emoji": "🍾", "project_id": "agmsb-k8s", "timestamp": "2021-06-01T17:39:15", }
Senden Sie nun Traffic an den Pfad
/east
.curl -H "host: store.example.com" http://VIP/east
Die Ausgabe bestätigt, dass die Anfrage vom Pod aus dem Cluster
gke-east-1
bereitgestellt wurde:{ "cluster_name": "gke-east-1", "zone": "us-east1-b", "host_header": "store.example.com", "node_name": "gke-gke-east-1-default-pool-7aa30992-7j7z.c.agmsb-k8s.internal", "pod_name": "store-5f5b954888-hz6mw", "pod_name_emoji": "🧜🏾", "project_id": "agmsb-k8s", "timestamp": "2021-06-01T17:40:48" }
Blau/Grün-Multi-Cluster-Routing mit Gateway
Die GatewayClasses gke-l7-global-external-managed-*
, gke-l7-regional-external-managed-*
und gke-l7-rilb-*
bieten viele erweiterte Funktionen für das Traffic-Routing, einschließlich Traffic-Aufteilung, Header-Abgleich, Header-Bearbeitung, Traffic-Spiegelung und mehr. In diesem Beispiel erfahren Sie, wie Sie mit der gewichteten Trafficaufteilung den Trafficanteil zweier GKE-Cluster explizit steuern.
In diesem Beispiel werden einige realistische Schritte beschrieben, die ein Dienstinhaber ausführen würde, um seine Anwendung in einen neuen GKE-Cluster zu verschieben oder zu erweitern. Das Ziel von Blau/Grün-Bereitstellungen ist es, das Risiko durch mehrere Validierungsschritte zu reduzieren, die bestätigen, dass der neue Cluster ordnungsgemäß funktioniert. In diesem Beispiel werden vier Phasen der Bereitstellung durchlaufen:
- 100%-Header-basierter Canary: Per HTTP-Header-Routing wird ausschließlich Test- oder synthetischer Traffic zum neuen Cluster gesendet.
- 100% – Traffic spiegeln: Der Nutzertraffic wird auf den Canary-Cluster gespiegelt. Damit wird die Kapazität des Canary-Clusters getestet, wozu 100 % des Nutzer-Traffics in diesen Cluster kopiert werden.
- 90% bis 10%: Eine Canary-Aufteilung des Traffic von 10 %, um den neuen Cluster langsam für echten Traffic verfügbar zu machen.
- 0% – 100%: Vollständige Umstellung auf den neuen Cluster mit der Option, zurückzugehen, falls Fehler auftreten.
Dieses Beispiel ähnelt dem vorherigen, mit dem Unterschied, dass stattdessen ein internes Multi-Cluster-Gateway bereitgestellt wird. Dadurch wird ein interner Application Load Balancer bereitgestellt, der nur innerhalb der VPC privat zugänglich ist. Sie verwenden die Cluster und dieselbe Anwendung, die Sie in den vorherigen Schritten bereitgestellt haben, mit Ausnahme der Bereitstellung über ein anderes Gateway.
Vorbereitung
Das folgende Beispiel baut auf einigen der Schritte unter Externes Multi-Cluster-Gateway bereitstellen auf. Führen Sie die folgenden Schritte aus, bevor Sie mit diesem Beispiel fortfahren:
-
In diesem Beispiel werden die Cluster
gke-west-1
undgke-west-2
verwendet, die Sie bereits eingerichtet haben. Diese Cluster befinden sich in derselben Region, da die GatewayClassgke-l7-rilb-mc
regional ist und nur Cluster-Back-Ends in derselben Region unterstützt. Stellen Sie die für jeden Cluster erforderlichen Services und ServiceExports bereit. Wenn Sie Services und ServiceExports aus dem vorherigen Beispiel bereitgestellt haben, haben Sie einige davon bereits bereitgestellt.
kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store-west-1-service.yaml kubectl apply --context gke-west-2 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store-west-2-service.yaml
In jedem Cluster werden ähnliche Ressourcen bereitgestellt:
service/store created serviceexport.net.gke.io/store created service/store-west-2 created serviceexport.net.gke.io/store-west-2 created
Nur-Proxy-Subnetz konfigurieren
Konfigurieren Sie ein Nur-Proxy-Subnetz für jede Region, in der Sie interne Gateways bereitstellen, falls noch nicht geschehen. Dieses Subnetz wird verwendet, um auf den Load-Balancer-Proxys interne IP-Adressen bereitzustellen. Es muss mit einem --purpose
konfiguriert werden, der auf nur REGIONAL_MANAGED_PROXY
gesetzt ist.
Sie müssen ein Nur-Proxy-Subnetz erstellen, bevor Sie Gateways erstellen, die interne Application Load Balancer verwalten. Jede Region eines VPC-Netzwerks (Virtual Private Cloud), in dem Sie interne Application Load Balancer verwenden, muss ein Nur-Proxy-Subnetz haben.
Der Befehl gcloud compute networks subnets create
wir mit einem Nur-Proxy-Subnetz erstellt.
gcloud compute networks subnets create SUBNET_NAME \
--purpose=REGIONAL_MANAGED_PROXY \
--role=ACTIVE \
--region=REGION \
--network=VPC_NETWORK_NAME \
--range=CIDR_RANGE
Dabei gilt:
SUBNET_NAME
: die Region des Nur-Proxy-Subnetzes.REGION
ist die Region des Nur-Proxy-Subnetzes.VPC_NETWORK_NAME
ist der Name des VPC-Netzwerks, das das Subnetz enthält.CIDR_RANGE
: der primäre IP-Adressbereich des Subnetzes. Die Subnetzmaske darf maximal/26
groß sein, damit mindestens 64 IP-Adressen für Proxys in der Region verfügbar sind. Als Subnetzmaske wird/23
empfohlen.
Gateway bereitstellen
Das folgende Gateway wird aus der GatewayClass gke-l7-rilb-mc
erstellt. Dies ist ein regionales internes Gateway, das nur GKE-Cluster in derselben Region ansprechen kann.
Wenden Sie das folgende
Gateway
-Manifest auf den Konfigurationsclustergke-west-1
in diesem Beispiel an:cat << EOF | kubectl apply --context gke-west-1 -f - kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-http namespace: store spec: gatewayClassName: gke-l7-rilb-mc listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute EOF
Überprüfen Sie, ob das Gateway erfolgreich eingerichtet wurde. Mit diesem Befehl können Sie speziell nach Ereignissen in diesem Gateway filtern:
kubectl get events --field-selector involvedObject.kind=Gateway,involvedObject.name=internal-http --context=gke-west-1 --namespace store
Die Gateway-Bereitstellung war erfolgreich, wenn die Ausgabe in etwa so aussieht:
LAST SEEN TYPE REASON OBJECT MESSAGE 5m18s Normal ADD gateway/internal-http store/internal-http 3m44s Normal UPDATE gateway/internal-http store/internal-http 3m9s Normal SYNC gateway/internal-http SYNC on store/internal-http was a success
Header-basierter Canary-Test
Beim Header-basierten Canary-Test kann der Serviceinhaber synthetischen Testtraffic abgleichen, der nicht von echten Nutzern stammt. So lässt sich einfach prüfen, ob das grundlegende Netzwerk der Anwendung funktioniert, ohne dieses Nutzern direkt freizugeben.
Wenden Sie das folgende
HTTPRoute
-Manifest auf den Konfigurationsclustergke-west-1
in diesem Beispiel an:cat << EOF | kubectl apply --context gke-west-1 -f - kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-store-route namespace: store labels: gateway: internal-http spec: parentRefs: - kind: Gateway namespace: store name: internal-http hostnames: - "store.example.internal" rules: # Matches for env=canary and sends it to store-west-2 ServiceImport - matches: - headers: - name: env value: canary backendRefs: - group: net.gke.io kind: ServiceImport name: store-west-2 port: 8080 # All other traffic goes to store-west-1 ServiceImport - backendRefs: - group: net.gke.io kind: ServiceImport name: store-west-1 port: 8080 EOF
Nach der Bereitstellung konfiguriert diese HTTPRoute folgendes Routingverhalten:
- Interne Anfragen an
store.example.internal
ohne den HTTP-Headerenv: canary
werden anstore
-Pods imgke-west-1
-Cluster weitergeleitet - Interne Anfragen an
store.example.internal
mit dem HTTP-Headerenv: canary
werden anstore
-Pods imgke-west-2
-Cluster weitergeleitet
Senden Sie Traffic an die Gateway-IP-Adresse, um zu prüfen, ob die HTTPRoute ordnungsgemäß funktioniert.
- Interne Anfragen an
Rufen Sie die interne IP-Adresse von
internal-http
ab.kubectl get gateways.gateway.networking.k8s.io internal-http -o=jsonpath="{.status.addresses[0].value}" --context gke-west-1 --namespace store
Ersetzen Sie VIP in den folgenden Schritten durch die IP-Adresse, die Sie als Ausgabe erhalten.
Senden Sie mit dem HTTP-Header
env: canary
eine Anfrage an das Gateway. Dadurch wird bestätigt, dass der Traffic angke-west-2
weitergeleitet wird. Verwenden Sie einen privaten Client in derselben VPC wie für den GKE-Cluster, um zu bestätigen, dass Anfragen korrekt weitergeleitet werden. Der folgende Befehl muss auf einem Computer ausgeführt werden, der privaten Zugriff auf die Gateway-IP-Adresse hat. Andernfalls funktioniert er nicht.curl -H "host: store.example.internal" -H "env: canary" http://VIP
Die Ausgabe bestätigt, dass die Anfrage von einem Pod aus dem Cluster
gke-west-2
bereitgestellt wurde:{ "cluster_name": "gke-west-2", "host_header": "store.example.internal", "node_name": "gke-gke-west-2-default-pool-4cde1f72-m82p.c.agmsb-k8s.internal", "pod_name": "store-5f5b954888-9kdb5", "pod_name_emoji": "😂", "project_id": "agmsb-k8s", "timestamp": "2021-05-31T01:21:55", "zone": "us-west1-a" }
Traffic-Spiegelung
In dieser Phase wird Traffic an den Ziel-Cluster gesendet, aber auch an den Canary-Cluster gespiegelt.
Die Spiegelung ist hilfreich, um festzustellen, wie sich die Trafficlast auf die Anwendungsleistung auswirkt, ohne dass sich dies auf Antworten an Ihre Clients auswirkt. Sie sind zwar nicht für alle Arten Rollouts erforderlich, können aber bei der Einführung großer Änderungen nützlich sein, die sich auf Leistung oder Last auswirken können.
Wenden Sie das folgende
HTTPRoute
-Manifest auf den Konfigurationsclustergke-west-1
in diesem Beispiel an:cat << EOF | kubectl apply --context gke-west-1 -f - kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-store-route namespace: store labels: gateway: internal-http spec: parentRefs: - kind: Gateway namespace: store name: internal-http hostnames: - "store.example.internal" rules: # Sends all traffic to store-west-1 ServiceImport - backendRefs: - name: store-west-1 group: net.gke.io kind: ServiceImport port: 8080 # Also mirrors all traffic to store-west-2 ServiceImport filters: - type: RequestMirror requestMirror: backendRef: group: net.gke.io kind: ServiceImport name: store-west-2 port: 8080 EOF
Senden Sie mit Ihrem privaten Client eine Anfrage an das
internal-http
-Gateway. Verwenden Sie den Pfad/mirror
, damit Sie diese Anfrage in einem späteren Schritt in den Anwendungslogs eindeutig identifizieren können.curl -H "host: store.example.internal" http://VIP/mirror
Die Ausgabe bestätigt, dass der Client eine Antwort von einem Pod im Cluster
gke-west-1
erhalten hat:{ "cluster_name": "gke-west-1", "host_header": "store.example.internal", "node_name": "gke-gke-west-1-default-pool-65059399-ssfq.c.agmsb-k8s.internal", "pod_name": "store-5f5b954888-brg5w", "pod_name_emoji": "🎖", "project_id": "agmsb-k8s", "timestamp": "2021-05-31T01:24:51", "zone": "us-west1-a" }
Damit ist bestätigt, dass der primäre Cluster auf Traffic reagiert. Sie müssen noch bestätigen, dass der Cluster, zu dem Sie migrieren, gespiegelten Traffic empfängt.
Prüfen Sie die Anwendungslogs eines
store
-Pods im Clustergke-west-2
. Die Logs sollten bestätigen, dass der Pod gespiegelten Traffic vom Load Balancer erhalten hat.kubectl logs deployment/store --context gke-west-2 -n store | grep /mirror
Diese Ausgabe bestätigt, dass Pods im Cluster
gke-west-2
auch die gleichen Anfragen erhalten. Ihre Antworten auf diese Anfragen werden jedoch nicht an den Client zurückgesendet. Die in den Logs angezeigten IP-Adressen sind die internen IP-Adressen des Load Balancers, die mit Ihren Pods kommunizieren.Found 2 pods, using pod/store-5c65bdf74f-vpqbs [2023-10-12 21:05:20,805] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:20] "GET /mirror HTTP/1.1" 200 - [2023-10-12 21:05:27,158] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:27] "GET /mirror HTTP/1.1" 200 - [2023-10-12 21:05:27,805] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:27] "GET /mirror HTTP/1.1" 200 -
Trafficaufteilung
Die Traffic-Aufteilung ist eine der am häufigsten verwendeten Methoden für die Einführung von neuem Code oder die sichere Bereitstellung in neuen Umgebungen. Der Dienstinhaber legt einen expliziten Prozentsatz des Traffics fest, der an die Canary-Back-Ends gesendet wird. Dieser Prozentsatz ist in der Regel ein sehr kleiner Teil des Gesamt-Traffics, damit der Erfolg des Rollouts mit akzeptablem Risiko für echte Nutzeranfragen bestimmt werden kann.
Wenn Sie eine Trafficaufteilung mit einem kleinen Teil des Traffics vornehmen, kann der Serviceinhaber den Zustand der Anwendung und der Antworten prüfen. Sind alle Signale fehlerfrei, so können sie zur vollständigen Umstellung übergehen.
Wenden Sie das folgende
HTTPRoute
-Manifest auf den Konfigurationsclustergke-west-1
in diesem Beispiel an:cat << EOF | kubectl apply --context gke-west-1 -f - kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-store-route namespace: store labels: gateway: internal-http spec: parentRefs: - kind: Gateway namespace: store name: internal-http hostnames: - "store.example.internal" rules: - backendRefs: # 90% of traffic to store-west-1 ServiceImport - name: store-west-1 group: net.gke.io kind: ServiceImport port: 8080 weight: 90 # 10% of traffic to store-west-2 ServiceImport - name: store-west-2 group: net.gke.io kind: ServiceImport port: 8080 weight: 10 EOF
Senden Sie mit Ihrem privaten Client eine kontinuierliche curl-Anfrage an das
internal- http
-Gateway.while true; do curl -H "host: store.example.internal" -s VIP | grep "cluster_name"; sleep 1; done
Die Ausgabe sieht in etwa so aus, was darauf hinweist, dass eine 90/10-Trafficaufteilung erfolgt.
"cluster_name": "gke-west-1", "cluster_name": "gke-west-1", "cluster_name": "gke-west-1", "cluster_name": "gke-west-1", "cluster_name": "gke-west-1", "cluster_name": "gke-west-1", "cluster_name": "gke-west-1", "cluster_name": "gke-west-1", "cluster_name": "gke-west-2", "cluster_name": "gke-west-1", "cluster_name": "gke-west-1", ...
Trafficumstellung
Die letzte Phase der Blau/Grün-Migration besteht darin, vollständig auf den neuen Cluster umzustellen und den alten Cluster zu entfernen. Wenn der Dienstinhaber einem vorhandenen Cluster tatsächlich einen zweiten Cluster hinzufügt, wäre dieser letzte Schritt anders, da zum Schluss Traffic an beide Cluster geht. In diesem Szenario wird ein einzelner store
-ServiceImport empfohlen, der Pods aus den Clustern gke-west-1
und gke-west-2
enthält. So kann der Load-Balancer anhand von Nähe, Zustand und Kapazität entscheiden, wohin der Traffic für eine Aktiv-Aktiv-Anwendung geleitet werden soll.
Wenden Sie das folgende
HTTPRoute
-Manifest auf den Konfigurationsclustergke-west-1
in diesem Beispiel an:cat << EOF | kubectl apply --context gke-west-1 -f - kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-store-route namespace: store labels: gateway: internal-http spec: parentRefs: - kind: Gateway namespace: store name: internal-http hostnames: - "store.example.internal" rules: - backendRefs: # No traffic to the store-west-1 ServiceImport - name: store-west-1 group: net.gke.io kind: ServiceImport port: 8080 weight: 0 # All traffic to the store-west-2 ServiceImport - name: store-west-2 group: net.gke.io kind: ServiceImport port: 8080 weight: 100 EOF
Senden Sie mit Ihrem privaten Client eine kontinuierliche curl-Anfrage an das
internal- http
-Gateway.while true; do curl -H "host: store.example.internal" -s VIP | grep "cluster_name"; sleep 1; done
Die Ausgabe sieht in etwa so aus; der gesamte Traffic wird jetzt an
gke-west-2
gesendet."cluster_name": "gke-west-2", "cluster_name": "gke-west-2", "cluster_name": "gke-west-2", "cluster_name": "gke-west-2", ...
Mit diesem letzten Schritt wird eine vollständige Blau/Grün-Anwendungsmigration von einem GKE-Cluster zu einem anderen GKE-Cluster abgeschlossen.
Kapazitätsbasiertes Load-Balancing bereitstellen
Die Übung in diesem Abschnitt veranschaulicht die Konzepte für globales Load-Balancing und Service-Kapazität. Dazu wird eine Anwendung in zwei GKE-Clustern in verschiedenen Regionen bereitgestellt. Der generierte Traffic wird mit verschiedenen Werten für die Anfragen pro Sekunde (RPS) gesendet, um zu zeigen, wie das Traffic-Load-Balancing auf Cluster und Regionen erfolgt.
Das folgende Diagramm zeigt die Topologie, die Sie bereitstellen, und veranschaulicht, wie der Traffic zwischen Clustern und Regionen überläuft, wenn er die Service-Kapazität überschreitet:
Weitere Informationen zur Traffic-Verwaltung finden Sie unter GKE-Traffic-Verwaltung.
Umgebung vorbereiten
Folgen Sie der Anleitung unter Multi-Cluster-Gateways aktivieren, um Ihre Umgebung vorzubereiten.
Prüfen Sie, ob die GatewayClass-Ressourcen im Konfigurationscluster installiert sind:
kubectl get gatewayclasses --context=gke-west-1
Die Ausgabe sieht in etwa so aus:
NAME CONTROLLER ACCEPTED AGE gke-l7-global-external-managed networking.gke.io/gateway True 16h gke-l7-global-external-managed-mc networking.gke.io/gateway True 14h gke-l7-gxlb networking.gke.io/gateway True 16h gke-l7-gxlb-mc networking.gke.io/gateway True 14h gke-l7-regional-external-managed networking.gke.io/gateway True 16h gke-l7-regional-external-managed-mc networking.gke.io/gateway True 14h gke-l7-rilb networking.gke.io/gateway True 16h gke-l7-rilb-mc networking.gke.io/gateway True 14h
Anwendung bereitstellen
Stellen Sie den Beispielwebanwendungsserver in beiden Clustern bereit:
kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/store-traffic-deploy.yaml
kubectl apply --context gke-east-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/store-traffic-deploy.yaml
Die Ausgabe sieht in etwa so aus:
namespace/store created
deployment.apps/store created
Service, Gateway und HTTPRoute bereitstellen
Wenden Sie das folgende
Service
-Manifest auf die Clustergke-west-1
undgke-east-1
an:cat << EOF | kubectl apply --context gke-west-1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: traffic-test annotations: networking.gke.io/max-rate-per-endpoint: "10" spec: ports: - port: 8080 targetPort: 8080 name: http selector: app: store type: ClusterIP --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: traffic-test EOF
cat << EOF | kubectl apply --context gke-east-1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: traffic-test annotations: networking.gke.io/max-rate-per-endpoint: "10" spec: ports: - port: 8080 targetPort: 8080 name: http selector: app: store type: ClusterIP --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: traffic-test EOF
Der Service wird mit
max-rate-per-endpoint
auf 10 Anfragen pro Sekunde annotiert. Bei zwei Replikaten pro Cluster hat jeder Service eine Kapazität von 20 RPS pro Cluster.Weitere Informationen zur Auswahl einer Service-Kapazitätsstufe für Ihren Service finden Sie unter Kapazität Ihres Service bestimmen.
Wenden Sie das folgende
Gateway
-Manifest auf den Konfigurationsclustergke-west-1
in diesem Beispiel an:cat << EOF | kubectl apply --context gke-west-1 -f - kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: store namespace: traffic-test spec: gatewayClassName: gke-l7-global-external-managed-mc listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute EOF
Das Manifest beschreibt ein externes, globales Multi-Cluster-Gateway, das einen externen Application Load Balancer mit einer öffentlich zugänglichen IP-Adresse bereitstellt.
Wenden Sie das folgende
HTTPRoute
-Manifest auf den Konfigurationsclustergke-west-1
in diesem Beispiel an:cat << EOF | kubectl apply --context gke-west-1 -f - kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: store namespace: traffic-test labels: gateway: store spec: parentRefs: - kind: Gateway namespace: traffic-test name: store rules: - backendRefs: - name: store group: net.gke.io kind: ServiceImport port: 8080 EOF
Das Manifest beschreibt eine HTTPRoute, die das Gateway mit einer Routingregel konfiguriert, die den gesamten Traffic an den Speicher-ServiceImport weiterleitet. Der
store
-ServiceImport gruppiert diestore
-Service-Pods in beiden Clustern und ermöglicht ihnen, vom Load Balancer als ein einzelner Service adressiert zu werden.Sie können die Ereignisse des Gateways nach einigen Minuten prüfen, um festzustellen, ob die Bereitstellung abgeschlossen ist:
kubectl describe gateway store -n traffic-test --context gke-west-1
Die Ausgabe sieht in etwa so aus:
... Status: Addresses: Type: IPAddress Value: 34.102.159.147 Conditions: Last Transition Time: 2023-10-12T21:40:59Z Message: The OSS Gateway API has deprecated this condition, do not depend on it. Observed Generation: 1 Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2023-10-12T21:40:59Z Message: Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2023-10-12T21:40:59Z Message: Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Last Transition Time: 2023-10-12T21:40:59Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Listeners: Attached Routes: 1 Conditions: Last Transition Time: 2023-10-12T21:40:59Z Message: Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Last Transition Time: 2023-10-12T21:40:59Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Name: http Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 12m mc-gateway-controller traffic-test/store Normal SYNC 6m43s mc-gateway-controller traffic-test/store Normal UPDATE 5m40s (x4 over 12m) mc-gateway-controller traffic-test/store Normal SYNC 118s (x6 over 10m) mc-gateway-controller SYNC on traffic-test/store was a success
Diese Ausgabe zeigt, dass das Gateway erfolgreich bereitgestellt wurde. Nach der Bereitstellung des Gateways kann es einige Minuten dauern, bis der Traffic weitergeleitet wird. Notieren Sie sich die IP-Adresse in dieser Ausgabe, da sie in einem folgenden Schritt verwendet wird.
Traffic bestätigen
Testen Sie, ob der Traffic an die Anwendung weitergeleitet wird. Testen Sie dazu die Gateway-IP-Adresse mit einem curl-Befehl:
curl GATEWAY_IP_ADDRESS
Die Ausgabe sieht in etwa so aus:
{
"cluster_name": "gke-west-1",
"host_header": "34.117.182.69",
"pod_name": "store-54785664b5-mxstv",
"pod_name_emoji": "👳🏿",
"project_id": "project",
"timestamp": "2021-11-01T14:06:38",
"zone": "us-west1-a"
}
Diese Ausgabe zeigt die Pod-Metadaten. Diese geben die Region an, in der die Anfrage verarbeitet wurde.
Traffic mithilfe von Lasttests prüfen
Wenn Sie prüfen möchten, ob der Load-Balancer funktioniert, können Sie in Ihrem gke-west-1
-Cluster einen Traffic-Generator bereitstellen. Der Traffic-Generator generiert Traffic auf verschiedenen Laststufen, um die Kapazitäts- und Überlauffunktionen des Load-Balancers zu demonstrieren. Die folgenden Schritte demonstrieren drei Laststufen:
- 10 RPS, was unter der Kapazität des Speicher-Service in
gke-west-1
liegt. - 30 RPS, was die Kapazität für den
gke-west-1
-Speicher-Service überschreitet und einen Traffic-Überlauf zugke-east-1
verursacht. - 60 RPS, was die Kapazität für die Services in beiden Clustern übersteigt.
Dashboard konfigurieren
Rufen Sie den Namen der zugrunde liegenden URL-Zuordnung für Ihr Gateway ab:
kubectl get gateway store -n traffic-test --context=gke-west-1 -o=jsonpath="{.metadata.annotations.networking\.gke\.io/url-maps}"
Die Ausgabe sieht in etwa so aus:
/projects/PROJECT_NUMBER/global/urlMaps/gkemcg1-traffic-test-store-armvfyupay1t
Rufen Sie in der Google Cloud Console die Seite Metrics Explorer auf.
Klicken Sie unter Messwert auswählen auf CODE: MQL.
Geben Sie die folgende Abfrage ein, um die Traffic-Messwerte für den Speicher-Service in den beiden Clustern zu beobachten:
fetch https_lb_rule | metric 'loadbalancing.googleapis.com/https/backend_request_count' | filter (resource.url_map_name == 'GATEWAY_URL_MAP') | align rate(1m) | every 1m | group_by [resource.backend_scope], [value_backend_request_count_aggregate: aggregate(value.backend_request_count)]
Ersetzen Sie
GATEWAY_URL_MAP
durch den URL-Zuordnungsnamen aus dem vorherigen Schritt.Klicken Sie auf Abfrage ausführen. Warten Sie nach der Bereitstellung des Lastgenerators im nächsten Abschnitt mindestens fünf Minuten, bis die Messwerte im Diagramm angezeigt werden.
Mit 10 RPS testen
Stellen Sie einen Pod in Ihrem
gke-west-1
-Cluster bereit:kubectl run --context gke-west-1 -i --tty --rm loadgen \ --image=cyrilbkr/httperf \ --restart=Never \ -- /bin/sh -c 'httperf \ --server=GATEWAY_IP_ADDRESS \ --hog --uri="/zone" --port 80 --wsess=100000,1,1 --rate 10'
Ersetzen Sie
GATEWAY_IP_ADDRESS
durch die Gateway-IP-Adresse aus dem vorherigen Schritt.Die Ausgabe sieht etwa so aus, was darauf hinweist, dass der Traffic-Generator Traffic sendet:
If you don't see a command prompt, try pressing enter.
Der Lastgenerator sendet kontinuierlich 10 RPS an das Gateway. Obwohl der Traffic aus einer Google Cloud-Region stammt, behandelt der Load-Balancer ihn als Client-Traffic von der US-Westküste. Zur Simulation einer realistischen Client-Diversität sendet der Lastgenerator jede HTTP-Anfrage als neue TCP-Verbindung. Dies bedeutet, dass der Traffic gleichmäßiger auf die Backend-Pods verteilt wird.
Es dauert bis zu fünf Minuten, bis der Generator Traffic für das Dashboard generiert.
Sehen Sie sich das Metrics Explorer-Dashboard an. Es werden zwei Zeilen angezeigt, die angeben, wie viel Traffic per Load-Balancing auf jeden Cluster verteilt wird:
Sie sollten sehen, dass
us-west1-a
etwa 10 RPS an Traffic empfängt, währendus-east1-b
keinen Traffic empfängt. Da der Traffic-Generator inus-west1
ausgeführt wird, wird der gesamte Traffic an den Service imgke-west-1
-Cluster gesendet.Beenden Sie den Lastgenerator mit Strg + C und löschen Sie dann den Pod:
kubectl delete pod loadgen --context gke-west-1
Mit 30 RPS testen
Stellen Sie den Lastgenerator noch einmal bereit, aber konfigurieren Sie ihn zum Senden von 30 RPS:
kubectl run --context gke-west-1 -i --tty --rm loadgen \ --image=cyrilbkr/httperf \ --restart=Never \ -- /bin/sh -c 'httperf \ --server=GATEWAY_IP_ADDRESS \ --hog --uri="/zone" --port 80 --wsess=100000,1,1 --rate 30'
Es dauert bis zu fünf Minuten, bis der Generator Traffic für das Dashboard generiert.
Rufen Sie das Cloud Ops-Dashboard auf.
Sie sollten sehen, dass etwa 20 RPS an
us-west1-a
und 10 RPS anus-east1-b
gesendet werden. Dies gibt an, dass der Service ingke-west-1
vollständig genutzt wird und 10 RPS an Traffic zum Service ingke-east-1
überlaufen.Beenden Sie den Lastgenerator mit Strg + C und löschen Sie dann den Pod:
kubectl delete pod loadgen --context gke-west-1
Mit 60 RPS testen
Stellen Sie den Lastgenerator bereit, der zum Senden von 60 RPS konfiguriert ist:
kubectl run --context gke-west-1 -i --tty --rm loadgen \ --image=cyrilbkr/httperf \ --restart=Never \ -- /bin/sh -c 'httperf \ --server=GATEWAY_IP_ADDRESS \ --hog --uri="/zone" --port 80 --wsess=100000,1,1 --rate 60'
Warten Sie fünf Minuten und sehen Sie sich Ihr Cloud Ops-Dashboard an. Es sollte nun zeigen, dass beide Cluster etwa 30 RPS erhalten. Da alle Services global überlastet sind, gibt es keinen Traffic-Überlauf und Services verarbeiten so viel Traffic wie möglich.
Beenden Sie den Lastgenerator mit Strg + C und löschen Sie dann den Pod:
kubectl delete pod loadgen --context gke-west-1
Bereinigen
Wenn Sie mit den Übungen auf dieser Seite fertig sind, entfernen Sie mit den folgenden Schritten die Ressourcen, damit Sie unerwünschte Kosten für Ihr Konto vermeiden:
Heben Sie die Registrierung der Cluster für die Flotte auf, wenn sie nicht für einen anderen Zweck registriert werden müssen.
Deaktivieren Sie die Funktion
multiclusterservicediscovery
.gcloud container fleet multi-cluster-services disable
Deaktivieren sie Multi-Cluster-Ingress:
gcloud container fleet ingress disable
Deaktivieren Sie die APIs:
gcloud services disable \ multiclusterservicediscovery.googleapis.com \ multiclusteringress.googleapis.com \ trafficdirector.googleapis.com \ --project=PROJECT_ID
Multi-Cluster-Gateway mit freigegebene VPC verwenden
Ein Multi-Cluster-Gateway kann auch in einer Umgebung mit freigegebener VPC bereitgestellt werden, mit unterschiedlichen Topologien, je nach Anwendungsfall.
In der folgenden Tabelle werden die unterstützten Multi-Cluster-Gateway-Topologien innerhalb einer Umgebung mit freigegebener VPC beschrieben:
Szenario | Flotten-Hostprojekt | Cluster konfigurieren | Arbeitslastcluster |
---|---|---|---|
1 | Hostprojekt mit freigegebener VPC | Hostprojekt mit freigegebener VPC | Hostprojekt mit freigegebener VPC |
2 | Dienstprojekt mit freigegebener VPC | Dienstprojekt mit freigegebener VPC (wie Flotten-Dienstprojekt) |
Dienstprojekt mit freigegebener VPC (wie Flotten-Dienstprojekt) |
Führen Sie die folgenden Schritte aus, um Multi-Cluster-Gateways in einer Umgebung mit freigegebener VPC zu erstellen:
Folgen Sie der Anleitung, um Multi-Cluster-Dienste mit freigegebener VPC einzurichten.
Dienste erstellen und in den Konfigurationscluster exportieren
Wenn Sie ein internes Multi-Cluster-Gateway verwenden möchten, erstellen Sie ein Nur-Proxy-Subnetz.
Erstellen Sie ein externes oder internes Multi-Cluster-Gateway und HTTPRoutes.
Nachdem Sie diese Schritte ausgeführt haben, können Sie die Bereitstellung je nach Topologie validieren.
Fehlerbehebung
Nur-Proxy-Subnetz für internes Gateway nicht vorhanden
Wenn das folgende Ereignis auf Ihrem internen Gateway angezeigt wird, ist für diese Region kein Nur-Proxy-Subnetz vorhanden. Stellen Sie ein Nur-Proxy-Subnetz bereit, um dieses Problem zu beheben.
generic::invalid_argument: error ensuring load balancer: Insert: Invalid value for field 'resource.target': 'regions/us-west1/targetHttpProxies/gkegw-x5vt-default-internal-http-2jzr7e3xclhj'. A reserved and active subnetwork is required in the same region and VPC as the forwarding rule.
Kein gesunder Upstream
Symptom:
Das folgende Problem kann auftreten, wenn Sie ein Gateway erstellen, aber nicht auf die Backend-Dienste zugreifen können (Antwortcode 503):
no healthy upstream
Grund:
Diese Fehlermeldung gibt an, dass der Prüfer für die Systemdiagnose keine fehlerfreien Backend-Dienste finden kann. Möglicherweise sind Ihre Back-End-Dienste in Ordnung, aber Sie müssen die Systemdiagnosen möglicherweise anpassen.
Workaround:
Um dieses Problem zu beheben, passen Sie Ihre Systemdiagnose anhand der Anforderungen Ihrer Anwendung (z. B. /health
) mithilfe einer HealthCheckPolicy
an.