服务网格 ASM(Service Mesh)支持与Karmada(Kubernetes Armada)配合,使您能够在多个Kubernetes集群中部署和运行云原生应用程序,而无需更改应用程序。Karmada提供了为云原生场景下的多集群应用程序管理提供即插即用的自动化,具有集中式多云管理、高可用性、故障恢复和流量调度等关键功能。本文介绍如何使用ASM与Karmada实现多集群应用管理。
背景信息
Karmada使用Kubernetes原生API定义联邦资源模板,以便轻松与现有Kubernetes采用的工具进行集成。同时,Karmada也提供了一个独立的Propagation (placement) Policy API 来定义多集群的调度要求。
支持1:N的策略映射机制。您无需每次创建联邦应用时都标明调度约束。
在使用默认策略的情况下,您可以直接与Kubernetes API交互。
集群模式
Karmada支持通过Push
和Pull
两种模式来管理成员集群。Push
和Pull
模式的主要区别在于部署资源清单时,访问成员集群的方式。
Push模式
Karmada控制平面将直接访问成员集群的kube-apiserver
,以获取集群状态并部署资源清单。
Pull模式
Karmada 控制平面不会直接访问成员集群,而是将其请求下放给名为karmada-agent
的额外组件处理。
每个karmada-agent
服务于一个集群,并承担以下职责:
将集群注册到 Karmada 中(创建
Cluster
对象)维护集群状态并向 Karmada 报告(更新
Cluster
对象的状态)监听来自 Karmada 执行空间(命名空间,格式为
karmada-es-<cluster name>
)的资源清单,并将监听到的资源部署到其所服务的集群中。
关键组件
Karmada的控制面包括以下组件:
Karmada API Server。
Karmada Controller Manager。
Karmada Scheduler。
ETCD存储了Karmada API对象,API Server是所有其他组件通讯的REST端点,Karmada Controller Manager根据您通过API服务器创建的API对象执行操作。
前提条件
在同一VPC下,已创建两个ACK集群(本示例为member1和member2)。具体操作,请参见创建ACK托管集群。
说明本示例以同一个VPC的两个集群作为示例场景。如果使用不同的VPC,则需要额外配置以使跨VPC能够在物理网络上连通。
在创建集群时,建议使用企业安全组。
已创建ASM实例(本示例为mesh1),且已在default命名空间上配置Sidecar注入策略。
已部署一个Karmada主集群实例(本示例为karmada-master),并将上述两个ACK集群作为成员集群(本示例为member1和member2)添加到Karmada主集群中。具体操作,请参见Karmada Installation。
已添加两个集群到ASM实例(mesh1),并创建Serverless入口网关。具体操作,请参见添加集群到ASM实例并创建Serverless入口网关。
步骤一:使用Karmada在多集群中部署应用
与使用ASM Serverless网关实现多集群入口中相同,本文同样使用Bookinfo示例。不同于手动将review-3和review-1、review-2分别部署到两个集群中的方式,本节演示基于karmada的Propagation Policy,只需在karmada-master集群中创建传播策略,即可实现同样的效果。
使用以下内容创建bookinfo-karmada.yaml。
执行以下命令,在karmada主集群中部署bookinfo应用。
kubectl --kubeconfig /etc/karmada/karmada-apiserver.config apply -f bookinfo-karmada.yaml
说明karmada主集群的kubeconfig文件默认保存位置为
/etc/karmada/karmada-apiserver.config
,如果您在部署主集群时选择了其他安装位置,请将--kubeconfig
后的路径替换为实际的路径。使用以下内容创建propagation.yaml。
apiVersion: policy.karmada.io/v1alpha1 kind: PropagationPolicy metadata: name: service-propagation spec: resourceSelectors: - apiVersion: v1 kind: Service name: productpage - apiVersion: v1 kind: Service name: details - apiVersion: v1 kind: Service name: reviews - apiVersion: v1 kind: Service name: ratings placement: clusterAffinity: clusterNames: - member1 - member2 --- apiVersion: policy.karmada.io/v1alpha1 kind: PropagationPolicy metadata: name: produtpage-propagation spec: resourceSelectors: - apiVersion: apps/v1 kind: Deployment name: productpage-v1 - apiVersion: v1 kind: ServiceAccount name: bookinfo-productpage placement: clusterAffinity: clusterNames: - member1 --- apiVersion: policy.karmada.io/v1alpha1 kind: PropagationPolicy metadata: name: details-propagation spec: resourceSelectors: - apiVersion: apps/v1 kind: Deployment name: details-v1 - apiVersion: v1 kind: ServiceAccount name: bookinfo-details placement: clusterAffinity: clusterNames: - member2 --- apiVersion: policy.karmada.io/v1alpha1 kind: PropagationPolicy metadata: name: reviews-propagation spec: resourceSelectors: - apiVersion: apps/v1 kind: Deployment name: reviews-v1 - apiVersion: apps/v1 kind: Deployment name: reviews-v2 - apiVersion: apps/v1 kind: Deployment name: reviews-v3 - apiVersion: v1 kind: ServiceAccount name: bookinfo-reviews placement: clusterAffinity: clusterNames: - member1 - member2 --- apiVersion: policy.karmada.io/v1alpha1 kind: PropagationPolicy metadata: name: ratings-propagation spec: resourceSelectors: - apiVersion: apps/v1 kind: Deployment name: ratings-v1 - apiVersion: v1 kind: ServiceAccount name: bookinfo-ratings placement: clusterAffinity: exclude: - member1
PropagationPolicy的
.spec.placement.clusterAffinity
表示对某一特定集群的调度限制,如果没有这个限制,任何集群都可以作为调度候选者。它有四个字段可以设置。
配置项
说明
LabelSelector
用于通过标签选择成员集群的过滤器。如果它非空且不为nil,则只会选择与此过滤器匹配的集群。
FieldSelector
用于通过字段选择成员集群。如果它非空且不为nil,仅匹配此筛选器的集群将被选择。
ClusterNames
您可以设置字段以指定所选集群的
ClusterNames
。ExcludeClusters
您可以设置字段以排除所选集群的
ClusterNames
。本示例只使用了
ClusterNames
和ExcludeClusters
两个字段,更多关于.spec.placement.clusterAffinity
字段的信息,请参见Resource Propagating。执行以下命令,部署PropagationPolicy。
kubectl --kubeconfig /etc/karmada/karmada-apiserver.config apply -f propagation.yaml
分别使用member1集群和member2集群的kubeconfig查看Deployment。
member1
kubectl --kubeconfig member1 get deployment
预期输出:
NAME READY UP-TO-DATE AVAILABLE AGE productpage-v1 1/1 1 1 12m reviews-v1 1/1 1 1 12m reviews-v2 1/1 1 1 12m reviews-v3 1/1 1 1 12m
member2
kubectl --kubeconfig member2 get deployment
预期输出:
NAME READY UP-TO-DATE AVAILABLE AGE details-v1 1/1 1 1 16m ratings-v1 1/1 1 1 16m reviews-v1 1/1 1 1 16m reviews-v2 1/1 1 1 16m reviews-v3 1/1 1 1 16m
步骤二:添加虚拟服务和网关规则
在default命名空间下,使用以下内容创建一个名为bookinfo的虚拟服务。具体操作,请参见管理虚拟服务。
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: bookinfo spec: hosts: - "*" gateways: - bookinfo-gateway http: - match: - uri: exact: /productpage - uri: prefix: /static - uri: exact: /login - uri: exact: /logout - uri: prefix: /api/v1/products route: - destination: host: productpage port: number: 9080
在default命名空间下,使用以下内容创建一个名为bookinfo-gateway的网关规则。具体操作,请参见管理网关规则。
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: bookinfo-gateway spec: selector: istio: ingressgateway # use istio default controller servers: - port: number: 80 name: http protocol: HTTP hosts: - "*"
步骤三:访问验证
获取入口网关的IP地址。具体操作,请参见获取入口网关地址。
在浏览器地址栏,输入
http://{Serverless入口网关的IP地址}/productpage
,并多次刷新页面。可以看到页面出现reviews的3个版本,且比例接近1:1:1。虽然review-v3和其他服务不在同一个集群中,也可以正常显示。