云原生网关默认采用多可用区部署,提供了地域级的、跨可用区的全局流量管理能力。在同城多活的场景下,能够确保对跨可用区的多个业务集群的请求实现高效负载均衡分配,在单个可用区内的业务集群发生故障时,可在1秒内完成故障节点的自动摘除从而实现故障转移,有效的保障服务连续性和高可用性。
容灾概述
目前云上容灾主要分为以下三类:
同城跨AZ容灾
同城容灾包含多活容灾和主备容灾,同城中心之间物理距离较近,网络延迟低,可防范AZ级别性质的灾难损害,例如火灾、断网或断电等。
跨地域多活容灾
跨地域多活容灾对于网络延迟相对较高,但可以防范地域性质的灾难损害,例如地震、水灾等。
两地三中心
两地三中心将同城双中心和跨地域灾备结合起来,兼具两者的优点,适用于应用与数据连续性和可用性要求高的场景。
从实际情况考虑,同城容灾相比于跨地域容灾,在数据容灾方面更容易实现,所以同城容灾仍然具有非常重要的意义。
功能优势
基于云原生网关的容灾方案与基于DNS流量分发的容灾方案对比优势如下:
云原生网关默认多可用区部署,提供地域级的全局流量管理能力。
基于DNS流量分发的容灾方案需要手动调整分发到各个集群的流量比例,而基于云原生网关的容灾方案则会根据工作负载总数量动态的调整分发到各集群的流量比例,针对于无法保证对等部署的场景下,可有效防止部署资源较少的集群的后端服务崩溃。
基于多集群网关的容灾支持七层路由转发能力,而基于DNS流量分发的容灾不支持七层路由转发。
基于DNS流量分发的容灾方案在IP切换时,通常会有客户端缓存而造成服务短暂不可用,而基于云原生网关的容灾方案则可以平滑地将流量Fallback到另一个集群的服务后端。
方案架构
基于云原生网关同地域跨可用区的全局流量管理能力,当单可用区(可用区I)发生故障后,可实现100%流量自动被路由到其它可用区(可用区J)。
说明 两个可用区各一个SLB,可有效避免SLB单点故障,当单可用区SLB发生故障后,可通过DNS切流。
一个云原生网关,多可用区部署,实现跨可用区、多业务集群的全局流量管理能力,可有效保证多集群的请求负载均衡,可实现单可用区故障后秒级、自动切流。
每个集群对应一个Nacos,可有效保证微服务调用在可用区内闭环,单可用区发生故障后触发网关自动切流后可保证微服务调用流量无损。
准备工作
创建两个Nacos引擎。
在两个不同可用区各创建一个K8s集群。具体操作,请参见创建Kubernetes托管版集群。
如果您要实现同城多活的其中一个K8s集群是在自建的IDC或其他云平台,您可以通过ACK One的注册集群快速入门将云下的K8s集群接入云端。在本文的可用区I的K8s集群,即是通过注册集群完成从自建到云上的接入。
展开查看自建K8s集群接入云上的操作步骤
通过kubeadm自建一个K8s集群。
查看集群网络模式。集群的网络插件使用的是Calico,网络模式是Calico IPIP模式。
自建集群接入注册集群。具体操作,请参见将目标集群接入注册集群中。
由于自建的K8s集群使用的网络模式是Calico IPIP模式,云上的资源如想访问自建集群内的Pod需要经过Node做路由转发,因此在接入完成后,还需要在VPC的路由表内配置一下Pod的网段到Node的路由条目。
说明 请根据实际情况打通网络。具体操作,请参见混合网络概述。
创建云原生网关。
说明 创建云原生网关时选择多可用区部署,请确保新创建的云原生网关和您的集群在同一VPC下。
步骤一:在集群中部署Demo应用
登录容器服务管理控制台。分别在不同可用区下的ACK集群中使用如下YAML部署Demo应用。其中nacos_address
和env
需要替换为您的实际环境参数。
可用区I的部署YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: duohuo-provider
labels:
app: duohuo-provider
spec:
replicas: 2
selector:
matchLabels:
app: duohuo-provider
template:
metadata:
labels:
app: duohuo-provider
spec:
containers:
- env:
- name: nacos_address #注册中心的endpoint
value: 'mse-a8473b30-nacos-ans.mse.aliyuncs.com:8848'
- name: env #所在可用区标识,izone,jzone
value: izone
image: 'registry.cn-hangzhou.aliyuncs.com/jinfengdocker/mse-duohuo-provider:v1'
imagePullPolicy: Always
name: duohuo-provider
ports:
- containerPort: 8080
protocol: TCP
resources:
limits:
cpu: '2'
memory: 1Gi
requests:
cpu: '0.5'
memory: 0.1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: duohuo-consumer
labels:
app: duohuo-consumer
spec:
replicas: 2
selector:
matchLabels:
app: duohuo-consumer
template:
metadata:
labels:
app: duohuo-consumer
spec:
containers:
- env:
- name: nacos_address #注册中心的endpoint
value: 'mse-a8473b30-nacos-ans.mse.aliyuncs.com:8848'
- name: env #所在可用区标识,izone,jzone
value: izone
image: 'registry.cn-hangzhou.aliyuncs.com/jinfengdocker/mse-duohuo-consumer:v1'
imagePullPolicy: Always
name: duohuo-consumer
ports:
- containerPort: 8080
protocol: TCP
resources:
limits:
cpu: '2'
memory: 1Gi
requests:
cpu: '0.5'
memory: 0.1Gi
---
apiVersion: v1
kind: Service
metadata:
name: duohuo-consumer-service
spec:
ports:
- name: http
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: duohuo-consumer
sessionAffinity: None
type: ClusterIP
可用区J的部署YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: duohuo-provider
labels:
app: duohuo-provider
spec:
replicas: 2
selector:
matchLabels:
app: duohuo-provider
template:
metadata:
labels:
app: duohuo-provider
spec:
containers:
- env:
- name: nacos_address # 注册中心的Endpoint
value: 'mse-7a4cd080-nacos-ans.mse.aliyuncs.com:8848'
- name: env # 所在可用区标识,izone,jzone
value: jzone
image: 'registry.cn-hangzhou.aliyuncs.com/jinfengdocker/mse-duohuo-provider:v1'
imagePullPolicy: Always
name: duohuo-provider
ports:
- containerPort: 8080
protocol: TCP
resources:
limits:
cpu: '2'
memory: 1Gi
requests:
cpu: '0.5'
memory: 0.1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: duohuo-consumer
labels:
app: duohuo-consumer
spec:
replicas: 2
selector:
matchLabels:
app: duohuo-consumer
template:
metadata:
labels:
app: duohuo-consumer
spec:
containers:
- env:
- name: nacos_address # 注册中心的Endpoint
value: 'mse-7a4cd080-nacos-ans.mse.aliyuncs.com:8848'
- name: env # 所在可用区标识,izone,jzone
value: jzone
image: 'registry.cn-hangzhou.aliyuncs.com/jinfengdocker/mse-duohuo-consumer:v1'
imagePullPolicy: Always
name: duohuo-consumer
ports:
- containerPort: 8080
protocol: TCP
resources:
limits:
cpu: '2'
memory: 1Gi
requests:
cpu: '0.5'
memory: 0.1Gi
---
apiVersion: v1
kind: Service
metadata:
name: duohuo-consumer-service
spec:
ports:
- name: http
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: duohuo-consumer
sessionAffinity: None
type: ClusterIP
部署成功后,您可以在对应的ACK集群中看到两个工作负载和一个服务。
步骤二:创建来源
在云原生网关中创建两个服务来源,关联您在两个可用区的容器集群。具体操作,请参见新建服务来源。
步骤三:创建服务
在云原生网关中创建服务。具体操作,请参见添加服务。
云原生网关支持跨集群的服务统一管理,创建的服务会自动将两个K8s集群中相同命名空间下的同名服务进行合并。
步骤四:云原生网关创建路由
在云原生网关中创建路由,设置域名和匹配规则。选择目标服务后保存并上线路由。具体操作,请参见新建路由规则。
步骤五:切流效果验证
云原生网关可根据后端集群的工作负载数及健康状态动态的调整流量。本文分别演示两个集群工作负载数量对等部署、非对等部署、机房故障场景下云原生网关自动切流效果。
使用如下Shell脚本,循环对网关发起请求。
#!/bin/bash
for (( i = 1; i < 1000000000; i++ )); do
curl http://114.55.XXX.XXX/helloDuohuo # IP需要替换成您网关的公网IP。
sleep 1
echo
done
两个集群工作负载数量对等部署
两个集群中工作负载的副本保持一致。
使用Shell脚本发起请求,输出结果如下表明流量被负载均衡到可用区I和可用区J,两个可用区的集群各承担了50%的流量。
两个集群工作负载数量非对等部署
可用区I的集群副本数量缩容为1。
使用Shell脚本发起请求,输出结果如下表明可用区J的集群承担了90%的流量,可用区I的集群承担了10%的流量。
机房故障场景下自动切流
可用区I的集群副本数量缩容为0。使用Shell脚本发起请求,输出结果如下表明100%的流量自动切换到了可用区J。
PTS压测
通过PTS压测,进一步观察可用区I故障后的自动切流时效性及切流过程中的流量损失。
PTS新建压测场景:
压测的RPS配置为100后,单击保存去压测。
压测执行到1分钟以后,手动把可用区I集群中的所有工作负载删除掉,模拟集群故障,观察流量损失。
可以看到MSE在I可用区的集群挂掉后,可实现秒级切流,切流过程中仅有不到1%的流量损失。