当它们的configmap被更改/更新时,我如何自动重新启动Kubernetes pod和与部署相关的pod ?
我知道有关于在配置映射发生变化时自动重启pod的讨论,但据我所知,这在Kubernetes 1.2中还没有。
因此(我认为)我想做的是“滚动重新启动”与使用配置映射的pod相关联的部署资源。在Kubernetes中,在不改变实际模板的情况下强制滚动重启部署是否可能?如果可能的话,如何实现?这是目前最好的方式还是有更好的选择?
当它们的configmap被更改/更新时,我如何自动重新启动Kubernetes pod和与部署相关的pod ?
我知道有关于在配置映射发生变化时自动重启pod的讨论,但据我所知,这在Kubernetes 1.2中还没有。
因此(我认为)我想做的是“滚动重新启动”与使用配置映射的pod相关联的部署资源。在Kubernetes中,在不改变实际模板的情况下强制滚动重启部署是否可能?如果可能的话,如何实现?这是目前最好的方式还是有更好的选择?
当前回答
考虑使用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'd ConfigMap名称的更改外,没有其他用途,这也应该导致重新启动pod。然后就变成:
其他回答
我发现最好的方法是运行Reloader
它允许您定义要监视的配置映射或秘密,当它们更新时,将执行部署的滚动更新。这里有一个例子:
你有一个部署foo和一个名为foo- ConfigMap的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
...
Helm 3文档页
通常情况下,配置映射或秘密作为配置文件注入到容器中。根据应用程序的不同,如果后续的头盔升级更新了这些配置,则可能需要重新启动,但如果部署规范本身没有更改,则应用程序将继续使用旧配置运行,从而导致部署不一致。
sha256sum函数可以与include函数一起使用,以确保在其他规范更改时更新部署模板部分:
kind: Deployment
spec:
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
[...]
在我的例子中,由于某些原因,$. template。BasePath没有工作,但$. chart。名称:
spec:
replicas: 1
template:
metadata:
labels:
app: admin-app
annotations:
checksum/config: {{ include (print $.Chart.Name "/templates/" $.Chart.Name "-configmap.yaml") . | sha256sum }}
您可以更新与您的部署无关的元数据注释。它将触发滚动更新
例如:
spec:
template:
metadata:
annotations:
configmap-version: 1
向配置映射添加不可变属性完全避免了这个问题。使用配置散列有助于无缝滚动更新,但对回滚没有帮助。你可以看看这个开源项目- 'Configurator' - https://github.com/gopaddle-io/configurator.git .'Configurator'通过以下使用自定义资源工作:
配置器将部署生命周期与configMap绑定在一起。当 配置映射被更新,并为此创建一个新版本 configMap。所有附加到configMap的部署 获得与最新configMap版本绑定的滚动更新。 当您将部署回滚到旧版本时,它会反弹到 configMap在滚动更新之前的版本。
通过这种方式,您可以维护配置映射的版本,并方便与配置映射一起滚转和回滚到部署。
目前这个问题的最佳解决方案(在兄弟回答的https://github.com/kubernetes/kubernetes/issues/22368链接中有深入引用)是使用部署,并将configmap视为不可变的。
当您想要更改配置时,请创建一个带有您想要进行更改的新ConfigMap,并将部署指向新的ConfigMap。如果新的配置被破坏,部署将拒绝缩小您的工作ReplicaSet。如果新的配置有效,那么旧的ReplicaSet将被缩放为0副本并删除,新的pod将使用新的配置启动。
虽然没有编辑ConfigMap那么快,但是更安全。