如何在Kubernetes中实现自动回滚?

6pp0gazn  于 2023-01-25  发布在  Kubernetes
关注(0)|答案(2)|浏览(184)

假设我有一个部署,由于某种原因,它在一段时间后没有响应。有没有办法告诉Kubernetes在失败时自动回滚到以前的版本?

7kqas0il

7kqas0il1#

你提到:
我部署了一个系统。不知什么原因过了一段时间没有React。
在这种情况下,可以使用liveness and readiness探测器:
Kubelet使用活动探测器来了解何时重新启动容器。例如,活动探测器可以捕获死锁,即应用程序正在运行但无法继续运行。在这种状态下重新启动容器有助于提高应用程序的可用性,尽管存在错误。
Kubelet使用就绪探测器来了解容器何时准备好开始接受流量。当Pod的所有容器都就绪时,该Pod被视为就绪。此信号的一个用途是控制将哪些Pod用作服务的后端。当Pod未就绪时,它将从服务负载平衡器中删除。
上述探测器可能会阻止您部署损坏的版本,但是liveness和readyness探测器无法将您的部署回滚到以前的版本。Github上有类似的issue,但我不确定在不久的将来是否会有任何进展。
如果您真的想自动化回滚过程,下面我将介绍一个您可能会发现有帮助的解决方案。
此解决方案需要从Pod中运行kubectl命令。简而言之,您可以使用脚本持续监视部署,并在出现错误时运行kubectl rollout undo deployment DEPLOYMENT_NAME
首先,您需要决定如何查找失败的部署。例如,我将使用以下命令检查执行更新超过10秒的部署:

**注:**您可以根据需要使用不同的命令。

kubectl rollout status deployment ${deployment} --timeout=10s

为了持续监控default命名空间中的所有部署,我们可以创建一个Bash脚本:

#!/bin/bash

while true; do
    sleep 60
    deployments=$(kubectl get deployments --no-headers -o custom-columns=":metadata.name" | grep -v "deployment-checker")
    echo "====== $(date) ======"
    for deployment in ${deployments}; do
        if ! kubectl rollout status deployment ${deployment} --timeout=10s 1>/dev/null 2>&1; then
            echo "Error: ${deployment} - rolling back!"
            kubectl rollout undo deployment ${deployment}
        else
            echo "Ok: ${deployment}"
        fi
    done
done

我们希望从Pod内部运行此脚本,因此我将其转换为ConfigMap,这将允许我们在卷中装载此脚本(请参见:将ConfigMap用作Pod中的文件):

$ cat check-script-configmap.yml
apiVersion: v1
kind: ConfigMap
metadata:
  name: check-script
data:
  checkScript.sh: |
    #!/bin/bash

    while true; do
        sleep 60
        deployments=$(kubectl get deployments --no-headers -o custom-columns=":metadata.name" | grep -v "deployment-checker")
        echo "====== $(date) ======"
        for deployment in ${deployments}; do
            if ! kubectl rollout status deployment ${deployment} --timeout=10s 1>/dev/null 2>&1; then
                echo "Error: ${deployment} - rolling back!"
                kubectl rollout undo deployment ${deployment}
            else
                echo "Ok: ${deployment}"
            fi
        done
    done        

$ kubectl apply -f check-script-configmap.yml
configmap/check-script created

我已经创建了一个单独的deployment-checker服务帐户,并分配了edit角色,我们的Pod将在此服务帐户下运行:

**注意:**我创建了一个部署,而不是单个Pod。

$ cat all-in-one.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: deployment-checker
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: deployment-checker-binding
subjects:
  - kind: ServiceAccount
    name: deployment-checker
    namespace: default
roleRef:
  kind: ClusterRole
  name: edit
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: deployment-checker
  name: deployment-checker
spec:
  selector:
    matchLabels:
      app: deployment-checker
  template:
    metadata:
      labels:
        app: deployment-checker
    spec:
      serviceAccountName: deployment-checker
      volumes:
        - name: check-script
          configMap:
            name: check-script
      containers:
      - image: bitnami/kubectl
        name: test
        command: ["bash", "/mnt/checkScript.sh"]
        volumeMounts:
        - name: check-script
          mountPath: /mnt

应用上述清单后,deployment-checker部署已创建并开始监视default命名空间中的部署资源:

$ kubectl apply -f all-in-one.yaml
serviceaccount/deployment-checker created
clusterrolebinding.rbac.authorization.k8s.io/deployment-checker-binding created
deployment.apps/deployment-checker created

$ kubectl get deploy,pod | grep "deployment-checker"
deployment.apps/deployment-checker   1/1     1            
pod/deployment-checker-69c8896676-pqg9h   1/1     Running

最后,我们可以检查它是如何工作的。我已经创建了三个部署(app-1app-2app-3):

$ kubectl create deploy app-1 --image=nginx
deployment.apps/app-1 created

$ kubectl create deploy app-2 --image=nginx
deployment.apps/app-2 created

$ kubectl create deploy app-3 --image=nginx
deployment.apps/app-3 created

然后我将app-1的图像更改为不正确的图像(nnnginx):

$ kubectl set image deployment/app-1 nginx=nnnginx
deployment.apps/app-1 image updated

deployment-checker日志中,我们可以看到app-1已回滚到以前的版本:

$ kubectl logs -f  deployment-checker-69c8896676-pqg9h
...
====== Thu Oct  7 09:20:15 UTC 2021 ======
Ok: app-1
Ok: app-2
Ok: app-3
====== Thu Oct  7 09:21:16 UTC 2021 ======
Error: app-1 - rolling back!
deployment.apps/app-1 rolled back
Ok: app-2
Ok: app-3
yqlxgs2m

yqlxgs2m2#

我偶然发现了Argo Rollout,它解决了这种非自动回滚和许多其他与部署相关的事情。
https://argoproj.github.io/argo-rollouts/

相关问题