tags:
– Kubernetes
– K8s系列
– DevOps
– ConfigMap
– Secret
– 配置管理
K8s 系列 | 第 7 天:ConfigMap 与 Secret:配置管理最佳实践
第 7/30 天 | 上一篇我们学习了 Namespace 与资源配额,今天来深入探讨 K8s 中配置管理的两大核心对象:ConfigMap 与 Secret。
一、引言
在微服务架构中,应用配置与代码分离是一项基本原则。Kubernetes 提供了ConfigMap 和 Secret 两种资源对象,分别用于管理非敏感配置和敏感数据(密码、API 密钥、证书等)。
为什么需要它们?
- 避免将配置硬编码到容器镜像中
- 支持多环境(开发/测试/生产)配置复用
- 配置变更无需重建镜像,滚动更新即可生效
- 敏感数据加密与权限控制
二、ConfigMap —— 非敏感配置管理
2.1 什么是 ConfigMap?
ConfigMap 是 K8s 中用于存储非敏感键值对配置的 API 对象。它支持四种数据来源:
| 来源类型 | 说明 |
|---|---|
| 字面量(literal) | 直接在 CLI 中指定 key=value |
| 文件(file) | 从本地文件读取内容 |
| 目录(directory) | 批量加载目录下所有文件 |
| YAML 清单 | 声明式定义 |
2.2 创建 ConfigMap
方式一:字面量创建
# 创建包含两个键值对的 ConfigMap
kubectl create configmap app-config
--from-literal=APP_ENV=production
--from-literal=APP_LOG_LEVEL=info
方式二:从文件创建
# 从配置文件创建
kubectl create configmap nginx-config
--from-file=nginx.conf
# 指定 key 名称(默认为文件名)
kubectl create configmap app-properties
--from-file=application.properties=./prod-app.properties
方式三:YAML 声明式创建
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: default
data:
APP_ENV: "production"
APP_LOG_LEVEL: "info"
nginx.conf: |
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend:8080;
}
}
2.3 使用 ConfigMap
Pod 可以通过环境变量或挂载卷两种方式使用 ConfigMap。
方式一:环境变量注入
apiVersion: v1
kind: Pod
metadata:
name: configmap-env-demo
spec:
containers:
- name: app
image: nginx:1.25
envFrom:
- configMapRef:
name: app-config # 注入全部键值对
env:
- name: DATABASE_URL # 注入单个键
valueFrom:
configMapKeyRef:
name: db-config
key: DATABASE_URL
方式二:挂载为卷文件
apiVersion: v1
kind: Pod
metadata:
name: configmap-volume-demo
spec:
containers:
- name: app
image: nginx:1.25
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d
readOnly: true
volumes:
- name: config
configMap:
name: nginx-config
⚠️ 注意:通过
subPath挂载单个文件时,ConfigMap 更新后文件不会自动同步。全量挂载目录则自动同步(延迟约 2~3 分钟)。
三、Secret —— 敏感数据管理
3.1 什么是 Secret?
Secret 用于存储敏感数据(密码、Token、SSH 密钥等),其值以 Base64 编码存储。K8s 默认开启了静态加密,并在 etcd 中加密保存。
| Secret 类型 | 用途 |
|---|---|
Opaque |
通用敏感数据(默认) |
kubernetes.io/service-account-token |
ServiceAccount Token |
kubernetes.io/dockerconfigjson |
私有镜像仓库认证 |
kubernetes.io/tls |
TLS 证书与密钥 |
bootstrap.kubernetes.io/token |
集群引导令牌 |
3.2 创建 Secret
方式一:命令式创建
# 通用 Secret
kubectl create secret generic db-credentials
--from-literal=DB_USER=admin
--from-literal=DB_PASSWORD='MyP@ssw0rd!'
# TLS 证书
kubectl create secret tls tls-secret
--cert=tls.crt
--key=tls.key
# 镜像仓库认证
kubectl create secret docker-registry regcred
--docker-server=https://index.docker.io/v1/
--docker-username=myuser
--docker-password=mypassword
--docker-email=user@example.com
方式二:YAML 声明式创建
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
data:
DB_USER: YWRtaW4= # echo -n "admin" | base64
DB_PASSWORD: TXlQQHNzdzByZCE= # echo -n "MyP@ssw0rd!" | base64
---
apiVersion: v1
kind: Secret
metadata:
name: tls-secret
type: kubernetes.io/tls
data:
tls.crt: LS0tLS1CRUdJTi... # Base64 编码的证书
tls.key: LS0tLS1CRUdJTi... # Base64 编码的私钥
⚠️ 安全提示:生产环境中不要将 Secret 的明文直接写入 YAML 文件然后提交到 Git。应使用 SealedSecret、External Secrets Operator 或 Vault 等工具管理。
3.3 使用 Secret
apiVersion: v1
kind: Pod
metadata:
name: secret-env-demo
spec:
containers:
- name: app
image: myapp:latest
envFrom:
- secretRef:
name: db-credentials
volumeMounts:
- name: tls
mountPath: /etc/ssl/certs
readOnly: true
volumes:
- name: tls
secret:
secretName: tls-secret
imagePullSecrets:
- name: regcred # 拉取私有镜像时使用
四、配置管理最佳实践
4.1 Immutable ConfigMap/Secret
K8s v1.21+ 支持将 ConfigMap/Secret 标记为 immutable(不可变),大幅降低 API Server 负载并提升性能。
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
immutable: true # 标记为不可变
data:
APP_ENV: production
标记 immutable 后,只能删除重建,不能原地更新。适合启动后不会变化的配置。
4.2 配置热更新策略
| 更新方式 | ConfigMap 更新生效 | 推荐场景 |
|---|---|---|
| 环境变量注入 | ❌ 需重启 Pod | 启动后不变的配置 |
| 挂载卷(全量) | ✅ 自动同步(~2-3min) | 频繁变动的配置 |
| 挂载卷(subPath) | ❌ 不自动同步 | 单个文件挂载 |
| Sidecar 重载 | ✅ 自行控制 | 需要精确重载时机 |
4.3 敏感数据生产建议
- 不要将明文 Secret 提交到 Git——使用
git-secrets或.gitignore过滤 - 使用 SealedSecret 加密后再提交到 Git:
bash
kubeseal --format yaml < db-secret.yaml > sealed-db-secret.yaml - 生产环境部署 External Secrets Operator 或 Vault Agent Sidecar,从外部 KMS 同步 Secret
- 启用 K8s 静态加密(v1.13+ 默认开启)并审计 etcd 访问
- 为每个环境(dev/staging/prod)使用独立的 Secret,避免跨环境泄露
4.4 完整的生产实践示例
下面是一个结合 ConfigMap、Secret、Deployment 的完整示例:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: production
data:
APP_NAME: "myapp"
APP_ENV: "production"
APP_LOG_LEVEL: "warn"
---
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
namespace: production
type: Opaque
data:
DB_PASSWORD: TXlQYXNzd29yZDIwMjY=
API_KEY: c2stcHJvZC1hcGkta2V5LTEyMzQ1Njc4OTA=
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:1.24.0
ports:
- containerPort: 8080
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secrets
volumeMounts:
- name: config-files
mountPath: /etc/myapp
readOnly: true
volumes:
- name: config-files
configMap:
name: app-config-files
imagePullSecrets:
- name: regcred
五、常见问题与排查
5.1 ConfigMap/Secret 找不到
# 检查是否存在
kubectl get configmap -n <namespace>
kubectl get secret -n <namespace>
# 检查 Pod 事件
kubectl describe pod <pod-name>
# 常见报错:找不到 ConfigMap/Secret
# Error: configmap "xxx" not found
# → 检查 namespace、名称拼写、是否已在同一命名空间
5.2 Secret Base64 解码查看
# 查看 Secret 的 Base64 值
kubectl get secret db-credentials -o jsonpath='{.data.DB_PASSWORD}'
# 解码获取明文(⚠️ 安全风险,仅调试用)
kubectl get secret db-credentials -o jsonpath='{.data.DB_PASSWORD}' | base64 -d
5.3 配置更新后没有生效
排查步骤:
# 1. 确认 ConfigMap 是否更新
kubectl describe configmap nginx-config
# 2. 检查 Pod 中文件内容
kubectl exec <pod-name> -- cat /etc/nginx/conf.d/default.conf
# 3. 重启 Deployment 强制加载新配置
kubectl rollout restart deployment myapp
六、总结
| 对比项 | ConfigMap | Secret |
|---|---|---|
| 存储内容 | 非敏感配置(文本、配置文件) | 敏感数据(密码、证书、Token) |
| 编码方式 | 明文 | Base64 编码 |
| 大小限制 | 1MB(etcd 限制) | 1MB(etcd 限制) |
| 自动加密 | ❌ | ✅(静态加密) |
| immutable | ✅ v1.21+ | ✅ v1.21+ |
| 推荐场景 | 环境变量、配置文件 | 密码、API 密钥、TLS 证书 |
掌握 ConfigMap 与 Secret 是 K8s 配置管理的基石,也是将应用从开发环境优雅迁移到生产环境的关键一步。
📖 下期预告
第 8 天:Volume 与 PersistentVolume:存储抽象层的核心机制
我们将深入 K8s 存储体系,学习 Pod 卷、PV、PVC 的概念与实战,解决容器存储的”有状态”难题。
🔗 系列目录:[K8s 系列 30 天从入门到生产运维](https://www.stellardata.top/tag/k8s系列/)
🏷️ 标签:#Kubernetes #K8s系列 #DevOps #ConfigMap #Secret #配置管理 #云原生















暂无评论内容