kubernetes如何使用kruise-rollout进行分批灰度发布

9 篇文章 0 订阅
6 篇文章 0 订阅

前言

部署在 Kubernetes 集群中的应用,在升级发布时可能会存在的问题:

1,由于 Kuberneter 底层 Pod 容器生命周期与网络组件生命周期是异步管理的,在升级时如果没有处理好应用优雅退出的问题,就很容易导致 http 访问请求 5xx

2,原生 Deployment 应用的滚动发布功能是一把梭的全量发布模式,没有灰度和分批控制发布的概念,一旦出现问题,故障影响范围就会迅速扩大

这也是为什么需要灰度发布,蓝绿发布,彩虹发布,金丝雀发布、A/B Test等多样化形式发布的重要原因,核心目标只有一个,就是为了确保服务的稳定性,减少或避免因变更带来的不稳定因素

今天我们主要来聊下,如何使用阿里云开源的 Kruise Rollouts 进行灰度发布(官网地址:Introduction | OpenKruise)Kruise Rollouts 是一个旁路组件,提供高级渐进式交付功能。它对金丝雀、灰度发布,蓝绿发布,A/B Test都有很好的支持

安装

kruise-rollout
# 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

kubectl-kruise

这里使用手动安装方式,下载安装包: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 上由于会验证安全身份,所以如果遇到弹窗:

 

就在设置 -> 安装性与隐私 -> 通用里面 选择放行和信任这个应用即可

 

后面再弹窗,直接选择打开就行了

 


 

Demo 例子

假设,我们有个 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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果您不想使用 `kubectl rollout status` 命令来检查部署状态,您可以尝试以下修改: ```groovy stage('Deploy') { when { expression { "${IS_DEPLOY}" == "true" } } steps { sh "pwd" sh "sed -i s#APP_NAME#${APP_NAME}#g deployment-${NAMESPACE}.yaml && sed -i s#TAG_TO_REPLACE#${IMAGE_TAG}#g deployment-${NAMESPACE}.yaml && sed -i s#IMAGE_TO_REPLACE#${IMAGE_NAME}#g deployment-${NAMESPACE}.yaml" sh "kubectl apply -f deployment-${NAMESPACE}.yaml -n ${NAMESPACE}" script { def max_restart_count = 1 def restart_count = 0 def deploy_successful = false while (!deploy_successful) { restart_count = sh(returnStdout: true, script: "kubectl get pods -l app=${APP_NAME} -n ${NAMESPACE} -o jsonpath='{range .items[*]}{@.status.containerStatuses[0].restartCount}{'\n'}{end}' | awk '{sum+=$1}END{print sum}'").trim().toInteger() if (restart_count > max_restart_count) { error "Pod restart count exceeded the threshold. Deployment ${APP_NAME} failed." break } def ready_pods = sh(returnStdout: true, script: "kubectl get pods -l app=${APP_NAME} -n ${NAMESPACE} -o jsonpath='{range .items[*]}{@.status.containerStatuses[0].ready}{'\n'}{end}'").trim().split("\\s+") if (ready_pods.every { it == "true" }) { echo "All pods are ready. Deploy ${APP_NAME} rolled out successfully" deploy_successful = true break } sleep 5 } } } } ``` 在这个修改后的代码中,我使用了一个布尔变量 `deploy_successful` 来判断部署是否成功。循环将一直执行,直到所有的 Pod 都准备就绪,并将 `deploy_successful` 设置为 `true`。 我通过使用 `kubectl get pods` 命令来获取每个 Pod 的 `ready` 状态,并将其存储在 `ready_pods` 列表中。然后,我使用 `every` 方法来检查所有 Pod 的 `ready` 状态是否都为 `true`。 请注意,这种方法可能需要更长的时间来完成循环,因为它依赖于每个 Pod 的状态。如果您希望更快速地检查部署状态,建议使用 `kubectl rollout status` 或其他更可靠的方法。 希望这对您有所帮助!如果您有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值