【Rollouts】基于OpenKruise Rollouts进行灰度发布
一、背景
业务发布特性版本时,想让一小部分用户使用新版本,又不想一次性量发布引起超预期范围的用户影响,从而引入灰度发布的功能。可以降低风险、提供稳定性和优化用户体验。
二、简介
Kruise Rollouts 是一个 Bypass(旁路) 组件,提供 高级渐进式交付功能 。支持金丝雀、蓝绿、多批次和A/B测试交付模式,同时它兼容 Gateway API 和各种Ingress 实现。
丰富的发布策略
•用于 Deployment、CloneSet、StatefulSet、Advanced StatefulSet、Advanced DaemonSet 的多批次更新策略。
•用于 Deployment 的金丝雀(Canary)更新策略。
•用于 Deployment、CloneSet 的蓝绿(Blue-Green)更新策略。
丰富的流量路由管理策略
•在更新工作负载时进行流量细粒度、加权流量转移。
•流量A/B测试,基于HTTP头和Cookie进行流量转移。
•端到端流量灰度
丰富的流量协议支持
•Ingress 控制器集成:NGINX、ALB、Higress。
•通过 GatewayAPI 进行服务网格集成。
•可插拔的Lua脚本,以便轻松扩展到其他 Kubernetes 流量协议(甚至CRD)。
三、与 Argo Rollout 和 Flux Flagger 的对比
| 组件 | Kruise Rollouts | Argo Rollouts | Flux Flagger |
|---|---|---|---|
| 核心概念 | 增强现有的工作负载 | 替换您的工作负载 | 管理您的工作负载 |
| 架构 | Bypass | 新的工作负载类型 | Bypass |
| 插拔和热切换 | 是 | 否 | 否 |
| 发布类型 | 多批次、金丝雀、A/B测试、全链路灰度、蓝绿 | 多批次、金丝雀、蓝绿、A/B测试 | 金丝雀、蓝绿、A/B测试 |
| 工作负载类型 | Deployment、StatefulSet、CloneSet、Advanced StatefulSet、Advanced DaemonSet | Agro-Rollout | Deployment、DaemonSet |
| 流量类型 | Ingress、GatewayAPI、CRD(需要 Lua 脚本) | Ingress、GatewayAPI、APISIX、Traefik、SMI 等等 | Ingress、GatewayAPI、APISIX、Traefik、SMI 等等 |
| 迁移成本 | 无需迁移工作负载和Pods | 必须迁移工作负载和Pods | 必须迁移Pods |
| HPA 兼容性 | 是 | 是 | 否 |
四、Rollout安装步骤
helm repo add openkruise https://openkruise.github.io/charts/
helm repo update
helm install kruise-rollout openkruise/kruise-rollout \
--set rollout.featureGates="AdvancedDeployment=true" \
--set resources.requests.cpu="200m" \
--set resources.limits.cpu="200m" \
--set resources.requests.memory="512Mi" \
--set resources.limits.memory="512Mi"
wget https://github.com/openkruise/kruise-tools/releases/download/v1.2.2/kubectl-kruise-linux-amd64-v1.2.2.tar.gz
tar -zxvf kubectl-kruise-linux-amd64-v1.2.2.tar.gz
mv linux-amd64/kubectl-kruise /usr/local/bin/kubectl-kruise
五、后继案例操作的工作负载
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: workload-demo
namespace: default
spec:
replicas: 10
selector:
matchLabels:
app: workload-demo
template:
metadata:
labels:
app: workload-demo
spec:
containers:
- name: busybox
image: busybox:latest
command: [ "/bin/sh", "-c", "sleep 100d" ]
env:
- name: VERSION
value: "version-1"
---
apiVersion: v1
kind: Service
metadata:
labels:
app: workload-demo
name: service-demo
spec:
ports:
- name: service-demo-0
port: 80
protocol: TCP
targetPort: 80
selector:
app: workload-demo
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-demo
spec:
ingressClassName: nginx
rules:
- host: demo.com
http:
paths:
- backend:
service:
name: service-demo
port:
number: 80
path: /
pathType: ImplementationSpecific
property:
ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
EOF
六、金丝雀发布
6.1简介
适用于Deployment资源。

