设置多云或混合网格
本页面介绍如何为以下平台设置多云或混合网格:
- 混合:Google Cloud 上的 GKE 和 Google Distributed Cloud (预览)
- 混合:GKE on Google Cloud 和 Google Distributed Cloud(预览版)
- 多云:GKE on Google Cloud 和 Amazon EKS(预览版)
按照以下说明,您可以设置两个集群,但您可以扩展此过程,将任意数量的集群加入网格中。
前提条件
- 所有集群都必须注册到同一舰队宿主项目。
- 所有 GKE 集群都必须位于同一网络上的共享 VPC 配置中。
- 必须能够从网格中的每个集群访问集群的 Kubernetes 控制层面地址和网关地址。GKE 集群所在的 Google Cloud 项目应可以创建外部负载均衡类型。我们建议您使用授权网络和 VPC 防火墙规则来限制访问权限。
- 不支持专用集群(包括 GKE 专用集群)。如果您使用本地集群(包括 Google Distributed Cloud 和 Google Distributed Cloud),则需要能够从 GKE 集群中的 Pod 访问 Kubernetes 控制平面地址和网关地址。我们建议您使用 CloudVPN 将 GKE 集群的子网连接到本地集群的网络。
- 若您使用 Istio CA,请对所有集群使用相同的自定义根证书。
准备工作
本指南假定您使用 asmcli
工具安装了 Cloud Service Mesh。您需要 asmcli
和 asmcli
下载到您运行 asmcli install
时在 --output_dir 中指定的目录的配置软件包。如需了解详情,请参阅安装依赖工具并验证集群以执行以下操作:
您需要访问要在网格中设置的所有集群的 kubeconfig 文件。 对于 GKE 集群,如需为集群创建新的 kubeconfig 文件,您可以在终端中导出 KUBECONFIG
环境和完整文件路径作为值,并生成 kubeconfig 条目。
设置环境变量和占位符
安装东-西网关时,您需要以下环境变量。
为网络名称创建环境变量:
GKE 集群默认使用集群网络名称:
export NETWORK_1="PROJECT_ID-CLUSTER_NETWORK" ``````
其他集群使用
default
:export NETWORK_2="default" ``````
如果您在具有不同 --network_id
值的其他集群上安装了 Cloud Service Mesh,则应该将相同的值传递给 NETWORK_2
。
安装东-西网关
在 CLUSTER_1(您的 GKE 集群)中安装一个 专门用于东西 CLUSTER_2(您的多云集群或本地集群)的流量:
asm/istio/expansion/gen-eastwest-gateway.sh \ --network ${NETWORK_1} \ --revision asm-1232-2 | \ ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_1 install -y -f -
请注意,默认情况下,此网关在互联网上是公开的。生产系统可能需要额外的访问限制(例如防火墙规则),以防止外部攻击。
在 CLUSTER_2 中安装专用于 CLUSTER_1 东-西流量的网关。
asm/istio/expansion/gen-eastwest-gateway.sh \ --network ${NETWORK_2} \ --revision asm-1232-2 | \ ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_2 install -y -f -
公开服务
由于集群位于不同的网络中,因此您需要在这两个集群中的东-西网关上公开所有服务 (\*.local
)。虽然此网关在互联网上是公开的,但只有具有可信 mTLS 证书和工作负载 ID 的服务才能访问其背后的服务,就像它们位于同一网络上一样。
通过每个集群的东-西网关公开服务
kubectl --kubeconfig=PATH_TO_KUBECONFIG_1 apply -n istio-system -f \
asm/istio/expansion/expose-services.yaml
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
服务部署到多集群环境,以验证跨集群负载均衡可正常工作。
启用边车注入
找到修订版本标签值,您将在后面的步骤中用到该值。
使用以下命令找到修订版本标签,您将在后面的步骤中用到该标签。
kubectl -n istio-system get pods -l app=istiod --show-labels
输出类似于以下内容:
NAME READY STATUS RESTARTS AGE LABELS istiod-asm-173-3-5788d57586-bljj4 1/1 Running 0 23h app=istiod,istio.io/rev=asm-173-3,istio=istiod,pod-template-hash=5788d57586 istiod-asm-173-3-5788d57586-vsklm 1/1 Running 1 23h app=istiod,istio.io/rev=asm-173-3,istio=istiod,pod-template-hash=5788d57586
在输出中的 LABELS
列下,记下 istiod
修订版本标签的值,该值位于前缀 istio.io/rev=
之后。在此示例中,该值为 asm-173-3
。在下一部分的步骤中使用该修订版本值。
安装 HelloWorld 服务
在每个集群中创建示例命名空间和服务定义。 在以下命令中,将 REVISION 替换为您在上一步中记下的
istiod
修订版本标签。for CTX in ${CTX_1} ${CTX_2} do kubectl create --context=${CTX} namespace sample kubectl label --context=${CTX} namespace sample \ istio-injection- istio.io/rev=REVISION --overwrite done
其中,REVISION 是您之前记下的
istiod
修订版本标签。输出如下:
label "istio-injection" not found. namespace/sample labeled
您可以安全地忽略
label "istio-injection" not found.
在这两个集群中创建 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}