ConfigMap 与 Secret 配置管理
镜像应尽量保持环境无关。地址、开关和日志级别属于配置;密码、令牌和证书属于密钥。两者都应与镜像解耦,但生命周期和访问控制不同,应分别管理。
本篇目标:理解配置解耦理念,能正确使用 ConfigMap 的环境变量和文件注入方式,理解 Secret 的类型与安全边界,并了解 External Secrets / Vault 的生产集成方式。

1. 应用配置解耦的理念
1.1 为什么代码与配置分离
- 同一镜像可在 dev/staging/prod 用不同配置运行——镜像不变,配置变;
- 修改配置不需要重新构建镜像;
- 敏感信息(密钥)不进入镜像,降低泄漏面;
- 配置可审计、可回滚(Git 管理)。
| 分类 | 存放对象 | 示例 |
|---|---|---|
| 非敏感配置 | ConfigMap | 日志级别、功能开关、连接地址 |
| 敏感密钥 | Secret | 密码、令牌、证书、API Key |
| 持久化数据 | PV/PVC(第 12 章) | 数据库文件、上传内容 |
2. ConfigMap:非敏感配置
2.1 创建 ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: api-config
namespace: learning
data:
LOG_LEVEL: info
FEATURE_CACHE: "true"
# 也可以存配置文件内容
app.yaml: |
server:
port: 8080
cache:
ttl: 300
kubectl create configmap api-config --from-literal=LOG_LEVEL=info -n learning
kubectl create configmap app-config --from-file=app.yaml -n learning
2.2 两种注入方式
# 方式 1:环境变量注入(启动时读取,之后修改 ConfigMap 不会更新)
envFrom:
- configMapRef:
name: api-config
# 方式 2:文件挂载(ConfigMap 更新后,kubelet 会在几十秒内同步到挂载目录)
volumeMounts:
- name: config
mountPath: /etc/app
volumes:
- name: config
configMap:
name: api-config
| 方式 | 热更新 | 适用场景 |
|---|---|---|
| 环境变量 | ❌ 只在启动时读取 | 启动参数、少量开关 |
| 文件挂载 | ✅ kubelet 自动同步(有延迟) | 配置文件、需要热更新的开关 |
2.3 Immutable ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: api-config-v2
namespace: learning
immutable: true # 创建后不可修改,避免误操作
data:
LOG_LEVEL: info
Immutable ConfigMap 配合版本化命名(如 api-config-v1、api-config-v2),每次变更创建新的、更新 Deployment 引用新的。这比修改同一个 ConfigMap 更可控、更有审计痕迹。
3. Secret:敏感配置管理
3.1 Secret 类型
apiVersion: v1
kind: Secret
metadata:
name: api-credentials
namespace: learning
type: Opaque
stringData:
API_TOKEN: replace-in-cd-or-external-secret
| 类型 | 用途 | 示例 |
|---|---|---|
Opaque | 通用键值对 | API Key、数据库密码 |
kubernetes.io/tls | TLS 证书和私钥 | Ingress 证书 |
kubernetes.io/dockerconfigjson | 私有镜像仓库凭据 | imagePullSecrets |
kubernetes.io/basic-auth | 基本认证 | 用户名/密码 |
kubernetes.io/service-account-token | ServiceAccount Token | 自动管理,一般不需手工创建 |
私有镜像仓库凭据的使用方式:
kubectl create secret docker-registry regcred \
--docker-server=registry.example.com \
--docker-username=<user> \
--docker-password=<token> \
-n learning
spec:
template:
spec:
imagePullSecrets:
- name: regcred
3.2 加密与安全边界
Secret 的默认 data 只是 Base64 编码,不是加密。echo "cGFzc3dvcmQ=" | base64 -d 就能解码。
生产基线应至少包括:
| 层面 | 做法 |
|---|---|
| 静态加密 | 开启 etcd 静态加密或使用云厂商 KMS |
| 访问控制 | RBAC 限制谁能 get secrets,审计 Secret 读取日志 |
| 不入 Git | 真实 Secret 不进 Git、终端历史或 CI 日志 |
| 外部密钥 | 对接 External Secrets、Vault 或云 Secret Manager |
| 短期身份 | 能用 OIDC/STS 临时凭据的,不放长期密钥 |
kubectl auth can-i get secrets -n learning
kubectl get rolebinding,clusterrolebinding -A -o wide | grep -i secret
3.3 注入到 Pod
envFrom:
- configMapRef:
name: api-config
- secretRef:
name: api-credentials
# 更精细:只取 Secret 中的特定 Key
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: api-credentials
key: DB_PASSWORD
只把所需键注入给所需容器。不要把整份平台级 Secret 挂给每个应用,也不要用 kubectl describe pod、调试脚本或日志打印环境变量。
4. 生产安保:External Secrets / Vault 集成
4.1 为什么需要外部密钥管理
Secret 存在 etcd 中,即使加密也仍是"集群内的秘密"。生产上更常见的做法是把真实密钥放在专门系统(Vault、云 Secret Manager),Kubernetes 侧只保留引用:
Vault / 云 Secret Manager(真实密钥的真相源)
│ 同步(External Secrets Operator / Vault Agent)
▼
Kubernetes Secret(集群内,供工作负载读取)
4.2 External Secrets Operator(ESO)
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: api-credentials
namespace: learning
spec:
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: api-credentials # 生成的 Secret 名称
data:
- secretKey: API_TOKEN
remoteRef:
key: secret/api
property: api_token
ESO 定期从外部源拉取密钥并同步为 Kubernetes Secret,工作负载的引用方式不变(仍读 Secret)。
4.3 选择建议
| 方案 | 特点 |
|---|---|
| External Secrets Operator | 从 Vault/AWS/GCP/Azure 同步为 Secret,改动小、推荐起步 |
| Vault Agent Injector | 应用启动时注入,密钥不落盘到 etcd,安全更强、集成成本更高 |
| 云 Secret Manager + CSI driver | 以卷方式挂载,密钥不落盘到 etcd |
5. 练习
练习 A
- 创建一个 ConfigMap,用环境变量注入到一个 Deployment 中,进入 Pod 用
env | grep确认变量可见 - 修改 ConfigMap,再次进入 Pod 确认环境变量未变化
- 改用 volume mount 方式挂载 ConfigMap,修改 ConfigMap 后等 30 秒,进入 Pod 确认文件内容已更新
练习 B
- 创建
kubernetes.io/tls类型的 Secret,挂载到一个 Pod,确认证书文件可读 - 创建
docker-registrySecret,检查imagePullSecrets是否让私有仓库镜像可拉取 - 用
kubectl auth can-i get secrets验证普通身份读不到 Secret,感受 RBAC 对密钥的保护
下一篇:PV 与 PVC 存储管理。