金丝雀发布流程:
①将v1版本工作负载设置为暂停滚动升级状态
②创建名称为[Name]-canary的v2版本工作负载资源,其副本数为v1版本工作负载的“20%”(总计将有120%的Pods),同时创建名称为[service-name]-canary的service、[ingress-name]-canary的ingress
③20%的流量将被引导到v2版本工作负载的实例上
④v2版本功能测试
⑤功能测试通过,执行命令进行切换版本。
kubectl-kruise rollout approve rollout/<rollouts-name> -n <namespace>
•v1版本工作负载使用滚动更新策略进行升级到v2版本
•清理名称为[Name]-canary的v2版本工作负载资源
⑥功能测试不通过,执行回滚命令。
kubectl kruise rollout undo rollout/<rollouts-name> -n <namespace>
6.2实操步骤
步骤一:创建workload-demo工作负载、service、ingress
步骤二:创建Rollout canary-rollouts关联workload-demo工作负载。
enableExtraWorkloadForCanary: true 设置为金丝雀发布
traffic: 20% 设置新的副本流量为20%
replicas: 20%设置新的副本实例数为20%
kubectl apply -f - <<EOF
apiVersion: rollouts.kruise.io/v1beta1
kind: Rollout
metadata:
name: canary-rollouts
spec:
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: workload-demo
strategy:
canary:
enableExtraWorkloadForCanary: true
steps:
- traffic: 20%
replicas: 20%
trafficRoutings:
- service: service-demo
ingress:
classType: nginx
name: ingress-demo
EOF
步骤三:升级工作负载的环境变量VERSION为version-2
kubectl patch deployment workload-demo -p \
'{"spec":{"template":{"spec":{"containers":[{"name":"busybox", "env":[{"name":"VERSION", "value":"version-2"}]}]}}}}'

步骤四:查看工作负载的副本、service、ingress情况
kubectl get replicaset -L pod-template-hash
kubectl get svc -owide | grep service-demo
kubectl get ingress -owide | grep ingress-demo



步骤五:批准金丝雀发布
kubectl-kruise rollout approve rollout/canary-rollouts -n default
步骤六:查看工作负载的副本、service、ingress情况。金丝雀发布完成。
kubectl get replicaset -L pod-template-hash
kubectl get svc -owide | grep service-demo
kubectl get ingress -owide | grep ingress-demo

6.3清理测试资源
kubectl delete Rollout canary-rollouts
kubectl delete deployment workload-demo
kubectl delete svc service-demo
kubectl delete ingress ingress-demo
七、多批次发布
7.1简介
可用于CloneSet、StatefulSet、Advanced StatefulSet和Deployment

canary:
enableExtraWorkloadForCanary: false
steps:
- replicas: 1
- replicas: 50%
- replicas: 100%
多批次发布步骤:
①按配置分批次进行升级
②在第一批中,将更新1个Pod到v2版本工作负载实例,然后等待手动确认升级下一批次任务
③执行批准命令
kubectl-kruise rollout approve rollout/<rollouts-name> -n <namespace>
④第二批将更新50%的Pod到v2版本工作负载实例
⑤继续执行批准命令
⑥第三批将全部的Pod都更新到v2版本工作负载实例
7.2操作步骤
步骤一:创建workload-demo工作负载
步骤二:创建Rollout multi-batch-rollouts关联workload-demo工作负载。
enableExtraWorkloadForCanary: false 关闭金丝雀发布
- replicas: 1 发布第一批次
- replicas: 50% 发布第二批次
- replicas: 100% 发布第三批次
kubectl apply -f - <<EOF
apiVersion: rollouts.kruise.io/v1beta1
kind: Rollout
metadata:
name: multi-batch-rollouts
namespace: default
spec:
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: workload-demo
strategy:
canary:
enableExtraWorkloadForCanary: false
steps:
- replicas: 1
- replicas: 50%
- replicas: 100%
EOF
步骤三:升级工作负载的环境变量VERSION为version-2,自动发布第一批次
kubectl patch deployment workload-demo -p \
'{"spec":{"template":{"spec":{"containers":[{"name":"busybox", "env":[{"name":"VERSION", "value":"version-2"}]}]}}}}'
步骤四:稍等片刻,我们将看到部署状态显示已升级 1个Pod。
kubectl get replicaset -L pod-template-hash

步骤五:批准发布第二批次
kubectl-kruise rollout approve rollout/multi-batch-rollouts -n default

步骤六:稍等片刻,我们将看到部署状态显示已升级 5个Pod。
kubectl get replicaset -L pod-template-hash

步骤七:批准发布第三批次
kubectl-kruise rollout approve rollout/multi-batch-rollouts -n default

