在 Google Cloud 外部设置多集群网格
本指南介绍如何为以下平台设置多集群网格:
- Google Distributed Cloud for VMware(纯软件)
- 适用于裸金属的 Google Distributed Cloud(纯软件)
- GKE on Azure(已弃用)
- GKE on AWS(已弃用)
- 关联集群,包括 Amazon EKS 集群和 Microsoft AKS 集群(已弃用)
本指南介绍如何设置两个集群,但您可以扩展此过程,将任意数量的集群加入网格中。
准备工作
本指南假设您使用 asmcli install 安装了 Cloud Service Mesh。您需要 asmcli 和 asmcli 下载到您运行 asmcli install 时在 --output_dir 中指定的目录的配置软件包。如果需要进行设置,请按照安装依赖工具并验证集群中的步骤操作:
您需要访问要在网格中设置的所有集群的 kubeconfig 文件。
设置环境变量和占位符
安装东-西网关时,您需要以下环境变量。
- 为项目编号创建环境变量。在以下命令中,将 FLEET_PROJECT_ID 替换为舰队宿主项目的项目 ID。 - export PROJECT_NUMBER=$(gcloud projects describe FLEET_PROJECT_ID \ --format="value(projectNumber)")
- 为网格标识符创建环境变量。 - export MESH_ID="proj-${PROJECT_NUMBER}"
- 按照 - asmcli要求的格式,为集群名称创建环境变量。- export CLUSTER_1="cn-FLEET_PROJECT_ID-global-CLUSTER_NAME_1" export CLUSTER_2="cn-FLEET_PROJECT_ID-global-CLUSTER_NAME_2"
- 使用此命令输出中 - NAME列下的值获取集群的上下文名称:- kubectl config get-contexts 
- 将环境变量设置为集群上下文名称,本指南后面将在许多步骤中用到这些环境变量: - export CTX_1=CLUSTER1_CONTEXT_NAME export CTX_2=CLUSTER2_CONTEXT_NAME 
安装东-西网关
在以下命令中:
- 将 - CLUSTER_NAME_1和- CLUSTER_NAME_2替换为您集群的名称。
- 将 - PATH_TO_KUBECONFIG_1和- PATH_TO_KUBECONFIG_2替换为您集群的 kubeconfig 文件。
GKE 集群
Mesh CA 或 CA Service
- 在 cluster1 中安装一个网关,专用于发送到 - $CLUSTER_2的东西流量。默认情况下,此网关在互联网上为公开。生产系统可能需要额外的访问限制(例如防火墙规则),以防止外部攻击。- asm/istio/expansion/gen-eastwest-gateway.sh \ --mesh ${MESH_ID} \ --cluster ${CLUSTER_1} \ --network default \ --revision asm-1271-5 | \ ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_1 \ install -y --set spec.values.global.pilotCertProvider=istiod -f -
- 在 - $CLUSTER_2中安装专用于- $CLUSTER_1的东-西流量的网关。- asm/istio/expansion/gen-eastwest-gateway.sh \ --mesh ${MESH_ID} \ --cluster ${CLUSTER_2} \ --network default \ --revision asm-1271-5 | \ ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_2 \ install -y --set spec.values.global.pilotCertProvider=istiod -f -
Istio CA
- 在 cluster1 中安装一个网关,专用于发送到 - $CLUSTER_2的东西流量。默认情况下,此网关在互联网上为公开。生产系统可能需要额外的访问限制(例如防火墙规则),以防止外部攻击。- asm/istio/expansion/gen-eastwest-gateway.sh \ --mesh ${MESH_ID} \ --cluster ${CLUSTER_1} \ --network default \ --revision asm-1271-5 | \ ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_1 \ install -y --set spec.values.global.pilotCertProvider=istiod -f -
- 在 - $CLUSTER_2中安装专用于- $CLUSTER_1的东-西流量的网关。- asm/istio/expansion/gen-eastwest-gateway.sh \ --mesh ${MESH_ID} \ --cluster ${CLUSTER_2} \ --network default \ --revision asm-1271-5 | \ ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_2 \ install -y --set spec.values.global.pilotCertProvider=istiod -f -
Azure、AWS 和关联
Mesh CA
- 在 cluster1 中安装一个网关,专用于发送到 - $CLUSTER_2的东西流量。默认情况下,此网关在互联网上为公开。生产系统可能需要额外的访问限制(例如防火墙规则),以防止外部攻击。- asm/istio/expansion/gen-eastwest-gateway.sh \ --mesh ${MESH_ID} \ --cluster ${CLUSTER_1} \ --network default \ --revision asm-1271-5 | \ ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_1 \ install -y --set spec.values.global.pilotCertProvider=istiod -f -
- 在 - $CLUSTER_2中安装专用于- $CLUSTER_1的东-西流量的网关。- asm/istio/expansion/gen-eastwest-gateway.sh \ --mesh ${MESH_ID} \ --cluster ${CLUSTER_2} \ --network default \ --revision asm-1271-5 | \ ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_2 \ install -y --set spec.values.global.pilotCertProvider=istiod -f -
Istio CA
- 在 cluster1 中安装一个网关,专用于发送到 - $CLUSTER_2的东西流量。默认情况下,此网关在互联网上为公开。生产系统可能需要额外的访问限制(例如防火墙规则),以防止外部攻击。- asm/istio/expansion/gen-eastwest-gateway.sh \ --mesh ${MESH_ID} \ --cluster ${CLUSTER_1} \ --network default \ --revision asm-1271-5 | \ ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_1 \ install -y --set spec.values.global.pilotCertProvider=istiod -f -
- 在 - $CLUSTER_2中安装专用于- $CLUSTER_1的东-西流量的网关。- asm/istio/expansion/gen-eastwest-gateway.sh \ --mesh ${MESH_ID} \ --cluster ${CLUSTER_2} \ --network default \ --revision asm-1271-5 | \ ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_2 \ install -y --set spec.values.global.pilotCertProvider=istiod -f -
公开服务
由于集群位于不同的网络中,因此您需要在这两个集群中的东-西网关上公开所有服务 (*.local)。虽然此网关在互联网上为公开,但只有具有可信 mTLS 证书和工作负载 ID 的服务才能访问其背后的服务,就像它们位于同一网络上一样。
- 通过 - CLUSTER_NAME_1的东-西网关公开服务。- kubectl --kubeconfig=PATH_TO_KUBECONFIG_1 apply -n istio-system -f \ asm/istio/expansion/expose-services.yaml
- 通过 - CLUSTER_NAME_2的东-西网关公开服务。- kubectl --kubeconfig=PATH_TO_KUBECONFIG_2 apply -n istio-system -f \ asm/istio/expansion/expose-services.yaml
启用端点发现
运行 asmcli create-mesh 命令以启用端点发现。此示例仅显示两个集群,但您可以运行此命令在更多集群上启用端点发现,但需遵循 GKE Hub 服务限制。
  ./asmcli create-mesh \
      FLEET_PROJECT_ID \
      PATH_TO_KUBECONFIG_1 \
      PATH_TO_KUBECONFIG_2
