This repository has been archived on 2026-05-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
2026-05-18 00:17:59 +08:00

5.3 KiB
Raw Permalink Blame History

tags, create time
tags create time
kubernetes
configmap
secret
configuration-management
2026-05-18 00:30

K8s 配置管理 — ConfigMap 与 Secret

概述

K8s 提供两种原生的配置注入机制:ConfigMap(普通配置)和 Secret(敏感信息)。理解它们的区别、注入方式和生效时机,是编写可维护 K8s manifest 的基础。更多安全方案(外部密钥管理)参见 ../03-CICD与GitOps/04-安全与发布策略。

ConfigMap — 非敏感配置注入

基本用法

apiVersion: v1
kind: ConfigMap
metadata:
  name: order-service-config
  namespace: production
data:
  # ========== 环境变量风格 ==========
  DATABASE_HOST: "mysql.production.svc.cluster.local"
  DATABASE_PORT: "3306"
  LOG_LEVEL: "info"
  MAX_CONNECTIONS: "100"
  
  # ========== 文件风格 (挂载为 volume) ==========
  application.yaml: |
    server:
      port: 8080
    spring:
      datasource:
        url: jdbc:mysql://${DATABASE_HOST}:${DATABASE_PORT}/orders
        pool-size: ${MAX_CONNECTIONS}
    logging:
      level:
        root: ${LOG_LEVEL}

两种注入方式

spec:
  containers:
  - name: order-service
    # 方式一:环境变量注入(简单直接)
    env:
    - name: DATABASE_HOST
      valueFrom:
        configMapKeyRef:
          name: order-service-config
          key: DATABASE_HOST
    
    # 方式二:volume 挂载配置文件(适合完整配置文件)
    volumeMounts:
    - name: config-volume
      mountPath: /etc/app/config/application.yaml
      subPath: application.yaml
  volumes:
  - name: config-volume
    configMap:
      name: order-service-config

[!tip] 热更新 vs 重建 Pod

  • 通过 环境变量 注入的配置需要重建 Pod 才能生效
  • 通过 volume 挂载 的 ConfigMap 在配置变更后,Pod 内文件会在约 1 分钟内自动更新(前提是应用本身支持配置热加载,如 Spring Cloud Context 的 @RefreshScope)

Secret — 敏感信息存储

基本用法

apiVersion: v1
kind: Secret
metadata:
  name: order-service-secrets
  namespace: production
type: Opaque
data:
  # Base64 编码(注意:这不是加密!只是编码)
  DB_PASSWORD: cGFzc3dvcmQxMjM=
  API_KEY: bXktc2VjcmV0LWFwaS1rZXk=

# 或者用 stringData(明文写入,K8s 自动编码)
---
apiVersion: v1
kind: Secret
metadata:
  name: order-service-secrets-v2
type: Opaque
stringData:
  DB_PASSWORD: password123     # K8s 自动转为 base64
  API_KEY: my-secret-api-key

使用 Secret 的方式:

# 方式一:作为环境变量注入
env:
- name: DB_PASSWORD
  valueFrom:
    secretKeyRef:
      name: order-service-secrets
      key: DB_PASSWORD

# 方式二:挂载为卷中的文件(更安全,避免暴露在 ps 输出中)
volumeMounts:
- name: secrets-volume
  readOnly: true
  mountPath: /etc/secrets
  defaultMode: 0400
volumes:
- name: secrets-volume
  secret:
    secretName: order-service-secrets

[!warning] Secret 的安全性边界

K8s Secret 默认以 base64 编码 存储在 etcd 中,任何人都可以解码。Base64 ≠ 加密。生产环境应启用以下至少一项:

  1. etcd 加密 — 开启 K8s EncryptionConfiguration,使 etcd 存储密文
  2. 外部密钥管理 — Sealed Secrets、External Secrets Operator 对接 AWS Secrets Manager / HashiCorp Vault
  3. RBAC 严格管控 — 限制谁可以读取 Secret 资源

ConfigMap vs Secret 对比

维度 ConfigMap Secret
用途 普通配置(URL、端口等) 敏感信息(密码、Token、证书)
存储格式 UTF-8 字符串 Base64 编码
挂载路径 /etc/config/... /etc/secrets/...
大小限制 1 MiB 1 MiB
安全建议 正常 RBAC 必须启用 etcd 加密或外置密钥管理

补充:动态配置重载实战

对于需要频繁变更的配置(如功能开关、灰度比例),可以通过 sidecar 模式实现自动重载:

spec:
  containers:
  - name: app
    image: myapp:latest
    volumeMounts:
    - name: config-volume
      mountPath: /etc/app/config
      readOnly: true
  - name: reload-sidecar                  # Watch 配置变更并发送 SIGUSR1
    image: busybox:latest
    command: ["sh", "-c"]
    args:
      - |
        LAST_MD5=""
        while true; do
          CURR_MD5=$(md5sum /etc/config/application.yaml | awk '{print $1}')
          if [ "$CURR_MD5" != "$LAST_MD5" ]; then
            kill -USR1 1  # 通知主进程重新加载配置
            LAST_MD5="$CURR_MD5"
          fi
          sleep 5
        done
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config
      readOnly: true
  volumes:
  - name: config-volume
    configMap:
      name: order-service-config
  - name: shared-config
    emptyDir: {}

[!note] sidecar 模式的权衡

优点:无需重启 Pod 即可热更新配置;缺点:增加了资源消耗和维护复杂度。Spring Boot 项目建议使用 Actuator /refresh 端点替代手动信号方案。

关联笔记