Kruise Rollout是基于Kubernetes的一个标准扩展组件,可以配合原生工作负载(Deployment、StatefulSet)以及OpenKruise工作负载(CloneSet、Adcanced StatefulSet),实现金丝雀发布、A/B Testing发布和蓝绿发布等功能。实现灰度发布、A/B Testing发布和蓝绿发布等功能。本文通过示例介绍如何使用Kruise Rollout灰度发布云原生应用。
索引
前提条件
已创建Kubernetes集群。具体操作,请参见创建ACK托管集群。
如需使用A/B Testing或金丝雀发布的能力,集群版本需为1.19及以上版本。
如需使用分批发布能力,则集群版本需为1.16及以上版本。
已安装kubectl-kruise。关于kubectl-kruise安装路径,请参见kubectl-kruise。
Kruise Rollout介绍
Kruise Rollout是OpenKruise社区开源的渐进式交付框架。Kruise Rollout支持配合流量和实例灰度的灰度发布、蓝绿发布、A/B Testing发布。基于Prometheus Metrics指标,Kruise Rollout还可以实现发布过程的自动化分批与暂停,并提供旁路的无感对接、兼容已有的多种工作负载(Deployment、CloneSet、StatefulSet)。更多信息,请参见Kruise Rollout。
Kruise Rollout是一种旁路式的工作机制。您只需配置一份Rollout资源并将其下发到K8s集群中,后续的业务发布、升级均无需额外操作,并且可以与Helm、PaaS平台低成本地无缝对接。使用Kruise Rollout实现灰度发布架构如下图所示。
准备工作
安装Kruise Rollout组件。
登录容器服务管理控制台,在左侧导航栏选择集群。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择 。
在组件管理页面,单击应用管理页签,然后在ack-kruise卡片右下方,单击安装。
在弹出的对话框确认信息后,单击确定。
下文基于不同示例介绍如何实现金丝雀发布、A/B Testing发布和蓝绿发布等。
示例1:基于Nginx Ingress实现金丝雀或A/B Testing发布
Nginx Ingress是目前较为普遍的对外暴露服务的方式,ACK集群默认提供此能力。本示例演示如何使用Kruise Rollout + Nginx Ingress实现金丝雀或A/B Testing发布。
安装Nginx Ingress Controller。
新建集群:创建集群时,在Ingress配置区域,选择安装Nginx Ingress。具体操作,请参见创建ACK托管集群。
已有集群:关于安装Nginx Ingress Controller的具体操作,请参见创建Nginx Ingress。
部署业务应用(Deployment、Service和Ingress)。
业务应用配置基于Deployment部署一个echoserver服务,并通过Nginx Ingress对外暴露服务。
使用以下内容,创建echoserver.yaml文件。
执行以下命令,部署业务应用。
kubectl apply -f echoserver.yaml
执行以下命令,获取外部IP。
kubectl get ingress
预期输出:
NAME CLASS HOSTS ADDRESS PORTS AGE echoserver <none> * EXTERNAL_IP 80 12m
执行以下命令,查看路由访问情况。
替换以下
<EXTERNAL_IP>
为您上一步获取的外部IP。curl http://<EXTERNAL_IP>/apis/echo
预期输出:
Hostname: echoserver-75d49c475c-ls2bs Pod Information: node name: version1 pod name: echoserver-75d49c475c-ls2bs pod namespace: default Server values: server_version=nginx: 1.13.3 - lua: 10008
定义Kruise Rollout灰度发布规则。
以下Rollout资源将定义灰度发布规则,发布分为三批:
第一批:A/B Testing发布,具有
header[User-Agent]=Andriod
的流量将导入到新版本,其他则为老版本。第二批:按照流量比例进行灰度,此批次将灰度50%的实例及流量。
第三批:将灰度完成所有的实例。
使用以下内容,创建rollout.yaml文件。
执行以下命令,将该Rollout资源下发到K8s集群。
kubectl apply -f rollout.yaml
执行以下命令,查看Rollout资源状态。
kubectl get rollout
预期输出:
NAME STATUS CANARY_STEP CANARY_STATE MESSAGE AGE rollouts-demo Healthy 3 Completed workload deployment is completed 7s rollout is healthy 32s
预期输出
STATUS=Healthy
:表明Rollout资源正常工作。
升级应用版本。
Kruise Rollout是一个常态化的配置,将其下发到集群中后,后续业务版本发布只需调整Deployment配置,无需再对Kruise Rollout进行额外操作。例如,业务将echoserver服务镜像版本升级到1.10.3,然后通过执行
kubectl apply -f echoserver.yaml
命令将Deployment部署到集群。将Deployment配置下发到K8s集群时,除kubectl方式外,也可以使用Helm、Vela等方式。修改echoserver.yaml文件,将echoserver服务镜像版本升级到1.10.3。
# echoserver.yaml apiVersion: apps/v1 kind: Deployment metadata: name: echoserver ... spec: ... containers: - name: echoserver # mac m1 can choice image e2eteam/echoserver:2.2-linux-arm image: openkruise-registry.cn-shanghai.cr.aliyuncs.com/openkruise/demo:1.10.3 imagePullPolicy: IfNotPresent env: - name: NODE_NAME # 可选操作。此处为清晰展示灰度效果,将value改为version2。 value: version2
执行以下命令,查看Rollout资源的状态。
kubectl get rollouts rollouts-demo -n default
预期输出:
NAME STATUS CANARY_STEP CANARY_STATE MESSAGE AGE rollouts-demo Progressing 1 StepPaused Rollout is in step(1/1), and you need manually confirm to enter the next step 41m
通过预期输出的
STATUS
和CANARY
,可观察Rollout的过程以及步骤。若预期输出
STATUS=Progressing
:表明已经在金丝雀发布过程中。若预期输出
CANARY_STEP=1
:表明当前处于第一批次。若预期输出
CANARY_STATE=StepPaused
:表明当前批次已经完成,是否需要继续,可以通过人工确认。
使用以下命令,将带有
header[User-Agent]=Andriod
的流量导入到新版本,其他的流量导入到老版本。# 特殊header的请求导入新版本,如以下的version2字段所示。 curl -H "User-Agent: Andriod" http://<EXTERNAL_IP>/apis/echo Hostname: echoserver-869877fc87-6bb5h Pod Information: node name: version2 pod name: echoserver-869877fc87-6bb5h pod namespace: default Server values: server_version=nginx: 1.13.3 - lua: 10008 # 其他的请求导入老版本,如以下的version1字段所示。 curl http://<EXTERNAL_IP>/apis/echo Hostname: echoserver-869877fc87-6bb5h Pod Information: node name: version1 pod name: echoserver-869877fc87-6bb5h pod namespace: default Server values: server_version=nginx: 1.13.3 - lua: 10008
确认灰度发布的新版本发布正常后,继续后续发布。
前面的步骤仅发布部分实例以及部分的金丝雀流量灰度,通过一些业务日志或监控确认新版本发布正常后,可通过
rollout.rollouts.kruise.io/rollouts-demo approved
命令继续后续发布,其中rollouts-demo
表示Rollout资源的名称。kubectl get rollouts rollouts-demo -n default NAME STATUS CANARY_STEP CANARY_STATE MESSAGE AGE rollouts-demo Progressing 1 StepPaused Rollout is in step(1/1), and you need manually confirm to enter the next step 41m # 命令行工具继续后续发布。 kubectl-kruise rollout approve rollouts/rollouts-demo -n default rollout.rollouts.kruise.io/rollouts-demo approved # 通过CANARY_STEP=2表明已经在进行后面的批次。 kubectl get rollout NAME STATUS CANARY_STEP CANARY_STATE MESSAGE AGE rollouts-demo Progressing 2 StepUpgrade Rollout is in step(2/3), and upgrade workload to new version 141m # 当STATUS=Healthy,且CANARY_STATE=Completed,表明本次rollout已经全部完结。 kubectl get rollout NAME STATUS CANARY_STEP CANARY_STATE MESSAGE AGE rollouts-demo Healthy 3 Completed Rollout progressing has been completed 144m
可选:若新版本服务异常,可进行业务回滚。
如果在Rollout过程中,发现新版本服务异常,可以通过Deployment配置恢复到之前版本。然后通过
kubectl apply -f echoserver.yaml
命令进行部署,无需对Rollout资源做任何改动。# echoserver.yaml apiVersion: apps/v1 kind: Deployment metadata: name: echoserver ... spec: ... containers: - name: echoserver # mac m1 can choice image e2eteam/echoserver:2.2-linux-arm. image: openkruise-registry.cn-shanghai.cr.aliyuncs.com/openkruise/demo:1.10.2 imagePullPolicy: IfNotPresent env: - name: NODE_NAME value: version1
示例2:基于MSE Ingress实现金丝雀或A/B Testing发布
安装MSE Ingress Controller。具体操作,请参见管理MSE Ingress Controller组件。
授予MSE Ingress Controller访问权限。具体操作,请参见授予MSE Ingress Controller访问权限。
创建MseIngressConfig和IngressClass。具体操作,请参见通过MSE Ingress访问容器服务。
部署业务应用(Deployment、Service和Ingress)。
业务应用配置与示例1的步骤2类似,此处需指定Ingress的
ingressClassName=mse
,其他应用配置及操作与示例1均相同。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: echoserver spec: # 此处须指定ingressClassName为mse。 ingressClassName: mse rules: - http: paths: - backend: service: name: echoserver port: number: 80 path: /apis/echo pathType: Exact
后续的Rollout配置、灰度发布及回滚操作与示例1:基于Nginx Ingress实现金丝雀或A/B Testing发布完全相同。具体操作,请参见示例1的步骤3~步骤6。
示例3:基于Pod实例个数灰度的分批发布(基于Nacos等微服务框架的应用)
大多基于微服务框架的应用(例如Nacos)部署到K8s集群时,并不需要配置对应的Service和Ingress,流量调度部分微服务框架已经集成。针对该类型的应用更适合使用Kruise Rollout的分批发布能力,而流量灰度的部分则由微服务框架提供。
部署业务应用(Deployment)。
此示例仅包含Deployment,不包含Service和Ingress资源,仅展示Kruise Rollout的分批发布能力,不展示微服务框架部分。
使用以下内容,创建echoserver.yaml文件。
执行以下命令,部署业务应用。
kubectl apply -f echoserver.yaml
定义Kruise Rollout灰度发布规则,并通过
kubectl apply -f rollout.yaml
将资源部署到K8s集群中。以下Rollout资源将定义灰度发布规则(无需配置
trafficRoutings
字段),发布分为三批:第一批:灰度1个Pod。
第二批:灰度50%的Pod。
第三批:将灰度完所有的实例。
# 将如下内容存储到文件rollout.yaml。 apiVersion: rollouts.kruise.io/v1alpha1 kind: Rollout metadata: name: rollouts-demo annotations: rollouts.kruise.io/rolling-style: partition spec: objectRef: workloadRef: apiVersion: apps/v1 kind: Deployment # Deployment Name name: echoserver strategy: canary: steps: # 手动决定是否开始下一批次。 - pause: {} # 灰度的Pod实例个数1个Pod,也支持配置百分比。 replicas: 1 # 此批次灰度50% Pod实例。 - replicas: 50% # 暂停60s自动进入下一批次,如果需要手动决定,请配置为:pause: {}。 pause: {duration: 60} - weight: 100 replicas: 100% pause: {duration: 60}
后续的灰度发布及回滚操作与示例1:基于Nginx Ingress实现金丝雀或A/B Testing发布完全相同。具体操作,请参见示例1的步骤4~步骤6。