K8s Lab 把当前仓库文档整理成一个可阅读的网页站点

Repository Reading Site

ConfigMap 与 Secret — 配置与敏感信息管理

一个 nginx 镜像可能在 dev 连 `postgres-dev`,在 prod 连 `postgres-prod`。如果配置写死在镜像里,每个环境要构建不同的镜像。 K8s 的理念是:**镜像不变,配置外置**。同一个镜像 + 不同的 ConfigMap = 不同环境的行为。 --- `data` 下的每个 key-value 就是一条配置。 **特点

Markdownphase-1/02-configmap-secret.md2026年4月9日 11:35

ConfigMap 与 Secret — 配置与敏感信息管理

为什么不把配置写死在镜像里?

一个 nginx 镜像可能在 dev 连 postgres-dev,在 prod 连 postgres-prod。如果配置写死在镜像里,每个环境要构建不同的镜像。

K8s 的理念是:镜像不变,配置外置。同一个镜像 + 不同的 ConfigMap = 不同环境的行为。


ConfigMap — 非敏感配置

创建方式

# 方式一:从字面值
kubectl -n dev create configmap app-config \
  --from-literal=APP_ENV=development \
  --from-literal=LOG_LEVEL=debug \
  --from-literal=DB_HOST=postgres.dev.svc.cluster.local

# 方式二:从文件
kubectl -n dev create configmap nginx-conf --from-file=nginx.conf

# 方式三:从 YAML
kubectl apply -f configmap.yaml

我们创建的 ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: dev
data:
  APP_ENV: development
  DB_HOST: postgres.dev.svc.cluster.local
  LOG_LEVEL: debug

data 下的每个 key-value 就是一条配置。

两种使用方式

1. 作为环境变量注入

spec:
  containers:
  - name: app
    env:
    - name: APP_ENV
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: APP_ENV
    # 或者一次性注入所有 key:
    envFrom:
    - configMapRef:
        name: app-config

特点: Pod 启动时读取一次,之后不会自动更新。修改 ConfigMap 后必须重启 Pod。

2. 挂载为文件

spec:
  containers:
  - name: app
    volumeMounts:
    - name: config-vol
      mountPath: /etc/config
  volumes:
  - name: config-vol
    configMap:
      name: app-config

挂载后目录结构:

/etc/config/
├── APP_ENV    → 内容: development
├── DB_HOST    → 内容: postgres.dev.svc.cluster.local
└── LOG_LEVEL  → 内容: debug

特点: 修改 ConfigMap 后,文件内容会自动更新(约 30-60 秒延迟)。但应用进程不一定会重新读取文件——需要应用自己支持 watch 配置文件变化,或者用 sidecar 触发 reload。

面试重点

Q: ConfigMap 更新后 Pod 能感知吗?

使用方式 自动更新? 原因
环境变量 不能 环境变量在进程启动时注入,之后不变
Volume 挂载 kubelet 定期同步挂载内容
subPath 挂载 不能 subPath 是静态绑定,不参与更新

Q: Immutable ConfigMap 是什么?

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
immutable: true    # 设置后不可修改,也不可取消
data:
  APP_ENV: production

好处:大规模集群中,kubelet 不需要持续 watch 不可变的 ConfigMap,减轻 API Server 压力。


Secret — 敏感信息(密码、证书、Token)

和 ConfigMap 的区别

特性 ConfigMap Secret
用途 普通配置 密码、证书、Token
存储 etcd 明文 etcd base64(默认不加密!)
传输 不加密 TLS 传输
内存 可用磁盘存储 tmpfs(内存挂载,不写磁盘)
大小限制 1MB 1MB

创建

kubectl -n dev create secret generic db-creds \
  --from-literal=username=admin \
  --from-literal=password=SuperSecret123

查看

# 看到的是 base64 编码(不是加密!)
$ kubectl -n dev get secret db-creds -o jsonpath="{.data}"
{"password":"U3VwZXJTZWNyZXQxMjM=","username":"YWRtaW4="}

# 解码
$ echo "U3VwZXJTZWNyZXQxMjM=" | base64 -d
SuperSecret123

关键安全认知

base64 不是加密,只是编码。 任何人拿到 Secret 的 YAML 都能解码出原文。

Secret 的安全性依赖:

  1. RBAC — 限制谁能 get Secret
  2. etcd 加密 — 配置 EncryptionConfiguration 对 etcd 中的 Secret 做 AES 加密(Phase 3 练习)
  3. 传输加密 — API Server 和 kubelet 之间走 TLS
  4. tmpfs 挂载 — Secret 挂载到 Pod 时用内存文件系统,不落盘

使用方式(同 ConfigMap)

# 环境变量
env:
- name: DB_PASSWORD
  valueFrom:
    secretKeyRef:
      name: db-creds
      key: password

# Volume 挂载
volumes:
- name: db-creds-vol
  secret:
    secretName: db-creds

Secret 的类型

类型 用途
Opaque 默认,任意 key-value
kubernetes.io/tls TLS 证书(tls.crt + tls.key)
kubernetes.io/dockerconfigjson Docker Registry 认证
kubernetes.io/service-account-token ServiceAccount Token

面试深度题

Q: 生产环境如何安全管理 Secret?

  1. etcd 加密 — EncryptionConfiguration + AES-CBC
  2. External Secrets Operator — 从 AWS Secrets Manager / Vault 同步
  3. Sealed Secrets — 加密后可安全存入 Git(GitOps 场景)
  4. RBAC 最小权限 — 只有需要的 ServiceAccount 能读 Secret
  5. 审计日志 — 记录谁访问了 Secret

实验验证总结

操作 结果
创建 ConfigMap app-config 含 APP_ENV, LOG_LEVEL, DB_HOST
创建 Secret db-creds 含 username, password(base64 编码)
解码 Secret echo <base64> | base64 -d 可直接还原明文

03-statefulset-daemonset-job.md