Pod 挂载 ConfigMap 的方式有哪些?
在 Kubernetes 中,ConfigMap 用于将配置数据与容器镜像解耦。Pod 挂载或使用 ConfigMap 主要有以下 4 种常见方式,外加一种通过 API 调用的方式。
以下是详细的分类和 YAML 示例:
1. 通过环境变量注入 (Environment Variables)
这是最常用的方式,适合遵循 "12-Factor App" 原则的应用。
A. 映射单个 Key 到指定环境变量
你可以选择 ConfigMap 中的特定 Key,将其赋值给容器内的特定环境变量名。
apiVersion: v1
kind: Pod
metadata:
name: env-single-pod
spec:
containers:
- name: test-container
image: busybox
env:
- name: SPECIAL_LEVEL_KEY # 容器内的环境变量名
valueFrom:
configMapKeyRef:
name: my-config # ConfigMap 的名称
key: log_level # ConfigMap 中的 Key
B. 将所有 Key 注入为环境变量 (envFrom)
如果 ConfigMap 中有很多键值对,可以使用 envFrom 一次性将所有 Key 导入为环境变量。
apiVersion: v1
kind: Pod
metadata:
name: env-all-pod
spec:
containers:
- name: test-container
image: busybox
envFrom:
- configMapRef:
name: my-config # ConfigMap 的名称
注意:ConfigMap 中的 Key 如果包含非法字符(如点号 .),在转换为环境变量时可能会被忽略或转换。
2. 通过数据卷挂载 (Volume Mount)
这种方式会将 ConfigMap 中的数据以文件的形式挂载到容器的文件系统中。
A. 挂载整个 ConfigMap (目录覆盖)
ConfigMap 中的每个 Key 会变成一个文件名,Value 变成文件内容。
特点:ConfigMap 更新后,容器内的文件会自动更新(有延迟),无需重启 Pod。
apiVersion: v1
kind: Pod
metadata:
name: volume-pod
spec:
containers:
- name: test-container
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/config # 挂载路径,该目录下的原有文件会被覆盖
volumes:
- name: config-volume
configMap:
name: my-config
B. 挂载特定的 Key (使用 items)
只挂载 ConfigMap 中的部分 Key,并且可以重命名生成的文件。
volumes:
- name: config-volume
configMap:
name: my-config
items:
- key: log_level # ConfigMap 中的 Key
path: app-log.conf # 挂载后的文件名
C. 使用 subPath 挂载单个文件 (不覆盖目录)
如果你想把配置文件挂载到 /etc/nginx/nginx.conf,但不想覆盖 /etc/nginx/ 下的其他文件,必须使用 subPath。
注意:使用 subPath 挂载的文件无法自动热更新。
apiVersion: v1
kind: Pod
metadata:
name: subpath-pod
spec:
containers:
- name: test-container
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/nginx.conf # 具体的文件路径
subPath: nginx.conf # 对应 volumes 中 items 的 path 或 key
volumes:
- name: config-volume
configMap:
name: my-config
3. 在容器命令中使用 (Command Line Arguments)
你可以利用 Kubernetes 的变量替换功能,先将 ConfigMap 定义为环境变量,然后在 command 或 args 中引用它。
apiVersion: v1
kind: Pod
metadata:
name: command-args-pod
spec:
containers:
- name: test-container
image: busybox
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: my-config
key: log_level
command: [ "/bin/sh", "-c", "echo Log level is $(LOG_LEVEL)" ]
4. 总结对比
| 方式 | 表现形式 | 热更新支持 | 适用场景 |
|---|---|---|---|
环境变量 (env) |
环境变量 | 不支持 (需重启 Pod) | 简单的配置,如 DB_HOST, DEBUG_MODE |
| Volume (目录) | 目录下的文件 | 支持 (自动更新) | 配置文件较多,或应用支持文件热加载 (如 Nginx) |
Volume (subPath) |
单个文件 | 不支持 (需重启 Pod) | 替换特定配置文件且不影响同一目录下的其他文件 |
| 命令行参数 | 启动参数 | 不支持 (需重启 Pod) | 需要通过 flag 启动的应用,如 ./app --config=... |
5. 补充:通过 Kubernetes API 直接读取
虽然不是“挂载”,但应用程序代码可以使用 Kubernetes Client (如 client-go) 直接调用 K8s API 获取 ConfigMap 的内容。这种方式耦合度最高,通常用于开发 Operator 或高度定制的云原生应用。