3. ConfigMap 实战:挂载配置文件、环境变量注入与热更新机制
ConfigMap 是 Kubernetes 中用于将非机密配置数据与 Pod 解耦的核心 API 对象。本章围绕三种典型使用模式——文件挂载、环境变量注入和热更新——展开实战讲解,并对比不同方式的适用场景与限制。
3.1 ConfigMap 创建方式对比
| 创建方式 | 命令示例 | 适用场景 |
|---|---|---|
| 字面量 | kubectl create configmap app-cfg --from-literal=key=value |
少量键值对,快速测试 |
| 文件 | kubectl create configmap app-cfg --from-file=app.properties |
完整配置文件,保留文件结构 |
| 目录 | kubectl create configmap app-cfg --from-file=config-dir/ |
多配置文件批量导入 |
| YAML 声明式 | kubectl apply -f configmap.yaml |
版本管理、CI/CD 集成 |
推荐做法:生产环境始终使用 YAML 声明式创建 ConfigMap,并纳入 Git 版本控制。字面量和文件方式适合开发调试阶段快速验证。
3.2 模式一:环境变量注入
将 ConfigMap 中的键值对以环境变量形式注入容器,适用于应用通过环境变量读取配置的场景(如 12-Factor App 风格)。
apiVersion: v1
kind: Pod
metadata:
name: env-demo
spec:
containers:
- name: app
image: nginx:1.25
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: database.host
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: app-config
key: database.port
envFrom:
- configMapRef:
name: app-config
optional: true
注意:通过
envFrom 批量注入时,如果 ConfigMap 中存在无效环境变量名(如包含连字符),Kubernetes 会跳过该键且不报错。建议使用 env 逐一定义关键变量,或确保键名符合环境变量命名规范(大写字母、数字、下划线)。
3.3 模式二:配置文件挂载
将 ConfigMap 以 Volume 形式挂载到容器文件系统,适用于应用需要读取完整配置文件(如 nginx.conf、application.yml)的场景。
apiVersion: v1
kind: Pod
metadata:
name: volume-demo
spec:
containers:
- name: app
image: nginx:1.25
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/conf.d
readOnly: true
volumes:
- name: config-volume
configMap:
name: nginx-config
items:
- key: default.conf
path: default.conf
关键行为:挂载 ConfigMap 时,如果
mountPath 指向一个已有目录,该目录下的原有文件会被隐藏(仅保留挂载的文件)。如需保留原有文件,使用 subPath 挂载单个文件。
3.4 模式三:热更新机制
ConfigMap 更新后,已挂载到 Pod 中的内容不会自动刷新,但 Kubernetes 会通过 inotify 机制在容器文件系统中同步更新。应用需要自行监听文件变化或触发重载。
3.5 热更新实战:Nginx 配置动态重载
以下示例展示如何利用 ConfigMap 挂载 + 容器内信号机制实现 Nginx 配置热更新。
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
default.conf: |
server {
listen 80;
server_name example.com;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-hotreload
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d
readOnly: true
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "while true; do inotifywait -e modify /etc/nginx/conf.d; nginx -s reload; done &"]
volumes:
- name: config
configMap:
name: nginx-config
生产建议:使用
inotifywait 或 fsnotify(Go)监听配置文件变更,触发应用重载。对于不支持热重载的应用(如 Java Spring Boot),可结合 preStop 钩子和滚动更新策略实现优雅重启。
3.6 三种注入方式对比总结
| 特性 | 环境变量注入 | 文件挂载 | subPath 挂载 |
|---|---|---|---|
| 热更新支持 | ❌ 不支持 | ✅ 支持(需应用监听) | ❌ 不支持 |
| 配置结构 | 扁平键值对 | 保留文件目录结构 | 单个文件 |
| 适用应用 | 12-Factor App | 传统配置文件应用 | 需保留目录原有文件 |
| 更新延迟 | 需重启 Pod | 10-30 秒 | 需重启 Pod |
| 推荐场景 | 数据库连接、开关标识 | Nginx、Redis、Logstash | 与 Sidecar 共享目录 |
安全提醒:ConfigMap 数据以明文存储,切勿存放密码、、证书等敏感信息。敏感配置请使用 Secret 对象,并启用加密存储(如 KMS 或 etcd 加密)。