前置准备
ArgoCD部署
准备域名及SSL证书
配置域名解析
在/etc/hosts里增加配置,将argo-devops.hua-ri.cn解析到ingress的外部IP:
1 | x.x.x.x argo-devops.hua-ri.cn |
创建tls密钥
需要执行secret名,记得是因为helm模板里没有支持指定secret名:
1 | kubectl create namespace argo |
然后,运行以下命令检查秘密是否已创建:
1 | kubectl get secrets -n argo |
部署argocd
获取ingressClassName
1 | kubectl get ingressclass |
期望结果:
1 | NAME CONTROLLER PARAMETERS AGE |
customs.yaml
1 | ## Globally shared configuration |
helm部署argocd
使用Helm一键部署Argo-CD服务。
1 | helm upgrade --install argocd argo/argo-cd --version 7.3.5 \ |
helm卸载argocd
简单卸载:
1 | helm uninstall argocd --namespace argo |
完全卸载:
1 | helm uninstall argocd --namespace argo |
访问Argo-CD Server服务
因为已经配置了域名解析,所以直接通过域名访问即可
获取Argo-CD Server的密码
通过下面的命令可以查看初始密码:
1 | kubectl get secret -n argo argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d |
argocd命令行登录Argo-CD服务
通过argocd命令行登录Argo-CD服务。
1 | argocd login argo-devops.hua-ri.cn |
Argo Rollout部署
1 | kubectl create namespace argo-rollouts |
应用测试仓库
可以构建一个测试用的仓库,具体内容参考下面的文件举例
main.go
1 | package main |
主要看这部分:
1 | r.GET("/api/check", func(c *gin.Context) { |
这个接口会在请求时返回{“message”: “v1”}。我们需要基于这个特性打两个镜像,v1版本返回{“message”: “v1”},v2版本返回{“message”: “v2”}.
Dockerfile
1 | # builder |
Makefile
1 | # Go parameters |
分别修改IMAGE_TAG值为v1和v2并打两个镜像。
打测试镜像
IMAGE_TAG=v1
Makefile文件中IMAGE_TAG值设置为v1,main.go中亦是如此。
Makefile:
1 | # Go parameters |
main.go:
1 | r.GET("/api/check", func(c *gin.Context) { |
IMAGE_TAG=v2
Makefile文件中IMAGE_TAG值设置为v2,main.go中亦是如此。
Makefile:
1 | # Go parameters |
main.go:
1 | r.GET("/api/check", func(c *gin.Context) { |
yaml测试仓库
同样的,也可以构建一个测试用的仓库,具体内容参考下面的文件举例
values.yaml
1 | ingress: |
Helm chart的顶级开关
/charts/ingress/values.yaml
1 | enabled: false |
在这里通过imageTag控制要部署的镜像版本,我们在测试argo rollout时,就是反复通过修改该字段实现的。
1 | imageTag: v2 |
/charts/ingress/Chart.yaml
1 | apiVersion: v2 |
/charts/ingress/.helmignore
1 | Patterns to ignore when building packages. |
这里和.gitignore功能差不多,在本文的影响可忽略。
/charts/ingress/templates/ingress.yaml
1 | {{- if .Values.enabled }} |
给稳定 Service 暴露外部 7 层入口。
- ingressClassName: ack-nginx # 阿里云 ACK 托管 nginx ingress
- host / path # 访问域名 bkce7-dev.hua-ri.cn/
- backend port 必须等于 Service 的 port 字段(9999)
/charts/ingress/templates/rollout.yaml
1 | {{- if .Values.enabled }} |
Argo Rollouts CRD 的核心资源,功能等价于 Deployment + 渐进式发布策略。
重要字段说明:
- replicas: 5 # 期望副本数(helm values 里的 replicaCount 被覆盖)
- strategy.canary # 使用金丝雀发布
- canaryService / stableService # 对应上面两个 Service
- trafficRouting.nginx # 用 nginx-ingress 做流量拆分
stableIngress: rollouts-demo-stable # 必须指向一个已经存在的 Ingress
additionalIngressAnnotations # 灰度规则:带 X-Canary: iwantsit 的请求去 canary - steps # 分阶段
- setCanaryScale(replicas:1) # 先扩 1 个新版本 Pod
- pause{} # 人工卡点(Argo CLI 或 UI 点 promote)
- setWeight(20)… # 后续按 20→40→60% 权重逐渐切换
- image 引用方式
image: {{ .Values.image}}:{{ .Values.imageTag | default .Chart.AppVersion }}
如果 imageTag 为空,tag 等于 1.16.0
/charts/ingress/templates/service.yaml
1 | {{- if .Values.enabled }} |
- 通过顶级开关决定是否开启渲染。
- 生成两个 ClusterIP Service
- rollouts-demo-stable # 稳定版本(金丝雀结束后的流量终点)
- rollouts-demo-canary # 金丝雀版本(只接收按权重或 header 分流的流量)
关键字段:
- targetPort: 8080 必须与容器里 containerPort: 8080 一致
- selector: app: argocd-demo 必须跟 rollout.yaml 里的 label 匹配,否则 endpoint 为空
详细分析rollout.yaml
下面把 rollout.yaml 拆成 4 个维度逐字段展开:
- 最外层元数据 & 选择器
- Pod 模板(template)
- 金丝雀策略(strategy.canary)
- 灰度步骤(steps)与常见扩展
最外层元数据 & 选择器
1 | apiVersion: argoproj.io/v1alpha1 |
Pod 模板(template)
这一块与 Deployment 的 spec.template 100 % 相同,字段不再赘述,只提示与 Rollout 相关的注意点:
- labels: app: argocd-demo 必须与 selector 完全一致,否则 Argo 会报 selector mismatch。
- 容器端口 8080 要与 Service 的 targetPort 对齐。
- image 写法:
1
image: {{ .Values.image }}:{{ .Values.imageTag | default .Chart.AppVersion }}
如果 .Values.imageTag 为空,则使用 Chart.AppVersion 作为 tag(示例中是 1.16.0)。
金丝雀策略(strategy.canary)
1 | strategy: |
字段解释:
- canaryService / stableService
这两个 Service 的 selector 在发布过程中会被 Argo 动态修改:- stableService → 旧版本 Pod
- canaryService → 新版本 Pod
- trafficRouting 支持多种实现
- nginx(示例)
- istio / smi / alb / traefik / apisix …
选了 nginx 就必须提供 stableIngress,Argo 会克隆该 Ingress 生成 rollouts-demo-stable-canary 并添加 canary 注解。
- additionalIngressAnnotations
只对新生成的 canary-ingress 生效,用来实现“按 header 强制走灰度”或“按 cookie 灰度”等高级策略。
灰度步骤(steps)
1 | steps: |
字段扩展
setCanaryScale 与 setWeight 可同时出现,互不冲突:
- setCanaryScale 控制 Pod 数量
- setWeight 控制 流量比例
pause 支持自动超时
1
2- pause:
duration: 5m # 5 分钟后自动 promote支持 analysis / experiment 步骤
1
2
3
4
5
6- analysis:
templates:
- templateName: success-rate
args:
- name: service-name
value: rollouts-demo-canary
流量导向图
Argo Rollout测试
前置准备
使用准备好的yaml仓库,分别创建Repositories和Application
原始部署的镜像版本是V2:
变更镜像版本为v1
将/charts/ingress/values.yaml内的imageTag由v2,变更为v1,并推送到远端:
如果此时通过argoCD查看,会发现会新建一个rs,并且rs拉起了v1版本的pod。
查看此时的流量分布情况:
灰度步骤一:只起一个新版本Pod,并且仅可以通过携带X-Canary头请求
在灰度步骤一时,我们仅起了一个新版本Pod,并且没有设置流量,但是在ArgoCD的网络视图里,
新旧两个ingress->两个对应svc->对应Pod副本都是存在流量的。
通过脚本进行测试:不带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check ; done |
批量请求结果:
1 | {"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"} |
发现所有请求的结果,都是旧版本的v2:{“message”:”v2”}
通过脚本进行测试:带X-Canary:
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check -H 'X-Canary: iwantsit' ; done |
批量请求结果:
1 | {"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"} |
发现所有请求的结果,都是新版本的v1:{“message”:”v1”}
通过脚本进行测试:带错误X-Canary:
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check -H 'X-Canary: huari' ; done |
批量请求结果:
1 | {"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"} |
发现所有请求的结果,都是旧版本的v2:{“message”:”v2”}
灰度步骤二:20 % 流量到新版本
继续推进到灰度步骤二:此时Pod版本数量未变,但切了20%的流量过去。
通过脚本进行测试:不带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check ; done |
批量请求结果:
1 | {"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"} |
发现新版本v1的占比是14/50,与切20%的流量大致一致
通过脚本进行测试:带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check -H 'X-Canary: iwantsit' ; done |
批量请求结果:
1 | {"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"} |
发现所有请求的结果,都是新版本的v1:{“message”:”v1”},因为使用了指定了X-Canary请求头,所以都是新版本v1的流量。
灰度步骤三:40% 流量到新版本
继续推进到灰度步骤三:
此时Pod版本数量未变,但理论上应该切了40%的流量过去。
通过脚本进行测试:不带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check ; done |
批量请求结果:
1 | {"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v1"} |
发现新版本v1的占比是19/50,与切40%的流量大致一致
通过脚本进行测试:带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check -H 'X-Canary: iwantsit' ; done |
批量请求结果:
1 | {"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"} |
发现所有请求的结果,都是新版本的v1:{“message”:”v1”},因为使用了指定了X-Canary请求头,所以都是新版本v1的流量。
灰度步骤四:60% 流量到新版本
继续推进到灰度步骤四:
此时Pod版本数量未变,但理论上应该切了60%的流量过去。
通过脚本进行测试:不带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check ; done |
批量请求结果:
1 | {"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"} |
发现新版本v1的占比是28/50,与切60%的流量大致一致
通过脚本进行测试:带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check -H 'X-Canary: iwantsit' ; done |
批量请求结果:
1 | {"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"} |
发现所有请求的结果,都是新版本的v1:{“message”:”v1”},因为使用了指定了X-Canary请求头,所以都是新版本v1的流量。
灰度步骤五:100% 流量到新版本
继续推进到灰度步骤四:发现新版本rs先拉起了5个新版本Pod,并最后将旧版本的5个旧版本Pod释放
通过脚本进行测试:不带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check ; done |
批量请求结果:
1 | {"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"} |
发现新版本v1的占比是50/50,已经旧版本的Pod已经没有实例了
通过脚本进行测试:带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check -H 'X-Canary: iwantsit' ; done |
批量请求结果:
1 | {"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"} |
发现所有请求的结果,都是新版本的v1:{“message”:”v1”},因为使用了指定了X-Canary请求头,所以都是新版本v1的流量。
变更镜像版本为v2
将/charts/ingress/values.yaml内的imageTag由v1,变更为v2,并将steps.setCanaryScale.replicas设置为2,也就是步骤一起两个实例,最后推送到远端:
此时新建了一个rs,并且镜像版本变更为v2:
灰度步骤一:只起一个新版本Pod,并且仅可以通过携带X-Canary头请求
在灰度步骤一时,我们仅起了两个新版本Pod,并且没有设置流量,但是在ArgoCD的网络视图里,新旧两个ingress->两个对应svc->对应Pod副本都是存在流量的。
通过脚本进行测试:不带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check ; done |
批量请求结果:
1 | {"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"} |
发现所有请求的结果,都是旧版本的v1:{“message”:”v1”}
通过脚本进行测试:带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check -H 'X-Canary: iwantsit' ; done |
批量请求结果:
1 | {"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"} |
发现所有请求的结果,都是新版本的v2:{“message”:”v2”}
通过脚本进行测试:带错误X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check -H 'X-Canary: huari' ; done |
批量请求结果:
1 | {"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"} |
发现所有请求的结果,都是旧版本的v1:{“message”:”v1”}
灰度步骤二:20 % 流量到新版本
继续推进到灰度步骤二:此时Pod版本数量未变,但理论上应该切了20%的流量过去。
通过脚本进行测试:不带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check ; done |
批量请求结果:
1 | {"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"} |
发现新版本v2的占比是9/50,与切20%的流量大致一致
通过脚本进行测试:带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check -H 'X-Canary: iwantsit' ; done |
批量请求结果:
1 | {"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"} |
发现所有请求的结果,都是新版本的v2:{“message”:”v2”},因为使用了指定了X-Canary请求头,所以都是新版本v2的流量。
灰度步骤三:40% 流量到新版本
继续推进到灰度步骤三:此时Pod版本数量未变,但理论上应该切了40%的流量过去。
通过脚本进行测试:不带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check ; done |
批量请求结果:
1 | {"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"} |
发现新版本v2的占比是21/50,与切40%的流量大致一致
通过脚本进行测试:带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check -H 'X-Canary: iwantsit' ; done |
批量请求结果:
1 | {"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"} |
发现所有请求的结果,都是新版本的v2:{“message”:”v2”},因为使用了指定了X-Canary请求头,所以都是新版本v2的流量。
灰度步骤四:60% 流量到新版本
继续推进到灰度步骤四:
此时Pod版本数量未变,但理论上应该切了60%的流量过去。
通过脚本进行测试:不带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check ; done |
批量请求结果:
1 | {"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v1"}{"message":"v2"}{"message":"v2"}{"message":"v1"}{"message":"v2"}{"message":"v1"} |
发现新版本v2的占比是29/50,与切60%的流量大致一致
通过脚本进行测试:带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check -H 'X-Canary: iwantsit' ; done |
批量请求结果:
1 | {"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"} |
发现所有请求的结果,都是新版本的v2:{“message”:”v2”},因为使用了指定了X-Canary请求头,所以都是新版本v2的流量。
灰度步骤五:100% 流量到新版本
继续推进到灰度步骤四:
发现新版本rs先拉起了5个新版本Pod,并最后将旧版本的5个旧版本Pod释放
通过脚本进行测试:不带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check ; done |
批量请求结果:
1 | {"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"} |
发现新版本v2的占比是50/50,旧版本的Pod已经没有实例了
通过脚本进行测试:带X-Canary
1 | for i in {1..50}; do curl http://bkce7-dev.hua-ri.cn/api/check -H 'X-Canary: iwantsit' ; done |
批量请求结果:
1 | {"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"}{"message":"v2"} |
发现所有请求的结果,都是新版本的v2:{“message”:”v2”},因为使用了指定了X-Canary请求头,所以都是新版本v2的流量。