K8s 存储与配置:PV/PVC、ConfigMap、Secret
用 PersistentVolume 保存有状态数据,用 ConfigMap 和 Secret 把配置与敏感信息安全地喂给容器。
容器天生是"用完即弃"的:Pod 被重建时,写在容器文件系统里的数据会全部丢失。当你在自己的服务器 / VPS 集群上跑数据库、上传目录或需要外部配置的应用时,就要用到 Kubernetes 的存储与配置对象。本文讲清三件事:持久化存储(PV/PVC)、配置(ConfigMap)、敏感信息(Secret)。
持久化存储:PV 与 PVC
Kubernetes 用两层抽象把"存储供给"和"存储使用"解耦:
- PersistentVolume(PV):一块真实的存储资源,由管理员或存储系统提供(本地磁盘、NFS、云盘等)。
- PersistentVolumeClaim(PVC):应用发出的"申领单",声明我需要多大容量、什么访问模式。
StorageClass 动态供给
手动创建 PV 很繁琐。生产中常用 StorageClass 实现动态供给:你只提交 PVC,集群自动创建对应的 PV。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-pvc
spec:
accessModes:
- ReadWriteOnce # 单节点读写,最常见
resources:
requests:
storage: 10Gi
storageClassName: standard # 换成你集群里实际的 StorageClass
用 kubectl get storageclass 查看可用的 StorageClass;省略 storageClassName 会使用集群默认的那个。创建后 kubectl get pvc 应看到状态变为 Bound。
在 Pod 里挂载:
spec:
containers:
- name: app
image: myapp:latest
volumeMounts:
- name: data
mountPath: /var/lib/app
volumes:
- name: data
persistentVolumeClaim:
claimName: data-pvc
这样 /var/lib/app 下的数据就独立于 Pod 生命周期,重建 Pod 也不丢。
> 提示:ReadWriteOnce 只能被单个节点挂载读写;多节点同时写需要 ReadWriteMany,且底层存储要支持(如 NFS)。有状态服务优先用 StatefulSet 配合 volumeClaimTemplates。
配置:ConfigMap
ConfigMap 存放非敏感的配置:环境变量、配置文件、命令行参数。
命令行快速创建:
kubectl create configmap app-config \
--from-literal=LOG_LEVEL=info \
--from-file=app.conf=./app.conf
在 Pod 中有两种消费方式。作为环境变量:
envFrom:
- configMapRef:
name: app-config
或挂载为文件(每个 key 变成一个文件):
volumeMounts:
- name: cfg
mountPath: /etc/app
volumes:
- name: cfg
configMap:
name: app-config
敏感信息:Secret
密码、API Key、证书等要放进 Secret,而不是 ConfigMap。用法几乎一致:
kubectl create secret generic db-secret \
--from-literal=DB_PASSWORD='s3cr3t'
挂载为环境变量:
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: DB_PASSWORD
关键安全提醒:Secret 只是 base64
很多人误以为 Secret 是"加密的"。它默认只是 base64 编码,任何能读该 Secret 的人一解码就是明文。 因此必须做到:
- 用 RBAC 收紧访问:只给真正需要的 ServiceAccount / 用户 get、list Secret 的权限。
- 开启静态加密(Encryption at Rest):配置 etcd 的加密,让 Secret 在磁盘上真正被加密。
- 别把 Secret 提交进 Git:明文或纯 base64 的 YAML 进仓库等于泄露;需要 GitOps 时用 Sealed Secrets、SOPS 或外部密钥管理(Vault 等)。
- 优先挂载为文件而非环境变量:环境变量容易被子进程继承或打进日志。
小结
- 有状态数据用 PVC 申领存储,靠 StorageClass 动态供给出 PV,挂载进 Pod 后数据独立于 Pod 生命周期。
- ConfigMap 存非敏感配置,Secret 存敏感信息,二者都可注入为环境变量或挂载为文件。
- Secret 默认不加密,只是 base64——务必配合 RBAC 最小权限、etcd 静态加密,并把密钥挡在 Git 之外。把这三块用对,你的应用就能在集群里既有状态又可配置,还足够安全。