多集群网络是一款有价值的工具,可用于实现区域高可用性、通过全球分布式用户邻近区域缩短延迟时间以及组织之间的团队隔离等用例。Google Kubernetes Engine (GKE) 为多集群网络提供内置功能,您可以在一组 GKE 集群中大规模启用和使用这些功能。此功能还能够让您在 GKE Standard 和 Autopilot 之间组合或迁移已部署的基础设施,以满足每个应用的架构需求。
借助 GKE Autopilot 集群,Google 负责管理基础设施,包括控制平面和节点。如果要改为配置和管理节点,不妨使用 GKE 提供的标准模式。如需详细了解模式之间的差异,请参阅选择集群操作模式。
本页面通过多个部署拓扑演示了这些功能。您将学习如何获取部署在单个 GKE 集群中的应用,并将其迁移到跨 GKE Standard 和 Autopilot 集群进行多集群部署。您可以使用 GKE 多集群 Service 来处理东-西流量,使用多集群网关启用多集群北-南网络。
本页面面向使用或计划使用 GKE 跨多个 Kubernetes 集群部署服务的云架构师和运营团队。在阅读本页面内容之前,请确保您熟悉 Kubernetes。
多集群 Service 和多集群网关
Kubernetes 可以在不同的云可用区使用单个控制层面运行,从而为您的服务提供弹性和更高的可用性。更进一步的,GKE 提供了 GKE 多集群 Service (MCS),它提供了跨集群服务发现和调用机制。使用此功能的服务可通过具有虚拟 IP 地址的集群进行发现和访问,这与集群中可访问的 ClusterIP
Service 的行为相匹配。此方法具有以下优势:
- Service 可以在同一区域内的多个集群中或在不同区域(东-西流量)之间进行负载均衡。
- 可以实现跨区域服务的高可用性选项。
- 有状态工作负载和无状态工作负载可以跨单独的集群进行部署和管理。
- 跨集群使用共享服务。
如需详细了解如何部署 MCS,请参阅配置多集群Service 。
GKE 提供了使用 GKE Gateway Controller的 Kubernetes Gateway API 实现。网关允许 GKE 部署 Google Cloud 负载均衡器,为 GKE 上部署的服务提供入站(北-南)流量路由。GKE 还提供多集群网关 (MCG),它可以扩展 GKE 网关控制器以预配负载均衡器,以将流量路由到不同 GKE 集群上部署的服务。
下图展示了将 MCS 和 MCG 结合使用时,您可以从一个控制层面管理服务部署和流量路由的互补性方面:
如需了解详情,请参阅部署多集群网关。
迁移概览
GKE 多集群网络功能可受益于各种配置文件的工作负载。例如,您可能具有无状态组件,而由于爆发流量的模型更经济高效,您希望将其迁移到 Autopilot。
或者,您可能希望将应用前端放置在更靠近用户的位置。此方法可提供更短的延迟时间和缓存,从而改善应用性能和用户体验。同时,您可能具有一些应用所依赖的有状态组件,这些组件只能位于一个位置。此配置需要北-男、多集群负载均衡,以将客户端流量发送到该位置的正确集群。您还需要东-西多集群负载均衡,以跨集群发送流量以到达有状态组件。
本页面使用 Online Boutique 云微服务演示应用来演示多集群模式,该模式可用于增强单地区演示的部署。从应用的单地区版本开始。然后,您可以使用多集群 Service 和多集群网关添加高可用性和弹性元素,并利用 Autopilot 减少运营工作量。
初始单集群部署
在下图中,Online Boutique 应用最初部署到名为 std-west 的单个 GKE Standard 模式集群,并使用 LoadBalancer
Service 公开:
迁移到多集群 Service
在下一个中间步骤中,您将创建两个额外的集群,无状态服务部署在其他区域中。您在与单个 std-west GKE Standard 集群不同的两个独立区域中创建两个名为 auto-east 和 auto-central 的 GKE Autopilot 集群,并将这些集群注册到 Google Cloud 舰队。
舰队是一种 Google Cloud 概念,舰队以逻辑方式组织集群和其他资源,让您可以使用和管理多集群功能,并在您的所有系统中应用一致的政策。
您可以使用 ServiceExport 将 onlineboutique 命名空间中 std-west 集群上的 cartservice 导出到新的舰队集群。您将在三个集群上都部署 Online Boutique 的前端 Service,并通过 ClusterIP 服务公开该服务。然后,使用 ServiceExports
将服务导出到集群组。Online Boutique 的中间件层等服务(如 productcatalog、shipping 和 adservice)也会部署到所有三个集群中。
在队列的任何集群中运行的 Pod
可以通过向该服务的 ClusterSet
URI 发送请求来访问导出的 Service
。请求路由到支持服务的端点。
前端 Service 能够在本地集群中使用中间件服务(例如 productcatalogservice 或 currencyservice)。此架构有助于将传入请求保持在前端响应请求的区域本地,并避免不必要的区域间网络流量费用。
下图展示了两项多集群 Service。无状态前端 Service 将部署到三个集群,有状态后端 cartservice 会部署到一个集群。该图还显示,在此中间步骤中,前端服务的入站流量仍然使用由前端外部 LoadBalancer
Service 创建的外部直通式网络负载均衡器路由到 us-west1 中的原始 GKE Standard 集群:
迁移到多集群网关
在最后一步中,您使用多集群网关将前端 Service 的入站流量从集群客户端请求路由到集群中多个集群中的服务。
名为 config-central 的第四个集群会添加到队列中,用于托管和管理作为此配置的一部分创建的网关和 HTTPRoute 资源的配置。HTTPRoute
资源会将 / 前缀映射到前端 ServiceImport。将 Online Boutique 的前端的流量发送到其中一个可用区域中运行状况良好的端点。此方法使 Online Boutique 应用架构具有高可用性的元素。
在下图中,多集群网关部署了一个全局 Cloud 负载均衡器,该负载均衡器将外部流量路由到部署在三个应用集群上的每个集群的无状态前端 Service。
在最终状态下,这种有规律的模式展示了应用的有状态部分(cartservice 和 redis-cart)和无状态部分(frontend、emailservice、checkoutservice、recommendationservice、paymentservice、productcatalogservice、currencyservice、shippingservice 和 adservice)之间的松散耦合。虽然不属于本页面讨论范围,但此方法为您提供了未来向有状态服务层增添弹性和高可用性的机会。
准备环境
在本指南中,您将使用 Cloud Shell 输入命令。Cloud Shell 让您能够使用Google Cloud 控制台中的命令行,并且包含 Google Cloud SDK 和其他工具,例如 Google Cloud CLI。Cloud Shell 在Google Cloud 控制台底部显示为一个窗口。初始化可能需要几分钟,但窗口会立即显示。
In the Google Cloud console, activate Cloud Shell.
在 Cloud Shell 中,定义本指南中使用的环境变量。 请将 PROJECT_ID 替换为您自己的项目 ID:
export PROJECT=PROJECT_ID gcloud config set project ${PROJECT}
启用此页面上所述步骤所需的服务:
gcloud services enable \ gkehub.googleapis.com \ multiclusteringress.googleapis.com \ dns.googleapis.com \ trafficdirector.googleapis.com \ cloudresourcemanager.googleapis.com \ multiclusterservicediscovery.googleapis.com \ container.googleapis.com gcloud container fleet multi-cluster-services enable
多集群 Service 可管理 Google Cloud 组件,例如 Cloud DNS、防火墙规则和 Cloud Service Mesh,因此还必须启用这些 API。如需了解详情,请参阅 Cloud Service Mesh 概览。
输出类似于以下示例:
Operation "operations/acf.p2-822685001869-ee4ebe78-6dd8-465e-b0fd-3b0e5f964bad" finished successfully. Waiting for Feature Multi-cluster Services to be created...done.
验证多集群 Service 是否显示 ACTIVE 状态:
gcloud container fleet multi-cluster-services describe
输出类似于以下示例:
createTime: '2021-11-30T21:59:25.245190894Z' name: projects/PROJECT_ID/locations/global/features/multiclusterservicediscovery resourceState: state: ACTIVE spec: {} updateTime: '2021-11-30T21:59:27.459063070Z'
如果状态的值不是 ACTIVE,请参阅多集群 Service 问题排查详情。
创建 Standard 和 Autopilot GKE 集群:
gcloud container clusters create std-west \ --location us-west1-a \ --num-nodes=6 \ --enable-ip-alias \ --release-channel regular \ --workload-pool=${PROJECT}.svc.id.goog \ --async gcloud container clusters create-auto auto-east \ --location us-east1 \ --release-channel regular \ --async gcloud container clusters create-auto auto-central \ --location us-central1 \ --release-channel regular \ --async gcloud container clusters create config-central \ --location us-central1 \ --num-nodes=1 \ --enable-ip-alias \ --release-channel regular \ --workload-pool=${PROJECT}.svc.id.goog \ --async
GKE Autopilot 集群上默认启用适用于 GKE 的工作负载身份联合,因此您不必使用
--workload-pool
标志,就像您在创建 GKE Standard 集群一样。等待集群的状态从 PROVISIONING 更改为 RUNNING。该过程最多可能需要运行 10 分钟。您可以使用监控循环来监控进度:
watch -n 20 --difference=permanent "gcloud container clusters list"
输出类似于以下示例:
NAME: auto-central LOCATION: us-central1 MASTER_VERSION: 1.21.5-gke.1802 MASTER_IP: 107.178.213.138 MACHINE_TYPE: e2-medium NODE_VERSION: 1.21.5-gke.1802 NUM_NODES: 3 STATUS: PROVISIONING NAME: config-central LOCATION: us-central1 MASTER_VERSION: 1.21.5-gke.1802 MASTER_IP: MACHINE_TYPE: e2-medium NODE_VERSION: 1.21.5-gke.1802 NUM_NODES: 9 STATUS: PROVISIONING NAME: auto-east LOCATION: us-east1 MASTER_VERSION: 1.21.5-gke.1802 MASTER_IP: 35.229.88.209 MACHINE_TYPE: e2-medium NODE_VERSION: 1.21.5-gke.1802 NUM_NODES: 3 STATUS: PROVISIONING NAME: std-west LOCATION: us-west1-a MASTER_VERSION: 1.21.5-gke.1802 MASTER_IP: 35.197.93.113 MACHINE_TYPE: e2-medium NODE_VERSION: 1.21.5-gke.1802 NUM_NODES: 6 STATUS: PROVISIONING
在所有集群都处于 RUNNING 状态后,按
CTRL-C
中断命令。添加 Identity and Access Management (IAM) 政策绑定,以向队列宿主项目 MCS 服务账号授予其自己项目的 Network User 角色:
gcloud projects add-iam-policy-binding ${PROJECT} \ --member "serviceAccount:${PROJECT}.svc.id.goog[gke-mcs/gke-mcs-importer]" \ --role "roles/compute.networkViewer"
您可以使用适用于 GKE 的工作负载身份联合向 MCS 服务授予对您的项目 VPC 网络配置的读取权限。因此,队列宿主项目的 MCS 导入程序 GKE 服务账号需要此角色。
输出类似于以下示例:
- members: - serviceAccount:PROJECT_ID.svc.id.goog[gke-mcs/gke-mcs-importer] role: roles/compute.networkViewer [...]
将 GKE Standard 集群和 Autopilot 集群注册到项目的舰队。如需了解详情,请参阅注册集群。此步骤最多可能需要 5 分钟
gcloud container fleet memberships register std-west \ --gke-cluster us-west1-a/std-west \ --enable-workload-identity \ --project=${PROJECT} gcloud container fleet memberships register auto-east \ --gke-cluster us-east1/auto-east \ --enable-workload-identity \ --project=${PROJECT} gcloud container fleet memberships register auto-central \ --gke-cluster us-central1/auto-central \ --enable-workload-identity \ --project=${PROJECT} gcloud container fleet memberships register config-central \ --gke-cluster us-central1/config-central \ --enable-workload-identity \ --project=${PROJECT}
对于每个命令,输出类似于以下示例:
Waiting for membership to be created...done. Created a new membership [projects/PROJECT_ID/locations/global/memberships/std-west] for the cluster [std-west] Generating the Connect Agent manifest... Deploying the Connect Agent on cluster [std-west] in namespace [gke-connect]... Deployed the Connect Agent on cluster [std-west] in namespace [gke-connect]. Finished registering the cluster [std-west] with the Hub.
连接到集群并生成 kubeconfig 条目:
gcloud container clusters get-credentials std-west \ --location us-west1-a --project $PROJECT gcloud container clusters get-credentials auto-east \ --location us-east1 --project $PROJECT gcloud container clusters get-credentials auto-central \ --location us-central1 --project $PROJECT gcloud container clusters get-credentials config-central \ --location us-central1 --project $PROJECT
对于每个命令,输出类似于以下示例:
Fetching cluster endpoint and auth data. kubeconfig entry generated for std-west.
重命名集群的上下文,以便在本页面的其余部分更轻松地使用集群:
kubectl config rename-context \ gke_${PROJECT}_us-west1-a_std-west \ std-west kubectl config rename-context \ gke_${PROJECT}_us-east1_auto-east \ auto-east kubectl config rename-context \ gke_${PROJECT}_us-central1_auto-central \ auto-central kubectl config rename-context \ gke_${PROJECT}_us-central1_config-central \ config-central
在本指南中,上下文根据其位置命名。虽然您可以提供备用名称,但本指南中的其余步骤将使用此步骤中使用的名称。
在 std-west 上创建命名空间 onlineboutique:
kubectl create namespace onlineboutique --context std-west
输出类似于以下示例:
namespace/onlineboutique created
克隆 Online Boutique GitHub 代码库并设置 WORKDIR 变量:
cd ~ git clone --branch release/v0.4.1 \ https://github.com/GoogleCloudPlatform/microservices-demo.git cd microservices-demo/release && export WORKDIR=`pwd`
在 std-west 上部署 Online Boutique。此过程为 Online Boutique 的所有微服务创建
Deployments
和Services
,并包含一个在外部公开 Online Boutique 前端服务的 LoadBalancer 类型 Service:cd $WORKDIR kubectl apply -f kubernetes-manifests.yaml \ -n onlineboutique --context=std-west
等待
LoadBalancer
Service 获取外部 IP:watch -n 20 --difference=permanent \ "kubectl get svc frontend-external -n onlineboutique --context=std-west"
一开始,输出类似于以下示例:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE frontend-external LoadBalancer 10.60.5.62 <pending> 80:30359/TCP 43s
Service
准备就绪后,EXTERNAL-IP 列将显示负载均衡器的公共 IP 地址。Service
准备就绪后,获取负载均衡器的外部 IP 地址,并使用 curl 来验证前端是否已准备就绪。如果此 curl 命令返回错误,请稍等片刻,然后重试:curl $(kubectl get svc frontend-external \ -n onlineboutique --context=std-west \ -o=jsonpath="{.status.loadBalancer.ingress[0].ip}") | \ grep -e Cluster -e Zone -e Pod
curl 命令的成功输出类似于以下示例:
<b>Cluster: </b>std-west<br/> <b>Zone: </b>us-west1-a<br/> <b>Pod: </b>frontend-b7bddcc97-wdjsk
在其余集群上创建命名空间 onlineboutique:
kubectl create namespace onlineboutique --context auto-east kubectl create namespace onlineboutique --context auto-central kubectl create namespace onlineboutique --context config-central
对于每个命令,输出类似于以下示例:
namespace/onlineboutique created
将 cartservice 从 std-west 集群导出到
ClusterSet
中的所有其他集群。ServiceExport
对象使用 GKE 多集群 Service 注册 cartservice 服务,以便导出到队列中存在命名空间 onlineboutique 的所有集群。如需了解详情,请参阅注册服务以进行导出。cat <<EOF>> $WORKDIR/cartservice-export.yaml kind: ServiceExport apiVersion: net.gke.io/v1 metadata: namespace: onlineboutique name: cartservice EOF kubectl apply -f $WORKDIR/cartservice-export.yaml \ -n onlineboutique --context=std-west
- 第一个清单用于前端
Deployment
、Service
和ServiceExport
。 - 第二个清单用于将中间件
Services
(emailservice、checkoutservice、recommendationservice、paymentservice、productcatalogservice、currencyservice、shippingservice 和 adservice)部署到正在运行前端的所有区域。通过将请求长时间保留在某个区域本地,可以避免产生不必要的区域间网络流量费用。 为包含清单的 GitHub 代码库设置环境变量:
export MANIFEST_REPO_PATH=https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/cluster-migration
应用清单以将前端层部署到所有三个工作负载集群中:
kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-frontend-manifests.yaml \ -n onlineboutique --context=std-west kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-frontend-manifests.yaml \ -n onlineboutique --context=auto-east kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-frontend-manifests.yaml \ -n onlineboutique --context=auto-central
应用清单以将中间件层部署到所有三个工作负载集群:
kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-middleware-manifests.yaml \ -n onlineboutique --context=std-west kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-middleware-manifests.yaml \ -n onlineboutique --context=auto-east kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-middleware-manifests.yaml \ -n onlineboutique --context=auto-central
确认所有集群都已成功注册到舰队:
gcloud container fleet memberships list --project=$PROJECT
以下示例输出表明所有集群都已成功注册:
NAME: auto-central EXTERNAL_ID: 21537493-32ea-4a41-990d-02be2c1b319f NAME: config-central EXTERNAL_ID: 4369423e-ea7b-482d-a0eb-93b560e67b98 NAME: std-west EXTERNAL_ID: 7fcb048b-c796-476b-9698-001a00f91ab3 NAME: auto-east EXTERNAL_ID: aae2d2ff-b861-4a38-bcaf-612f14810012
在 config-central 集群上安装 Gateway API 自定义资源定义:
kubectl --context=config-central kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v0.5.0" \ | kubectl apply -f -
此步骤会安装 Gateway API 自定义资源定义,包括
GatewayClass
、Gateway
和HTTPRoute
资源。自定义资源定义由 Kubernetes 网络特殊兴趣组维护。安装后,您可以使用 GKE 网关控制器。为您的舰队启用多集群 Ingress(如果尚未启用)。启用此功能也会启用多集群网关控制器。
gcloud container fleet ingress enable \ --config-membership=config-central \ --project=$PROJECT gcloud container fleet ingress describe --project=$PROJECT
输出类似于以下示例:
createTime: '2021-12-08T23:10:52.505888854Z' name: projects/PROJECT_ID/locations/global/features/multiclusteringress resourceState: state: ACTIVE spec: multiclusteringress: configMembership: projects/zl-mcs-expf61cbd13/locations/global/memberships/config-central state: state: code: OK description: Ready to use updateTime: '2021-12-08T23:11:37.994971649Z' updateTime: '2021-12-08T23:11:38.098244178Z'
如果状态的值不是 ACTIVE,请参阅多集群 Ingress 的问题排查和操作。
确认 config-central 集群上有
GatewayClasses
:kubectl get gatewayclasses --context=config-central
输出类似于以下示例:
NAME CONTROLLER AGE gke-l7-global-external-managed networking.gke.io/gateway 18s gke-l7-global-external-managed-mc networking.gke.io/gateway 19s gke-l7-regional-external-managed networking.gke.io/gateway 18s gke-l7-regional-external-managed-mc networking.gke.io/gateway 19s gke-l7-gxlb networking.gke.io/gateway 74s gke-l7-gxlb-mc networking.gke.io/gateway 16s gke-l7-rilb networking.gke.io/gateway 74s gke-l7-rilb-mc networking.gke.io/gateway 16s
不同的
GatewayClass
资源具有不同的功能。如需详细了解何时使用类型,请参阅 GatewayClass 功能。将
external-http
网关资源部署到config-central
:cat <<EOF>> $WORKDIR/external-http-gateway.yaml kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: external-http namespace: onlineboutique spec: gatewayClassName: gke-l7-global-external-managed-mc listeners: - protocol: HTTP port: 80 name: http EOF kubectl apply -f external-http-gateway.yaml \ -n onlineboutique --context=config-central
如
gatewayClassName
字段所示,此资源属于GatewayClass
gke-l7-global-external-managed-mc,后者管理第 7 层外部 Cloud Load Balancing 并公开多集群应用。在 config-central 上部署名为 public-frontend-route 的
HTTPRoute
:cat <<EOF>> $WORKDIR/public-frontend-route.yaml kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: public-frontend-route namespace: onlineboutique spec: parentRefs: - name: "external-http" hostnames: - "store.example.com" rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: frontend group: net.gke.io kind: ServiceImport port: 80 EOF kubectl apply -f public-frontend-route.yaml \ -n onlineboutique --context=config-central
当您部署
HTTPRoute
资源时,该资源会创建外部第 7 层 Cloud Load Balancing 资源并公开由在 std-west、auto-east 和 auto-central 集群中运行的前端服务提供支持的前端ServiceImport
。下图显示部署多集群网关后,流量如何路由到三个应用集群上的任何一个前端前端多集群 Service:
等待负载均衡器准备好已预配的外部 IP 地址,然后继续执行下一步。分配 IP 地址最多可能需要 10 分钟时间。您可以使用监控循环来监控进度。负载均衡器的名称采用 gkemcg-onlineboutique-external-http-k09mfhk74gop 格式:
watch -n 20 --difference=permanent \ "gcloud compute forwarding-rules list \ | grep -A 5 NAME..*external-http"
输出类似于以下示例:
NAME: gkemcg-onlineboutique-external-http-k09mfhk74gop REGION: IP_ADDRESS: 34.149.29.176 IP_PROTOCOL: TCP TARGET: gkemcg-onlineboutique-external-http-k09mfhk74gop
负载均衡器准备就绪后,在 Cloud Shell 中运行以下命令,以导出通过 external-http-gateway.yaml 应用创建的负载均衡器的外部 IP 地址public-frontend-route.yaml 清单:
export EXTERNAL_LB_IP=$(kubectl --context=config-central \ -n onlineboutique get gateway external-http \ -o=jsonpath='{.status.addresses[0].value}')
使用适当的标头向负载均衡器发送请求后,它会返回前端服务传送的 HTML 内容。例如,由于您配置了
HTTPRoute
资源以将store.example.com
主机名映射到前端ServiceImport
,因此在发出 HTTP 请求时必须提供HOST
标头。如果以下 curl 示例返回错误,请等待几分钟,然后重试:curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP | \ grep -e Cluster -e Zone -e Pod
curl 命令的成功输出类似于以下示例:
<b>Cluster: </b>auto-central<br/> <b>Zone: </b>us-central1-f<br/> <b>Pod: </b>frontend-7c7d596ddc-jdh8f
创建客户端 pod:
kubectl run --context=std-west \ --image=radial/busyboxplus:curl client-west \ -- sh -c 'while sleep 3600; do :; done' kubectl run --context=auto-east \ --image=radial/busyboxplus:curl client-east \ -- sh -c 'while sleep 3600; do :; done' kubectl run --context=auto-central \ --image=radial/busyboxplus:curl client-central \ -- sh -c 'while sleep 3600; do :; done'
在 pod 运行完毕之后,使用 curl 命令从 std-west 集群中的客户端
Pod
向负载均衡器端点发送请求并查看响应:kubectl exec -it --context=std-west client-west \ -- curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP | \ grep -e Cluster -e Zone -e Pod
curl 命令的成功输出类似于以下示例:
<b>Cluster: </b>std-west<br/> <b>Zone: </b>us-west1-a<br/> <b>Pod: </b>frontend-7cf48b79cf-trzc4
从 auto-east 集群的客户端
Pod
运行相同的 curl 请求,并查看响应:kubectl exec -it --context=auto-east client-east \ -- curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP | \ grep -e Cluster -e Zone -e Pod
curl 命令的成功输出类似于以下示例:
<b>Cluster: </b>auto-east<br/> <b>Zone: </b>us-east1-d<br/> <b>Pod: </b>frontend-6784b6df98-scdws
由于这是一个 Autopilot 集群,因此集群可能需要预配其他资源来调度
Pod
。如果您看到输出类似于以下示例,请稍等片刻,然后重试:Error from server (BadRequest): pod client-east does not have a host assigned
从 auto-central 集群中的客户端
Pod
运行 curl,并检查响应:kubectl exec -it --context=auto-central client-central \ -- curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP | \ grep -e Cluster -e Zone -e Pod
curl 命令的成功输出类似于以下示例:
<b>Cluster: </b>auto-central<br/> <b>Zone: </b>us-central1-b<br/> <b>Pod: </b>frontend-6784b6df98-x2fv4
这些结果确认流量路由到距离请求来源最近的位置中的相应 pod。
从 std-west 集群中的 client-west
Pod
中运行 curl 命令,并可以看到结果来自 us-west1 中的前端:kubectl exec -it --context=std-west client-west \ -- curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP | \ grep -e Cluster -e Zone -e Pod
curl 命令的成功输出类似于以下示例:
<b>Cluster: </b>std-west<br/> <b>Zone: </b>us-west1-a<br/> <b>Pod: </b>frontend-7cf48b79cf-trzc4
删除 std-west 集群中的前端
Deployment
:kubectl delete deploy frontend \ -n onlineboutique --context=std-west
输出类似于以下示例:
deployment.apps "frontend" deleted
从 std-west 集群中的 client-west
Pod
发送另一个请求。您应该看到来自 auto-east 或 auto-central 集群的其余部分之一的前端Deployments
的响应:kubectl exec -it --context=std-west client-west \ -- curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP | \ grep -e Cluster -e Zone -e Pod
类似以下示例的输出表明响应此请求的运行状况良好的
Pod
的位置:<b>Cluster: </b>auto-central<br/> <b>Zone: </b>us-central1-b<br/> <b>Pod: </b>frontend-6784b6df98-x2fv4
或
<b>Cluster: </b>auto-east<br/> <b>Zone: </b>us-east1-d<br/> <b>Pod: </b>frontend-6784b6df98-scdws
多次运行该命令以查看交替结果。
创建和配置 GKE 集群
为了演示本指南中的多集群模式,您需要在三个单独的云区域中使用三个应用集群,并使用一个集群来托管网关资源的配置。您可以使用与项目关联的集群注册所有集群。一个 Google Cloud 项目只能包含一个队列。此项目称为队列宿主项目。
在 GKE Standard 上部署 Online Boutique
在演示部署的第一步中,您将全套 Online Boutique 应用服务部署到 us-west1 中的单个 GKE Standard 集群 std-west。
您现在有一个在 us-west1-a 中运行的单地区版本的 Online Boutique。
您还可以使用网络浏览器导航到分配给 frontend-external LoadBalancer
Service 的外部 IP,以访问应用并观察其行为。初始部署如下图所示:
将 cartservice 导出为多集群 Service
在本部分中,您将开始向应用添加高可用性元素。您将后端 cartservice 作为多集群 Service 导出到 GKE Autopilot 集群。
将应用清单应用于多集群模式
在本部分中,您将应用两个精选清单来部署多集群模式。这些清单包含您之前应用于 std-west 集群的 kubernetes-manifests.yaml 的选定部分:
在队列的任何集群中运行的 Pod
可以通过采用格式 SERVICE_NAME.NAMESPACE.svc.clusterset.local
向该服务的 ClusterSet
URI 发送请求来访问导出的 Service
。例如,所有三个示例集群中的前端 Deployments
都能够通过向 cartservice.onlineboutique.svc.clusterset.local 发出请求来使用 onlineboutique
命名空间中的 cartservice。
因此,在每个清单中,cartservice 的主机名都更新为其 ClusterSet
URI。这一步至关重要。如果此服务主机名未更新,则前端 Service 将要求使用 kube-dns 以获取 cartservice
而不是 cartservice.onlineboutique.svc.clusterset.local
。此行为会导致 cartservice 本地版本不可用的集群出现 HTTP Status 500
错误,并导致前端 pod 运行状况不佳。
现在,您已经有前端 Deployment
、Service
和 ServiceExport
在 std-west、auto-east 和 auto-central 集群中处于活动状态。您还在每个集群中在本地运行了 Online Boutique 中间件服务。但是,外部流量仍然仅路由到 us-west1 中的初始集群中运行的 Service
,如下图所示:
启用和配置多集群网关
在本部分中,您将流量路由到所有三个集群中的前端的外部负载均衡。为了实现这种配置,请使用多集群网关 (MCG)。这些设置 MCG 的步骤遵循启用多集群网关中更详细的说明。
在这些步骤中,您将使用 config-central 集群来托管网关资源的配置。
测试应用多区域路由行为
使用多集群 Service 和多集群网关的一项强大功能是将外部请求路由到地理位置最近的集群。
如需测试应用多区域行为,请生成源自已部署集群的各个区域的流量。创建三个小型 pod,每个服务集群一个(std-west、auto-east 和 auto-central),这可用于将 HTTP 请求发送到负载均衡器端点。结果使您可查看哪个前端 Pod
在响应。
测试应用多区域弹性
除了高效的流量路由之外,在多个区域运行服务还可以提供在罕见但仍然可能出现的基础架构故障情况下的弹性。
通过删除特定集群中的前端 Deployments
来测试行为,然后从这些区域的客户端 Pod
重试 curl 命令。观察应用是否仍然可用,并查看响应请求的 Pod
的位置。
在此演示部署中,您已使用多集群 Service 和多集群网关向 Online Boutique 应用添加了弹性和地理分布元素。请求会路由到最近的地理区域,即使某个地区中的前端或中间件服务遇到问题,最终用户仍然可以成功使用该应用。