如何使用 Istio 进行多集群部署管理:多控制平面

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 本文摘自于阿里云高级技术专家王夕宁撰写的《Istio 服务网格技术解析与实战》一书,讲述了如何使用 Istio 进行多集群部署管理来阐述服务网格对多云环境、多集群即混合部署的支持能力。

image.png

在多控制平面拓扑的配置中,每个 Kubernetes 集群都会安装相同的 Istio 控制平面,并且每个控制平面只会管理自己集群内的服务端点。通过使用 Istio 网关、公共根证书颁发机构(CA)以及服务条目 ServiceEntry,可以将多个集群配置组成一个逻辑上的单一服务网格。这种方法没有特殊的网络要求,因此通常被认为是在 Kubernetes 集群之间没有通用网络连接时的一种最简单方法。

在这种拓扑配置下,Kubernetes 跨集群通信需要服务之间的双向 TLS 连接,要在集群之间启用双向 TLS 通信,每个集群的 Citadel 将配置由共享的根 CA 生成的中间 CA 证书,如图所示。

image.png
(多控制平面)

部署控制平面

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

在每个 Kubernetes 集群中实施以下步骤,以在所有集群中部署相同的 Istio 控制平面配置。

1. 使用以下的命令为生成的 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

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

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

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

helm
template install/kubernetes/helm/istio --name istio --namespace istio-system \
-f
install/kubernetes/helm/istio/values-istio-multicluster-gateways.yaml >
./istio.yaml
kubectl
apply -f ./istio.yaml

确保上述步骤在每个 Kubernetes 集群中都执行成功。当然,通过 helm 生成 istio.yaml 的命令执行一次即可。

设置 DNS

为远程集群中的服务提供 DNS 解析,则现有应用程序不需要做修改就可以运行,因为应用程序通常期望通过其 DNS 名称来解析服务并访问所得到的 IP 地址。Istio 本身不使用 DNS 在服务之间路由请求,同一个 Kubernetes 集群下的服务会共享一个相同的 DNS 后缀(例如 svc.cluster.local)。Kubernetes DNS 为这些服务提供 DNS 解析能力。为了给远程集群中的服务提供相似的设置,将远程集群中的服务以 ..global 的格式命名。

Istio 安装包中附带了一个 CoreDNS 服务器,该服务器将为这些服务提供DNS解析能力。为了利用这个 DNS 解析能力,需要配置 Kubernetes 的 DNS 服务指向该 CoreDNS 服务。该 CoreDNS 服务将作为 .global DNS 域的 DNS 服务器。

对于使用 kube-dns 的集群,请创建以下配置项或更新现有的配置项:

kubectl
apply -f - <apiVersion:
v1
kind:
ConfigMap
metadata:
name: kube-dns
namespace: kube-system
data:
stubDomains: |

