如何使用 Istio 进行多集群部署管理:单控制平面 Gateway 连接拓扑

本文涉及的产品
应用实时监控服务-用户体验监控,每月100OCU免费额度
应用实时监控服务-应用监控,每月50GB免费额度
可观测监控 Prometheus 版,每月50GB免费额度
简介: 本文摘自于由阿里云高级技术专家王夕宁撰写的《Istio 服务网格技术解析与实践》一书,讲述了如何使用 Istio 进行多集群部署管理来阐述服务网格对多云环境、多集群即混合部署的支持能力。

头图.png

作者 | 王夕宁  阿里巴巴高级技术专家

导读:本文摘自于由阿里云高级技术专家王夕宁撰写的《Istio 服务网格技术解析与实践》一书,讲述了如何使用 Istio 进行多集群部署管理来阐述服务网格对多云环境、多集群即混合部署的支持能力。

前文详情:
如何使用 Istio 进行多集群部署管理:单控制平面 VPN 连接拓扑

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

集群感知的服务路由

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

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

1.png
(集群感知的服务路由)

如图所示,主集群 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 密钥:

kubectl
create namespace istio-system
kubectl
create 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 服务器,如下所示:

for
i 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 中去掉再执行更新操作。具体命令如下所示:

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

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

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

kubectl
apply -f ./istio-auth.yaml

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

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

kubectl
create -f - <<EOF
apiVersion:
networking.istio.io/v1alpha3
kind:
Gateway
metadata:
  name: cluster-aware-gateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 15443
      name: tls
      protocol: TLS
    tls:
      mode: AUTO_PASSTHROUGH
    hosts:
    - "*"
EOF

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

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

istio-remote 组件

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

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

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

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

helm
template --name istio-remote --namespace=istio-system \
--values
install/kubernetes/helm/istio/values-istio-remote.yaml \
--set
global.mtls.enabled=true \
--set
gateways.enabled=true \
--set
security.selfSigned=false \
--set
global.controlPlaneSecurityEnabled=true \
--set
global.createRemoteSvcEndpoints=true \
--set
global.remotePilotCreateSvcEndpoint=true \
--set
global.remotePilotAddress=${LOCAL_GW_ADDR} \
--set
global.remotePolicyAddress=${LOCAL_GW_ADDR} \
--set
global.remoteTelemetryAddress=${LOCAL_GW_ADDR} \
--set
gateways.istio-ingressgateway.env.ISTIO_META_NETWORK="network2" \
--set
global.network="network2" \
install/kubernetes/helm/istio
> istio-remote-auth.yaml

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

kubectl
apply -f ./istio-remote-auth.yaml

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

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

export
REMOTE_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=$(kubectl
config view --minify=true -o "jsonpath={.clusters[].cluster.server}")
SECRET_NAME=$(kubectl
get sa istio-multi -n istio-system -o jsonpath='{.secrets[].name}')
CA_DATA=$(kubectl
get secret ${SECRET_NAME} -n istio-system -o
"jsonpath={.data['ca\.crt']}")
TOKEN=$(kubectl
get secret ${SECRET_NAME} -n istio-system -o
"jsonpath={.data['token']}" | base64 --decode)
cat
<<EOF > n2-k8s-config
apiVersion:
v1
kind:
Config
clusters:
  - 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 中的服务与实例一样:

kubectl
create secret generic n2-k8s-secret --from-file n2-k8s-config -n istio-system
kubectl
label 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 中,执行如下命令:

kubectl
create namespace app1
kubectl
label namespace app1 istio-injection=enabled
kubectl
apply -n app1 -f samples/sleep/sleep.yaml
kubectl
apply -n app1 -f samples/helloworld/service.yaml
kubectl
apply -n app1 -f samples/helloworld/helloworld.yaml -l version=v1
export
SLEEP_POD=$(kubectl get -n app1 pod -l app=sleep -o
jsonpath={.items..metadata.name})

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

kubectl
create namespace app1
kubectl
label namespace app1 istio-injection=enabled
kubectl
apply -n app1 -f samples/helloworld/service.yaml
kubectl
apply -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 控制平面中了:

微信图片_20200428144254.jpg

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

kubectl
exec -it -n app1 $SLEEP_POD sh

2.png

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

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

3.png

《Istio服务网格技术解析与实战》读者可免费体验 ASM 产品进行学习!点击了解阿里云服务网格产品 ASM:www.aliyun.com/product/servicemesh

作者简介

王夕宁 阿里云高级技术专家,阿里云服务网格产品 ASM 及 Istio on Kubernetes 技术负责人,专注于 Kubernetes、云原生、服务网格等领域。曾在 IBM 中国开发中心工作,担任过专利技术评审委员会主席,拥有 40 多项相关领域的国际技术专利。《Istio 服务网格解析与实战》一书由其撰写,详细介绍了 Istio 的基本原理与开发实战,包含大量精选案例和参考代码可以下载,可快速入门 Istio 开发。Gartner 认为,2020 年服务网格将成为所有领先的容器管理系统的标配技术。本书适合所有对微服务和云原生感兴趣的读者,推荐大家对本书进行深入的阅读。

