千家信息网

使用 Istio 进行多集群部署管理及单控制平面Gateway连接拓扑的示例分析

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,本篇文章给大家分享的是有关使用 Istio 进行多集群部署管理及单控制平面Gateway连接拓扑的示例分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小
千家信息网最后更新 2025年02月01日使用 Istio 进行多集群部署管理及单控制平面Gateway连接拓扑的示例分析

本篇文章给大家分享的是有关使用 Istio 进行多集群部署管理及单控制平面Gateway连接拓扑的示例分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

单控制平面拓扑下,多个 Kubernetes 集群共同使用在其中一个集群上运行的单个 Istio 控制平面。控制平面的 Pilot 管理本地和远程集群上的服务,并为所有集群配置 Envoy Sidecar 代理。

集群感知的服务路由

Istio 1.1 中引入了集群感知的服务路由能力,在单一控制平面拓扑配置下,使用 Istio 的 Split-horizon EDS(水平分割端点发现服务)功能可以通过其入口网关将服务请求路由到其他集群。基于请求源的位置,Istio 能够将请求路由到不同的端点。

在该配置中,从一个集群中的 Sidecar 代理到同一集群中的服务的请求仍然被转发到本地服务 IP。如果目标工作负载在其他集群中运行,则使用远程集群的网关 IP 来连接到该服务。

(集群感知的服务路由)

如图所示,主集群 cluster1 运行全套的 Istio 控制平面组件,同时集群 cluster2 仅运行 Istio Citadel、Sidecar Injector 和 Ingress 网关。不需要 VPN 连接,不同集群中的工作负载之间也不需要直接网络访问。

从共享的根 CA 为每个集群的 Citadel 生成中间 CA 证书,共享的根 CA 启用跨不同集群的双向 TLS 通信。为了便于说明,我们将 samples/certs 目录下 Istio 安装中提供的示例根 CA 证书用于两个集群。在实际部署中,你可能会为每个集群使用不同的 CA 证书,所有 CA 证书都由公共根 CA 签名。

在每个 Kubernetes 集群中(包括示例中的集群 cluster1 与 cluster2)使用以下命令为生成的 CA 证书创建 Kubernetes 密钥:

kubectlcreate namespace istio-systemkubectlcreate secret generic cacerts -n istio-system \  --from-file=samples/certs/ca-cert.pem \  --from-file=samples/certs/ca-key.pem \  --from-file=samples/certs/root-cert.pem \  --from-file=samples/certs/cert-chain.pem

Istio 控制平面组件

在部署全套 Istio 控制平面组件的集群 cluster1 中,按照以下步骤执行:

1.安装 Istio 的 CRD 并等待几秒钟,以便将它们提交给 Kubernetes API 服务器,如下所示:

fori in install/kubernetes/helm/istio-init/files/crd*yaml; do kubectl apply -f $i;done

2.然后开始在集群 cluster1 中部署 Istio 控制平面。

如果 helm 依赖项缺失或者不是最新的,可以通过 helm dep update 来更新这些依赖项。需要注意的是,因为没有使用 istio-cni,可以暂时将其从依赖项 requirements.yaml 中去掉再执行更新操作。具体命令如下所示:

helmtemplate --name=istio --namespace=istio-system \--setglobal.mtls.enabled=true \--setsecurity.selfSigned=false \--setglobal.controlPlaneSecurityEnabled=true \--setglobal.meshExpansion.enabled=true \--setglobal.meshNetworks.network2.endpoints[0].fromRegistry=n2-k8s-config \--setglobal.meshNetworks.network2.gateways[0].address=0.0.0.0 \--setglobal.meshNetworks.network2.gateways[0].port=15443 \install/kubernetes/helm/istio> ./istio-auth.yaml

请注意,网关地址设置为 0.0.0.0。这是一个临时占位符值,在集群 cluster2 部署之后将更新为其网关的公共 IP 值。

将 Istio 部署到 cluster1,如下所示:

kubectlapply -f ./istio-auth.yaml

确保上述步骤在 Kubernetes 集群中执行成功。

3. 创建网关以访问远程服务,如下所示:

kubectlcreate -f - <

上述网关配置了一个专用端口 15443 用来将传入流量传递到请求的 SNI 标头中指定的目标服务,从源服务到目标服务一直使用双向 TLS 连接。

请注意虽然该网关定义应用于集群 cluster1,但因为两个集群都与同一个 Pilot 进行通信,此网关实例同样也适用于集群 cluster2。

istio-remote 组件

在另一集群 cluster2 中部署 istio-remote 组件,按照以下步骤执行:

1.首先获取集群 cluster1 的入口网关地址,如下所示:

exportLOCAL_GW_ADDR=$(kubectl get svc --selector=app=istio-ingressgateway \  -n istio-system -ojsonpath="{.items[0].status.loadBalancer.ingress[0].ip}")

通过执行以下命令,使用 Helm 创建 Istio remote 部署 YAML 文件:

