一、k8s使用Reloader实现更新configmap后自动重启pod
一)configMap和secret更新存在的问题及解决方案概述
在日常使用kubernetes过程中,需要经常使用到configMap或Secret时,但存在的问题:在更新完configMap或secret后,已经启动的pod无法感知到其变化,不会滚动更新pod。给人感觉是新配置未生效。
如果业务自身支持 reload 操作,比如 nginx,那么我们可以使用 inotify 感知到文件更新或者直接定期 reload(可以配合 readinessProbe 一起使用)。但是如果业务不支持热加载配置,就需要使用到 Kubernetes 自身提供的滚动更新功能了。
由于更新 configmap 或 secret 不会触发 Pod 的滚动更新,所以需要引入一个开源工具 Reloader,它通过监控 Pod 引用的 configmap 或 secret 资源,如果发现变更,就会自动触发对 Deploymentconfigs、Deployment、Statefulset、Daemonsets 和 Rollouts 等资源的滚动更新。
二)安装Reloader
1、使用kubectl apply -f yaml文件安装
Reloader
- 限制条件:Kubernetes版本在1.9以及以上
- 集群安装
reloader
- 通过添加注解
annotation
的方式实现
kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml
1、全局 configmap 触发更新
apiVersion: apps/v1 kind: DaemonSet metadata: name: filebeat namespace: log labels: k8s-app: filebeat annotations: reloader.stakater.com/auto: "true"
2、按照指定的 configmap 变更自动触发资源对象的配置更新
单configMap更新
apiVersion: apps/v1 kind: DaemonSet metadata: name: filebeat namespace: log labels: k8s-app: filebeat annotations: configmap.reloader.stakater.com/reload: "filebeat-config"
多个configMap更新,以逗号对多个 configmap 进行隔离
apiVersion: apps/v1 kind: DaemonSet metadata: name: filebeat namespace: log labels: k8s-app: filebeat annotations: configmap.reloader.stakater.com/reload: "filebeat-config,devops-config"
checksum 注解
checksum 注解是 Helm Charts 中最常用的滚动更新方法,即在 Deployment 的 annotations 中加上 Secret 或者 ConfigMap 的 sha256sum,这样已有的 Pod 就会随着 Secret 或者 ConfigMap 的变更而更新。
kind: Deployment spec: template: metadata: annotations: checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} [...]
添加这一节的效果就是,在/configmap.yaml
中有任何内容改变,都会导致Deployment的sepc下的annotation被更新,进而驱动重建pod,达到我们想要的效果。
2、使用helm安装
添加helm仓库
helm repo add stakater https://stakater.github.io/stakater-charts
对helm仓库进行更新
helm repo update
使用helm安装Reloader
helm install stakater stakater/reloader
默认会将 Reloader 部署到 default 命名空间中。Reloader默认监控所有命名空间中的资源,若只是需要监控单一命名空间,name需要在使用helm安装时覆盖配置。
helm install ops-reloader stakater/reloader --set reloader.watchGlobally=false --namespace test
这样 Reloader 会安装到 test 命名空间中,并且只会监控该命名空间下的 Deployment、Statefulset、Daemonsets 和 Rollouts 资源。
如果只需要对 Configmap 和 Secret 中的一个资源进行监控,那么可以在 Helm 安装的过程中设置如下值来实现忽略 Secret 或 Configmap 资源(或者直接在 values.yaml 文件中设置):
需要注意的是,同一时刻只能有一个资源被忽略,如果同时忽略了两种资源会导致 Reloader 出现异常。如果的确不需要再对 Configmap 和 Secret 进行监控,可以将 Reloader Pod 的副本数设置为 0 或直接卸载
3、使用Kustomize安装
# kubectl apply --help -k, --kustomize='': Process a kustomization directory. This flag can't be used together with -f or -R. --openapi-patch=true: If true, use openapi to calculate diff when the openapi presents and the resource can be found in the openapi spec. Otherwise, fall back to use baked-in types.
如果想要部署到其他命名空间,可以将 Manifest 文件下载到本地后再进行修改。
使用 Manifest 同样可以配置对其中一种资源进行忽略,可以在 spec.template.spec.containers.args
下面配置如下参数
同一时刻只能有一种资源被忽略。
三)使用Reloader
1、监控所有configMap和secret并自动更新
例如:现在有一个名为devops的Deployment资源,并且引用了一个名为devops-confgmap的ConfigMap资源和一个名为devops-secret的Secret资源。那么我们可以在Deloyment的Manifest的metadata字段中添加如下注释信息
kind: Deployment metadata: name: devops annotations: reloader.stakater.com/auto: "true" spec: ... ...
这样Reloader就会发现这个Pod中引用的所有的ConfigMap或Secret,并且在这两个资源更新的时候滚动更新这个Pod。
如果另一个 Pod 也引用了同一个 ConfigMap 或者 Secret,但是没有添加注释信息,那么在 ConfigMap 或者 Secret 变更时,不会滚动更新这个 Pod
如果这个名称为 devops 的 Deployment 资源中引用了多个 ConfigMap 或者 Secret 资源,那么上面这样的配置就会导致任意一个 ConfigMap 或 Secret 资源更新时,都会触发 Pod 滚动更新。所以如果我们需要仅针对部分 ConfigMap 资源更新的情况再触发指定 Pod 的滚动更新,可以使用如下特殊的注释信息,首先在 Deploymentconfigs、Deployment、Statefulset、Daemonsets 或 Rollouts 的 Manifest 中定义如下注释:
kind: Deployment metadata: name: devops annotations: reloader.stakater.com/auto: "true" spec: ... ...
那么 Reloader 就会在任何标有如下注释信息的 ConfigMap 或 Secret 资源发生更新时滚动更新这个 Pod,不管这个 ConfigMap 或 Secret 资源是通过 volume 还是 env 方式挂载的
kind: ConfigMap metadata: annotations: reloader.stakater.com/match: "true" data: key: value
需要注意的一点是, reloader.stakater.com/search 和 reloader.stakater.com/auto 不能同时生效。如果已经指定了 reloader.stakater.com/auto: "true" 这个注释,那么这个 Pod 就会在任何一个 ConfigMap 或 Secret 改变时开始滚动更新,不论是否还有其他的相关注释。
2、监控指定的 ConfigMap 资源
Reloader 也支持监控指定的 ConfigMap 或 Secret 资源,在这些资源发生变更时才会触发滚动更新。这样就避免了在 Pod 中使用的任意 ConfigMap 或 Secret 发生变化时都会滚动升级 Pod。实现这种方式之前,首先需要删除 reloader.stakater.com/auto 注释,或者将其设置为 "false"。
例如现在有一个名为 devops的 Deployment 资源,并且其中引用了多个 ConfigMap 资源,现在指定只有其中名为 foo-configmap 的资源更新时才触发 Deployment 的滚动升级,那么需要在 Deployment 的 metadata 中指定如下注释:
kind: Deployment metadata: annotations: configmap.reloader.stakater.com/reload: "devops-configmap" spec: template: metadata:
也可以同时指定多个ConfigMap资源
kind: Deployment metadata: annotations: configmap.reloader.stakater.com/reload: "devops-configmap,dev-configmap,ops-configmap" spec: template: metadata:
3、健康指定的secret资源
监控指定的 Secret 资源也是同样的方式,不过注释的内容需要更改为 secret.reloader.stakater.com/reload
:
kind: Deployment metadata: annotations: secret.reloader.stakater.com/reload: "devops-secret" spec: template: metadata:
也可以指定多个Secret
kind: Deployment metadata: annotations: secret.reloader.stakater.com/reload: "devops-secret,dev-secret,ops-secret" spec: template: metadata:
四)对Reloader配置进行更改
Reloader 在安装或更新的时候支持对其部分配置进行修改,参考如下表: