2. Kubernetes配置管理基础:ConfigMap与Secret的创建、使用场景与生命周期管理

在Kubernetes集群中,将应用配置与容器镜像解耦是实现环境一致性的核心前提。ConfigMap与Secret是Kubernetes提供的两种原生配置资源,分别用于管理非敏感配置与敏感数据。本章将深入讲解这两种资源的创建方式、典型使用场景以及从创建到销毁的完整生命周期管理策略。

2.1 ConfigMap与Secret的核心定位

ConfigMap用于存储键值对形式的非敏感配置数据,如环境变量、配置文件内容、命令行参数等。Secret则用于存储敏感信息,如密码、、TLS证书等,其数据以Base64编码存储,并支持更细粒度的访问控制与加密机制。

对比维度 ConfigMap Secret
数据敏感性 非敏感,明文存储 敏感,Base64编码,支持加密
默认存储大小 1 MiB(可通过etcd调整) 1 MiB(可通过etcd调整)
访问控制 RBAC + Namespace隔离 RBAC + Namespace隔离 + 加密(可选)
数据注入方式 环境变量、卷挂载、命令行参数 环境变量、卷挂载
典型用途 应用配置文件、日志级别、功能开关 数据库密码、TLS证书、OAuth令牌
实践建议:始终遵循“最小权限原则”——非敏感配置使用ConfigMap,敏感数据使用Secret。切勿将密码或密钥硬编码到ConfigMap中。

2.2 创建ConfigMap与Secret

2.2.1 创建ConfigMap

Kubernetes支持四种创建ConfigMap的方式,适用于不同的配置来源场景。

  • 字面量创建:直接通过命令行指定键值对,适合少量配置项。
  • 文件创建:从本地文件读取内容,文件名作为键,文件内容作为值。
  • 目录创建:从目录批量导入多个文件,每个文件生成一个键值对。
  • YAML声明式创建:通过资源清单定义,适合版本管理与CI/CD集成。
# 字面量创建
kubectl create configmap app-config --from-literal=LOG_LEVEL=info --from-literal=DB_HOST=localhost

# 从文件创建
kubectl create configmap nginx-config --from-file=nginx.conf

# 从目录创建
kubectl create configmap multi-config --from-file=./configs/

# YAML声明式创建
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: production
data:
  LOG_LEVEL: "debug"
  DB_HOST: "postgres.prod.svc.cluster.local"
  DB_PORT: "5432"
  app.properties: |
    feature.flag.new-ui=true
    cache.ttl=300
EOF

2.2.2 创建Secret

Secret的创建方式与ConfigMap类似,但数据需要经过Base64编码。Kubernetes提供了三种主要创建方式:

  • 字面量创建:使用--from-literal参数,数据自动编码。
  • 文件创建:从文件读取内容,自动编码为Base64。
  • YAML声明式创建:需要手动将值编码为Base64字符串。
# 字面量创建Secret
kubectl create secret generic db-secret \
  --from-literal=username=admin \
  --from-literal=password=S3cur3P@ss

# 从文件创建Secret
kubectl create secret generic tls-secret \
  --from-file=tls.crt=server.crt \
  --from-file=tls.key=server.key

# YAML声明式创建(需手动Base64编码)
echo -n "admin" | base64
echo -n "S3cur3P@ss" | base64

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
  namespace: production
type: Opaque
data:
  username: YWRtaW4=
  password: UzNjdXIzUEBzcw==
EOF
安全警告:YAML文件中的Secret数据以Base64编码存储,但Base64不是加密。在生产环境中,务必启用etcd加密(--encryption-provider-config)并配合RBAC严格限制Secret的访问权限。

2.3 使用场景:将配置注入Pod

ConfigMap与Secret主要通过三种方式注入到Pod中:环境变量、卷挂载、命令行参数。不同的注入方式适用于不同的应用架构与配置更新需求。

核心原则:环境变量方式适合静态配置,Pod重启后生效;卷挂载方式支持动态更新,配置变更后文件自动刷新。

2.3.1 环境变量注入

apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: myapp:1.0
    env:
    # 从ConfigMap单个键注入
    - name: LOG_LEVEL
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: LOG_LEVEL
    # 从Secret单个键注入
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-secret
          key: password
    # 批量导入ConfigMap所有键值对
    envFrom:
    - configMapRef:
        name: app-config
    - secretRef:
        name: db-secret

2.3.2 卷挂载注入

apiVersion: v1
kind: Pod
metadata:
  name: config-pod
spec:
  containers:
  - name: app
    image: myapp:1.0
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config
      readOnly: true
    - name: secret-volume
      mountPath: /etc/secrets
      readOnly: true
  volumes:
  - name: config-volume
    configMap:
      name: app-config
  - name: secret-volume
    secret:
      secretName: db-secret

2.4 ConfigMap与Secret的生命周期管理

配置资源的生命周期包括创建、更新、使用、回收四个阶段。理解每个阶段的操作要点,是保障配置环境一致性的基础。

ConfigMap / Secret 生命周期管理 创建 kubectl create / apply 存储 etcd + RBAC 注入 环境变量 / 卷挂载 更新 滚动更新 / 重启 回收 kubectl delete / 自动清理 关键操作 创建时指定命名空间 更新后需重启Pod

2.4.1 更新策略与Pod重启

当ConfigMap或Secret更新后,已运行的Pod不会自动获取新配置。根据注入方式不同,更新生效的机制也不同:

  • 环境变量注入:必须重启Pod(如通过kubectl rollout restart deployment)才能读取新值。
  • 卷挂载注入:Kubelet会定期同步(默认约60秒),挂载的文件会自动更新,但应用需要监听文件变化或支持热加载。
  • SubPath挂载:不支持自动更新,必须重启Pod。
最佳实践:对于需要频繁更新的配置,优先使用卷挂载方式,并让应用实现文件变化监听(如使用inotify或fsnotify)。对于不频繁变更的配置,使用环境变量方式配合滚动更新即可。

2.4.2 版本管理与回滚

ConfigMap与Secret本身不支持版本控制,但可以通过资源名称或标签实现版本管理:

策略 实现方式 适用场景
命名版本 在资源名称中加入版本号,如app-config-v1、app-config-v2 需要保留历史配置,支持快速回滚
标签版本 使用version: v1标签标记,通过标签选择器引用 与GitOps工具(如ArgoCD)集成
不可变ConfigMap 设置immutable: true,禁止更新,只能重建 生产环境关键配置,防止意外修改
# 不可变ConfigMap示例
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config-immutable
  namespace: production
immutable: true
data:
  DB_HOST: "postgres.prod.svc.cluster.local"
  DB_PORT: "5432"

2.4.3 回收与清理

当配置资源不再使用时,应及时清理以避免资源泄漏和安全隐患:

  • 手动删除:kubectl delete configmap <name> 或 kubectl delete secret <name>
  • 自动清理:结合GitOps工具,当配置资源从Git仓库中移除时自动删除。
  • 命名空间删除:删除整个命名空间会级联删除其下所有ConfigMap和Secret。
注意:删除ConfigMap或Secret前,请确保没有Pod正在引用它们。如果Pod引用了不存在的配置资源,Pod将无法启动(CrashLoopBackOff状态)。建议先更新Deployment移除引用,再删除配置资源。

2.5 配置一致性保障要点

在集群发布中,配置环境一致性需要从以下四个维度进行保障:

  1. 命名空间隔离:不同环境(dev/staging/prod)使用独立命名空间,避免配置串扰。
  2. 配置模板化:使用Kustomize或Helm管理不同环境的配置差异,避免手动复制粘贴。
  3. 变更审计:所有配置变更通过Git仓库提交,配合CI/CD流水线自动部署。
  4. 一致性校验:在发布流水线中加入配置校验步骤,确保目标集群的ConfigMap/Secret与预期一致。
配置环境一致性保障四维模型 命名空间隔离 环境独立Namespace 配置模板化 Kustomize / Helm 变更审计 Git + CI/CD 一致性校验 流水线自动检查 一致性 四个维度协同工作,确保配置在开发、测试、生产环境之间保持一致且可追溯