网站首页 > 文章精选 正文
一 背景
1.1 配置中心问题
在云原生中配置中心,例如:Configmap和Secret对象,虽然可以进行直接更新资源对象
- 对于引用这些有些不变的配置是可以打包到镜像中的,那可变的配置呢?
- 信息泄漏,很容易引发安全风险,尤其是一些敏感信息,比如密码、密钥等。
- 每次配置更新后,都要重新打包一次,升级应用。镜像版本过多,也给镜像管理和镜像中心存储带来很大的负担。
- 定制化太严重,可扩展能力差,且不容易复用。
1.2 使用方式
Configmap或Secret使用有两种方式,一种是env系统变量赋值,一种是volume挂载赋值,env写入系统的configmap是不会热更新的,而volume写入的方式支持热更新!
- 对于env环境的,必须要滚动更新pod才能生效,也就是删除老的pod,重新使用镜像拉起新pod加载环境变量才能生效。
- 对于volume的方式,虽然内容变了,但是需要我们的应用直接监控configmap的变动,或者一直去更新环境变量才能在这种情况下达到热更新的目的。
应用不支持热更新,可以在业务容器中启动一个sidercar容器,监控configmap的变动,更新配置文件,或者也滚动更新pod达到更新配置的效果。
二 解决方案
ConfigMap 和 Secret 是 Kubernetes 常用的保存配置数据的对象,你可以根据需要选择合适的对象存储数据。通过 Volume 方式挂载到 Pod 内的,kubelet 都会定期进行更新。但是通过环境变量注入到容器中,这样无法感知到 ConfigMap 或 Secret 的内容更新。
目前如何让 Pod 内的业务感知到 ConfigMap 或 Secret 的变化,还是一个待解决的问题。但是我们还是有一些 Workaround 的。
如果业务自身支持 reload 配置的话,比如nginx -s reload,可以通过 inotify 感知到文件更新,或者直接定期进行 reload(这里可以配合我们的 readinessProbe 一起使用)。
如果我们的业务没有这个能力,考虑到不可变基础设施的思想,我们是不是可以采用滚动升级的方式进行?没错,这是一个非常好的方法。目前有个开源工具Reloader,它就是采用这种方式,通过 watch ConfigMap 和 Secret,一旦发现对象更新,就自动触发对 Deployment 或 StatefulSet 等工作负载对象进行滚动升级。
三 reloader简介
3.1 reloader简介
Reloader 可以观察 ConfigMap 和 Secret 中的变化,并通过相关的 deploymentconfiggs、 deploymentconfiggs、 deploymonset 和 statefulset 对 Pods 进行滚动升级。
3.2 reloader安装
- helm安装
$helmrepoaddstakaterhttps://stakater.github.io/stakater-charts
$helmrepoupdate
$helminstallstakater/reloader
- Kustomize
$kubectlapply-khttps://github.com/stakater/Reloader/deployments/kubernetes
- 资源清单安装
$kubectlapply-fhttps://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml
clusterrole.rbac.authorization.k8s.io/reloader-reloader-rolecreated
clusterrolebinding.rbac.authorization.k8s.io/reloader-reloader-role-bindingcreated
deployment.apps/reloader-reloadercreated
serviceaccount/reloader-reloadercreated
NAMEREADYSTATUSRESTARTSAGE
pod/reloader-reloader-66d46d5885-nx64t1/1Running015s
NAMEREADYUP-TO-DATEAVAILABLEAGE
deployment.apps/reloader-reloader1/11116s
NAMEDESIREDCURRENTREADYAGE
replicaset.apps/reloader-reloader-66d46d588511116s
reloader 能够配置忽略cm或者secrets资源,可以通过配置在reader deploy中的spec.template.spec.containers.args,如果两个都忽略,那就缩小deploy为0,或者不部署reoader。
ArgsDescription--resources-to-ignore=configMapsTo ignore configMaps--resources-to-ignore=secretsTo ignore secrets
3.3 配置
3.3.1 自动更新
reloader.stakater.com/search 和 reloader.stakater.com/auto 并不在一起工作。如果你在你的部署上有一个 reloader.stakater.com/auto : "true"的注释,该资源对象引用的所有configmap或这secret的改变都会重启该资源,不管他们是否有 reloader.stakater.com/match : "true"的注释。
kind:Deployment
metadata:
annotations:
reloader.stakater.com/auto:"true"
spec:
template: metadata:
3.3.2 制定更新
指定一个特定的configmap或者secret,只有在我们指定的配置图或秘密被改变时才会触发滚动升级,这样,它不会触发滚动升级所有配置图或秘密在部署,后台登录或状态设置中使用。
一个制定deployment资源对象,在引用的configmap或者secret种,只有reloader.stakater.com/match: "true"为true才会出发更新,为false或者不进行标记,该资源对象都不会监视配置的变化而重启。
kind:Deployment
metadata:
annotations:
reloader.stakater.com/search:"true"
spec:
template:
cm配置
kind:ConfigMap
metadata:
annotations:
reloader.stakater.com/match:"true"
data:
key:value
3.3.3 指定cm
如果一个deployment挂载有多个cm或者的场景下,我们只希望更新特定一个cm后,deploy发生滚动更新,更新其他的cm,deploy不更新,这种场景可以将cm在deploy中指定为单个或着列表实现。
例如:一个deploy有挂载nginx-cm1和nginx-cm2两个configmap,只想nginx-cm1更新的时候deploy才发生滚动更新,此时无需在两个cm中配置注解,只需要在deploy中写入configmap.reloader.stakater.com/reload:nginx-cm1,其中nginx-cm1如果发生更新,deploy就会触发滚动更新。
如果多个cm直接用逗号隔开
# configmap对象
kind:Deployment
metadata:
annotations:
configmap.reloader.stakater.com/reload:"nginx-cm1"
spec:
template: metadata:
# secret对象
kind:Deployment
metadata:
annotations:
secret.reloader.stakater.com/reload:"foo-secret"
spec:
template: metadata:
无需在cm或secret中添加注解,只需要在引用资源对象中添加注解即可。
四 测试
4.1 deploy
apiVersion:apps/v1
kind:Deployment
metadata:
annotations:
reloader.stakater.com/search:"true"
labels:
run:nginx
name:nginx
namespace:default
spec:
replicas:1
selector:
matchLabels:
run:nginx
template:
metadata:
labels:
run:nginx
spec:
containers:
-image:nginx
name:nginx
volumeMounts:
-name:nginx-cm
mountPath:/data/cfg
readOnly:true
volumes:
-name:nginx-cm
configMap:
name:nginx-cm
items:
-key:config.yaml
path:config.yaml
mode:0644
4.2 configmap
apiVersion:v1
data:
config.yaml:|
# project settings
DEFAULT_CONF:
port: 8888
UNITTEST_TENCENT_ZONE: ap-chongqing-1
kind:ConfigMap
metadata:
name:nginx-cm
annotations:
reloader.stakater.com/match:"true"
4.3 测试
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-68c9bf4ff7-9gmg6 1/1 Running 0 10m
$ kubectl get cm
NAME DATA AGE
nginx-cm 1 28m
# 更新cm内容
$ kubectl edit cm nginx-cm
configmap/nginx-cm edited
# 查看po发生了滚动更新,重新加载配置文件
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-66c758b548-9dllm 0/1 ContainerCreating 0 4s
nginx-68c9bf4ff7-9gmg6 1/1 Running 0 10m
五 Reloader 使用注意事项
- Reloader 为全局资源对象,建议部署在一个公共服务的ns下,然后其他ns也可以正常使用reloader特性。
- Reloader.stakater.com/auto : 如果配置configmap或者secret在 deploymentconfigmap/deployment/daemonsets/Statefulsets
- secret.reloader.stakater.com/reload 或者 configmap.reloader.stakater.com/reload 注释中被使用,那么 true 只会重新加载 pod,不管使用的是 configmap 还是 secret。
- reloader.stakater.com/search 和 reloader.stakater.com/auto 不能同时使用。如果你在你的部署上有一个 reloader.stakater.com/auto : "true"的注释,那么它总是会在你修改了 configmaps 或者使用了机密之后重新启动,不管他们是否有 reloader.stakater.com/match : "true"的注释。
六 反思
Reloader通过 watch ConfigMap 和 Secret,一旦发现对象更新,就自动触发对 Deployment 或 StatefulSet 等工作负载对象进行滚动升级。
如果我们的应用内部没有去实时监控配置文件,利用该方式可以非常方便的实现配置的热更新。
猜你喜欢
- 2025-07-09 五分钟轻松熟悉一个k8s Operator应用制作
- 2025-07-09 iLogtail 使用入门 - K8S 环境日志采集到 SLS
- 2025-07-09 k8s之配置CNI网络(k8s 网络配置)
- 2025-07-09 Linux系统K8S集群架构及常用操作命令之K9S安装及使用
- 2025-07-09 Centos 安装部署Kubernetes(K8s)(k8s环境搭建 centos)
- 2025-07-09 集群外部署Prometheus+Grafana监控K8S解析
- 2025-07-09 k8s安装UI管理工具Kuboard安装(k8s安装步骤)
- 2025-07-09 k8s中使用Helm安装生产级别redis集群
- 2025-07-09 K8s集群(K8s集群添加新节点更新步骤)
- 2025-07-09 Kubernetes (k8s) 基本命令速查(k8s kubernetes教程)
- 最近发表
-
- 五分钟轻松熟悉一个k8s Operator应用制作
- iLogtail 使用入门 - K8S 环境日志采集到 SLS
- k8s之配置CNI网络(k8s 网络配置)
- Linux系统K8S集群架构及常用操作命令之K9S安装及使用
- Centos 安装部署Kubernetes(K8s)(k8s环境搭建 centos)
- 集群外部署Prometheus+Grafana监控K8S解析
- k8s安装UI管理工具Kuboard安装(k8s安装步骤)
- k8s中使用Helm安装生产级别redis集群
- K8s集群(K8s集群添加新节点更新步骤)
- Kubernetes (k8s) 基本命令速查(k8s kubernetes教程)
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)
- mysql数据库面试题 (57)