Istio 中的多集群部署与管理

 

  

本文节选自ServiceMesher 社区出品的开源电子书《Istio Handbook——Istio 服务网格进阶实战》,作者钟华,来自腾讯云。

Istio 在 1.1 后提供了两类多集群的连通的部署模式:

1. 多控制面2. 单控制面,也称为 “共享控制面” 模式

多控制面模式

多控制面模式,各网格之间服务实例无法自动共享,互相访问不透明。应用场景有限,实现相对简单。

单控制面模式

单控制面模式,根据各集群是否属于同一个网络,还可以细分为「单网络单控制面」和「多网络单控制面」:

 单网络单控制面模式,支持多 Kubernetes 集群融合为一个服务网格,但是该种模式对网络有严格的要求:需要所有集群处于同一个扁平网络,Pod IP 互通且不重叠,使用 VPN 连通多集群网络是常见的一个选项。不过这些网络需求在实际环境可能难以满足,也限制了该模式的应用场景。• 多网络单控制面模式,同样实现了多 Kubernetes 集群融合为一个服务网格,且在网络上没有上述限制,每个多 Kubernetes 集群是一个独立的网络,甚至可以分布于不同地域。但其实现也最复杂,且该模式要求开启服务间 mTLS 通信,通信效率上也有一定影响。

多控制面

多控制面部署模式中,每个 Kubernetes 集群中都包含一套独立的 istio 控制面,istio 并不会主动打通各集群间的服务访问,用户需要主动注册集群间互访的服务条目,这些包括设置 DNS 和 gateway,注册 ServiceEntry 等。下面我们以集群 1 访问集群 2 中的 httpbin.bar 服务为例,解析多控制面服务网格连通的核心流程。

配置各集群 CA 证书

多控制面模式下的集群间互访,要求使用双向 TLS 通信。因为每个集群中都有独立的 CA,如果这些 CA 使用自签名证书将无法互相验证,因此各集群需要共享 root CA,利用 root CA 再为每个子集群签发 intermediate CA 证书。

我们以 istio 源码中提供的示例 CA 证书为例,在各集群中创建一个名为 cacerts 的 secret,istiod 中的 CA 会自动读取并使用这些证书。

                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 源码中提供了一套示例的 CA 证书,位于 samples/certs/ 目录下,需要注意这套证书已广泛播,仅供线下测试使用,一定不要在生产环境使用!以避免不必要的安全风险。

安装控制面

使用 IstioOperator 在各集群中分别安装控制面:

                $ istioctl install \-f manifests/examples/multicluster/values-istio-multicluster-gateways.yaml

Operator manifest 配置概要如下:

                apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:addonComponents:istiocoredns:enabled: truecomponents:egressGateways:- name: istio-egressgatewayenabled: truevalues:global:podDNSSearchNamespaces:- global- default.svc.cluster.globalmultiCluster:enabled: truecontrolPlaneSecurityEnabled: truegateways:istio-egressgateway:env:# Needed to route traffic via egress gateway if desired.ISTIO_META_REQUESTED_NETWORK_VIEW: "external"

上面的配置会安装一个 istiocoredns 服务,用于解析远端服务的 DNS 地址。该服务使用的镜像是 coredns 官方镜像。

podDNSSearchNamespaces 配置会影响后续 Pod 注入的内容,具体地会调整 Pod 的 dnsConfig,该配置将修改 Pod /etc/resolv.conf 文件中 DNS searches 配置,为 Pod 增加了 2 个 DNS 搜索域。

                dnsConfig:searches:- global- default.svc.cluster.global

在多控制面网格拓扑中,每个集群身份都是对等的,对某个集群来说,任何其他集群都是远端集群。Kubernetes service 默认使用 svc.cluster.local 作为域名后缀,Kubernetes 集群内自带的 DNS 服务(KubeDNS 或者 CoreDNS),负责解析 service 域名。

