【问题标题】:Redeploy statefulset with CrashLoopBackOff status in kubernetes在 kubernetes 中重新部署具有 CrashLoopBackOff 状态的 statefulset
【发布时间】:2021-05-10 15:18:41
【问题描述】:

我就是这样做的:

  1. 部署有状态集。 pod 将始终以错误退出以引发状态为 CrashLoopBackOff 的失败 pod:kubectl apply -f error.yaml
  2. 更改 error.yaml (echo a => echo b) 并重新部署有状态集:kubectl apply -f error.yaml
  3. Pod 保持错误状态,不会立即重新部署,而是等待一段时间后重新启动 Pod。

请求 pod 状态:

$ kubectl get pod errordemo-0
NAME          READY   STATUS             RESTARTS   AGE
errordemo-0   0/1     CrashLoopBackOff   15         59m

error.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: errordemo
  labels:
    app.kubernetes.io/name: errordemo
spec:
  serviceName: errordemo
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: errordemo
  template:
    metadata:
      labels:
        app.kubernetes.io/name: errordemo
    spec:
      containers:
        - name: demox
          image: busybox:1.28.2
          command: ['sh', '-c', 'echo a; sleep 5; exit 1']
      terminationGracePeriodSeconds: 1

问题

即使 pod 处于错误状态,我如何才能实现立即重新部署? 我找到了这些解决方案,但我希望有一个命令来实现这一点(在现实生活中我正在使用 helm,我只想为我的部署调用 helm upgrade):

  • 在重新部署之前杀死 pod
  • 在重新部署之前缩小规模
  • 在重新部署之前删除 statefulset

kubernetes 为什么不立即重新部署 pod?

  • 在我的演示示例中,我必须等到 kubernetes 在等待一段时间后尝试重新启动 pod。
  • 没有错误的 pod(例如echo a; sleep 10000;)将立即重新启动。这就是为什么我设置terminationGracePeriodSeconds: 1
  • 但在我的实际部署中(我使用 helm),我也遇到过从未重新部署 pod 的情况。不幸的是,我无法在一个简单的示例中重现此行为。

【问题讨论】:

  • 您可以在部署模板中添加新注释,例如修订或类似内容,添加变量 {{ .Release.Revision }}。如果您运行 helm upgrade,这应该会强制使用新版本进行部署......希望这会有所帮助。如果没有,那么也许我没有明白你的意思。

标签: kubernetes kubernetes-helm kubectl


【解决方案1】:

你可以设置spec.podManagementPolicy: "Parallel"

Parallel pod management 告诉 StatefulSet 控制器并行启动或终止所有 Pod,而不是在启动或终止另一个 Pod 之前等待 Pod 变为 Running 和 Ready 或完全终止。

记住默认的 podManagementPolicy 是OrderedReady

OrderedReady pod management 是 StatefulSets 的默认值。它告诉 StatefulSet 控制器遵守上面演示的排序保证

如果您的应用程序需要有序更新,那么您无能为力。

【讨论】:

  • 谢谢,这有帮助!我的 StatefulSet 中只有一个 pod。我使用 StatefulSets 是因为我需要一个单例。
  • 还有一个问题:我的用例是一个严格的单例。 Parallel 选项是否会影响规则,即必须在创建新 Pod 之前关闭 Pod? “等待......完全终止”究竟是什么意思?在我的测试中,一切似乎都按预期工作。 IE。在创建新 pod 之前首先关闭 pod。
  • 如果是OrderedReady,当有例如3 个 pod pod-0、pod-1、pod-2、k8s 会先移除 pod-2,并确保在开始移除 pod-1 之前终止。当 pod-1 完全终止时,它才开始终止 pod-0。在它们全部终止后,它将开始启动新的 pod。一个接一个。
  • 在 Parallel 策略的情况下,k8s 仍然等待 pod 终止,然后才开始在它们的位置启动现在的 pod,但这样做是并行的。这意味着当有 3 个 pod 时,它们都可以一次性终止,一旦一个 pod 完全终止,k8s 会在其位置启动一个新的 pod。
  • 这很好,因为顾名思义,starefulsets 是有状态的——这意味着您很可能正在使用持久卷在某处持久保存状态。在这种情况下升级时,你很可能希望新的 pod 在旧的 pd 之后继承这些数据卷,但是为了实现它,旧的 pod 必须释放卷,这就是 k8s 等待旧的 pod 完全终止的原因,释放卷,以便它们可以安装在新的 pod 中。我希望这是有道理的:D
猜你喜欢
  • 2017-05-25
  • 2023-03-16
  • 2023-03-26
  • 2020-05-28
  • 2018-07-15
  • 1970-01-01
  • 1970-01-01
  • 2021-10-13
  • 2023-04-06
相关资源
最近更新 更多