步骤八:稍等片刻,我们将看到部署状态显示已全部升级。
kubectl get replicaset -L pod-template-hash

7.3执行回退步骤
步骤一:执行回退命令
kubectl kruise rollout undo rollout/multi-batch-rollouts

步骤二:第一批次回退一个Pod
kubectl get replicaset -L pod-template-hash

步骤三:继续批准第二批次回滚
kubectl-kruise rollout approve rollout/multi-batch-rollouts -n default

步骤四:查看工作负载的副本情况
kubectl get replicaset -L pod-template-hash

步骤五:继续批准第三批次回滚
kubectl-kruise rollout approve rollout/multi-batch-rollouts -n default

步骤六:查看工作负载的副本情况
kubectl get replicaset -L pod-template-hash

7.4清理资源
kubectl delete Rollout multi-batch-rollouts
kubectl delete deployment workload-demo
kubectl delete svc service-demo
kubectl delete ingress ingress-demo
八、蓝绿灰度发布
8.1简介
适用于Deployment和CloneSet

蓝绿发布流程:
blueGreen:
steps:
- replicas: 100% # step 1
traffic: 0%
- replicas: 100% # step 2
traffic: 10%
- replicas: 100% # step 3
traffic: 100%
①在第一批中,扩容100%数量的v2版本的Pod,同时创建名称为[service-name]-canaryd service。此时有200%的Pod,没有任何请求路由到新版本Pods
②第二批创建[ingress-name]-canary的ingress将10%的流量路由到新版本,然后等待手动确认下一批次任务。
③第三批将100%的流量路由到新版本,需要手动确认以完成发布
④新版本已经通过验证并确认
⑤稳定版本的Pods将会缩容,发布结束
8.2操作步骤
步骤一:创建workload-demo工作负载、service、ingress
步骤二:创建Rollout blue-green-rollouts关联workload-demo工作负载。
- replicas: 100% # 发布第一批次,副本数加倍,流量不导入到新副本实例
traffic: 0%
- replicas: 100% # 发布第二批次,10%流量导入到新副本实例
traffic: 10%
- replicas: 100% # 发布第三批次,100%流量导入到新副本实例
traffic: 100%
kubectl apply -f - <<EOF
apiVersion: rollouts.kruise.io/v1beta1
kind: Rollout
metadata:
name: blue-green-rollouts
spec:
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: workload-demo
strategy:
blueGreen:
steps:
- replicas: 100% # step 1
traffic: 0%
- replicas: 100% # step 2
traffic: 10%
- replicas: 100% # step 3
traffic: 100%
trafficRoutings:
- service: service-demo
ingress:
classType: nginx
name: ingress-demo
EOF
步骤三:升级工作负载的环境变量VERSION为version-2,自动发布第一批次
kubectl patch deployment workload-demo -p \
'{"spec":{"template":{"spec":{"containers":[{"name":"busybox", "env":[{"name":"VERSION", "value":"version-2"}]}]}}}}'

步骤四:查看工作负载的副本、service、ingress情况
kubectl get replicaset -L pod-template-hash
kubectl get svc -owide | grep service-demo
kubectl get ingress -owide | grep ingress-demo

步骤五:手动批准第二批发布
kubectl-kruise rollout approve rollout/blue-green-rollouts -n default

步骤六:查看工作负载的副本、service、ingress情况
kubectl get replicaset -L pod-template-hash
kubectl get svc -owide | grep service-demo
kubectl get ingress -owide | grep ingress-demo
kubectl get ingress ingress-demo-canary -oyaml | grep canary

步骤七:手动批准第三批发布
kubectl-kruise rollout approve rollout/blue-green-rollouts -n default

步骤八:查看工作负载的副本、service、ingress情况
kubectl get replicaset -L pod-template-hash
kubectl get svc -owide | grep service-demo
kubectl get ingress -owide | grep ingress-demo
kubectl get ingress ingress-demo-canary -oyaml | grep canary

步骤九:批准完成发布
kubectl-kruise rollout approve rollout/blue-green-rollouts -n default
kubectl get replicaset -L pod-template-hash
kubectl get svc -owide | grep service-demo
kubectl get ingress -owide | grep ingress-demo

8.3清理测试资源
kubectl delete Rollout blue-green-rollouts
kubectl delete deployment workload-demo
kubectl delete svc service-demo
kubectl delete ingress ingress-demo
- 点赞
- 收藏
- 关注作者
评论(0)