CFN Cloud
Cloud Future New Life
en zh
2025-10-08 · 0 次浏览

ConfigMap 与 Secret

把配置和敏感信息从镜像中解耦出来。

ConfigMap 用于普通配置,Secret 用于敏感信息(密码、证书)。它们帮助保持镜像不可变,同时让配置在不同环境之间可控、可审计。

这篇快速上手补充了创建方式、环境变量与文件挂载、滚动更新触发以及安全实践。

适用场景

  • 应用配置文件、开关、日志级别等非敏感参数。
  • 数据库密码、API Token、TLS 证书等敏感信息。

为什么使用 ConfigMap 与 Secret

  • 将配置与镜像解耦,避免重复构建。
  • 便于在不同环境中切换参数。
  • 支持凭据轮换与最小权限访问。

创建 ConfigMap 与 Secret

可以直接用命令创建:

kubectl create configmap app-config --from-literal=LOG_LEVEL=info
kubectl create secret generic db-secret --from-literal=DB_PASSWORD='changeme'

对应的 YAML:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  LOG_LEVEL: "info"
---
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
stringData:
  DB_PASSWORD: "changeme"

作为环境变量注入

全量导入:

envFrom:
  - configMapRef:
      name: app-config
  - secretRef:
      name: db-secret

或只映射指定键:

env:
  - name: LOG_LEVEL
    valueFrom:
      configMapKeyRef:
        name: app-config
        key: LOG_LEVEL
  - name: DB_PASSWORD
    valueFrom:
      secretKeyRef:
        name: db-secret
        key: DB_PASSWORD

以文件挂载

更适合配置文件或证书:

volumes:
  - name: config
    configMap:
      name: app-config
  - name: secret
    secret:
      secretName: db-secret
volumeMounts:
  - name: config
    mountPath: /etc/app/config
    readOnly: true
  - name: secret
    mountPath: /etc/app/secret
    readOnly: true

变更触发滚动更新

ConfigMap/Secret 变化不会自动重启 Pod,常见做法是在 Deployment 中加 checksum 注解:

metadata:
  annotations:
    checksum/config: "{{ .Values.configChecksum }}"

不用 Helm 时可手动滚动:

kubectl rollout restart deployment/my-app

命名空间与范围

ConfigMap/Secret 是命名空间级资源,Pod 与配置必须在同一命名空间。跨命名空间引用默认不允许。

安全建议

  • Secret 只是 base64 编码,默认不加密,应开启 API Server 的 at-rest 加密。
  • 用 RBAC 限制读取权限,避免无关 Pod 挂载。
  • 生产环境可使用 Vault 或云 KMS 管理密钥。
  • 不要把 Secret 提交到 git。

变更触发滚动更新

ConfigMap/Secret 变化不会自动重启 Pod,常见做法是在 Deployment 中加 checksum 注解:

metadata:
  annotations:
    checksum/config: "{{ .Values.configChecksum }}"

不用 Helm 时可手动滚动:

kubectl rollout restart deployment/my-app

通过文件创建

配置文件或证书可以直接从文件创建:

kubectl create configmap app-config --from-file=app.yaml=./app.yaml
kubectl create secret generic tls-secret --from-file=tls.crt=./tls.crt --from-file=tls.key=./tls.key

目录场景:

kubectl create configmap app-config --from-file=./config-dir

示例:应用 Deployment

下面是一个最小示例,演示 env 和文件挂载并用:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: app
        image: nginx:1.27
        envFrom:
        - configMapRef:
            name: app-config
        - secretRef:
            name: db-secret
        volumeMounts:
        - name: config
          mountPath: /etc/app/config
          readOnly: true
        - name: secret
          mountPath: /etc/app/secret
          readOnly: true
      volumes:
      - name: config
        configMap:
          name: app-config
      - name: secret
        secret:
          secretName: db-secret

排查思路

查看 Pod 是否加载正确:

kubectl describe pod <pod-name>

查看配置内容:

kubectl get configmap app-config -o yaml
kubectl get secret db-secret -o yaml

也可以 exec 进入 Pod 查看挂载文件:

kubectl exec -it <pod-name> -- ls -l /etc/app/config
kubectl exec -it <pod-name> -- ls -l /etc/app/secret

如果环境变量读取异常,检查 key 名称及命名空间是否一致。

大小与拆分策略

ConfigMap 有大小限制,建议把大文件拆分成多个资源,或放到对象存储。Secret 也有体积限制,证书和密钥建议分开管理,便于轮换。

常见坑点

  • ConfigMap 体积上限约 1MiB,避免塞入大文件。
  • 以 env 注入的 Secret 只在 Pod 启动时读取。
  • 多容器场景下要保持名称一致。

不要把 ConfigMap 当数据存储使用。

配置变更与应用加载

ConfigMap 挂载为文件时,Kubernetes 会更新文件内容,但应用不一定自动重载。建议确认应用是否支持 reload,必要时通过滚动更新或热加载机制触发刷新。

轮换与生命周期

Secret 需要定期轮换。如果是 env 注入,必须重启 Pod;文件挂载虽会更新,但多数应用仍需要 reload 信号。

可以制定版本化策略,发布新 Secret 后保留旧版本一段时间再淘汰。

权限与审计

只给需要的 ServiceAccount 读取权限,避免全命名空间可见。对敏感配置建议配合审计日志或 GitOps 流程,保证变更可追溯。

配置拆分与命名

建议按应用拆分 ConfigMap/Secret,并使用统一的命名规则。这样在排错或回滚时更容易定位对应资源,减少误操作。

同时建议在 README 或运维文档中记录配置默认值与覆盖方式,避免误修改导致线上故障。

实操要点

  • 先做快速盘点:kubectl get nodeskubectl get pods -Akubectl get events -A
  • 对比“期望状态”和“实际状态”,kubectl describe 往往能解释漂移或失败原因。
  • 名称、Label、Selector 要一致,避免 Service 或控制器找不到 Pod。

快速检查清单

  • 资源定义与业务意图一致。
  • Namespace、权限、镜像与环境匹配。
  • 上线前具备健康探针与可观测日志。

参考链接