在该模式下,为了区别请求的目的端是本集群服务还是远端集群服务,istio 使用 svc.cluster.global 指向远端集群服务。默认情况下,isito 本身不会影响 Kubernetes 集群内的 DSN 条目。不过我们上一步中安装了一个 istiocoredns,该组件会负责解析 svc.cluster.global 的域名查询。

配置 ServiceEntry

为了实现在本集群中访问远端集群的服务,我们需要在本集群中注册远端服务的 ServiceEntry,设置 ServiceEntry 需要注意以下几点:

•Host 格式 <service name>.<namespace>.global,对该域名的查询请求,将由上一步配置的 istiocoredns 进行解析。• 需要在 ServiceEntry 提供 VIP,可以理解为远端目标服务在本集群中的 service IP,每个远端服务需要配置不同的 VIP,同时这些 VIP 不能和本集群中的其他 service IP 重叠。

以集群 1 访问 集群 2 中的 httpbin.bar 服务为例,我们需要在 集群 1 中配置以下 ServiceEntry:

                apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:name: httpbin-bar
spec:hosts:- httpbin.bar.globallocation: MESH_INTERNALports:- name: http1number: 8000protocol: httpresolution: DNSaddresses:- 240.0.0.2endpoints:- address: {{ CLUSTER2_GW_ADDR }}ports:http1: 15443 # Do not change this port value

其中 addresses (240.0.0.2) 用于设置目的服务的 VIP,同时该服务的 endpoints 中,CLUSTER2_GW_ADDR 需要填写集群 2 的 ingress gateway 地址。这会告诉 istio: 应该将集群 1 访问 240.0.0.2 的流量,路由到集群 2 的 ingress gateway。

以上配置的 VIP 并不会作为集群间 IP 层的实际目的地址,当集群 1 中的某个 client 发起对该 IP 访问后,流量会被拦截到对应的 sidecar 中,sidecar 会根据 xDS 信息,将目的 IP 转换为 集群 2 的 ingress gateway 地址。为了避免冲突,这里推荐使用 E 类网络地址 240.0.0.0/4,该网络地址段作为保留范围并未广泛使用。

SNI 感知网关分析

SNI(Server Name Indication)指定了 TLS 握手时要连接的主机名。SNI 协议是为了支持同一个 IP(和端口)支持多个域名。

目的网关端口 15443 预设了 SNI 感知的 listener,具体地,从集群 1 中 client 发出的流量拦截到 sidecar 后,sidecar 会将其转换为 mTLS 流量,并带上 SNI 信息(httpbin)转发出去。流量到达集群 2 的 ingress gateway 15443 端口后,该 ingress gateway 会提取 SNI 信息,分析出实际的目的服务为 httpbin 服务,最终转发给集群 2 中 httpbin 服务的 pod。

                {"name": "0.0.0.0_15443","active_state": {"listener": {"name": "0.0.0.0_15443","address": {"socket_address": {"address": "0.0.0.0","port_value": 15443}},"filter_chains": [{"filter_chain_match": {"server_names": ["*.global"]},"filters": [{"name": "envoy.filters.network.sni_cluster"},{"name": "envoy.filters.network.tcp_cluster_rewrite","config": {"cluster_pattern": "\\.global$","cluster_replacement": ".svc.cluster.local"}},......{"name": "envoy.tcp_proxy","typed_config": {"stat_prefix": "BlackHoleCluster","cluster": "BlackHoleCluster"}}]}],"listener_filters": [{"name": "envoy.listener.tls_inspector",......}],"traffic_direction": "OUTBOUND"}}
}

其中,envoy.listener.tls_inspector 将检测 TLS 流量,并可以提取 SNI 作为 server name,进行路由决策。tcp_cluster_rewrite 将后缀以 global$ 结尾的 cluster 替换为 svc.cluster.local,进而转发到网格内部,以此实现了 TLS 层的路由。

单控制面

