"我能不能不把配置写死在镜像里?"
"账号密码怎么注入 Pod 才算安全?"
"ConfigMap 和 Secret 到底啥区别?用错会出事吗?"
Kubernetes 提供了强大的配置与敏感信息管理机制,即 ConfigMap 和 Secret。学会用它们,不仅能让你的部署更灵活、安全,还能让微服务真正实现"配置即服务"。
为什么需要配置中心?
在传统部署中,配置通常硬编码进代码或写死在镜像里,这带来诸多问题:
- 修改配置必须重构镜像或重启服务
- 无法在不同环境中复用相同镜像
- 敏感信息(如数据库密码)容易泄露
- 难以实现 DevOps 所需的"配置解耦"
Kubernetes 通过 ConfigMap 和 Secret 实现了:
✅ 配置与代码分离
✅ 动态加载配置
✅ 安全地传递敏感信息
ConfigMap:管理普通配置信息
ConfigMap 用于存储非敏感的配置信息,如:
- 应用的参数设置
- 环境变量配置
- 配置文件内容
创建 ConfigMap 的三种方式:
1. 从文件创建
bash
kubectl create configmap app-config --from-file=./app.properties
2. 从字面值创建
bash
kubectl create configmap app-config --from-literal=ENV=prod --from-literal=VERSION=1.2.3
3. 使用 YAML 配置
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
ENV: "prod"
VERSION: "1.2.3"
config.yaml: |
port: 8080
logLevel: info
使用 ConfigMap 的四种方式
1. 注入为环境变量
yaml
envFrom:
- configMapRef:
name: app-config
2. 注入为单个变量
yaml
env:
- name: APP_ENV
valueFrom:
configMapKeyRef:
name: app-config
key: ENV
3. 挂载为文件(适合配置文件)
yaml
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
4. 热更新(需结合 subPath 使用或应用自身支持 reload)
注意:ConfigMap 挂载为文件后,默认更新不生效,除非应用主动 watch 文件或使用第三方控制器(如 Reloader)。
Secret:管理敏感配置信息
Secret 用于存储敏感信息,如:
- 数据库账号密码
- JWT 签名密钥
- TLS 证书与私钥
创建 Secret 的三种方式:
1. 从字面值(需 base64 编码)
yaml
kubectl create secret generic db-secret \
--from-literal=username=admin \
--from-literal=password=123456
2. 使用 YAML 编写(注意 base64 编码)
yaml
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
username: YWRtaW4= # admin
password: MTIzNDU2 # 123456
3. TLS 类型 Secret(自动编码)
bash
kubectl create secret tls tls-secret \
--cert=./tls.crt \
--key=./tls.key
使用 Secret 的三种方式
1. 注入为环境变量
yaml
env:
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-secret
key: username
2. 挂载为文件
yaml
volumeMounts:
- name: secret-volume
mountPath: /etc/secret
volumes:
- name: secret-volume
secret:
secretName: db-secret
3. 使用 ServiceAccount 绑定 ImagePullSecret(用于拉取私有镜像)
⚔️ ConfigMap vs Secret 核心对比
特性 | ConfigMap | Secret |
---|---|---|
存储类型 | 明文 | base64 编码(并非加密) |
用途 | 一般配置信息 | 敏感信息(密码、证书) |
挂载方式 | 环境变量、文件 | 环境变量、文件 |
加密支持 | ❌ 默认无加密 | ✅ 可结合加密机制(如 KMS) |
安全性 | 低 | 高(但仍建议配合 RBAC) |
实战案例:配置数据库连接信息
yaml
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
username: YWRtaW4=
password: MTIzNDU2
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 1
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: my-app:v1
env:
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-secret
key: username
- name: DB_PASS
valueFrom:
secretKeyRef:
name: db-secret
key: password
Secret 的安全最佳实践
✅ 开启 Kubernetes API Server 的加密存储(EncryptionConfiguration)
✅ 使用 RBAC 限制访问 Secret 的权限✅ 定期轮换密钥与 Secret✅ 使用 External Secrets 工具(如 External Secrets Operator)接入云上密钥管理系统(AWS Secrets Manager、Vault 等)
配置加载流程

总结:ConfigMap 与 Secret 不是选一个,而是一起用!
- ✅ 配置文件统一管理?用 ConfigMap
- ✅ 数据库密码传入?用 Secret
- ✅ 不想改代码就能换配置?挂载 + 环境变量是关键
- ✅ 想安全地管理密钥?配合 RBAC + 加密 + 密钥轮换