前面学习了Volume的多种类型对象,本章将再讲解一种特殊的资源对象:ConfigMap。
日常
许多应用经常会有从配置文件、命令行参数或者环境变量中读取一些配置信息,这些配置信息我们肯定不会直接写死到应用程序中去的,例如有个应用连接redis
服务,那redis做了迁移或者修改了密码,这时候还得重新去修改代码,重新制作一个镜像,这肯定是不可取的,而ConfigMap
就是来解决这种情况的。
ConfigMap 是 Kubernetes 中用于存储非敏感配置数据的资源对象,通过键值对(Key-Value)形式保存配置信息,支持纯文本、JSON、XML 等多种格式
ConfigMap的功能特性:
其主要功能包括:
- 配置解耦:将应用配置与容器镜像分离,便于独立管理。
- 灵活注入:支持通过环境变量、命令行参数或文件挂载方式注入配置到容器。
- 动态更新:修改 ConfigMap 后,挂载为文件的配置可自动更新(需约 30 秒至 1 分钟),而环境变量需重启 Pod。
特性
- 命名空间级别:仅作用于同一命名空间内的资源。
- 大小限制:单个 ConfigMap 数据总量不超过 1 MiB。
- 键名规范:键名仅允许字母、数字、
-
、_
或.
,且data
与binaryData
字段的键名不可重复。
1.举例说明
创建configmap
configmap的格式
kind: ConfigMap
apiVersion: v1
metadata:
name: cm-demo
namespace: default
data:
key1: value1 #单行配置文件内容1
key2: value2 #单行配置文件内容2
config.properties: | # 多行配置文件内容3
db.host=127.0.0.1
db.port=3306
1.通过命令行创建configmap
通过kubectl create configmap -h 的方式获取提示
Examples:
# Create a new config map named my-config based on folder bar
kubectl create configmap my-config --from-file=path/to/bar
# Create a new config map named my-config with specified keys instead of file basenames on disk
kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt
# Create a new config map named my-config with key1=config1 and key2=config2
kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2
# Create a new config map named my-config from the key=value pairs in the file
kubectl create configmap my-config --from-file=path/to/bar
# Create a new config map named my-config from an env file
kubectl create configmap my-config --from-env-file=path/to/foo.env --from-env-file=path/to/bar.env
官方一共给了5个例子
1.创建一个名为my-config的configmap,将目录 bar
下的所有文件创建为 ConfigMap,每个文件对应一个键值对,
键:文件名(如 file1.txt
)
值:文件内容(如 file1.txt
的文本)
使用场景:批量挂载配置文件到容器,例如存放 Nginx 的多个虚拟主机配置
2.创建一个名为my-config的configmap,源文件地址为/path/to/bar/file1.txt和/path/to/bar/file2.txt
键:key1
和 key2
(覆盖默认的文件名)
值:对应文件的内容
场景:需要显式控制键名时使用,例如将多个文件映射为统一命名的配置项
3. 创建一个名为my-config的configmap,将目录 bar
下的所有文件创建为 ConfigMap,直接在命令行中定义键值对
键:key1
、key2
值:config1
、config2
场景:快速注入简单配置(如数据库地址、日志级别)
4. 同1
5.创建一个名为my-config的configmap,直接从外部文件(.env)内容挂载到configmap中解析 .env
文件中的键值对,合并到 ConfigMap:
键:.env
文件中的变量名(如 DB_HOST
)
值:对应的变量值(如 127.0.0.1
)
场景:兼容传统环境变量配置方式,支持多文件合并。
看不懂没关系,下面有更简单的yaml格式方式来创建。
2.通过yaml文件创建configmap
下面例子里面一共创建了3个键值对,一个是多行配置,里面包含2个键值对,一个是单行配置文件,包含一个键值对,在使用过程中,都是将多行配置键值对通过文件的方式进行挂载,而单行直接通过环境变量的方式进行挂载
# 多行配置文件内容
db.host=127.0.0.1
db.port=3306
# 单行配置文件内容
log.level: "info"
# cat cm1.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config #这个configmap的名字,后面可以通过环境变量的方式挂载进入pod的yaml文件
data:
config.properties: | # 多行配置文件内容
db.host=127.0.0.1
db.port=3306
log.level: "info" # 单行键值对
创建pod识别configmap
1.环境变量的方式注入单行键值对
创建一个pod的yaml文件并且使用上面的cm变量
#cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app-container
image: m.daocloud.io/docker.io/nginx:latest
# 环境变量注入(可选,适用于单值配置)
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: log.level
验证结果,得知$LOG_LEVEL已经注意到新的pod里面
root@k8s-master:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
app-pod 1/1 Running 0 2m57s
testcm1-pod 0/1 CreateContainerConfigError 0 36m
root@k8s-master:~# kubectl exec -it app-pod -- /bin/bash
root@app-pod:/# echo $LOG_LEVEL
info
2.挂载配置文件的方式注入多行键值对
#cat pod2.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app-container
image: m.daocloud.io/docker.io/nginx
volumeMounts:
- name: config-volume # 卷名称,需与 volumes 字段对应
mountPath: /etc/app-config # 容器内挂载路径
volumes:
- name: config-volume # 卷名称,与 volumeMounts 对应
configMap:
name: app-config # 引用的 ConfigMap 名称
items: # 可选:筛选并自定义文件名
- key: config.properties # 选择 ConfigMap 中的键
path: db.conf # 挂载为 /etc/app-config/db.conf
验证结果,发现db.conf已经挂载到指定目录
root@k8s-master:~/configmap# kubectl get pod
NAME READY STATUS RESTARTS AGE
app-pod 1/1 Running 0 41m
root@k8s-master:~/configmap# kubectl apply -f pod2.yaml
pod/app-pod2 created
root@k8s-master:~/configmap#
root@k8s-master:~/configmap# kubectl get pod
NAME READY STATUS RESTARTS AGE
app-pod 1/1 Running 0 41m
app-pod2 1/1 Running 0 4s
root@k8s-master:~/configmap# kubectl exec -it app-pod2 -- /bin/bash
root@app-pod2:/# cat /etc/app-config/db.conf
db.host=127.0.0.1
db.port=3306
3.通过command的方式注入键值对
# cat pod3.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-pod3
spec:
containers:
- name: app-pod3
image: m.daocloud.io/docker.io/nginx
command: [ "/bin/bash", "-c", "echo $(log.level) && sleep 3600" ] #通过命令行输出环境变量显示加载的CM值
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: log.level
envFrom:
- configMapRef:
name: app-config
验证结果,发现db.conf已经挂载到指定目录
4.对比总结
上面举例了ConfigMap 3种注入的方式,具体采用哪一种可以根据项目需求而定。
维度 | 环境变量注入 | 挂载配置文件 | Command 注入 |
---|---|---|---|
数据格式 | 单行键值对 | 多行文本/完整文件 | 单行键值对 |
动态更新支持 | 需重启 Pod | 自动更新 | 需重启 Pod |
配置复杂度 | 低 | 高(支持嵌套结构) | 中(依赖脚本处理) |
适用场景 | 简单参数(端口、开关) | 复杂配置(JSON、XML) | 动态生成启动命令 |
性能影响 | 无 | 文件 I/O 可能影响性能 | 脚本执行可能增加启动耗时 |
5.选择建议
- 优先挂载配置文件:适用于需动态更新或复杂配置的场景。
- 慎用 Command 注入:仅在必须通过命令拼接参数时使用,避免过度依赖 Shell 脚本。
- 环境变量用于简单配置:如开关、基础参数等无需频繁更新的场景。
通过合理组合这三种方式,可高效管理 Kubernetes 应用的配置,同时平衡灵活性与性能。
2. 高级功能与注意事项
2.1 热更新机制
- Volume 挂载:ConfigMap 更新后,容器内文件自动同步(约 30 秒延迟)。
- 环境变量:需删除并重建 Pod 以生效。
2.2 不可变 ConfigMap
在 Kubernetes 中,将 ConfigMap 设置为不可变(immutable: true
)是一种优化配置管理和提升集群稳定性的重要手段。设置了这个字段,就不能通过热更新或者edit的方式去修改更新配置,只能通过删除重建更新配置。
举例:
apiVersion: v1
kind: ConfigMap
metadata:
name: immutable-config
immutable: true
data:
key: "value"