与多控制面网格不同,单控制面网格中的所有集群,共享一个 istio 控制面,单控制面作为流控规则的唯一下发入口,会 watch 所有 Kubernetes 集群的服务发现数据,所有集群数据面的 Envoy 都会连接单控制面,获得 xDS 信息。

「单网络单控制面」和 「多网络单控制面」的安装流程类似,简述如下。

配置各集群 CA 证书

对于「多网络」模式,跨集群通信必须经过 istio gateway,gateway 同样利用 SNI 进行路由感知,这种模式必须开启 mTLS,因此需要提前配置各集群的 CA 证书,步骤和「多控制面」流程一致,不再赘述。

「单网络」模式中的跨集群通信是 pod 与 pod 直连,没有经过 istio gateway,因此并不需要强制使用 mTLS,可以不用配置 mTLS 证书,但是如果业务上需要开启 mTLS 通信,多个集群各自的自签名证书无法互相验证,因此也需要配置自签名的 CA 证书。

主集群安装控制面

我们将控制面所在的 Kubernetes 称为主集群,其他集群称为远端集群。

我们使用 IstioOperator 进行安装,安装之前,每个集群都要确定以下 2 个重要的拓扑配置:

• 集群标识:每个集群都需要有一个唯一的集群名;• 网络标识:标识集群所属的网络,「单网络模式」中,所有集群的网络标识都相同,「多网络模式」中,某些或者所有集群的网络标识不同。

以上两个配置,会作为 pod 元数据写入到各集群的 sidecar injector 的配置中(configmap istio-sidecar-injector),然后再以环境变量的形式注入到 pod 的模板中,分别名为 ISTIO_META_CLUSTER_ID 和 ISTIO_META_NETWORK

istio 会结合这些信息,来判断 2 个 pod 是否属于同一个集群,以及是否属于同一个网络,进而配置不同的路由策略。比如在「多网络单控制面」模式下,处于同一网络的 pod 访问,将使用 pod ip 互通,而当访问另一个网络中的 pod 时,流量目的端将配置为对方网络的 gateway 地址。

远端集群安装

                apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:values:global:multiCluster:clusterName: ${REMOTE_CLUSTER_NAME}network: ${REMOTE_CLUSTER_NETWORK}remotePilotAddress: ${ISTIOD_REMOTE_EP}## 多网络模式需要以下配置,单网络模式不需要# components:#  ingressGateways:#  - name: istio-ingressgateway#    enabled: false

远端集群中仍然安装了一个完整的 istiod,似乎和主集群一样。不过如果我们仔细分析远端集群的配置,我们可以发现,远端集群其实只需要独立的 sidecar injector 和负责本集群证书的 citadel ,在 istio 1.5 之前,远端集群中的确只有这 2 个组件。不过 istio 1.5 将所有控制面组件合并为一个单体,因此目前远端集群中也安装了一个完整的 istiod。

理论上,主集群中的 istiod 也应该可以提供远端集群的 pod 注入服务和证书服务,不过这些在 istio 1.5 中还未完成,预计在后续版本中会逐步提供,届时远端集群中不再需要安装 istiod,会更加的简单。

配置多网络模式的 Gateway

如果是选择「多网络单控制面」,各集群都需要安装一个入流量网关。这包括 2 个步骤,首先需要在每个集群中安装网关对应的 deployment 和 service。然后要在控制面所在集群中安装 istio gateway CRD:

                apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:name: cluster-aware-gatewaynamespace: istio-system
spec:selector:istio: ingressgatewayservers:- port:number: 443name: tlsprotocol: TLStls:mode: AUTO_PASSTHROUGHhosts:- "*.local"

关于 mTLS 和 AUTO_PASSTHROUGH

通常来说,istio ingress gateway 需要配套指定服务的 VirtualService,用以指定 ingress 流量的后端服务。但在「多网络模式」中,该 ingress gateway 需要作为本数据面所有服务的流量入口。也就是所有服务共享单个 ingress gateway (单个 IP),这里其实是利用了 TLS 中的 SNI(Server Name Indication)[1]

