内容简介:在 Kubernetes 的使用过程中,很多人会使用 Configmap 资源来进行配置文件的加载。Configmap 对象是支持热更新的,也就是说,对 Configmap 的变更,会同时反应到加载该 Configmap 的 Pod 之中。但美中不足的是,很多应用都不会检测配置文件的更新,因此就算是通过对 Configmap 的变更,完成了配置文件的修改,应用还是无法做出即时的响应的。可以在外部进行滚动更新;或者改写业务容器,监控文件变化之后重新启动业务进程。在 Kubernetes 1.10 中新增的 P
在 Kubernetes 的使用过程中,很多人会使用 Configmap 资源来进行配置文件的加载。Configmap 对象是支持热更新的,也就是说,对 Configmap 的变更,会同时反应到加载该 Configmap 的 Pod 之中。但美中不足的是,很多应用都不会检测配置文件的更新,因此就算是通过对 Configmap 的变更,完成了配置文件的修改,应用还是无法做出即时的响应的。可以在外部进行滚动更新;或者改写业务容器,监控文件变化之后重新启动业务进程。
在 Kubernetes 1.10 中新增的 Pod 内共享进程命名空间的功能,给这个问题带来了一点新思路:做一个 Sidecar 用于对配置文件进行监控,发现文件变化之后,发送重新载入的信号给业务进程,要求业务进程自行刷新。这样就无需对业务容器所在镜像进行修改了。
这种方法当然也有个局限性,需要业务进程支持这种信号。
下面以 Apache 为例,看看这种方式的用法。
创建 Configmap
用一个简化的 httpd.conf
文件,生成 Configmap,例如:
kubectl create cm apache --from-file httpd.conf
如此就生成了一个名为 apache 的 Configmap。
创建 Sidecar 容器镜像
这个镜像要完成的任务有两个:监控文件变化,如果内容变化,则发送信号给业务进程。文件内容变化的监控,可以用哈希码或者 inotify 调用来完成,这里使用 inotifywait
命令做一个死循环,发现特定事件后,则发出信号:
#!/bin/sh
while :
do
# 获取文件名称
REAL=`readlink -f ${FILE}`
# 监控指定事件
inotifywait -e delete_self "${REAL}"
# 获取特定进程名称的 PID
PID=`pgrep ${PROCESS} | head -1`
# 发送信号
kill "-${SIGNAL}" "${PID}"
done
这里没有用监控本地文件的 -m
或者 -e modify
事件,而是用了 delete_self
,这是 Configmap 加载生成文件的差异,也可以考虑用环境变量来替换这一事件。
然后构建镜像:
FROM alpine RUN apk add --update inotify-tools ENV FILE="/tmp" PROCESS="httpd" SIGNAL="USR1" COPY entry.sh /usr/local/bin CMD ["/usr/local/bin/entry.sh"]
这里假设镜像名称为 dustise/inotify:latest
。
创建实验负载
我们选择 Apache 作为业务应用的示范,它能够接受 USR1
信号进行重新载入。
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: apache
spec:
selector:
matchLabels:
app: apache
template:
metadata:
labels:
app: apache
spec:
shareProcessNamespace: true
containers:
- name: apache
image: httpd:alpine
ports:
- containerPort: 80
volumeMounts:
- name: apache
mountPath: /usr/local/apache2/conf/
- name: refresh
image: dustise/inotify
securityContext:
capabilities:
add:
- SYS_PTRACE
volumeMounts:
- name: apache
mountPath: /etc/httpd
env:
- name: FILE
value: "/etc/httpd/httpd.conf"
- name: PROCESS
value: "httpd"
- name: SIGNAL
value: "USR1"
volumes:
- name: apache
configMap:
name: apache
---
apiVersion: v1
kind: Service
...
type: ClusterIP
这段代码:
-
在
template.spec中加入了shareProcessNamespace: true,表示启用进行命名空间共享功能; - 新建了一个伴行的 Sidecar 容器;
- Apache 和 Sidecar 共享来自同一个 Configmap 的配置文件,根据加载情况为 Sidecar 定义了环境变量。
测试一下
接下来可以使用 kubectl logs
命令来监控两个容器的日志输出:
$ kubectl logs -f apache-6b8b68c857-dp6xx -c refresh Setting up watches. Watches established. $ kubectl logs -f apache-6b8b68c857-dp6xx -c apache ... [Wed May 15 18:46:47.795261 2019] [mpm_event:notice] [pid 7:tid 139810635549544] AH00489: Apache/2.4.39 (Unix) configured -- resuming normal operations [Wed May 15 18:46:47.795330 2019] [core:notice] [pid 7:tid 139810635549544] AH00094: Command line: 'httpd -D FOREGROUND'
然后使用 kubectl edit cm apache
,修改配置文件(例如删除点注释)。稍候片刻,发现两个容器的输出都发生了变化:
Sidecar
/etc/httpd/..2019_05_15_18_43_33.773288813/httpd.conf DELETE_SELF Setting up watches. Watches established.
脚本检测到了配置文件发生了删除事件,发送信号,并重新启动监控。
Apache
[Wed May 15 18:46:47.775392 2019] [mpm_event:notice] [pid 7:tid 139810635549544] AH00493: SIGUSR1 received. Doing graceful restart
Apache 收到了 USR1 信号,进行了优雅重启。
结论
对于支持信号控制的第软件,例如 Nginx、Gunicorn、HA-Proxy 等都可以使用这种方式来完成配置刷新工作。能够有效的避免重启或修改业务应用的老大难问题。
以上所述就是小编给大家介绍的《用 Sidecar 应用 Configmap 更新》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Domain-Driven Design Distilled
Vaughn Vernon / Addison-Wesley Professional / 2016-6-2 / USD 36.99
Domain-Driven Design (DDD) software modeling delivers powerful results in practice, not just in theory, which is why developers worldwide are rapidly moving to adopt it. Now, for the first time, there......一起来看看 《Domain-Driven Design Distilled》 这本书的介绍吧!