如何在配置映射更改/更新时自动重新启动与部署关联的 Kubernetes Pod 及其相关 Pod?
我知道已经谈论了在配置映射更改时自动重新启动Pod的能力,但据我所知,这在Kubernetes 1.2中尚不可用。
因此,我想要做的(我认为)是对消耗该配置映射的Pod相关的部署资源进行“滚动重启”。是否有可能强制在Kubernetes中滚动重启部署而不更改实际模板中的任何内容?目前这是最好的方法还是存在更好的选择?
如何在配置映射更改/更新时自动重新启动与部署关联的 Kubernetes Pod 及其相关 Pod?
我知道已经谈论了在配置映射更改时自动重新启动Pod的能力,但据我所知,这在Kubernetes 1.2中尚不可用。
因此,我想要做的(我认为)是对消耗该配置映射的Pod相关的部署资源进行“滚动重启”。是否有可能强制在Kubernetes中滚动重启部署而不更改实际模板中的任何内容?目前这是最好的方法还是存在更好的选择?
目前解决此问题最好的方法(在https://github.com/kubernetes/kubernetes/issues/22368 中提到,链接在兄弟回答中)是使用部署(Deployments),并将您的ConfigMaps视为不可变。
当您想要更改配置时,创建一个新的ConfigMap,并在其中包含您想要进行的更改,并将您的部署指向新的ConfigMap。如果新配置无效,则部署将拒绝缩小工作的副本集。如果新配置有效,则旧的ReplicaSet将缩放为0个副本并删除,新的Pod将使用新的配置启动。
虽然不如直接就地编辑ConfigMap快速,但更加安全。
在配置地图更新时发出Pod信号是正在开发的功能(https://github.com/kubernetes/kubernetes/issues/22368)。
您始终可以编写自定义pid1以注意到confimap已更改并重新启动您的应用程序。
您还可以例如:在2个容器中挂载相同的配置地图,在第二个容器中公开HTTP健康检查,如果配置地图内容的哈希值发生更改,则失败,并将其作为第一个容器的活动探针推送(因为Pod中的容器共享同一网络命名空间)。当探测失败时,kubelet会为您重启第一个容器。
当然,如果您不关心Pod在哪些节点上,可以直接删除它们,复制控制器将为您“重新启动”它们。
kubectl scale deployment/update-demo --replicas=0; kubectl scale deployment/update-demo --replicas=4;
- Nick Hkubectl rollout restart deployment/my-deploy
,k8s 将管理类似于更新部署的滚动重启。这也适用于 DaemonSets 和 StatefulSets。 - nijave我发现最好的方法是运行Reloader
它允许您定义要监视的configmaps或secrets,当它们被更新时,会执行您的deployment的滚动更新。下面是一个例子:
假设您有一个部署foo
和一个名为foo-configmap
的ConfigMap。 每次更改configmap时,您希望滚动deployment的pods。 您需要使用以下命令运行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
...
通常情况下,配置文件以 configmap 或 secret 的形式注入到容器中。根据应用程序的不同,在使用 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 }}
helm
3。因此,该链接已过时。它指向master
分支。以下URL将引导您进入(目前)最新的helm
2文档:https://github.com/helm/helm/blob/release-2.16/docs/charts_tips_and_tricks.md#automatically-roll-deployments-when-configmaps-or-secrets-change - Marcel Hoyer对于 k8s
>
1.15
版本,作为 CI/CD 的一部分,使用配置路径连接到卷挂载的方式进行滚动重启 对我来说效果最好。使用重新加载插件或在部署清单 YML 中设置restartPolicy: Always
并不适用于我。无需更改应用程序代码,对于静态资源和微服务都有效。
kubectl rollout restart deployment/<deploymentName> -n <namespace>
您可以更新与您的部署不相关的元数据注释。这将触发滚动更新。
例如:
例如:
spec:
template:
metadata:
annotations:
configmap-version: 1
template.spec
下面,我相信这个方法是可行的。 - Saikiran Yerramspec.template.metadata.labels
下的标签可以起作用!(已编辑答案,正在审核中)。这是一种非常优雅的方法 👍 - Alok Kumar Singhkubectl rollout restart deployment/mydeployname
来触发相同配置的新部署。https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#-em-restart-em- - Symmetric我曾遇到这样的问题:部署在子图表中,而控制它的值则在父级图表的值文件中。以下是我们用来触发重启的代码:
spec:
template:
metadata:
annotations:
checksum/config: {{ tpl (toYaml .Values) . | sha256sum }}
显然,这将在任何值更改时触发重新启动,但它适用于我们的情况。最初在子图表中的内容仅在子图表中的config.yaml更改时才起作用:
checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }}
kustomize
(或 kubectl apply -k
)并利用其强大的 configMapGenerator
功能。例如,来自:https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/configmapgenerator/。apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# Just one example of many...
- name: my-app-config
literals:
- JAVA_HOME=/opt/java/jdk
- JAVA_TOOL_OPTIONS=-agentlib:hprof
# Explanation below...
- SECRETS_VERSION=1
然后,在您的部署中简单引用my-app-config
。使用kustomize
进行构建时,它将自动查找并更新对my-app-config
的引用,以及带有更新后缀(例如 my-app-config-f7mm6mhf59
)。
奖励提示:更新密码:我还使用此技术来强制重新加载密码(因为它们受到相同的影响)。虽然我个人完全独立地管理我的密码(使用Mozilla的sops),但您可以在密钥保管库旁边捆绑一个配置映射,例如:部署中:
# ...
spec:
template:
spec:
containers:
- name: my-app
image: my-app:tag
envFrom:
# For any NON-secret environment variables. Name is automatically updated by Kustomize
- configMapRef:
name: my-app-config
# Defined separately OUTSIDE of Kustomize. Just modify SECRETS_VERSION=[number] in the my-app-config ConfigMap
# to trigger an update in both the config as well as the secrets (since the pod will get restarted).
- secretRef:
name: my-app-secrets
然后,像我上面所做的那样,在你的 ConfigMap 中添加一个变量,如 SECRETS_VERSION
。每次更改 my-app-secrets
时,只需增加 SECRETS_VERSION
的值,除了触发 kustomize
的 ConfigMap 名称更改外,它没有任何其他作用,这也应该导致 pod 重新启动。所以现在变成了:
我也在这个问题上纠结了很长时间,希望能以一种优雅而快速的方式解决它。
这是我的20美分:
使用标签作为答案,如here所述,如果您正在更新标签,则不起作用。但如果您始终添加标签,则可以起作用。更多详细信息请参见here。
提到的答案here是我认为最优雅的快速解决方法,但它处理删除时会有问题。我补充了这个答案:
我正在其中一个Kubernetes Operator中执行此操作,其中在一个协调循环中只执行一个任务。
v2
。version: v2
和product: prime
的ConfigMap cm-v2
并返回。如果存在,请执行下一步。product: prime
但不具有version: v2
的部署。如果找到此类部署,请删除它们并返回。否则,执行下一步。product: prime
但不具有version: v2
的ConfigMap。否则,执行下一步。product: prime
和version: v2
的Deployment deployment-v2
,并将配置地图附加为cm-v2
,然后返回。否则,不执行任何操作。本地选项无需第三方
Kubernetes如果将配置映射作为卷挂载(如果有子路径则不适用),它会自动重新加载。
示例:https://medium.com/@harsh.manvar111/update-configmap-without-restarting-pod-56801dce3388
第三方选项
当更改/更新其configmap时,如何自动重启与部署相关的Kubernetes pod和pod?
如果您将configmap用作环境,则必须使用外部选项。
当卷中使用的 ConfigMap 被更新时,投影键也被最终更新。kubelet 检查每个周期同步时装载的 ConfigMap 是否是最新的。但是,kubelet 用其本地缓存获取 ConfigMap 的最新值。可以使用 KubeletConfiguration 结构中的 ConfigMapAndSecretChangeDetectionStrategy 字段配置缓存类型。ConfigMap 可以通过 watch (默认),基于 ttl 或将所有请求直接重定向到 API server 进行传播。因此,从 ConfigMap 更新到新键被投影到 Pod 的时间总延迟可能长达 kubelet 同步周期 + 缓存传播延迟,其中缓存传播延迟取决于所选缓存类型(它等于 watch 传播延迟、缓存的 ttl 或零,分别对应不同缓存类型)。apiVersion: v1
kind: ConfigMap
metadata:
name: config
namespace: default
data:
foo: bar
POD配置
spec:
containers:
- name: configmaptestapp
image: <Image>
volumeMounts:
- mountPath: /config
name: configmap-data-volume
ports:
- containerPort: 8080
volumes:
- name: configmap-data-volume
configMap:
name: config
$ kubectl set env deployment my deployment --env="LAST_RESTART=$(date)" --namespace ...
。 - maciek