验证多集群连接
本部分介绍如何将示例 HelloWorld 和 Sleep 服务部署到多集群环境,以验证跨集群负载均衡可正常工作。
启用边车注入
- 在每个集群中创建示例命名空间。 - for CTX in ${CTX_1} ${CTX_2} do kubectl create --context=${CTX} namespace sample done
- 在已创建的命名空间中启用边车注入。 - 建议:运行以下命令以将默认注入标签应用于命名空间: - for CTX in ${CTX_1} ${CTX_2} do kubectl label --context=${CTX} namespace sample \ istio.io/rev- istio-injection=enabled --overwrite done- 我们建议您使用默认注入,但也支持基于修订版本的注入:请按照以下说明操作: - 使用以下命令查找 - istiod的修订版本标签:- kubectl get deploy -n istio-system -l app=istiod -o \ jsonpath={.items[*].metadata.labels.'istio\.io\/rev'}'{"\n"}'
- 将修订版本标签应用于命名空间。在以下命令中, - REVISION_LABEL是您在上一步中记下的- istiod修订版本标签的值。- for CTX in ${CTX_1} ${CTX_2} do kubectl label --context=${CTX} namespace sample \ istio-injection- istio.io/rev=REVISION_LABEL --overwrite done
 
安装 HelloWorld 服务
- 在这两个集群中创建 HelloWorld 服务: - kubectl create --context=${CTX_1} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l service=helloworld -n sample- kubectl create --context=${CTX_2} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l service=helloworld -n sample
将 HelloWorld v1 和 v2 部署到每个集群
- 将 - HelloWorld v1部署到- CLUSTER_1,并将- v2部署到- CLUSTER_2,这可帮助以后验证跨集群负载均衡:- kubectl create --context=${CTX_1} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l version=v1 -n sample- kubectl create --context=${CTX_2} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l version=v2 -n sample
- 使用以下命令确认 - HelloWorld v1和- v2正在运行。验证输出是否如下所示:- kubectl get pod --context=${CTX_1} -n sample- NAME READY STATUS RESTARTS AGE helloworld-v1-86f77cd7bd-cpxhv 2/2 Running 0 40s - kubectl get pod --context=${CTX_2} -n sample- NAME READY STATUS RESTARTS AGE helloworld-v2-758dd55874-6x4t8 2/2 Running 0 40s 
部署 Sleep 服务
- 将 - Sleep服务部署到这两个集群。此 pod 将出于演示目的生成虚假网络流量:- for CTX in ${CTX_1} ${CTX_2} do kubectl apply --context=${CTX} \ -f ${SAMPLES_DIR}/samples/sleep/sleep.yaml -n sample done
- 等待在每个集群中启动 - Sleep服务。验证输出是否如下所示:- kubectl get pod --context=${CTX_1} -n sample -l app=sleep- NAME READY STATUS RESTARTS AGE sleep-754684654f-n6bzf 2/2 Running 0 5s - kubectl get pod --context=${CTX_2} -n sample -l app=sleep- NAME READY STATUS RESTARTS AGE sleep-754684654f-dzl9j 2/2 Running 0 5s 
验证跨集群负载均衡
多次调用 HelloWorld 服务,并检查输出以验证来自 v1 和 v2 的交替回复:
- 调用 - HelloWorld服务:- kubectl exec --context="${CTX_1}" -n sample -c sleep \ "$(kubectl get pod --context="${CTX_1}" -n sample -l \ app=sleep -o jsonpath='{.items[0].metadata.name}')" \ -- /bin/sh -c 'for i in $(seq 1 20); do curl -sS helloworld.sample:5000/hello; done'- 输出类似于如下所示内容: - Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8 Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv ... 
- 再次调用 - HelloWorld服务:- kubectl exec --context="${CTX_2}" -n sample -c sleep \ "$(kubectl get pod --context="${CTX_2}" -n sample -l \ app=sleep -o jsonpath='{.items[0].metadata.name}')" \ -- /bin/sh -c 'for i in $(seq 1 20); do curl -sS helloworld.sample:5000/hello; done'- 输出类似于如下所示内容: - Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8 Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv ... 
恭喜,您已验证负载均衡的多集群 Cloud Service Mesh!
清理
完成负载均衡验证后,请从集群中移除 HelloWorld 和 Sleep 服务。
kubectl delete ns sample --context ${CTX_1}
kubectl delete ns sample --context ${CTX_2}