使用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" http://
7、确认灰度发布的新版本发布正常后,继续后续发布。
kubectl-kruise rollout approve server -n default