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 集群中的创建、存储与消费路径:

ConfigMap 与 Secret 架构关系 ConfigMap & Secret 创建与消费流程 kubectl create YAML 声明式 API Server etcd 集群 ConfigMap 对象 Secret 对象 kubelet 同步 Pod Volume 挂载 Pod 环境变量注入 关键说明: • ConfigMap 与 Secret 均通过 API Server 写入 etcd,kubelet 根据 Pod 定义从 API Server 拉取。 • Volume 挂载方式支持热更新(约 1-2 分钟延迟);环境变量注入方式仅在 Pod 创建时生效。

2.5 Pod 中引用方式

ConfigMap 和 Secret 在 Pod 中可通过以下三种方式消费:

  1. 环境变量:将键值对映射为 Pod 环境变量。
  2. Volume 挂载:将整个 ConfigMap/Secret 挂载为文件系统目录。
  3. 命令行参数:通过 $(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 脚本或代码仓库。