传统的 ingress gateway 承载的是南北流量 (server-client),这里的 ingress gateway 属于网格内部流量,承载的是东西流量 (server-server)。设置 AUTO_PASSTHROUGH,可以允许服务无需配置 VirtualService,而直接使用 TLS 中的 SNI 值来表示 upstream,服务相关的 service/subset/port 都可以编码到 SNI 内容中。

注册远端集群服务发现

对最简单的单集群服务网格,pilot 会连接所在 kubernetes 集群的 api server,自动将该集群的服务发现数据(如 service,endpoint 等)接入控制面。对于多集群模式,pilot 需要用户主动提供,如何去连接远端集群的 api server。istio 约定方式是:用户将远端集群的访问凭证 (kube config 文件) 存于主集群的 secret 中,同时打上固定 label istio/multiCluster: "true"

一份远端集群访问凭证 secret 模板类似这样:

                apiVersion: v1
kind: Secret
metadata:name: istio-remote-secret-{{ REMOTE_CLUSTER_NAME }}namespace: istio-systemlabels:istio/multiCluster: "true"
type: Opaque
stringData:{{ REMOTE_CLUSTER_NAME }}: |-apiVersion: v1clusters:- cluster:server: {{ REMOTE_CLUSTER_API_SERVER_ADDRESS }}name: {{ REMOTE_CLUSTER_NAME }}contexts:- context:cluster: {{ REMOTE_CLUSTER_NAME }}user: {{ REMOTE_CLUSTER_USER }}name: {{ REMOTE_CLUSTER_NAME }}current-context: {{ .REMOTE_CLUSTER_CTX }}kind: Configusers:- name: {{ REMOTE_CLUSTER_USER }}user:token: {{ REMOTE_CLUSTER_TOKEN }}

secret name 并不重要,pilot 会 watch 所有包含 label istio/multiCluster: "true" 的 secret。istio 提供了生成以上 secret 的简化命令,注意生成的远端集群 secret,最终是 apply 到主集群中:

                $ istioctl x create-remote-secret --name ${REMOTE_CLUSTER_NAME} --context=${REMOTE_CLUSTER_CTX} | \kubectl apply -f - --context=${MAIN_CLUSTER_CTX}

至此「单控制面」服务网格搭建完毕。如果配置正确,主集群中的控制面将会 watch 远端集群的服务数据,pilot 会整合所有集群的服务发现数据和流控规则,以 xDS 形式下发到各集群数据面。

部署模式选择

「多控制面」模式,严格的讲每个 kubernetes 集群仍然是独立的服务网格,适合于业务界限明显的多集群,集群间服务互访不多,大部分场景下,各集群服务和流控偏向于独立治理,对于有互访需求的小部分服务,需要用户显式地进行服务连通注册。

「单控制面」模式,将多个集群联结为一个统一的服务网格,集群间同名服务自动共享服务实例。这种模式适合于业务联系紧密的多集群,甚至是业务对等的多集群。这些集群间服务互访较多,所有集群共享流控治理规则。可以实现「地域感知路由」、「异地容灾」等高级的网格应用场景。

至于选择「单网络单控制面」还是「多网络单控制面」,更多的是依赖集群间的网络连通现状。「单网络」模式要求集群与集群处于同一个网络平面,pod IP 不重叠且可以直连;如果网络拓扑不满足,那么可以选择「多网络」模式,该模式下每个集群都有一个入口网关,供其他集群访问流量进入,不过需要考虑的是业务能否接受 mTLS 带来的开销。

以上是 istio 最常见的多集群模式,istio 还可以实现其他更复杂的拓扑,比如多个远端集群,有部分属于相同网络,另一部分属于不同网络;另外控制面组件还可能以冗余的方式,分布到多个集群,这样可以有多个主集群,用以提高控制面的可用性。不过这些模式对服务网格的理解和运维能力要求更高,用户应该谨慎选型。

