基于云原生网关实现微服务的多版本线上灰度
1. 创建资源
1、在体验实验室页面左侧,单击创建资源,创建所需资源(本场景默认会提供一个云原生网关集群和一个ACK集群)。
2、在页面左侧导航栏中,单击云产品资源列表,查看本次实验资源相关信息。
说明 :
资源创建过程需要10分钟左右(需要创建一个K8s集群,感谢您的耐心等待~)。完成实验资源的创建后,您可以在云产品资源列表查看已创建的资源信息,例如:K8s集群ID、网关ID、IP地址、用户名和密码等。
2. ACK部署微服务
本实验中通过浏览器发起测试请求,请求访问到云原生网关的入口地址,云原生网关会根据你配置的路由策略再将请求转发到Kubernates集群上部署Demo服务的Pod,所以现在需要ACK(托管版的Kubernates集群)部署我们的Demo服务。
1. 双击打开虚拟桌面的Firefox ESR浏览器,在RAM用户登录框中单击下一步,复制云产品资源列表中子用户密码,按CTRL+V把密码粘贴到密码输区,登录子账户(后续在远程桌面里的粘贴操作均使用CTRL + V快捷键)。
2. 复制容器服务控制台地址,在FireFox浏览器打开新页签,粘贴并访问容器服务控制台。
https://cs.console.aliyun.com/#/k8s/cluster/list
3. 在集群列表页面,根据集群ID找到具体ACK集群,单击详情。
4. 进入详情页面,在集群信息页选择点击集群资源,找到安全组信息。
5. 点开安全组右侧ID连接,在打开的安全组规则页,点击手动添加填写如下优先级1、协议类型全部、端口范围-1/-1、授权对象0.0.0.0/0再保存。这里是设置安全组规则允许网关访问(因为演示直接设置了0.0.0.0/0)。
6. 切回容器服务的详情页面,在左侧栏展开工作负载,选择点击无状态Tab。
7. 复制以下yaml内容(v1版本的Demo),再点击当前页面点击使用YAML创建资源,清空模版将内容粘贴进去,点击创建。
apiVersion: apps/v1 kind: Deployment metadata: name: go-httpbin-v1 namespace: default spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: app: go-httpbin strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: labels: app: go-httpbin version: v1 spec: containers: - args: - '--version=v1' image: 'registry.cn-hangzhou.aliyuncs.com/mse-ingress/httpbin:v1' imagePullPolicy: Always name: go-httpbin
8. 确认创建成功后,再次点击无状态,即可查看到已经部署的版本v1的Demo服务(pod带有version=v1标签)。
9. 同样操作我们再复制以下yaml内容部署v2版本的Demo(pod带有version=v2标签)。
apiVersion: apps/v1 kind: Deployment metadata: name: go-httpbin-v2 namespace: default spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: app: go-httpbin strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: labels: app: go-httpbin version: v2 spec: containers: - args: - '--version=v2' image: 'registry.cn-hangzhou.aliyuncs.com/mse-ingress/httpbin:v1' imagePullPolicy: Always name: go-httpbin
10. 完成无状态资源的创建后,在左侧栏展开网络,选择点击服务,接下来我们需要创建3个服务资源。
11. 服务资源的创建类似无状态资源,我们依次复制三个yaml内容,点击使用YAML创建资源完成创建。
包含v1和v2两个版本Demo的服务go-httpbin-all:
apiVersion: v1 kind: Service metadata: name: go-httpbin-all spec: ports: - port: 80 targetPort: 8080 protocol: TCP selector: app: go-httpbin
只包含v1版本Demo的服务go-httpbin-v1:
apiVersion: v1 kind: Service metadata: name: go-httpbin-v1 spec: ports: - port: 80 targetPort: 8080 protocol: TCP selector: app: go-httpbin version: v1
只包含v2版本Demo的服务go-httpbin-v2:
apiVersion: v1 kind: Service metadata: name: go-httpbin-v2 spec: ports: - port: 80 targetPort: 8080 protocol: TCP selector: app: go-httpbin version: v2
至此,我们完成了所有需要的Demo无状态和服务资源的创建工作,本次主题使用Kubernates容器服务作为我们微服务的服务发现来源,云原生网关其实还支持Nacos注册中心等多种服务发现方式,此处时间有限暂不展开。
3. 网关订阅微服务
1. 在FireFox浏览器打开新页签,复制云原生网关控制台地址,粘贴并访问云原生网关控制台。
https://mse.console.aliyun.com/#/microgw
2. 在网关列表页,根据ID找到具体网关集群,单击管理。
3. 进入详情页,左侧栏展开服务管理,选择点击来源管理。
4. 点击创建来源,选择容器服务来源类型,在下拉列表中选择已经部署Demo服务的ACK集群,点击确定完成来源的关联。
5. 左侧栏选择点击服务列表,点击创建服务,选择容器服务来源,选择default命名空间,勾选中部署好的3个Demo服务移到右侧,最后点击确定完成服务的导入订阅。
至此,我们完成了云原生网关关联订阅后端微服务的操作,下一步开始请求验证吧。
4. 配置路由并验证
1. 左侧栏选择点击路由配置,点击创建路由。
2. 在创建路由表单中,如下填写点击下一步选择目标服务,最后点击保存并上线。
- 路由名称输入route-v1
- 关联域名选择默认的*(本次主题不涉及域名及证书配置,选择*即可)
- 匹配规则中只勾选路径(Path),选择精确匹配,填写/version(其余匹配规则暂不填写)
- 目标服务选择单服务,在下拉列表中选择go-httpbin-v1
3. 在路由配置列表页,找到刚创建的route-v1路由,确认已正常发布。
4. 路由发布成功后,我们左侧栏点击基本概览,找到网关入口部分,复制一个公网类型入口地址IP。
5. 在FireFox浏览器打开新页签,粘贴刚复制的IP地址,再后面填写/version,回车访问网关验证。
至此,我们完成了网关一个简单的路由配置,并且使用浏览器顺利访问到了v1版本的Demo。
5. 多路由条件灰度
多路由条件灰度,顾名思义此方式是通过增加一条包含更多匹配条件的路由实现流量的灰度。
假设本次需求:url中包含test=true参数的请求访问到v2版本的Demo,即http://ip/version?test=true访问到v2版本服务。
1. 左侧栏选择点击路由配置,点击创建路由。
2. 在创建路由表单中,如下填写,点击下一步选择目标服务,最后点击保存并上线。
- 路由名称输入route-test
- 关联域名选择默认的*(本次主题不涉及域名及证书配置,选择*即可)
- 匹配规则中勾选路径(Path),选择精确匹配,填写/version
- 匹配规则中勾选请求参数(Query),添加请求参数,填写test 精确匹配 true
- 目标服务选择单服务,在下拉列表中选择go-httpbin-v2
3. 路由创建成功后,同样确认发布生效。
4. 切到FireFox浏览器,在原来的地址栏继续填写?test=true,回车访问验证。
至此,我们实现了带test=true参数的请求访问到v2版本的Demo,不带参数的普通请求放到v1的Demo。
6. 多服务权重灰度
很多业务场景中我们的灰度需求并不依赖于具体请求的流量特征,只想要随机的权重将流量分配到不同的服务,用来观察迭代变更带来的稳定性变化。
假设本次需求:http://ip/version的访问流量80%转到v1版本的Demo,20%转到v2版本的Demo。
1. 左侧栏选择点击路由配置,因为切换了灰度场景,我们点击操作栏的下线route-test和route-v1避免干扰。
2. 再点击创建路由,表单中,如下填写,最后点击保存并上线。
- 路由名称输入route-multi
- 关联域名选择默认的*(本次主题不涉及域名及证书配置,选择*即可)
- 匹配规则中只勾选路径(Path),选择精确匹配,填写/version(其余匹配规则暂不填写)
- 下一步目标服务选择多服务,点击添加目标服务,在下拉列表中选择go-httpbin-v1配置80的权重,再点击添加目标服务,在下拉列表中选择go-httpbin-v2配置20的权重
3. 路由创建成功后,同确认已发布生效。
4. 切到FireFox浏览器,在地址栏填写http://你的网关入口IP/version,持续点击刷新或回车访问验证。
至此,我们会发现大部分请求返回version:v1,少部分请求返回version:v2,符合流量权重8:2的分配。
7. 单服务标签灰度
前面两种灰度方案都涉及到go-httpbin-v1和go-httpbin-v2两个K8s Service资源。但是有些部署场景只暴露了一个go-httpbin-all的情况下,我们怎么实现灰度,本章节简单演示通过标签机制实现这个需求,当然云原生网关标签机制不仅限于Kubernates服务发现机制,同时也兼容Nacos元信息的标签能力,此处篇幅有限暂不展开。
假设本次需求:在后端只暴露了一个go-httpbin-all微服务的情况下,http://ip/version的访问流量20%转到v1版本的Demo,80%转到v2版本的Demo。
1. 左侧栏展开服务管理,选择点击服务列表,列表页选择go-httpbin-all(这个服务包含有v1和v2两个版本Demo)并点击,进入服务详情页。
2. 进入详情页后,点击添加新版本,版本名称填写v1、标签名选择version、标签值选择v1,点击对号保存后同样操作添加v2版本。因为Demo服务pod资源上有version标签,所有此处服务详情可以选取到相应的标签。
3. 左侧栏选择点击路由配置,同样切换了灰度场景,我们点击操作栏的下线route-multi避免干扰。
4. 再点击创建路由,表单中,如下填写,最后点击保存并上线。
- 路由名称输入route-single
- 关联域名选择默认的*(本次主题不涉及域名及证书配置,选择*即可)
- 匹配规则中只勾选路径(Path),选择精确匹配,填写/version(其余匹配规则暂不填写)
- 下一步目标服务选择标签路由,点击添加目标服务,在下拉列表中选择go-httpbin-all版本选择v1配置20的权重,再点击添加目标服务,在下拉列表中选择go-httpbin-all版本选择v2配置80的权重
5. 路由创建成功后,同样确认发布生效。
6. 切到FireFox浏览器,在地址栏填写http://你的网关入口IP/version,持续点击刷新或回车访问验证。
至此,我们通过单服务标签机制实现灰度得到验证少部分请求返回version:v1,大部分请求返回version:v2,符合流量权重2:8的分配。
实验地址:https://developer.aliyun.com/adc/scenario/dcd7abe6f8334ec39eca415a5ddaa98d