服务网格 ASM(Service Mesh)支持多主控制面架构,即由多个服务网格实例共同管理多个Kubernetes集群的架构模式。多主控制面架构相比单个ASM实例添加多个Kubernetes集群,在配置隔离、配置下发延迟等方面有明显优势,更适用于搭建业务对等部署的多集群容灾方案。本文将介绍如何基于两个ACK集群搭建包含两个ASM实例的多主控制面架构。
背景信息
多主控制面架构是一种使用服务网格管理多个Kubernetes集群的架构模式。在这种架构中,多个服务网格实例分别管理各自的Kubernetes集群的数据面组件,并为集群中的网格代理分发配置。同时,这些实例依靠共享的信任根证书,实现跨集群的服务发现和通信。
相比直接在一个ASM实例中添加多个集群,多主控制面架构有着以下优势:
拥有更好的配置推送延迟表现:多个集群通常跨地域、可用区或VPC部署。在这种情况下,使用多个ASM实例分别连接到就近的Kubernetes集群中的网格代理拥有更好的配置推送性能表现。
配置和环境隔离性更好:多个集群分别由多个ASM实例管理。每个ASM实例可以部署不同的控制面资源,从而实现对配置和版本的灰度或隔离。同时,在升级ASM实例时可以多个控制面分批进行升级,从而更好地确保线上环境的可用性。
稳定性表现更佳:遇到可用区、地域不可用或网络问题等极端情况时,一个控制面连接所有集群的方式,可能会出现集群因为无法连接到控制面而无法同步配置或启动的问题;而在多主控制面架构下,正常地域或可用区中的网格代理仍可正常连接到控制面,不影响服务网格配置的下发与网格代理的正常启动。
构建多主控制面架构,需要创建复用相同网格根证书的多个ASM实例。网格根证书是控制面为网格代理签发身份验证所用证书时使用的根证书。通过复用相同的根证书,连接到每个ASM实例的网格代理之间可以实现相互信任以及使用mTLS协议相互访问。
前提条件
已创建两个Kubernetes集群,分别命名为cluster-1和cluster-2,都设置为开启使用EIP暴露API Server。具体操作,请参见创建ACK托管集群。
步骤一:创建两个复用根证书的ASM实例,并各添加一个集群
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页单击创建新网格,具体创建时使用的关键配置项见下表。
配置项
示例值
网格名称
mesh-1。
地域
选择和cluster-1集群相同的地域。
Istio版本
选择v1.22.6.71-g7d67a80b-aliyun或以上版本。
Kubernetes集群
选择cluster-1,选择后,专有网络、交换机配置项将会自动填充。
具体操作以及其他配置项的说明,请参见创建ASM实例。创建后,稍等2-3分钟直至mesh-1实例的状态转变为运行中。
再次在网格管理页单击创建新网格,具体创建时使用的关键配置项见下表。
配置项
示例值
网格名称
mesh-2。
地域
选择和cluster-2集群相同的地域。
Istio版本
选择v1.22.6.71-g7d67a80b-aliyun或以上版本。
Kubernetes集群
选择cluster-2,选择后,专有网络、交换机配置项将会自动填充。
网格根证书
单击展开高级选项,选中复用已有ASM实例根证书,在下方下拉框中选择mesh-1。
具体操作以及其他配置项的说明与mesh-1相同。创建后,稍等2-3分钟直至mesh-2实例的状态转变为运行中。
步骤二:以仅服务发现模式将集群添加到ASM实例
步骤一执行后,mesh-1实例将会添加并管理cluster-1集群,mesh-2实例将会添加并管理cluster-2集群。此外,两个ASM实例还需要以仅服务发现模式添加对方所管理的集群,以发现对方集群中的服务以及服务端点。
在mesh-1实例中以仅服务发现模式添加cluster-2集群。
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例名称mesh-1,然后在左侧导航栏,选择集群与工作负载管理 > Kubernetes集群,然后单击添加。
在添加Kubernetes集群页面,找到cluster-2集群,然后单击集群操作列中的添加(仅服务发现)。在弹出的对话框中单击确定。添加集群后,在网格实例 > 基本信息页面,可以看到ASM实例的状态变为更新中。数秒之后(时长与添加的集群数量有关),单击页面右上方的,ASM实例的状态会变为运行中。在Kubernetes集群页面,可以看到已添加集群的信息。
在mesh-2实例中以仅服务发现模式添加cluster-1集群。
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例名称mesh-2,然后在左侧导航栏,选择集群与工作负载管理 > Kubernetes集群,然后单击添加。
在添加Kubernetes集群页面,找到cluster-1集群,然后单击集群操作列中的添加(仅服务发现)。在弹出的对话框中单击确定。添加集群后,在网格实例 > 基本信息页面,可以看到ASM实例的状态变为更新中。数秒之后(时长与添加的集群数量有关),单击页面右上方的,ASM实例的状态会变为运行中。在Kubernetes集群页面,可以看到已添加集群的信息。
当以仅服务发现模式添加Kubernetes集群时,ASM实例仅会对该集群内的服务以及服务端点进行服务发现,但不会向该集群下发任何数据面组件。同时,针对ASM实例所做的任何配置修改无法作用于以仅服务发现模式添加的Kubernetes集群。
仅服务发现模式仅适用于构建多主控制面架构的场景。如果您希望ASM实例直接管理您的Kubernetes集群,请直接将集群添加到ASM实例。具体操作,请参见添加集群到ASM实例。
步骤三(可选):在两个ASM实例中进行多集群网络配置
如果cluster-1、cluster-2两个Kubernetes集群分别位于不同的网络(即两个集群存在跨VPC、跨地域等情况),且集群间网络没有通过CEN打通,则需要在两个ASM实例中进行多集群网络配置,并为cluster-1、cluster-2分别部署跨集群网格代理,以保证集群间的相互访问可达。关于跨集群网格代理的更多信息,请参见使用ASM跨集群网格代理实现多集群跨网络互通。
在mesh-1实例中配置cluster-1和cluster-2集群的网络配置。
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例mesh-1名称,然后在左侧导航栏,选择集群与工作负载管理 > Kubernetes集群。
单击多集群网络配置按钮,按照以下方式配置多集群网络。
为cluster-1集群指定所属逻辑网络为network1,并为cluster-1集群启用跨集群网格代理访问。
为cluster-2集群指定所属逻辑网络为network2。
在mesh-2实例中配置cluster-1和cluster-2集群的网络配置。
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例mesh-2名称,然后在左侧导航栏,选择集群与工作负载管理 > Kubernetes集群。
单击多集群网络配置按钮,按照以下方式配置多集群网络。
为cluster-1集群指定所属逻辑网络为network1。
为cluster-2集群指定所属逻辑网络为network2,并为cluster-2集群启用跨集群网格代理访问。
步骤四:在两个ASM实例中部署示例应用
如下图所示,本节将在cluster-1部署sleep服务和helloworld服务的v1版本,cluster-2部署helloworld服务的v2版本。两个集群中的服务可以通过ASM跨集群网络代理实现相互访问。
在mesh-1实例和mesh-2实例中为default命名空间开启自动注入。具体操作,参考管理全局命名空间。
使用以下内容,创建sleep应用和helloworld应用的v1版本。
在cluster-1中部署此YAML。具体操作,请参见通过编排模板创建Linux应用。
使用以下内容,创建helloworld应用的v2版本。
在cluster-2中部署此YAML。具体操作,请参见通过编排模板创建Linux应用。
步骤五:验证多主控制面架构下部署的应用互相访问
使用cluster-1集群的kubeconfig,执行以下命令。
kubectl exec -it deploy/sleep -- sh -c 'for i in $(seq 1 10); do curl helloworld:5000/hello; done;'
预期输出:
Hello version: v1, instance: helloworld-v1-7b888xxxxx-xxxxx Hello version: v1, instance: helloworld-v1-7b888xxxxx-xxxxx Hello version: v2, instance: helloworld-v2-7b949xxxxx-xxxxx Hello version: v2, instance: helloworld-v2-7b949xxxxx-xxxxx Hello version: v1, instance: helloworld-v1-7b888xxxxx-xxxxx Hello version: v2, instance: helloworld-v2-7b949xxxxx-xxxxx Hello version: v2, instance: helloworld-v2-7b949xxxxx-xxxxx Hello version: v2, instance: helloworld-v2-7b949xxxxx-xxxxx Hello version: v2, instance: helloworld-v2-7b949xxxxx-xxxxx Hello version: v1, instance: helloworld-v1-7b888xxxxx-xxxxx
可以看到helloworld的版本在v1和v2之间来回切换。
执行以下命令,将cluster-1集群中的sleep应用的Pod副本数量改为0。
kubectl scale deploy sleep --replicas=0
使用以下内容创建单独的sleep应用。
apiVersion: v1 kind: ServiceAccount metadata: name: sleep --- apiVersion: v1 kind: Service metadata: name: sleep labels: app: sleep service: sleep spec: ports: - port: 80 name: http selector: app: sleep --- apiVersion: apps/v1 kind: Deployment metadata: name: sleep spec: replicas: 1 selector: matchLabels: app: sleep template: metadata: labels: app: sleep spec: terminationGracePeriodSeconds: 0 serviceAccountName: sleep containers: - name: sleep image: registry.cn-hangzhou.aliyuncs.com/acs/curl:8.1.2 command: ["/bin/sleep", "infinity"] imagePullPolicy: IfNotPresent
在cluster-2集群中部署以上内容。具体操作,请参见通过编排模板创建Linux应用。
使用cluster-2集群的kubeconfig再次执行以下命令。
kubectl exec -it deploy/sleep -- sh -c 'for i in $(seq 1 10); do curl helloworld:5000/hello; done;'
预期输出:
Hello version: v1, instance: helloworld-v1-7b888xxxxx-xxxxx Hello version: v2, instance: helloworld-v2-7b949xxxxx-xxxxx Hello version: v2, instance: helloworld-v2-7b949xxxxx-xxxxx Hello version: v2, instance: helloworld-v2-7b949xxxxx-xxxxx Hello version: v2, instance: helloworld-v2-7b949xxxxx-xxxxx Hello version: v1, instance: helloworld-v1-7b888xxxxx-xxxxx Hello version: v2, instance: helloworld-v2-7b949xxxxx-xxxxx Hello version: v1, instance: helloworld-v1-7b888xxxxx-xxxxx Hello version: v2, instance: helloworld-v2-7b949xxxxx-xxxxx Hello version: v2, instance: helloworld-v2-7b949xxxxx-xxxxx
可以看到helloworld的版本仍然在v1和v2之间来回切换。