helmtemplate --name istio-remote --namespace=istio-system \--valuesinstall/kubernetes/helm/istio/values-istio-remote.yaml \--setglobal.mtls.enabled=true \--setgateways.enabled=true \--setsecurity.selfSigned=false \--setglobal.controlPlaneSecurityEnabled=true \--setglobal.createRemoteSvcEndpoints=true \--setglobal.remotePilotCreateSvcEndpoint=true \--setglobal.remotePilotAddress=${LOCAL_GW_ADDR} \--setglobal.remotePolicyAddress=${LOCAL_GW_ADDR} \--setglobal.remoteTelemetryAddress=${LOCAL_GW_ADDR} \--setgateways.istio-ingressgateway.env.ISTIO_META_NETWORK="network2" \--setglobal.network="network2" \install/kubernetes/helm/istio> istio-remote-auth.yaml

2. 将 Istio remote 组件部署到 cluster2,如下所示:

kubectlapply -f ./istio-remote-auth.yaml

确保上述步骤在 Kubernetes 集群中执行成功。

3.更新集群 cluster1 的配置项 istio,获取集群 cluster2 的入口网关地址,如下所示:

exportREMOTE_GW_ADDR=$(kubectl get --context=$CTX_REMOTE svc --selector=app=istio-ingressgateway-n istio-system -o jsonpath="{.items[0].status.loadBalancer.ingress[0].ip}")

在集群 cluster1 中编辑命名空间 istio-system 下的配置项 istio,替换 network2 的网关地址,从 0.0.0.0 变成集群 cluster2 的入口网关地址 ${REMOTE_GW_ADDR}。保存后,Pilot 将自动读取更新的网络配置。

4.创建集群 cluster2 的 Kubeconfig。通过以下命令,在集群 cluster2 上创建服务账号 istio-multi 的 Kubeconfig,并保存为文件 n2-k8s-config:

CLUSTER_NAME="cluster2"SERVER=$(kubectlconfig view --minify=true -o "jsonpath={.clusters[].cluster.server}")SECRET_NAME=$(kubectlget sa istio-multi -n istio-system -o jsonpath='{.secrets[].name}')CA_DATA=$(kubectlget secret ${SECRET_NAME} -n istio-system -o"jsonpath={.data['ca\.crt']}")TOKEN=$(kubectlget secret ${SECRET_NAME} -n istio-system -o"jsonpath={.data['token']}" | base64 --decode)cat< n2-k8s-configapiVersion:v1kind:Configclusters:  - cluster:      certificate-authority-data: ${CA_DATA}      server: ${SERVER}    name: ${CLUSTER_NAME}contexts:  - context:      cluster: ${CLUSTER_NAME}      user: ${CLUSTER_NAME}    name: ${CLUSTER_NAME}current-context:${CLUSTER_NAME}users:  - name: ${CLUSTER_NAME}    user:      token: ${TOKEN}EOF

5.将集群 cluster2 加入到 Istio 控制平面。

在集群 clusterl 执行以下命令,将上述生成的集群 cluster2 的 kubeconfig 添加到集群 cluster1 的 secret 中,执行这些命令后,集群 cluster1 中的 Istio Pilot 将开始监听集群 cluster2 的服务和实例,就像监听集群 cluster1 中的服务与实例一样:

kubectlcreate secret generic n2-k8s-secret --from-file n2-k8s-config -n istio-systemkubectllabel secret n2-k8s-secret istio/multiCluster=true -n istio-system

部署示例应用

为了演示跨集群访问,在第一个 Kubernetes 集群 cluster1 中部署 sleep 应用服务和版本 v1 的 helloworld 服务,在第二个集群 cluster2 中部署版本 v2 的 helloworld 服务,然后验证 sleep 应用是否可以调用本地或者远程集群的 helloworld 服务。

1.部署 sleep 和版本 v1 的 helloworld 服务到第一个集群 cluster1 中,执行如下命令:

kubectlcreate namespace app1kubectllabel namespace app1 istio-injection=enabledkubectlapply -n app1 -f samples/sleep/sleep.yamlkubectlapply -n app1 -f samples/helloworld/service.yamlkubectlapply -n app1 -f samples/helloworld/helloworld.yaml -l version=v1exportSLEEP_POD=$(kubectl get -n app1 pod -l app=sleep -ojsonpath={.items..metadata.name})

2.部署版本 v2 的 helloworld 服务到第二个集群 cluster2 中,执行如下命令:

kubectlcreate namespace app1kubectllabel namespace app1 istio-injection=enabledkubectlapply -n app1 -f samples/helloworld/service.yamlkubectlapply -n app1 -f samples/helloworld/helloworld.yaml -l version=v2

3.登录到命名空间 istio-system 下的 istio-pilot 容器中,运行 curl localhost:8080/v1/registration | grep helloworld -A 11 -B 2 命令,如果得到如下类似的结果就说明版本 v1 与 v2 的 helloworld 服务都已经注册到 Istio 控制平面中了:

4.验证在集群 cluster1 中的 sleep 服务是否可以正常调用本地或者远程集群的 helloworld 服务,在集群 cluster1 下执行如下命令:

kubectlexec -it -n app1 $SLEEP_POD sh

登录到容器中,运行 curl helloworld.app1:5000/hello。

如果设置正确,则在返回的调用结果中可以看到两个版本的 helloworld 服务,同时可以通过查看 sleep 容器组中的 istio-proxy 容器日志来验证访问的端点 IP 地址,返回结果如下所示:

以上就是使用 Istio 进行多集群部署管理及单控制平面Gateway连接拓扑的示例分析,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注行业资讯频道。

0