课程推荐

为了更多开发者能够享受到 Serverless 带来的红利,这一次,我们集结了 10+ 位阿里巴巴 Serverless 领域技术专家,打造出最适合开发者入门的 Serverless 公开课,让你即学即用,轻松拥抱云计算的新范式——Serverless。

点击即可免费观看课程:https://developer.aliyun.com/learning/roadmap/serverless

阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的公众号。”

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
负载均衡 Kubernetes API
Istio:Gateway设计与实现
Istio:Gateway设计与实现
996 0
Istio:Gateway设计与实现
|
6月前
|
监控 Cloud Native 安全
【阿里云云原生专栏】云原生下的API管理:阿里云API Gateway的应用场景与优势
【5月更文挑战第23天】阿里云API Gateway是高性能的API托管服务,适用于微服务API聚合、安全管理及流量控制。它提供统一入口、多种认证方式和流量控制策略,确保服务稳定性。具备高度可扩展性、丰富插件生态和简化API生命周期管理等特点。通过简单步骤,如创建API、配置后端服务、设置认证和发布,即可快速上手。作为云原生时代的API管理解决方案,阿里云API Gateway助力企业高效、安全地管理API,推动业务创新和数字化转型。
96 1
|
Kubernetes JavaScript API
如何理解 Istio Ingress, 它与 API Gateway 有什么区别?东西流量?南北流量?
这三者都和流量治理密切相关,那么流量治理在过去和现在有什么区别呢?都是如何做的呢? 在学习istio的时候对流量管理加深了理解。什么是东西流量?什么是南北流量?
273 0
关于Spring Cloud Gateway与下游服务器的连接分析
背景 最近面试了不少同学,有很大一部分简历上会提到网关,我一般都会顺着往下问他们的网关是怎么做的。 基本上都是说直接使用的Spring Cloud Gateway或者基于Spring Cloud Gateway二次开发。 这种时候我会继续问一个比较基础的问题:Spring Cloud Gateway作为网关,会把接收到的请求转发给下游服务,那么Spring Cloud Gateway跟下游的服务之间保持的是长连还是短连?还是说每次转发的时候都会新建立一个连接吗?
|
运维 Kubernetes Cloud Native
上了 istio 的贼船之 API Gateway
通过将传统微服务架构的这些控制面功能解耦到 istio,可以让微服务应用本身专注于业务开发,是一个比较简的单体 springboot 应用。再结合 k8s 的高扩展性,研发整体的迭代速度和运维效率还是比较高的,缺点是无论是 k8s 还是 istio ,学习成本偏高,需要团队至少 2 人具有专业知识,对于招聘成本、系统升级都有风险。
上了 istio 的贼船之 API Gateway
|
关系型数据库 MySQL
node线上项目连接mysql出现 504 Gateway Time-Out
node线上项目连接mysql出现 504 Gateway Time-Out
Istio - crds - Ingress Gateway
入口网关(Ingress Gateway)是 Istio 重要的资源对象之一,是用于管理网格边缘入站的流量,通过入口网关就可以很轻松的将网格内部的服务暴露到外部提供访问。
218 0
Istio - crds - Ingress Gateway
|
Prometheus Kubernetes 负载均衡
如何使用 Istio 进行多集群部署管理:多控制平面
本文摘自于阿里云高级技术专家王夕宁撰写的《Istio 服务网格技术解析与实战》一书,讲述了如何使用 Istio 进行多集群部署管理来阐述服务网格对多云环境、多集群即混合部署的支持能力。
如何使用 Istio 进行多集群部署管理:多控制平面
|
Kubernetes Cloud Native Shell
如何使用 Istio 进行多集群部署管理:单控制平面 Gateway 连接拓扑
本文摘自于由阿里云高级技术专家王夕宁撰写的《Istio 服务网格技术解析与实践》一书,讲述了如何使用 Istio 进行多集群部署管理来阐述服务网格对多云环境、多集群即混合部署的支持能力。
如何使用 Istio 进行多集群部署管理:单控制平面 Gateway 连接拓扑
|
16天前
|
监控 安全 Cloud Native
云原生安全:Istio在微服务架构中的安全策略与实践
【10月更文挑战第26天】随着云计算的发展,云原生架构成为企业数字化转型的关键。微服务作为其核心组件,虽具备灵活性和可扩展性,但也带来安全挑战。Istio作为开源服务网格,通过双向TLS加密、细粒度访问控制和强大的审计监控功能,有效保障微服务间的通信安全,成为云原生安全的重要工具。
38 2