使用cube-openkruise Rollout 實現灰度發布
OpenKruise是基于Kubernetes的一個標準擴展組件,可以配合原生Kubernetes使用,高效管理應用容器、Sidecar及鏡像分發等功能。本文介紹如何使用 Rollout 實現灰度發布。
前提條件
已安裝Kubernetes托管版集群,且集群版本不低于1.23。
背景信息
OpenKruise包含了多種自定義Workload,用于無狀態應用、有狀態應用、Sidecar容器、Daemon應用等部署管理,提供了原地升級等擴展策略。OpenKruise 社區開源的漸進式交付框架。Kruise Rollout支持配合流量和實例灰度的灰度發布、藍綠發布、A/B Testing發布。基于Prometheus Metrics指標,Kruise Rollout還可以實現發布過程的自動化分批與暫停,并提供旁路的無感對接、兼容已有的多種工作負載(Deployment、CloneSet、StatefulSet)。
使用說明
OpenKruise包含CloneSet、Advanced StatefulSet、Advanced DaemonSet等控制器。常用控制器說明如下:
| 控制器 | 功能 |
|---|---|
| CloneSet | 管理無狀態應用,對標Kubernetes原生Deployment。關于CloneSet的詳細介紹,請參見Cloneset。資源(YAML)的字段與Deployment不完全兼容,但功能上全覆蓋,并提供比Deployment更豐富的策略。 |
| Advanced StatefulSet | 管理有狀態應用,對標Kubernetes原生StatefulSet。關于Advanced StatefulSet的詳細介紹,請參見Advanced StatefulSet。資源(YAML)字段與原生StatefulSet完全兼容,只需要把apiVersion改為apps.kruise.io/v1alpha1,另外提供了optional字段來擴展發布策略(原地升級、并行發布等) |
| Advanced DaemonSet | 管理Daemon應用,對標Kubernetes原生DaemonSet。關于Advanced DaemonSet的詳細介紹,請參見Advanced DaemonSet。資源(YAML)字段與原生DaemonSet完全兼容,只需要把apiVersion改為apps.kruise.io/v1alpha1,另外提供了optional字段來擴展發布策略(熱升級、灰度、按Node標簽灰度等 |
| SidecarSet | 獨立管理Sidecar容器和注入。關于SidecarSet的詳細介紹,請參見SidecarSet。在獨立CR中定義Sidecar容器和Label Selector,OpenKruise會在所有符合Selector條件的Pod創建時注入定義好的Sidecar容器,并支持對已注入Sidecar容器做原地升級 |
| UnitedDeployment | 管理不同區域下的多個Sub Workload,關于UnitedDeployment的詳細介紹,請參見UnitedDeployment。目前支持將CloneSet、StatefulSet、Advanced StatefulSet作為Sub Workload,您可以用一個UnitedDeployment來定義不同區域中的Sub Workload部署Replicas。 |
安裝 OpenKruise
在集群的菜單“插件”-“插件市場”中安裝cube-openkruise插件。
基于Nginx Ingress實現金絲雀或A/B Testing發布
演示如何使用Kruise Rollout + Nginx Ingress實現金絲雀或A/B Testing發布。
1、部署業務應用(Deployment、Service和Ingress)
Kubectl apply –f -<<eof
apiVersion: apps/v1
kind: Deployment
metadata:
name: server
labels:
app: server
spec:
replicas: 6
selector:
matchLabels:
app: server
template:
metadata:
labels:
app: server
spec:
containers:
- name: server
image: server:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
env:
- name: NODE_NAME
value: v1
- name: PORT
value: '8080'
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
---
apiVersion: v1
kind: Service
metadata:
name: server
labels:
app: server
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: server
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: server
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- http:
paths:
- backend:
service:
name: server
port:
number: 80
path: /apis/echo
pathType: Exact
2、定義Kruise Rollout灰度發布規則。
kubectl apply –f -<< eof
apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
metadata:
name: server
annotations:
rollouts.kruise.io/rolling-style: partition
spec:
objectRef:
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: server
strategy:
canary:
steps:
- matches:
- headers:
- type: Exact
name: User-Agent
value: Andriod
pause: {}
replicas: 1
- weight: 50
replicas: 50%
pause: {duration: 60}
- weight: 100
replicas: 100%
pause: {duration: 60}
trafficRoutings:
# Service Name
- service: echoserver
ingress:
# Ingress Name
name: echoserver
3、查看狀態
kubectl get rollout
4、升級應用版本,修改鏡像版本
kubectl patch deploy echo --patch '{"spec": {"template": {"spec": {"containers": [{"name": "server","image": "server:v2"}]}}}}'
5、執行以下命令,查看Rollout資源的狀態。
kubectl get rollouts server -n default
6、使用以下命令,將帶有header[User-Agent]=Andriod的流量導入到新版本,其它的流量導入到老版本。
curl -H "User-Agent: Andriod" //
7、確認灰度發布的新版本發布正常后,繼續后續發布。
kubectl-kruise rollout approve server -n default