告别硬编码,用 ConfigMap 管理 Kubernetes 中的配置文件
·
概述
通常一个微服务,里面会有一堆配置:
- 数据库地址
- 日志级别
- 第三方 API 密钥(先忽略安全问题)
- 功能开关
一开始,你把它们写在代码里,或者打包进镜像。
但很快发现:
- 想改个超时时间?得重新构建镜像、重新部署!
- 测试环境和生产环境配置混在一起
- 配置散落在各个服务中,难以统一管理
这就像每次换 Wi-Fi 密码,都要重装手机系统——太荒谬了!
在 Kubernetes 中,这个问题有优雅的解法:ConfigMap
什么是 ConfigMap
ConfigMap 是 Kubernetes 的一种资源对象,用于:
- 存储非敏感的配置数据(如字符串、配置文件)
- 将配置与容器镜像解耦
- 支持动态更新(部分场景)
配置不是代码的一部分,而是运行时注入的参数
ConfigMap 中的数据可以以两种方式注入到 Pod:
- 环境变量(Environment Variables)
- 挂载为文件(Volume Mount)
为什么不用直接写在 YAML 里
如果直接在 Deployment 里写 env 会怎样?
env:
- name: DB_HOST
value: "prod-db.example.com"
这确实可行,但问题在于:
- 配置无法复用(多个服务要重复写)
- 修改配置需改 Deployment,触发滚动更新
- 无法用版本控制单独管理配置
而 ConfigMap 让配置独立存在,像“配置中心”的轻量版
创建 ConfigMap 的三种方式
方式 1:从字面值创建(适合少量键值对)
kubectl create configmap app-config \
--from-literal=log_level=info \
--from-literal=db_host=mysql.default.svc.cluster.local \
--from-literal=feature_new_ui=true
查看内容:
kubectl get configmap app-config -o yaml
输出片段:
data:
log_level: info
db_host: mysql.default.svc.cluster.local
feature_new_ui: "true"
方式 2:从文件创建(适合配置文件)
假设你有一个 app.properties:
# app.properties
server.port=8080
spring.datasource.url=jdbc:mysql://db:3306/mydb
logging.level.root=INFO
创建 ConfigMap:
kubectl create configmap app-config-from-file \
--from-file=app.properties
注意:文件名会成为 ConfigMap 中的 key,内容是 value。
方式 3:从 YAML 文件定义(推荐)
创建 configmap.yaml:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-config
data:
# 键值对形式
log_level: "debug"
db_host: "mysql.prod.svc"
# 多行配置文件(用 | 保留格式)
nginx.conf: |
server {
listen 80;
location / {
root /usr/share/nginx/html;
}
}
app.json: |
{
"timeout": 5000,
"retry": 3
}
应用:
kubectl apply -f configmap.yaml
这种方式支持复杂结构,且可纳入 Git 版本管理
在 Pod 中使用 ConfigMap
场景 1:作为环境变量注入
# deployment-env.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: app
image: my-app:1.0
envFrom:
- configMapRef:
name: my-app-config # 引用上面的 ConfigMap
Pod 启动后,容器内会自动拥有这些环境变量:
echo $log_level # 输出: debug
echo $db_host # 输出: mysql.prod.svc
注意:如果 ConfigMap 更新,已运行的 Pod 不会自动更新环境变量!需重建 Pod。
场景 2:挂载为配置文件(推荐用于复杂配置)
# deployment-volume.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-app
spec:
template:
spec:
containers:
- name: nginx
image: nginx:alpine
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/conf.d # 挂载到容器目录
volumes:
- name: config-volume
configMap:
name: my-app-config
items:
- key: nginx.conf # ConfigMap 中的 key
path: default.conf # 在挂载目录中的文件名
效果:
- 容器内的
/etc/nginx/conf.d/default.conf内容 = ConfigMap 中nginx.conf的值 - Nginx 启动时会自动加载这个配置
优势:配置以文件形式存在,应用无需改造!
实战:部署一个带配置的 Node.js 应用
Step 1:准备配置
app-config.yaml:
apiVersion: v1
kind: ConfigMap
metadata:
name: nodejs-config
data:
PORT: "3000"
DB_URL: "mongodb://mongo:27017/mydb"
LOG_LEVEL: "info"
Step 2:编写 Deployment(使用环境变量)
nodejs-deploy.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-app
spec:
replicas: 1
selector:
matchLabels:
app: nodejs
template:
metadata:
labels:
app: nodejs
spec:
containers:
- name: app
image: node:18-alpine
command: ["sh", "-c"]
args:
- |
echo "Server starting on port $$PORT";
while true; do echo "Ping DB: $$DB_URL"; sleep 10; done
envFrom:
- configMapRef:
name: nodejs-config
Step 3:部署并验证
kubectl apply -f app-config.yaml
kubectl apply -f nodejs-deploy.yaml
# 查看日志
kubectl logs -l app=nodejs
输出:
Server starting on port 3000
Ping DB: mongodb://mongo:27017/mydb
...
配置成功注入
ConfigMap vs Secret:怎么选
| 特性 | ConfigMap | Secret |
|---|---|---|
| 存储内容 | 非敏感配置(如端口、开关) | 敏感信息(密码、密钥、Token) |
| 存储格式 | 明文(Base64 可读) | Base64 编码(仍需配合 RBAC) |
| 使用方式 | 几乎相同(env / volume) | 几乎相同 |
| 安全建议 | ❌ 不要存密码! | ✅ 用 Secret + 加密插件(如 Sealed Secrets) |
重要:数据库密码、API Key 等绝不能放在 ConfigMap 中
ConfigMap 能热更新吗
- 挂载为文件:✅ 是!Kubelet 会定期同步(默认每秒检查),文件内容会自动更新(但应用需支持 reload)
- 作为环境变量:❌ 否!Pod 创建时注入,之后不会变
提示:Nginx、Spring Boot 等支持配置重载的应用,适合用 Volume 方式。
最佳实践
| 建议 | 说明 |
|---|---|
| ✅ 用 YAML 文件管理 ConfigMap | 便于 Git 版本控制 |
✅ 按应用/环境命名(如 user-svc-prod-config) |
避免冲突 |
| ✅ 复杂配置用 Volume 挂载 | 比环境变量更清晰 |
| ❌ 不要存敏感信息 | 用 Secret 代替 |
| ✅ 配合 CI/CD 自动更新 | 实现配置即代码(Configuration as Code) |
总结
| 问题 | ConfigMap 解法 |
|---|---|
| 配置写死在镜像里? | ✅ 外部化,独立管理 |
| 多环境配置混乱? | ✅ 创建 dev-config / prod-config |
| 改配置要重打包? | ✅ 只需更新 ConfigMap(部分场景自动生效) |
| 配置无法复用? | ✅ 多个 Pod 引用同一个 ConfigMap |
更多推荐




所有评论(0)