如何在不停机的情况下更改 k8s 部署的 matchLabels?

问题描述 投票:0回答:3

Kubernetes 类型

Deployment
不允许在
spec.selector.matchLabels
中进行补丁更改,因此任何想要更改标签的新部署(由 Helm 或其他方式管理)都无法在部署中使用 RollingUpdate 功能。在不造成停机的情况下实现新部署的最佳方式是什么?

最小示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: foo
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: foo
  template:
    metadata:
      labels:
        app: foo
    spec:
      containers:
        - name: foo
          image: ubuntu:latest
          command: ["/bin/bash", "-ec", "sleep infinity"]

应用此选项,然后将标签(matchLabels 和metadata.labels)编辑为

foo2
。如果您尝试应用这个新部署,k8s 会抱怨(根据设计)
Deployment "foo" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"foo2"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable

我现在能想到的唯一方法是使用新的部署名称,这样新的部署就不会尝试修补旧的部署,然后删除旧的部署,并由入口/负载均衡器资源处理转换。然后我们可以使用旧名称重新部署,并删除新名称,完成迁移。

有没有办法用更少的 k8s CLI 步骤来做到这一点?也许我可以编辑/删除一些东西,让旧的 Pod 保持活动状态,同时新的 Pod 以相同的名称推出?

kubernetes deployment migration downtime
3个回答
5
投票

我刚刚做到了这一点,并且遵循了您描述的四步过程。我想答案是否定的,没有更好的办法了。

我的服务由 Helm 管理。为此,我实际上创建了四个需要按顺序推出的合并请求:

  1. 添加相同的部署“foo-temp”,只是名称不同。
  2. 删除部署 foo。
  3. 使用所需的标签选择器重新创建部署 foo。
  4. 删除部署 foo-temp。

我测试了简化流程(结合步骤 1 和 2),但它不起作用 - helm 在创建另一个部署之前删除了一个部署,然后你就停机了。

好消息是:就我而言,我不需要更改任何其他描述符(图表),所以它并没有那么糟糕。所有关系(流量路由等)都是通过标签匹配建立的。由于 foo-temp 具有相同的标签,因此关系会自动发挥作用。唯一的问题是我的 HPA 引用了名称,而不是标签。我没有修改它,而是将 foo-temp 保留为没有 HPA,只是为其指定了大量副本。当步骤 2 和步骤 3 之间不存在目标时,HPA 不会抱怨。


0
投票

更简单的方法是临时配置旧标签和新标签。一旦您的

Pods
拥有两个标签,删除您的
Deployment
并孤立 pod
:

kubectl delete deployment YOUR-DEPLOYMENT --cascade=orphan

现在

Deployment
消失了,但您的 Pod 仍在运行,您可以再次部署
Deployment
,这次使用新的标签选择器。它将找到正在运行的
Pods
,因为它们也有新标签。

完成此操作后,您可以从豆荚上取下旧标签来完成。


-3
投票

根据我的经验,当我使用helm时

helm upgrade release -f values .

我没有停机时间。另外,在使用 helm 时,我注意到,直到新部署在 X/X 准备就绪之前,它不会终止旧部署。我可以建议使用它。这样就可以尽可能无痛。

另外,从 Kubernetes 文档的更新部署部分来看, 当且仅当 Deployment 的 Pod 模板(即 .spec.template)发生更改时,才会触发 Deployment 的推出。

因此,您可以使用 helm 来更改标签。

希望我能有点帮助。

当心!未经尝试的方法:kubectl 有一个编辑子命令,它使我能够更新 ConfigMaps、PersistentVolumeClaims 等。也许您可以使用它来更新您的部署。 语法:

kubectl edit [resource] [resource-name]

但在此之前,请选择合适的文本编辑器,因为您将处理 yaml 格式的文件。通过使用来做到这一点,

export KUBE_EDITOR=/bin/{nano,vim,yourFavEditor}
© www.soinside.com 2019 - 2024. All rights reserved.