引用链接

[1] SNI(Server Name Indication): https://en.wikipedia.org/wiki/Server_Name_Indication

开源电子书 Istio Handbook

ServiceMesher 社区作为中国最早研究和推广 Service Mesh 技术的开源技术社区,于今年 2 月重启了开源电子书 Istio Handbook 的创作,本书侧重本书更加注重基础知识的提炼及实战经验分享,当前已有 21 人参与了编写,创作仍在进行中,欢迎更多人参与进来,参与方式及在线浏览地址为 https://www.servicemesher.com/istio-handbook

以下为已参与编写的作者名单,ServiceMesher 社区期待您的加入!

点击 阅读原文 查看更多

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/308912.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

认证授权方案之授权初识

1.前言回顾&#xff1a;认证授权方案之JwtBearer认证在上一篇中&#xff0c;我们通过JwtBearer的方式认证&#xff0c;了解在认证时&#xff0c;都是基于Claim的&#xff0c;因此我们可以通过用户令牌获取到用户的Claims&#xff0c;在授权过程中对这些Claims进行验证&#xff…

[数据结构]树、森林与二叉树之间的相互转换方法

树、二叉树与森林的相互转换 本文只给出树、森林与二叉树之间的转换方法&#xff0c;而详细的证明过程不在本文讨论范围之内。 树 → 二叉树 在所有兄弟结点之间加一连线。 对每个结点&#xff0c;除了保留与其长子的连线外&#xff0c;去掉该结点与其它孩子的连线。 二叉树 …

Blazor.Server以正确的方式集成Ids4

&#xff08;一个真正的以后端形式来集成认证中心的方案&#xff09;❤本文导读首先特别感谢张善友老师提供技术指导&#xff0c;源于上周我发了一篇文章《[Mvp.Blazor] 集成Ids4&#xff0c;实现统一授权认证》&#xff0c;我本来是想通过像vue框架那样&#xff0c;通过引oidc…

作为一个有理想的程序员,必读的书都有哪些?

很多程序员朋友问我&#xff1a;“哪本最具影响力的书&#xff0c;是每个程序员都应该读的&#xff1f;” 笔者从事软件开发15年&#xff0c;看过的计算机相关的书籍不下百本了&#xff0c;如果非要推荐的话&#xff0c;给大家精选以下10本&#xff0c;希望对大家有所帮助&…

认证授权方案之JwtBearer认证

1.前言回顾&#xff1a;认证方案之初步认识JWT在现代Web应用程序中&#xff0c;即分为前端与后端两大部分。当前前后端的趋势日益剧增&#xff0c;前端设备&#xff08;手机、平板、电脑、及其他设备&#xff09;层出不穷。因此&#xff0c;为了方便满足前端设备与后端进行通讯…

使用过滤器模式,让客户关怀中的代码更加干净整洁

一&#xff1a;实际场景介绍我们在给用户做订单催付通知的时候&#xff0c;会有这样的一种场景&#xff0c;用户在系统后台设置一组可以催付的规则&#xff0c;比如说订单金额大于xx元&#xff0c;非黑名单用户&#xff0c;来自哪个地区&#xff0c;已购买过某个商品&#xff0…

C++实现各种排序以及复杂度,稳定性分析

代码如下: #include<iostream> using namespace std;void Bubble_Sort(int *a, int n) {bool flag;int tmp 0;for (int i n - 1; i > 0; i--){flag false;for (int j 0; j < i; j){if (a[j] > a[j 1]){swap(a[j], a[j 1]);flag true;}}if (!flag) break…

Webapi管理和性能测试工具WebBenchmark

WebBenchmark是一款基于开源通讯组件Beetlex扩展的Webapi管理和性能测试工具&#xff0c;在传统工具中一般管理工具缺乏性能压测能力或有性能压测的缺少管理功能&#xff1b;WebBenchmark的设计目标是就管理和性能测试能力同时具备。接下来介绍一下工具的功能和使用&#xff1a…

