ConfigMap 与 Secret 基础:核心概念与创建管理
在 Kubernetes 中,ConfigMap 和 Secret 是解耦应用配置与容器镜像的核心原语。它们将配置数据从 Pod 定义中抽离出来,使得同一镜像可以在不同环境(开发、测试、生产)中复用,同时满足安全审计对敏感信息的隔离要求。
2.1 ConfigMap:非敏感配置管理
ConfigMap 用于存储非机密的键值对数据,例如环境变量、命令行参数或配置文件内容。其设计目标是让配置与镜像分离,实现“一次构建,多次部署”。
2.1.1 核心特性
- 数据格式:键值对(
key: value)或文件内容(key: |多行文本)。 - 存储限制:单个 ConfigMap 大小上限为 1 MiB(etcd 限制)。
- 更新机制:更新 ConfigMap 后,已挂载的 Volume 会在 1-2 分钟内同步(取决于 kubelet 同步周期);通过环境变量注入的配置不会自动更新。
- 命名空间:ConfigMap 属于命名空间资源,只能被同一命名空间内的 Pod 引用。
2.1.2 创建方式
| 创建方式 | 命令/示例 | 适用场景 |
|---|---|---|
| 字面量键值对 | kubectl create configmap app-config --from-literal=key1=val1 --from-literal=key2=val2 |
少量配置项,快速测试 |
| 从文件导入 | kubectl create configmap app-config --from-file=./app.properties |
配置文件(如 .env、.properties) |
| 从目录导入 | kubectl create configmap app-config --from-file=./config-dir/ |
多文件配置目录 |
| YAML 声明式 | kubectl apply -f configmap.yaml |
生产环境,版本控制 |
最佳实践:生产环境始终使用 YAML 声明式定义 ConfigMap,并纳入 GitOps 工作流。避免使用
--from-literal 传递敏感信息。
2.1.3 YAML 示例
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: production
data:
# 键值对
APP_ENV: "production"
LOG_LEVEL: "info"
# 多行配置文件
nginx.conf: |
server {
listen 80;
server_name example.com;
}
2.2 Secret:敏感信息保护
Secret 用于存储机密数据,如密码、、TLS 证书。其数据以 Base64 编码存储,但请注意:Base64 不是加密,仅提供简单的混淆。真正的安全依赖于 etcd 加密、RBAC 控制和审计日志。
2.2.1 核心特性
- 数据编码:值必须经过 Base64 编码(Kubernetes 1.25+ 支持
stringData字段明文输入)。 - 存储安全:默认存储在 etcd 中;建议启用 etcd 静态加密(
--encryption-provider-config)。 - 访问控制:通过 RBAC 限制 Secret 的 get/list/watch 权限。
- 大小限制:与 ConfigMap 相同,单 Secret 上限 1 MiB。
2.2.2 Secret 类型
| 类型 | 用途 | 示例 |
|---|---|---|
Opaque |
通用键值对(默认) | 数据库密码、 |
kubernetes.io/service-account- |
服务账号令牌 | 自动挂载到 Pod |
kubernetes.io/dockercfg |
私有镜像仓库认证 | Docker registry 凭证 |
kubernetes.io/tls |
TLS 证书与私钥 | Ingress 证书 |
kubernetes.io/basic-auth |
HTTP 基本认证 | 用户名+密码 |
2.2.3 创建方式
# 字面量创建(自动 Base64 编码)
kubectl create secret generic db-secret \
--from-literal=username=admin \
--from-literal=password='S3cur3P@ss'
# 从文件创建
kubectl create secret generic tls-secret \
--from-file=tls.crt=./server.crt \
--from-file=tls.key=./server.key
# 声明式 YAML(使用 stringData 避免手动编码)
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
stringData:
username: admin
password: S3cur3P@ss
安全警告:切勿将 Secret 的 YAML 文件明文提交到 Git 仓库。使用
stringData 字段时,kubectl apply 后数据会被编码为 Base64 并持久化到 etcd。建议配合 Sealed Secrets、External Secrets Operator 或 Vault 进行加密管理。
2.3 ConfigMap 与 Secret 对比
| 维度 | ConfigMap | Secret |
|---|---|---|
| 数据敏感性 | 非敏感,明文存储 | 敏感,Base64 编码 |
| 默认 etcd 加密 | 否 | 否(需手动启用) |
| RBAC 最小权限 | 宽松 | 严格限制 |
| 审计日志 | 可选 | 建议启用 |
| 更新后 Pod 同步 | Volume 挂载自动同步 | Volume 挂载自动同步 |
| 环境变量注入 | 支持 | 支持 |
2.4 架构关系图
下图展示了 ConfigMap 与 Secret 在 Kubernetes 集群中的创建、存储与消费路径:
2.5 Pod 中引用方式
ConfigMap 和 Secret 在 Pod 中可通过以下三种方式消费:
- 环境变量:将键值对映射为 Pod 环境变量。
- Volume 挂载:将整个 ConfigMap/Secret 挂载为文件系统目录。
- 命令行参数:通过
$(VAR_NAME)语法引用环境变量。
推荐策略:对于需要热更新的配置(如日志级别、功能开关),使用 Volume 挂载方式;对于启动后不变的配置(如数据库连接池大小),使用环境变量注入。
2.6 安全审计要点
- 最小权限原则:为 ServiceAccount 配置 RBAC 时,只授予必要的 Secret get 权限,避免使用
secrets/*通配符。 - 静态加密:在 etcd 层面启用
--encryption-provider-config,使用 AES-CBC 或 KMS 加密 Secret 数据。 - 审计日志:启用 Kubernetes 审计日志,记录所有 Secret 的 get/list/watch 操作,并定期审查。
- 避免明文存储:禁止将 Secret 的 Base64 编码值直接写入 CI/CD 脚本或代码仓库。