跳到主要内容

管理配置、密钥与数据

镜像应尽量保持环境无关。地址、开关和日志级别属于配置;密码、令牌和证书属于密钥;数据库文件和上传内容属于持久化数据。三者生命周期和访问控制不同,应分别管理。

本篇目标:能正确使用 ConfigMap 的环境变量和文件注入方式,理解 Secret 的安全边界,区分 PV/PVC/StorageClass 的职责。

Kubernetes 配置、密钥与持久化存储关系


1. ConfigMap:非敏感配置​

apiVersion: v1
kind: ConfigMap
metadata:
name: api-config
namespace: learning
data:
LOG_LEVEL: info
FEATURE_CACHE: "true"
# 也可以存配置文件内容
app.yaml: |
server:
port: 8080
cache:
ttl: 300

1.1 两种注入方式​

# 方式 1:环境变量注入(启动时读取,之后修改 ConfigMap 不会更新)
envFrom:
- configMapRef:
name: api-config

# 方式 2:文件挂载(ConfigMap 更新后,kubelet 会在几十秒内同步到挂载目录)
volumeMounts:
- name: config
mountPath: /etc/app
volumes:
- name: config
configMap:
name: api-config
方式热更新适用场景
环境变量❌ 只在启动时读取启动参数、少量开关
文件挂载✅ kubelet 自动同步(有延迟)配置文件、需要热更新的开关
文件挂载热更新不等于应用自动重载

ConfigMap 更新后,挂载文件内容会变化,但应用不会自动重启或重载配置。需要应用自身支持文件监听(如 inotify),或通过 kubectl rollout restart 触发滚动重启。

1.2 Immutable ConfigMap​

apiVersion: v1
kind: ConfigMap
metadata:
name: api-config-v2
namespace: learning
immutable: true # 创建后不可修改,避免误操作
data:
LOG_LEVEL: info

Immutable ConfigMap 配合版本化命名(如 api-config-v1、api-config-v2),每次变更创建新的、更新 Deployment 引用新的。这比修改同一个 ConfigMap 更可控、更有审计痕迹。


2. Secret:降低暴露面,不等于保险箱​

apiVersion: v1
kind: Secret
metadata:
name: api-credentials
namespace: learning
type: Opaque
stringData:
API_TOKEN: replace-in-cd-or-external-secret

2.1 Secret 类型​

类型用途示例
Opaque通用键值对API Key、数据库密码
kubernetes.io/tlsTLS 证书和私钥Ingress 证书
kubernetes.io/dockerconfigjson私有镜像仓库凭据imagePullSecrets
kubernetes.io/basic-auth基本认证用户名/密码
kubernetes.io/service-account-tokenServiceAccount Token自动管理,一般不需手工创建

2.2 Secret 的安全边界​

Secret 的默认 data 只是 Base64 编码,不是加密。echo "cGFzc3dvcmQ=" | base64 -d 就能解码。

生产基线应至少包括:

层面做法
静态加密开启 etcd 静态加密或使用云厂商 KMS
访问控制RBAC 限制谁能 get secrets,审计 Secret 读取日志
不入 Git真实 Secret 不进 Git、终端历史或 CI 日志
外部密钥对接 External Secrets、Vault 或云 Secret Manager,工作负载运行时读取
短期身份能用 OIDC/STS 临时凭据的,不放长期密钥
# 查看谁有权限读某 Namespace 的 Secret
kubectl auth can-i get secrets -n learning
kubectl get rolebinding,clusterrolebinding -A -o wide | grep -i secret

3. 注入到 Pod​

envFrom:
- configMapRef:
name: api-config
- secretRef:
name: api-credentials

只把所需键注入给所需容器。不要把整份平台级 Secret 挂给每个应用,也不要用 kubectl describe pod、调试脚本或日志打印环境变量。

# 更精细:只取 Secret 中的特定 Key
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: api-credentials
key: DB_PASSWORD

4. PersistentVolumeClaim:申请存储​

4.1 核心概念​

概念职责谁来创建
PV(PersistentVolume)集群可用的一块具体存储资源管理员或 StorageClass 动态供给
PVC(PersistentVolumeClaim)Namespace 内应用对容量和访问模式的申请应用开发者
StorageClass动态供给、性能与回收策略模板平台团队
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: uploads
namespace: learning
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard # 指定 StorageClass
resources:
requests:
storage: 20Gi

4.2 StorageClass 关键参数​

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: pd.csi.storage.gke.io # 取决于 CSI 驱动
parameters:
type: pd-ssd # 供应商特定参数
reclaimPolicy: Retain # 删除 PVC 时保留 PV
volumeBindingMode: WaitForFirstConsumer # 等 Pod 调度后再创建卷(避免跨 AZ)
allowVolumeExpansion: true # 允许在线扩容
参数含义建议
reclaimPolicy: Delete删除 PVC 时自动删除 PV 和云盘开发/测试环境,注意数据丢失风险
reclaimPolicy: Retain删除 PVC 后 PV 保留,需手动清理生产环境首选
volumeBindingMode: ImmediatePVC 创建后立即绑定 PV可能跨 AZ 绑定,导致 Pod 无法挂载
volumeBindingMode: WaitForFirstConsumerPod 调度后才在 Pod 所在 AZ 创建卷生产首选,避免跨 AZ 挂载问题
allowVolumeExpansion: true允许在线扩容 PVC建议开启,避免扩容需要重建

4.3 临时存储​

不是所有存储都需要持久化:

类型生命周期典型场景
emptyDir随 Pod 创建,Pod 删除时清空Pod 内容器间共享临时数据、缓存
emptyDir.medium: Memory同上,但用 tmpfs(内存)高性能临时缓存
hostPath绑定宿主机路径日志采集(DaemonSet 只读挂载)、Docker socket
volumes:
- name: cache
emptyDir:
medium: Memory
sizeLimit: 256Mi

5. 数据安全检查​

  • 先确认访问模式:ReadWriteOnce 不表示任何节点都可同时读写,它只允许单节点挂载为读写;
  • 确认 reclaimPolicy、PVC 保留策略和备份恢复流程;
  • 数据库优先使用托管服务,或采用经过验证的 Operator;
  • 删除 Namespace、PVC 或 StatefulSet 前,先确认数据卷和快照影响;
  • 用恢复演练验证备份,而不只验证"备份任务成功"。

6. 练习​

练习 A

  1. 创建一个 ConfigMap,用环境变量注入到一个 Deployment 中,进入 Pod 用 env | grep 确认变量可见
  2. 修改 ConfigMap,再次进入 Pod 确认环境变量未变化
  3. 改用 volume mount 方式挂载 ConfigMap,修改 ConfigMap 后等 30 秒,进入 Pod 确认文件内容已更新

练习 B

  1. 创建一个 PVC(1Gi),挂载到一个 busybox Pod 的 /data 目录
  2. 在 /data 中写入文件,删除 Pod,重建 Pod 挂载同一 PVC,确认数据还在
  3. 创建 emptyDir 卷(不要 PVC),重复上述操作,确认删除 Pod 后数据丢失

验收清单

  • 会区分 ConfigMap、Secret 和 PVC 的用途
  • 知道 Secret Base64 编码不等于加密,了解至少 3 项 Secret 安全实践
  • 知道 ConfigMap 环境变量 vs 文件挂载的热更新差异
  • 知道 PVC 是申请,StorageClass 决定动态供给方式
  • 理解 WaitForFirstConsumer 的作用和 reclaimPolicy 的取舍
  • 会在删除资源前检查存储与备份影响

下一篇:控制调度、资源与权限。