Abstract Factory(抽象工厂)--对象创建模式

Abstract Factory &#xff08;抽象工厂&#xff09;–对象创建模式 一、意图 提供一个创建一系列相关或者相互依赖的接口&#xff0c;而无需指定它们具体的类。 二、动机 1.在软件系统中&#xff0c;经常面临着“一系列相互依赖的对象”的创建工 作;同时&#xff0c;由于需求…

Builder(生成器)--对象创建型模式

Builder&#xff08;生成器&#xff09;–对象创建型模式 一、意图 将一个复杂的对象构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 二、动机 1.在软件系统中&#xff0c;有时候面临着“一个复杂对象”的创建工作&#xff0c;其通常由各个部分的子对…

Gartner:缺乏技术人才将影响企业数字化转型

导语大多数公司在数字化转型的阶段对所需的技能方面都处于“盲目”状态。正文随着COVID-19响应加快了数字化转型的速度和规模&#xff0c;缺乏数字化技能可能会危害人才计划不统一的公司。甚至在冠状病毒大流行之前&#xff0c;董事会就将数字/技术中断列为2020年的头等大事&am…

DEBUG org.springframework.web.servlet.DispatcherServlet - Error rendering view [org.thymeleaf.spring

报错信息如下: 报错原因: thymeleaf有一些限制&#xff0c;使用th语言&#xff0c;内容为空就会报错 改成这样解决问题:

Factory Method(工厂方法)--对象创建型模式

Factory Method&#xff08;工厂方法&#xff09;–对象创建型模式 一、意图 定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。 二、动机 1.在软件系统中&#xff0c;经常面临着创建对象的工作;由于需求的变化…

全内存的redis用习惯了?那能突破内存限制类redis产品ssdb呢?

首先说一下背景&#xff0c;在双十一的时候&#xff0c;我们系统接受X宝的订单推送&#xff0c;原先的实现方式是使用 redis 的 List 作为推送数据的承载&#xff0c;在非大促的场景下&#xff0c;一切运行正常&#xff0c;内存占用大概3-4G&#xff0c;机器是16G内存。由于提前…

Prototype(原型)--对象创建模式

Prototype&#xff08;原型&#xff09;–对象创建模式 一、意图 用原型实例指定创建对象的种类&#xff0c;并且通过拷贝这些原型创建新的对象。 二、动机 1.在软件系统中&#xff0c;经常面临着“某些结构复杂的对象”的创建工作&#xff1b;由于需求的变化&#xff0c;这些…

认证授权方案之授权揭秘 (上篇)

一、前言回顾&#xff1a;认证授权方案之授权初识从上一节中&#xff0c;我们在对授权系统已经有了初步的认识和使用&#xff0c;可以发现&#xff0c;asp.net core为我们提供的授权策略是一个非常强大丰富且灵活的认证授权方案&#xff0c;能够满足大部分的授权场景。在Config…

Singleton(单件)--对象创建模式

Singleton&#xff08;单件&#xff09;–对象创建模式 一、意图 保证一个类仅有一个实例&#xff0c;并提供一个访问它的全局访问点。 二、动机 1.在软件系统中&#xff0c;经常有这样一些特殊的类&#xff0c;必须保证它们在系统中只存在一个实例&#xff0c;才能确保它们的…

龙芯团队 在移值 MIPS64 下的.NET Core 进度速报

写在开始前我们的主要业务基于 dotnet core 2.x 与 3.1 完成&#xff0c;目前 dotnet core 3.1 支持的 CPU 架构列表中还不包含龙芯&#xff0c;且在 gitlab issue 中表示官方当前没有对 MIPS 的支持计划。更具体操作系统与 CPU 架构列表见 [Download .NET Core 3.1](https://d…