在Kubernetes中更新configmap时重启Pod吗?


119

更改/更新它们的配置映射后,如何自动重启Kubernetes Pod和与部署关联的Pod?


我知道有人在谈论配置映射更改时自动重启Pod的功能,但据我所知,Kubernetes 1.2尚不提供此功能。

所以(我认为)我想做的是与消耗配置映射的Pod相关联的部署资源的“滚动重启” 。是否可以(如果可以的话)在Kubernetes中强制重新启动部署的滚动而不更改实际模板中的任何内容?这是目前最好的方法还是有更好的选择?


$ kubectl set env deployment my deployment --env="LAST_RESTART=$(date)" --namespace ...为我做这份工作
Maciek

Answers:


59

在配置映射更新中向pod发出信号是工作中的一项功能(https://github.com/kubernetes/kubernetes/issues/22368)。

您始终可以编写一个自定义pid1来通知confimap已更改,然后重新启动您的应用程序。

您还可以例如:在2个容器中装载相同的配置映射,在第二个容器中公开http运行状况检查,如果配置映射内容的哈希值发生更改,则该操作将失败,并将其作为第一个容器的活动性探针(由于容器位于pod共享相同的网络名称空间)。当探测失败时,kubelet将为您重新启动第一个容器。

当然,如果您不关心Pod位于哪个节点,则只需删除它们,复制控制器就会为您“重新启动”它们。


“删除窗格”的意思是:收集所有窗格名称,删除一个,等待直到被替换,删除第二个,等待直到被替换,等等。对吗?
Torsten Bronger '16

6
使用部署,我会先缩小然后再放大。但是,您仍然会有少量的停机时间。您可以在一行中完成操作以减少这种情况... kubectl scale deployment/update-demo --replicas=0; kubectl scale deployment/update-demo --replicas=4;
Nick H

如果您不想找到所有吊舱,也不必担心停机时间-只需删除RC,然后重新创建RC。
提请

1
这是否意味着它所挂载的卷已更新,您只需要重新读取Pod上的文件,而无需重新启动整个Pod?
马特·威廉姆森

@NickH方便又肮脏,幸运的是,在我看来,停机时间是可以接受的,这很好,谢谢!
ChocolateAndCheese

129

当前解决此问题的最佳方法(在同级答案中的https://github.com/kubernetes/kubernetes/issues/22368中进行了深入引用)是使用Deployments,并认为您的ConfigMap是不可变的。

当您要更改配置时,请使用要进行的更改创建一个新的ConfigMap,并将部署指向新的ConfigMap。如果新配置损坏,则部署将拒绝按比例缩小您的工作副本集。如果新配置有效,则旧的ReplicaSet将缩放为0个副本并删除,新的Pod将以新的配置启动。

速度不如仅编辑ConfigMap那样快,但更安全。


2
这也是我们采取的方法
Johan

4
值得一提的是,新的实验工具kustomize支持自动创建确定性的configmap哈希,这意味着您无需手动创建新的configmap:github.com/kubernetes-sigs/kustomize/blob/…–
对称

这就是Spinnaker在后台所做的事情,因此,如果您使用它,则不必担心。
Gus

31

https://github.com/kubernetes/helm/blob/master/docs/charts_tips_and_tricks.md#user-content-automatically-roll-deployments-when-configmaps-or-secrets-change

通常,将configmap或密钥作为配置文件注入到容器中。根据应用程序的不同helm upgrade,如果使用后续版本进行更新,则可能需要重新启动,但是如果部署规范本身未更改,则应用程序将继续使用旧配置运行,从而导致部署不一致。

sha256sum功能可以与该include功能一起使用,以确保在其他规范更改时更新部署模板部分:

kind: Deployment
spec:
  template:
    metadata:
      annotations:
        checksum/config: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
[...]

就我而言,由于某些原因,它$.Template.BasePath无法正常工作,但$.Chart.Name可以:

spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: admin-app
      annotations:
        checksum/config: {{ include (print $.Chart.Name "/templates/" $.Chart.Name "-configmap.yaml") . | sha256sum }}

8
不适用于Kubernetes的一般用法,仅适用于Helm
Emii Khaos,

2
答案很有帮助,但可能与该问题无关
Anand Singh Kunwar

helm3是最近发布的。因此,链接已过时。它指向master分支。下面的网址会导致(目前)最新helm2个文档:github.com/helm/helm/blob/release-2.16/docs/...
马塞尔·霍耶

很酷的解决方案。我更改为sha1sum,因为在我的情况下sha256sum具有65个字符,结果为Deployment.apps "xxx" is invalid: metadata.labels: Invalid value: "xxx": must be no more than 63 characters。替代方法是| trunc 63,但是sha1sum应该“更独特”。
iptizer

31

我发现最好的方法是运行Reloader

它允许您定义要查看的配置映射或机密,当它们更新时,将对您的部署执行滚动更新。这是一个例子:

您有一个部署foo和一个名为的ConfigMap foo-configmap。您希望每次更改configmap时都滚动部署的Pod。您需要使用以下命令运行Reloader:

kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml

然后在部署中指定此注释:

kind: Deployment
metadata:
  annotations:
    configmap.reloader.stakater.com/reload: "foo-configmap"
  name: foo
...

Reloader与kubernetes> = 1.9兼容
jacktrade

11

您可以更新与您的部署无关的元数据标签。它将触发滚动更新

例如:

metadata:
  labels:
    configmap-version: 1

我正在寻找有关元数据的文档:标签:configmap-version:1
c4f4t0r

7
元数据标签更改不会触发Pod重新启动
dan carter

这个答案有问题,所以我需要问。如果我们更新元数据,Kubernetes集群会触发滚动更新吗?@ maoz-zadok
titus

我相信只要元数据标签位于下方,此方法就可以正常工作template.spec
Saikiran Yerram

1

如果部署位于子图表中,而控制它的值位于父图表的值文件中,则出现此问题。这是我们用来触发重启的内容:

spec:
  template:
    metadata:
      annotations:
        checksum/config: {{ tpl (toYaml .Values) . | sha256sum }}

显然,这将在任何值更改时触发重新启动,但适用于我们的情况。仅当子图中的config.yaml更改时,子图中的原始内容才有效:

    checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }}

0

我执行了量子的解决方案,并且效果很好。但是我不明白的是,pod实际上并没有重新启动。pod仍然相同,但是有变化!

例如:Pod自50分钟运行以来,我进行了更改,并且更改已在线,因此我可以在浏览器中看到它,并且Pod仍在运行+50分钟!我正在使用Helm3 ...您知道在不重新启动configmap的情况下使这成为可能吗?


1
好!我发现了...因为我们将configmap挂载为一个卷并动态更新...这就是为什么当我执行此“'checksum'”操作时,我的pod不会重新启动,但是更改在那里了!好的解决方案:)
易卜拉欣·耶斯莱

-1

另一种方法是将其粘贴到“部署”的命令部分:

...
command: [ "echo", "
  option = value\n
  other_option = value\n
" ]
...

另外,要使其更像ConfigMap,请使用其他Deployment,它将只在该command部分中托管该配置并kubectl create在其上执行,同时为其名称添加唯一的“版本”(例如计算内容的哈希值)并修改所有使用该配置的部署:

...
command: [ "/usr/sbin/kubectl-apply-config.sh", "
  option = value\n
  other_option = value\n
" ]
...

kubectl-apply-config.sh如果它能正常工作,我可能会发布。

(不要那样做;它看起来太糟糕了)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.