{"global": ["$(kubectl get

svc -n istio-system istiocoredns -o jsonpath={.spec.clusterIP})"]}
EOF

对于使用 CoreDNS 的集群,请创建以下配置项或更新现有的配置项:

kubectl
apply -f - <apiVersion:
v1
kind:
ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |

.:53 {
    errors
    health
    kubernetes cluster.local in-addr.arpa

ip6.arpa {

       pods insecure
       upstream
       fallthrough in-addr.arpa ip6.arpa
    }
    prometheus :9153
    proxy . /etc/resolv.conf
    cache 30
    reload
    loadbalance
}
global:53 {
    errors
    cache 30
    proxy . $(kubectl get svc -n

istio-system istiocoredns -o jsonpath={.

      spec.clusterIP})
}

EOF

部署示例应用

为了演示跨集群访问,在一个 Kubernetes 集群中部署 sleep 应用服务,在第二个集群中部署 httpbin 应用服务,然后验证 sleep 应用是否可以调用远程集群的 httpbin 服务。

1. 部署 sleep 服务到第一个集群 cluster1 中,执行如下命令:

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

1. 部署 httpbin 服务到第二个集群 cluster2 中,执行如下命令:

kubectl
create namespace app2
kubectl
label namespace app2 istio-injection=enabled
kubectl
apply -n app2 -f samples/httpbin/httpbin.yaml

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

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

1. 为了让在集群 cluster1 中的服务 sleep 能够访问集群 cluster2 中的服务 httpbin,我们需要在集群 cluster1 中为服务 httpbin 创建一个服务条目 ServiceEntry 资源。服务条目 ServiceEntry 的主机名应该是..globalname,其中 name 和 namespace 分别对应于集群 cluster2 中的远程服务的名称和命名空间。

对于 *.global 域下服务的 DNS 解析,需要为这些服务分配一个 IP 地址,并且保证 .globalDNS 域中的每个服务在集群中必须具有唯一的 IP 地址。这些 IP 地址在 pod 之外是不可路由的。在这个例子中,我们将使用网段 127.255.0.0/16 来避免与其他的IP冲突。这些 IP 的应用流量将由 Sidecar 代理捕获并路由到适当的其他远程服务。

在集群 cluster1 中创建该 httpbin 服务对应的 ServiceEntry,执行如下命令:

1.png
2.png

上面的配置将会使集群 cluster1 中访问 httpbin.app2.global 的所有流量,包括访问它的任何端口的流量,都会被路由到启用了双向 TLS 连接的端点 :15443 上。

端口 15443 的网关是一个特殊的 SNI 感知的 Envoy 代理,它是在前面开始部分中作为多集群 Istio 安装步骤的一部分预先配置和安装的。进入端口 15443 的流量将在目标集群的适当内部服务的 pod 中进行负载均衡。

在集群 cluster1 下执行如下命令查看容器 istiocoredns,可以看到上述 ServiceEntry 的域名映射关系已经被加载:

export
ISTIO_COREDNS=$(kubectl get -n istio-system po -l app=istiocoredns -o
jsonpath={.items..metadata.name})
kubectl
logs --tail 2 -n istio-system ${ISTIO_COREDNS} -c istio-coredns-plugin

执行结果如下所示:

image.png

1. 验证在集群 cluster1 中的 sleep 服务是否可以正常调用位于集群 cluster2 中的 httpbin 服务,在集群 cluster1 执行如下命令:

kubectl
exec $SLEEP_POD -n app1 -c sleep -- curl httpbin.app2.global:8000/headers

执行结果如下所示:

image.png

至此,集群 cluster1 与 cluster2 在多控制平面配置下完成了连通。

跨集群的版本路由

通过前面的文章,我们已经了解了 Istio 的很多功能,例如基本版本的路由等,可以在单个 Kubernetes 集群上很容易地实现。而很多真实的业务场景中,基于微服务的应用程序并非那么简单,而是需要在多个位置跨集群去分配和运行服务。那么问题就来了,是否 Istio 的这些功能同样可以很简单地运行在这些真实的复杂环境中呢?

下面我们将会通过一个示例来了解 Istio 的流量管理功能如何在具有多个控制平面拓扑的多集群网格中正常运行。

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

kubectl
create namespace hello
kubectl
label namespace hello istio-injection=enabled
kubectl
apply -n hello -f samples/sleep/sleep.yaml
kubectl
apply -n hello -f samples/helloworld/service.yaml
kubectl
apply -n hello -f samples/helloworld/helloworld.yaml -l version=v1

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

kubectl
create namespace hello
kubectl
label namespace hello istio-injection=enabled
kubectl
apply -n hello -f samples/helloworld/service.yaml
kubectl
apply -n hello -f samples/helloworld/helloworld.yaml -l version=v2
kubectl
apply -n hello -f samples/helloworld/helloworld.yaml -l version=v3

1. 如前面章节中所述,多控制平面下,需要使用以 .global 为后缀的 DNS 名称访问远程服务。

在我们的例子中,它是 helloworld.hello.global,所以我们需要在集群 cluster1 中创建服务条目 ServiceEntry 和目标规则 DestinationRule。服务条目 ServiceEntry 将使用集群 cluster2 的入口网关作为端点地址来访问服务。

通过使用以下命令在集群 cluster1 中创建 helloworld 服务对应的服务条目 ServiceEntry 和目标规则DestinationRule:

5.png
6.png

1. 在两个集群上创建目标规则。在集群 cluster1 中创建子集 v1 对应的目标规则,执行如下命令:

4.png

而在集群 cluster2 中创建子集 v2 和 v3 对应的目标规则,执行如下命令:

3.png

1. 创建虚拟服务以路由流量。

应用下面的虚拟服务将会使得来自用户 jason 对 helloworld 的流量请求指向位于集群 cluster2 中的版本 v2 和 v3,其中 v2 比例为 70%,v3 比例为 30%;来自任何其他用户对 helloworld 的流量请求都将转到位于集群 cluster1 中的版本 v1:

1.png
2.png

执行多次调用,可以从下面的执行结果中看出,上述流量路由的规则生效,这也说明了在多控制平面拓扑下,用于路由的规则定义与在本地集群的使用方式是一样的:

image.png

设置多集群网格的最简单方法是使用多控制平面拓扑,因为它没有特殊的网络要求。通过上述示例可以看出,在单个 Kubernetes 集群上运行的路由功能同样很容易地在多个集群中使用运行。

本文转自<阿里巴巴云原生技术圈>——阿里巴巴云原生小助手

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
3天前
|
Kubernetes 数据可视化 微服务
掌握 Istio:部署完成后如何运用?
本文介绍了在Ubuntu 20.04单机环境下使用Istio服务网格的配置与测试过程。主要内容包括: 1. **环境准备**:使用一台IP为10.9.2.83的机器。 2. **Istio简介**:Istio简化了Kubernetes集群中的服务间通信、流量管理、安全性和可观测性。 3. **部署Bookinfo示例**: - 创建命名空间`istio-demo`并启用自动注入功能。 - 部署Bookinfo应用,包含四个微服务,并验证其正常运行。
14 0
|
3月前
|
Kubernetes 监控 容器
Istio安装及Bookinfo环境部署
文章详细介绍了如何在Kubernetes集群上安装和配置Istio服务网格,并通过部署Bookinfo示例应用来演示Istio的核心功能,如流量管理、服务监控和故障注入等。
66 1
Istio安装及Bookinfo环境部署
|
4月前
|
Kubernetes 负载均衡 C++
Istio的部署模型介绍
Istio的部署模型介绍
69 1
|
6月前
|
Kubernetes 监控 负载均衡
Istio:微服务开发的终极利器,你还在为繁琐的通信和部署流程烦恼吗?
本文介绍了服务网格(Service Mesh)的概念及其在微服务架构中的重要性。微服务强调围绕业务构建团队和去中心化的数据管理,带来更高的灵活性和扩展性。然而,随着服务数量增加,网络通信成为挑战,包括服务发现、路由和安全等问题。 Service Mesh如Istio应运而生,通过边车代理解决服务间通信,提供服务发现、负载均衡、智能路由、安全和监控等功能。它与Kubernetes结合,增强了容器环境的服务管理能力。Istio的bookinfo示例展示了其在多语言微服务中的应用,简化了代码中的服务调用逻辑,使开发更专注于业务本身。
758 3
Istio:微服务开发的终极利器,你还在为繁琐的通信和部署流程烦恼吗?
|
Kubernetes 前端开发 Dubbo
Spring Boot+gRPC构建微服务并部署到Istio(详细教程)
Spring Boot+gRPC构建微服务并部署到Istio(详细教程)
|
SpringCloudAlibaba Kubernetes Java
Istio初体验:使用Spring Boot+gRPC构建微服务并部署
Istio初体验:使用Spring Boot+gRPC构建微服务并部署
651 0
|
消息中间件 Dubbo NoSQL
云原生系列一:Aeraki --- 管理 Istio 服务网格中任何 7 层协议
​ 今天由叶秋学长来介绍如何通过 Aeraki 来在服务网格中为 Dubbo、Thrift 等协议的服务提供七层流量路由、本地限流、全局限流,以及如何基于 Aeraki Protocol快速开发一个自定义协议,并在 Istio 服务网格中对采用自定义协议的服务进行管理。 本篇文章作为系列教程的先导篇,叶秋学长将从全局视角带您了解 Aeraki Mesh。 Aeraki [Air-rah-ki]是希腊语中“微风”的意思。虽然 Istio 在中连接微服务,但 Aeraki 提供了一个框架,允许 Istio 支持更多的第 7 层协议,而不仅仅是 HTTP 和 gRPC。我们希望这股"微风"
365 1
云原生系列一:Aeraki --- 管理 Istio 服务网格中任何 7 层协议
|
监控 负载均衡 数据可视化
微服务治理 Istio 1.6部署和应用(下)
微服务治理 Istio 1.6部署和应用
微服务治理 Istio 1.6部署和应用(下)
|
自然语言处理 Kubernetes 负载均衡
微服务治理 Istio 1.6部署和应用(上)
微服务治理 Istio 1.6部署和应用
微服务治理 Istio 1.6部署和应用(上)
|
Kubernetes 监控 安全
基于阿里云 ASK 的 Istio 微服务应用部署初探
本文会通过在 ASK 上试用 Istio 部署微服务应用的方式,来验证 ASK 对标准 Kubernetes 的兼容性。Istio 作为 Service Mesh(服务网格)的领导解决方案,一方面本身足够复杂具有代表性,另一方面它也代表了云原生时代微服务架构的趋势具有参考意义。