ACK One多集群网关基于MSE Ingress提供了强大的多集群南北向流量的管理,可以快速帮您实现同城应用多活容灾、流量多集群负载均衡、基于Header路由流量到指定集群等能力。本文介绍如何通过多集群网关管理多集群应用的南北流量。
前提条件
已在ACK One Fleet实例中创建Namespace,该Namespace与关联集群中部署应用的Namespace一致。
多集群网关的优势
在容器服务领域,管理集群内服务的南北向流量的常用方式是使用Ingress资源进行管理。但Ingress为单集群维度,无法独立为多个集群中的应用流量进行管理,因此,ACK One基于MSE Ingress实现地域级的Global Ingress来统一处理多集群应用的南北向流量,并提供强大的流量管理能力,帮助您快速、低成本地实现同城应用多活容灾、流量多集群负载均衡、基于Header路由流量到指定集群等能力。此外,多集群网关使用易上手的Ingress API进行管理,极大地降低了使用门槛。
使用多集群网关会产生一定的费用,关于多集群网关的计费信息,请参见普通实例计费概述。
步骤一:在ACK One Fleet实例中创建多集群网关
在ACK One Fleet示例中通过创建MseIngressConfig对象创建一个多集群网关(网关默认可用区高可用),并将关联集群添加至多集群网关。
获取ACK One Fleet实例的虚拟交换机ID并记录。
通过阿里云CLI获取
执行以下命令,获取交换机实例ID。
aliyun adcp DescribeHubClusterDetails --ClusterId <your_fleet_clusterid>
从预期输出的
VSwitches
中复制一个交换机实例ID。
通过控制台获取
登录ACK One控制台,在左侧导航栏,选择舰队 > 舰队信息。
在舰队信息页面,单击基础信息页签,在关联云资源区域,找到虚拟交换机,然后复制对应的交换机实例ID。
使用以下内容,创建gateway.yaml文件。
说明请将
${vsw-id}
替换为您上一步获取的交换机ID,${cluster1}
、${cluster2}
替换为您待添加的关联集群ID。子集群
${cluster1}
、${cluster2}
的安全组的入方向需要允许该交换机网段的IP和所有端口通过。
apiVersion: mse.alibabacloud.com/v1alpha1 kind: MseIngressConfig metadata: annotations: mse.alibabacloud.com/remote-clusters: ${cluster1},${cluster2} name: ackone-gateway-hongkong spec: common: instance: replicas: 3 spec: 2c4g network: vSwitches: - ${vsw-id} ingress: local: ingressClass: mse name: mse-ingress
执行以下命令,在Fleet实例中创建多集群网关。
kubectl apply -f gateway.yaml
执行以下命令,查看网关状态。
确认网关是否创建成功并处于监听状态。
kubectl get mseingressconfig ackone-gateway-hongkong
预期输出:
NAME STATUS AGE test Listening 3m15s
预期输出中网关状态为Listening,表明云原生网关创建成功处于运行状态,并自动监听集群中IngressClass为
mse
的Ingress资源。通过MseIngressConfig创建的多集群网关会按照Pending、Running、Listening的状态依次变化。各状态说明如下:
Pending:表明云原生网关正在创建中,需等待3分钟左右。
Running:表明云原生网关创建成功,并处于运行状态。
Listening:表明云原生网关处于运行状态,并监听集群中Ingress资源。
Failed:表明云原生网关处于非法状态,可以查看Status字段中Message来进一步明确原因。
执行以下命令,确认关联集群是否已成功添加至多集群网关。
kubectl get mseingressconfig ackone-gateway-hongkong -ojsonpath="{.status.remoteClusters}"
预期输出:
[{"clusterId":"c7fb82****"},{"clusterId":"cd3007****"}]
预期输出中已包含指定的ClusterID,并且无Failed信息,表明关联集群已成功添加至多集群网关。
步骤二:使用GitOps部署Demo应用
使用GitOps将Demo应用部署到两个关联的ACK集群中。具体操作,请参见GitOps快速入门。
创建2个GitOps Application,分别对应2个关联集群。示例:web-demo-cluster1、web-demo-cluster2。
Source
配置如下:Repository URL
设置为https://github.com/AliyunContainerService/gitops-demo.git
Revision
设置为HEAD
Path
设置为manifests/helm/web-demo
DESTINATION
分别选择2个关联集群,namespace
设置为web-demo
。Helm Values Files
中的参数名称为envName
,value
分别为cluster1
、cluster2
。
部署后的Deployment和Service的YAML文件如下。
步骤三:使用MSE Ingress管理多集群流量
通过在Ingress中指定IngressClass来使用MSE Ingress,并且使用不同的Annotation实现不同的流量管理能力。MSE Ingress不仅支持Nginx-Ingress核心和常用的Annotation,还针对Nginx-Ingress Annotation未支持的流量治理配置,推出额外的Annotation以弥补Nginx-Ingress的不足。MSE Ingress支持的Annotations请参见MSE Ingress支持的Annotation。下文以典型的多集群流量管理场景为例说明。
Ingress对象和Demo应用中Service对象的Namespace需要保持一致。
示例1:默认负载均衡到所有服务后端
在ACK One Fleet实例中创建以下Ingress对象,可以默认将流量负载均衡到所有集群的同名服务后端,所有副本均衡。路由到不同集群的流量比例等同于集群中的副本数量的比例,例如,Cluster 1和Cluster 2中副本数比例为9:1,则流量在Cluster 1和Cluster 2中的流量比也为9:1。本例使用1:1的副本数演示。拓扑如下所示:
使用以下内容,创建ingress-demo.yaml文件。
以下Ingress对象的YAML文件中,通过域名
example.com
下的/svc1
路由规则暴露后端服务service1
。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web-demo namespace: web-demo spec: ingressClassName: mse rules: - host: example.com http: paths: - path: /svc1 pathType: Exact backend: service: name: service1 port: number: 80
执行以下命令,在ACK One Fleet实例中部署Ingress。
kubectl apply -f ingress-demo.yaml
执行以下命令,获取多集群网关对外IP。
kubectl get ingress web-demo -nargocd -ojsonpath="{.status.loadBalancer}"
执行以下命令,查看流量的路由情况。
替换以下
XX.XX.XX.XX
为上一步获取的多集群网关对外IP。for i in {1..50}; do curl -H "host: example.com" XX.XX.XX.XX/svc1; sleep 1; done
预期输出:
This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster2 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is
预期输出表明,流量被路由到所有集群上。
示例2:流量仅路由到指定集群
在ACK One Fleet实例中创建以下Ingress对象,可以将流量仅路由到Cluster 1的服务后端。拓扑如下所示:
使用以下内容,创建ingress-demo-cluster-one.yaml文件。
以下Ingress对象的YAML文件中,通过添加两个Annotations
mse.ingress.kubernetes.io/service-subset
、mse.ingress.kubernetes.io/subset-labels
以实现域名example.com
下的/service1
路由规则暴露后端服务service1
。关于MSE Ingress支持的Annotations详情,请参见MSE Ingress支持的Annotation。mse.ingress.kubernetes.io/service-subset
:服务的子版本名称。建议定义为与目标集群相关且可读性强的值。mse.ingress.kubernetes.io/subset-labels
:指定目标集群的ID。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: mse.ingress.kubernetes.io/service-subset: cluster-demo-1 mse.ingress.kubernetes.io/subset-labels: | topology.istio.io/cluster ${cluster1-id} name: web-demo-cluster-one namespace: web-demo spec: ingressClassName: mse rules: - host: example.com http: paths: - path: /service1 pathType: Exact backend: service: name: service1 port: number: 80
执行以下命令,在ACK One Fleet实例中部署Ingress。
kubectl apply -f ingress-demo-cluster-one.yaml
执行以下命令,获取多集群网关对外IP。
kubectl get ingress web-demo -nargocd -ojsonpath="{.status.loadBalancer}"
执行以下命令,查看流量的路由情况。
替换以下
XX.XX.XX.XX
为上一步获取的多集群网关对外IP。for i in {1..50}; do curl -H "host: example.com" XX.XX.XX.XX/service1; sleep 1; done
预期输出:
This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! ...
预期输出表明,固定的流量被路由到Cluster 1上。
示例3:根据Header将流量路由到指定集群
如需根据自定义Header将流量路由到指定集群的服务后端,您可以在ACK One Fleet实例中创建Example 1
或者Example 2
Ingress对象,然后再创建以下Ingress对象(此Ingress对象无法单独生效)。拓扑如下所示:
基于Header方式进行流量调度时,您需要在Ingress的注解上配置Canary注解和Header匹配策略,同时需确保已存在另一个Ingress中不包含Canary注解且存在相同的Host + Path访问另一个集群中的服务。即Header方式的Ingress不能单独生效,需搭配使用另一个不指定Header的Ingress指向另一个集群中的服务。
使用以下内容,创建ingress-demo-header.yaml文件。
以下Ingress对象的YAML文件中,通过域名
example.com
下的/service1
路由规则暴露后端服务service1
。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: mse.ingress.kubernetes.io/service-subset: cluster-demo-2 mse.ingress.kubernetes.io/subset-labels: | topology.istio.io/cluster c15d48ca9d1fd43f9bbb89c56a474843c nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-by-header: "stage" nginx.ingress.kubernetes.io/canary-by-header-value: "gray" name: web-demo-cluster-second namespace: web-demo spec: ingressClassName: mse rules: - host: example.com http: paths: - path: /service1 pathType: Exact backend: service: name: service1 port: number: 80
执行以下命令,在ACK One Fleet实例中部署Ingress。
kubectl apply -f ingress-demo-header.yaml
执行以下命令,获取多集群网关对外IP。
kubectl get ingress web-demo -nargocd -ojsonpath="{.status.loadBalancer}"
执行以下命令,查看流量的路由情况。
替换以下
XX.XX.XX.XX
为上一步获取的多集群网关对外IP。for i in {1..50}; do curl -H "host: example.com" -H "stage: gray" xx.xx.xx.xx/service1; sleep 1; done
预期输出:
This is env cluster2 ! Config file is This is env cluster2 ! Config file is This is env cluster2 ! Config file is This is env cluster2 ! Config file is This is env cluster2 ! Config file is ...
预期输出表明,流量根据Header
stage: gray
被路由到Cluster 2上。
示例4:多集群应用跨集群容灾
多集群网关具备多集群应用跨集群容灾的能力,无需额外配置。例如,上述配置的多集群网关管理了两个关联的ACK集群的流量,如果其中一个集群的服务异常或被删除,流量会自动转到另一个可用集群。上述示例1、示例2、示例3均一样,即使已经指定路由到某个集群,但当此集群上的应用异常后,也会被容灾到其他集群上。
以下以示例3为例说明,在正常情况下,添加Header stage: gray
,您可以访问到Cluster 2的后端,当Cluster 2的Deployment副本数被缩为0时,请求会切换至Cluster 1的后端。拓扑如下所示:
执行以下命令,获取多集群网关对外IP。
kubectl get ingress web-demo -nargocd -ojsonpath="{.status.loadBalancer}"
执行以下命令,查看流量的路由情况。
替换以下
XX.XX.XX.XX
为上一步获取的多集群网关对外IP。for i in {1..50}; do curl -H "host: example.com" -H "stage: gray" XX.XX.XX.XX/service1; sleep 1; done
预期输出:
This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is ...
预期输出表明,流量被自动容灾到Cluster 1上。
示例5:根据权重进行流量路由
在示例1中,您可以通过调节集群中副本数的比例,实现按比例路由流量到不同的集群。本示例介绍如何在Annotations中配置权重来按比例路由流量到不同的集群,也可以使用该方式进行灰度发布。您可以在ACK One Fleet实例中创建以下2个Ingress对象实现该能力,拓扑如下所示:
基于权重方式进行流量调度时,您需要在Ingress的注解上配置Canary注解和Header匹配策略,同时需保证已存在另一个Ingress不含有Canary注解且存在相同的Host + Path访问另一个集群中的服务。即权重方式的Ingress不能单独生效,需搭配使用另一个不指定权重的Ingress指向另一个集群中的服务。
使用以下内容,创建ingress-weight.yaml文件。
以下Ingress对象的YAML文件中,替换YAML中的
${cluster1-id}
为目标集群ID。通过添加Annotations以实现域名example.com
下的/svc1-w
路由规则暴露后端服务service1
。mse.ingress.kubernetes.io/service-subset
:服务的子版本名称。建议定义为与目标集群相关且可读性强的值。mse.ingress.kubernetes.io/subset-labels
:目标ACK集群的ID。nginx.ingress.kubernetes.io/canary
:设置为"true"
,表示开启灰度发布能力。nginx.ingress.kubernetes.io/canary-weight
:请求到该集群的流量百分比(值为0~100的整数)。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: mse.ingress.kubernetes.io/service-subset: cluster-demo-1 mse.ingress.kubernetes.io/subset-labels: | topology.istio.io/cluster ${cluster1-id} name: web-demo-weight namespace: web-demo spec: ingressClassName: mse rules: - host: example.com http: paths: - path: /svc1-w pathType: Exact backend: service: name: service1 port: number: 80 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: mse.ingress.kubernetes.io/service-subset: cluster-demo-2 mse.ingress.kubernetes.io/subset-labels: | topology.istio.io/cluster ${cluster2-id} nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "10" name: web-demo-weight-canary namespace: web-demo spec: ingressClassName: mse rules: - host: example.com http: paths: - path: /svc1-w pathType: Exact backend: service: name: service1 port: number: 80
执行以下命令,在ACK One Fleet实例中部署Ingress。
kubectl apply -f ingress-weight.yaml -nargocd
执行以下命令,获取多集群网关对外IP。
kubectl get ingress web-demo -nargocd -ojsonpath="{.status.loadBalancer}"
执行以下命令,查看流量的路由情况。
替换以下
XX.XX.XX.XX
为上一步获取的多集群网关对外IP。for i in {1..50}; do curl -H "host: example.com" XX.XX.XX.XX/svc1-w; sleep 1; done
预期输出:
This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster2 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster1 ! Config file is This is env cluster2 ! Config file is This is env cluster1 ! Config file is ...
预期输出表明,根据权重进行流量路由,90%的流量被路由到Cluster 1上,10%的流量被路由到Cluster 2上。
- 本页导读 (1)