K8s 存储 Volume 与配置管理 ConfigMap、Secret 学习
本篇主要学习 Kubernetes 卷 Volume 存储体系,包含各类本地 / 网络卷、PV/PVC 持久化存储;以及配置管理对象 ConfigMap、Secret,掌握配置解耦、敏感信息管理,配套实验操作与核心原理。
一、Kubernetes Volume(卷)
参考官方文档:https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/ Pod 中容器的文件是临时的,容器重启数据丢失。Volume 卷就是为 Pod 提供存储,实现数据持久、多容器共享数据。
环境准备:
bash
kubectl create ns storage
kubectl config set-context --current --namespace storage
1. Volume 常见类型
- 临时卷:
emptyDir - 节点本地存储:
hostPath、local - 网络存储:NFS、iSCSI、Ceph、GlusterFS
- 配置类卷:secret、configMap
- 持久存储声明:
persistentVolumeClaim(PVC)
2. emptyDir 临时空目录卷
特点
- Pod 调度到节点上时自动创建目录;
- 同一 Pod 多个容器共享该卷;
- Pod 从节点删除(删除 / 调度漂移),emptyDir 数据全部永久丢失;容器重启数据还在。
- 实际宿主机路径:
/var/lib/kubelet/pods/<pod‑uid>/volumes/kubernetes.io~empty‑dir/xxx
实验关键点:
- spec.volumes 定义卷;spec.containers.volumeMounts 把卷挂载到容器内目录
- 多容器挂载同一个 emptyDir,容器之间可以读写共享文件
- 删除 Pod,宿主机上对应的目录自动消失,数据丢失
3. hostPath 主机路径卷
特点
- 将宿主机 Node 节点的真实目录 / 文件直接挂载进 Pod 容器;
- Pod 删除,宿主机节点上数据依然保留;
- ⚠️缺陷:强绑定节点,Pod 漂移到其他节点,读取到别的节点的文件,多节点集群不适合业务,多用于监控、日志收集等单节点测试。
- volumeMounts 支持
readOnly:true设置只读挂载。
实验:Pod 内创建文件,删除 Pod,登录 node 查看,文件依旧存在宿主机/busyboxdir。
4. NFS 网络文件存储卷
NFS 属于 NAS 网络存储,数据存放在远端 NFS 服务器,Pod 删除数据不会丢失,Pod 可以调度集群任意节点。
操作步骤:
- NFS 服务端(master 节点)安装
nfs‑kernel‑server,创建共享目录,配置/etc/exports; - 所有 worker 节点安装客户端
nfs‑common; - Pod 的 volumes 指定 nfs 配置(服务端 IP、共享路径),挂载到容器 nginx 网页目录;
- 访问 PodIP,读取 NFS 服务器上的 index.html;在 Pod 内新建文件,NFS 服务器目录可见;删除 Pod,NFS 服务器数据保留。
NFS 支持 RWO、ROX、RWX 全部三种访问模式。
二、PV & PVC 持久化存储架构
参考官方文档:https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/
架构概念
- PV (PersistentVolume) 持久卷:集群级资源,由集群管理员预先创建,代表后端真实存储(NFS、磁盘等),生命周期独立 Pod。
- PVC (PersistentVolumeClaim) 持久卷申领 :命名空间 Namespace 级别资源,开发人员用来申请存储资源,指定需要多大存储、访问模式;K8s 自动匹配合适 PV,完成绑定(Bound)。
解耦:开发人员只写 PVC,不需要关心底层存储是什么设备。
完整实验流程
- 管理员编写 pv.yaml,定义 NFS 后端 PV,设置容量、访问模式;
kubectl apply创建 PV,状态变为 Available。 - 用户编写 pvc.yaml,声明需要的存储大小、accessModes,创建 PVC。
- k8s 控制器自动匹配 PV,PVC 状态变成 Bound,完成绑定。
- Pod 通过
persistentVolumeClaim卷引用 PVC,挂载到容器目录使用存储。 - 删除 Pod,PV/PVC 依然存在,数据保存在 NFS 后端。
PV 重要参数
1)accessModes 访问模式
表格
| 模式 | 缩写 | 说明 |
|---|---|---|
| ReadWriteOnce | RWO | 仅单个节点读写挂载,同节点多个 Pod 可以共享 |
| ReadOnlyMany | ROX | 多个节点只读挂载 |
| ReadWriteMany | RWX | 多个节点同时读写挂载 |
| ReadWriteOncePod | RWOP | k8s1.22+,整个集群仅单个 Pod 读写,CSI 卷支持 |
注意:一块卷同一时刻只能使用一种访问模式。不同存储后端支持模式不一样,NFS 支持全部三种 RWO/ROX/RWX。
2)volumeMode 卷模式
Filesystem(默认):文件系统,挂载到容器目录,会自动格式化设备;业务最常用。Block:原始块设备,不做文件系统,直接给 Pod 使用裸块设备,Pod 内应用自己处理块设备。Pod 中使用volumeDevices.devicePath指定设备路径,不是 mountPath。
PV 与 PVC 匹配规则
- 访问模式匹配:PV 支持模式 ≥ PVC 申请的模式;
- 存储容量满足最低需求,相同访问模式卷按容量从小到大优先分配;
storageClassName存储类:实现 PV 分类;PVC 必须和 PV 的 storageClassName 完全一致才能匹配。
PV 回收策略 persistentVolumeReclaimPolicy
PVC 被删除之后,如何处理后端存储。
-
Retain(默认,保留) 删除 PVC 后,PV 状态变成 Released;PV 还保留原来 PVC 的 claimRef 绑定信息,不能直接被新 PVC 绑定使用 。需要手动 edit pv 删除
claimRef字段,PV 回到 Available,才能重新绑定。删除 PV 对象,不会删除后端存储真实数据。
-
Recycle(已经废弃):清空目录,回收复用,不再推荐。
-
Delete(删除):删除 PVC,同时删除底层存储资源;NFS 不支持 Delete 回收策略 ,会报
no deletable volume plugin matched;云厂商云盘支持。
小技巧:PV 预先写死
claimRef,可以强制该 PV 只能绑定指定 namespace 下指定名字 PVC。
弃用卷插件
很多树内存储插件逐步废弃,推荐统一使用 CSI 容器存储接口对接外部存储。
三、Kubernetes Configure 配置管理
将应用配置和容器镜像解耦,配置从镜像剥离出来,ConfigMap 存放普通配置,Secret 存放密码密钥等敏感信息。
环境准备
bash
kubectl create ns configure
kubectl config set-context --current --namespace configure
1. ConfigMap
ConfigMap 存储非敏感的配置,纯文本,不加密,最大 1MiB。 字段说明:
data:普通 UTF‑8 字符串配置;binaryData:二进制 base64 数据;immutable:true设置不可修改 ConfigMap,修改会报错,提升性能。
ConfigMap 三种创建方式
--from‑literal键值对直接创建
bash
kubectl create configmap mysql --from-literal=password=redhat
--from‑file指定单个文件创建,文件名 = key,文件内容 = value
bash
kubectl create configmap web1 --from-file=./index.html
--from‑file指定目录,目录内所有文件生成 key‑value
bash
kubectl create configmap web2 --from-file=./web2
也可以直接编写 yaml 文件创建。
Pod 中两种引用 ConfigMap
① 环境变量引用 configMapKeyRef
容器级别生效,把 cm 中的 key 注入容器环境变量。
bash
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
configMapKeyRef:
name: mysql
key: password
缺点:ConfigMap 更新后,已经运行 Pod 的环境变量不会自动刷新,需要重建 Pod 生效。
② Volume 卷挂载方式引用(Pod 级别)
- 方式 A:引用 ConfigMap 全部 key,全部映射为文件到容器目录;cm 更新,挂载的配置文件 kubelet 会自动同步刷新(周期同步)。
- 方式 B:引用 cm 中特定 key,可以指定映射文件名。
- 使用
subPath:只挂载单个文件,不会覆盖整个目录。
kube‑proxy 组件就是使用 ConfigMap 保存代理配置,修改 cm 后删除 pod,重建 pod 加载新配置。
综合案例 haproxy+web
需求:
- haproxy 配置文件存放在 ConfigMap,volume 挂载,做负载均衡转发到 webapp‑1、webapp‑2;
- webapp‑1、webapp‑2 两个 nginx Pod,各自对应 ConfigMap 保存 index.html、error.html 页面内容;
- 流程:创建 webapp‑1、webapp‑2 的 cm 与 pod,拿到两个 podIP,写入 haproxy.cfg 配置,创建 haproxy 的 cm,启动 haproxy pod;访问 haproxy:8080 实现轮询访问两个后端 web。
四、Secret(保存敏感数据)
参考官方文档:https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/ Secret 专门保存密码、token、证书等敏感信息。 ⚠️注意:Secret 只是做base64 编码,不是加密,集群内部有权限的用户可以解码拿到明文,不要把 Secret 当作强加密方案。
Secret 与 ConfigMap 对比:
- ConfigMap:明文存储普通配置;
- Secret:数据做 base64 编码,用于敏感凭据。
Secret 三种类型
generic(Opaque):通用,保存任意键值密码、配置文件;docker‑registry:镜像仓库登录凭证;tls:保存 SSL 证书公钥私钥。
创建 Secret (generic)
--from‑literal键值对
bash
kubectl create secret generic mysecret1 --from-literal=user=tom --from-literal=password1=redhat
--from‑file普通文件;--from‑env‑fileenv 格式文件;- 目录导入;
- 直接写 yaml,data 字段的值必须是 base64 编码后字符串。
docker‑registry 类型:保存镜像仓库账号密码,给 imagePullSecrets 拉取私有镜像。 tls 类型:传入 crt 证书、key 私钥,创建 tls secret。
Pod 引用 Secret
-
环境变量 secretKeyRef:注入容器环境变量,secret 更新不会自动刷新 pod 环境变量,重建 pod 生效。
-
Volume 挂载方式
:secret 文件挂载进容器,secret 更新,挂载文件 kubelet 自动热更新。
- 挂载全部 key;
- 指定部分 key 挂载;
- subPath 挂载单个 secret 文件。
Secret 文件权限控制
defaultMode设置 secret 全部挂载文件权限(十进制数字,对应八进制权限);- items 下
mode可以设置单独 key 文件权限。 默认挂载文件权限:644(十进制 420)。
综合实验需求
部署 mysql+wordpress 博客应用
- mysql 数据库密码、wordpress 凭证使用 Secret 存储;
- nginx 虚拟主机 vhost 配置使用 ConfigMap 注入配置。
五、知识点梳理总结
- Volume 卷:
- emptyDir:Pod 删除数据丢失,多容器共享;
- hostPath:绑定节点,Pod 删除数据保留,不适合多节点业务;
- NFS 网络存储,数据独立 Pod 持久;
- PV/PVC:存储资源解耦,管理员维护 PV,开发使用 PVC 申请存储;掌握访问模式、回收策略、匹配逻辑。
- ConfigMap:普通配置解耦,两种引用方式;环境变量不会热更新,卷挂载可以热更新。
- Secret:敏感凭据 base64 编码存储,三种类型,同样支持环境变量和 volume 挂载。
- subPath 作用:只挂载单个配置文件,避免覆盖容器整个目录。
- immutable:设置 cm/secret 不可变更,防止误修改,提升性能。
六、环境清理
bash
kubectl delete ns storage
kubectl delete ns configure