赞
踩
部署在 Kubernetes 集群中的应用,在升级发布时可能会存在的问题:
1,由于 Kuberneter 底层 Pod 容器生命周期与网络组件生命周期是异步管理的,在升级时如果没有处理好应用优雅退出的问题,就很容易导致 http 访问请求 5xx
2,原生 Deployment 应用的滚动发布功能是一把梭的全量发布模式,没有灰度和分批控制发布的概念,一旦出现问题,故障影响范围就会迅速扩大
这也是为什么需要灰度发布,蓝绿发布,彩虹发布,金丝雀发布、A/B Test等多样化形式发布的重要原因,核心目标只有一个,就是为了确保服务的稳定性,减少或避免因变更带来的不稳定因素
今天我们主要来聊下,如何使用阿里云开源的 Kruise Rollouts 进行灰度发布(官网地址:Introduction | OpenKruise)Kruise Rollouts 是一个旁路组件,提供高级渐进式交付功能。它对金丝雀、灰度发布,蓝绿发布,A/B Test都有很好的支持
- # Firstly add openkruise charts repository if you haven't do this.
- $ helm repo add openkruise https://openkruise.github.io/charts/
-
- # [Optional]
- $ helm repo update
- #
- helm install kruise-rollout openkruise/kruise-rollout --version 0.4.0
-
- # 下载安装包
- # helm pull openkruise/kruise-rollout --untar --untardir .
安装完成后,查看 crd 资源的方式:
- (base) ➜ blue_green_deploy kubectl get crd -A
- NAME CREATED AT
- batchreleases.rollouts.kruise.io 2023-08-25T09:59:30Z
- rollouthistories.rollouts.kruise.io 2023-08-25T09:59:30Z
- rollouts.rollouts.kruise.io 2023-08-25T09:59:30Z
- trafficroutings.rollouts.kruise.io 2023-08-25T09:59:30Z
这里使用手动安装方式,下载安装包:Releases · openkruise/kruise-tools · GitHub
这里是 mac m1 系统,选择 darwin-arm64 即可,解压之后拷贝到系统的 bin 目录即可:
- tar -zxvf kubectl-kruise-darwin-amd64.tar.gz
- mv darwin-arm64/kubectl-kruise /usr/local/bin/
现在就可以使用:
- # 查看帮助文档了
- kubectl-kruise --help
注意在 mac 上由于会验证安全身份,所以如果遇到弹窗:
就在设置 -> 安装性与隐私 -> 通用里面 选择放行和信任这个应用即可
后面再弹窗,直接选择打开就行了
假设,我们有个 Deployment 目前是 V1 版本:
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: py-hello-blue
- spec:
- selector:
- matchLabels:
- app: hello
- color: blue
- replicas: 6
- template:
- metadata:
- labels:
- app: hello
- color: blue
- spec:
- terminationGracePeriodSeconds: 30
- containers:
- - name: hello
- imagePullPolicy: Always
- image: localhost:5001/py-http:1
- ports:
- - containerPort: 8888
- resources:
- requests:
- memory: "50Mi"
- limits:
- memory: "200Mi"
- lifecycle:
- preStop:
- exec:
- command: ["sleep", "5"]
- # command: ["/usr/bin/tini", "--", "bash", "-c"]
- command: ["sh", "-c"]
- args:
- - |
- python app.py
为了让发布更丝滑,我们先绑定 kruise-rollout 灰度发布策略:
- apiVersion: rollouts.kruise.io/v1alpha1
- kind: Rollout
- metadata:
- name: rollout-blue
- namespace: default
- annotations:
- rollouts.kruise.io/rolling-style: partition
- spec:
- objectRef:
- workloadRef:
- apiVersion: apps/v1
- kind: Deployment
- name: py-hello-blue
- strategy:
- canary:
- steps:
- - replicas: 1
- - replicas: 50%
- - replicas: 100%
策略如下:6 个副本的发布批次
第一批:发布一个副本 = 1
第二批:发布剩下的 50%,5*0.5 不四舍五入取整 = 2
第三批:发布剩下的所有 = 3
现在,我们将 yaml 文件里面的版本升级为 2,然后重新执行 apply 后,使用 kubectl get pods -w 命令观察发布过程:
过程,旧的先终止,然后等优雅退出的 30 秒过后,就彻底销毁了,新的一个来拉起来了:
查看发布 rollout 策略的状态,执行命令
kubectl get rollout
结果显示,灰度完就终止了:
这个时候,我们去请求我们的 pod多请求几次就能看到新发布的pod 已经生效了:
继续发布 第二批
kubectl kruise rollout approve rollout/rollout-blue -n default
查看 deployment 状态和发布进度:
- # 查看发布状态
- kubectl get deployments.apps
- # 查看发布的 hash 值,按时间可以看出来
- kubectl get replicasets.apps -L pod-template-hash
第二批发完之后,显示如下:
然后我们继续查看灰度发布的执行阶段:
可以看到进行到了完成了第二个阶段:
如果没问题,继续执行第三批发布:
kubectl kruise rollout approve rollout/rollout-blue -n default
如果在没有发布完,显示Progressing,StepUpgrade
执行完显示:
kurise 并不直接提供回滚能力,需要借助原生的方式重新 set image 即可, 在这里不需要对 rollout crd 做任何事情,yaml 文件里面的镜像版本改回到之前的 v1 版本即可,然后 kubectl apply -f 到 k8s 集群,再次查看状态会显示 rollout 已经取消
- NAME STATUS CANARY_STEP CANARY_STATE MESSAGE AGE
- rollout-blue Healthy 1 StepReady Rollout progressing has been cancelled 77m
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。