Kubernetes 存储入门笔记:从 Volume 到 PVPVC 全解析
Kubernetes 存储入门笔记:从 Volume 到 PV/PVC 全解析
一、Volume 核心概念与价值
在 Kubernetes 中,容器的文件系统是临时的 —— 当容器崩溃重启后,运行时产生的数据会全部丢失;且 Pod 内多容器间可能需要共享数据。传统存储方式(如直接挂载宿主机目录)无法适配 K8s 的动态编排特性(如 Pod 漂移、节点扩展),因此 K8s 抽象出Volume概念解决数据存储问题。
1.1 Volume 的本质
Volume 本质是一个可被 Pod 内容器访问的目录,其数据可在容器重启后保留,生命周期与 Pod 一致(长于容器生命周期)。Pod 通过spec.volumes定义 Volume,通过spec.containers.volumeMounts指定容器内挂载路径,使用方式与物理机挂载目录完全一致。
1.2 K8s Volume vs Docker Volume
特性 | Docker Volume | K8s Volume |
---|---|---|
生命周期 | 无管理,独立于容器 / Pod | 与 Pod 一致,随 Pod 创建 / 销毁 |
功能支持 | 仅基础目录挂载,驱动限制多(如单驱动) | 支持多类型、多驱动,可传递复杂参数 |
扩展性 | 有限,依赖手动配置 | 原生支持集群级存储管理,适配动态编排 |
多容器共享 | 支持但配置复杂 | 原生支持,通过volumeMounts直接共享 |
1.3 Volume 核心价值
-
数据持久化:解决容器重启数据丢失问题;
-
跨容器共享:实现 Pod 内多容器间文件共享;
-
存储解耦:屏蔽底层存储差异(如 NFS、Ceph),统一通过 Volume 接口访问;
-
生命周期管理:随 Pod 生命周期自动管理,减少手动运维成本。
二、常见 Volume 类型及实践
K8s 支持多种 Volume 类型,适配不同场景(临时共享、宿主机挂载、跨节点共享等)。以下为核心类型的详细解析:
2.1 emptyDir:Pod 内临时共享存储
定义
emptyDir 是一种临时 Volume,在 Pod 创建时自动生成,随 Pod 删除而销毁,用于 Pod 内多容器间的数据共享。
特点
-
生命周期:与 Pod 完全绑定,Pod 删除则数据丢失;
-
存储介质:默认使用节点本地介质(磁盘 / SSD),可通过medium: Memory指定使用 tmpfs(内存文件系统,速度快但节点重启数据丢失);
-
使用简单:无需底层存储依赖,直接定义即可。
优缺点
优点 | 缺点 |
---|---|
零配置,即开即用 | 数据非持久化,Pod 删除后丢失 |
支持内存级高速存储 | 仅限 Pod 内共享,无法跨节点访问 |
实践示例:双容器共享数据
# nginx-empty.yaml
apiVersion: apps/v1 # API版本,apps/v1适用于Deployment等有状态应用
kind: Deployment # 资源类型,Deployment用于管理Pod的创建和扩展
metadata:name: nginx # Deployment名称,用于标识资源
spec:replicas: 1 # 副本数,指定创建1个Pod实例selector:matchLabels:app: nginx # 标签选择器,匹配带有app: nginx标签的Podtemplate:metadata:labels:app: nginx # Pod标签,需与selector匹配spec:containers:- name: nginx01 # 第一个容器名称image: nginx:1.7.9 # 使用的镜像volumeMounts: # 容器内挂载配置- mountPath: /opt # 容器内挂载路径,emptyDir将被挂载到这里name: share-volume # 挂载的Volume名称,需与volumes中定义的一致- name: nginx02 # 第二个容器名称image: nginx:1.7.9 # 使用的镜像command: ["sh", "-c", "sleep 3600"] # 容器启动命令,保持容器运行volumeMounts: # 容器内挂载配置- mountPath: /mnt # 容器内挂载路径,与nginx01共享数据name: share-volume # 挂载的Volume名称,与volumes中定义的一致volumes: # Volume定义部分- name: share-volume # Volume名称,供容器挂载引用emptyDir: {} # 定义为emptyDir类型,{}表示使用默认配置# 若需使用内存存储,可改为:# emptyDir:# medium: Memory # 指定使用内存文件系统tmpfs
- 部署后,在nginx01的/opt创建文件,nginx02的/mnt目录可直接访问该文件,实现数据共享。
2.2 HostPath:挂载宿主机文件 / 目录
定义
HostPath 将宿主机的文件或目录挂载到 Pod 中,实现 Pod 与宿主机的数据共享。
特点
-
存储介质:依赖宿主机文件系统,数据生命周期与宿主机一致(不受 Pod 影响);
-
类型参数:通过type指定挂载校验规则(如File要求宿主机路径必须是文件,DirectoryOrCreate自动创建不存在的目录)。
优缺点
优点 | 缺点 |
---|---|
实现简单,直接复用宿主机存储 | 强依赖节点,Pod 漂移到其他节点后数据不可访问(需固定节点) |
适合节点级配置共享(如时区文件) | 存在权限风险(容器可能修改宿主机关键文件) |
实践示例:挂载宿主机时区文件
# nginx-hostPath.yaml
apiVersion: apps/v1 # API版本
kind: Deployment # 资源类型
metadata:name: nginx # Deployment名称
spec:replicas: 1 # 副本数selector:matchLabels:app: nginx # 标签选择器template:metadata:labels:app: nginx # Pod标签spec:containers:- name: nginx # 容器名称image: nginx:1.7.9 # 使用的镜像volumeMounts: # 容器内挂载配置- mountPath: /etc/localtime # 容器内挂载路径,覆盖容器默认时区文件name: timezone-time # 挂载的Volume名称volumes: # Volume定义部分- name: timezone-time # Volume名称hostPath: # 定义为hostPath类型path: /etc/localtime # 宿主机上的文件路径,需存在type: File # 类型校验,确保宿主机路径是文件# 其他常用type值:# Directory:必须是已存在的目录# DirectoryOrCreate:不存在则创建目录# FileOrCreate:不存在则创建文件
- 部署后,容器内date命令显示时区与宿主机一致,解决容器时区偏差问题。
2.3 NFS:跨节点共享存储
定义
NFS(Network File System)是一种网络文件系统,可通过网络将远程服务器的共享目录挂载到 Pod,实现跨节点数据共享。
特点
-
跨节点访问:支持多节点的 Pod 共享同一存储,适合无状态应用的静态资源共享(如前端静态文件);
-
依赖底层服务:需提前部署 NFS 服务器并配置共享目录。
优缺点
优点 | 缺点 |
---|---|
支持跨节点共享,适配集群环境 | 存在单点故障风险(生产不推荐,建议用分布式存储如 Ceph) |
配置简单,兼容性强 | 性能受网络影响,不适合高 IO 场景 |
实践示例:挂载 NFS 共享目录
- 部署 NFS 服务(所有节点安装客户端,服务器配置共享目录):
# 所有节点安装NFS客户端,用于挂载NFS共享目录
yum -y install nfs-utils# NFS服务器配置共享目录(在NFS服务器节点执行)
mkdir /opt/wwwroot && echo "Test NFS" > /opt/wwwroot/index.html # 创建测试文件
vim /etc/exports # 编辑NFS配置文件,添加共享规则
# 添加内容:/opt/wwwroot 192.168.10.0/24(rw,sync,no_root_squash)
# 说明:
# /opt/wwwroot:共享的目录路径
# 192.168.10.0/24:允许访问的网段
# rw:读写权限;sync:同步写入;no_root_squash:保留root权限systemctl start nfs && systemctl start rpcbind # 启动NFS相关服务
systemctl enable nfs && systemctl enable rpcbind # 设置开机自启
- 创建挂载 NFS 的 Deployment:
# nginx-nfsvolume.yaml
apiVersion: apps/v1 # API版本
kind: Deployment # 资源类型
metadata:name: nginx # Deployment名称
spec:replicas: 1 # 副本数selector:matchLabels:app: nginx # 标签选择器template:metadata:labels:app: nginx # Pod标签spec:containers:- name: nginx # 容器名称image: nginx:1.7.9 # 使用的镜像volumeMounts: # 容器内挂载配置- mountPath: /usr/share/nginx/html # Nginx默认静态文件目录name: nfs-volume # 挂载的Volume名称volumes: # Volume定义部分- name: nfs-volume # Volume名称nfs: # 定义为nfs类型server: 192.168.10.101 # NFS服务器的IP地址,需替换为实际地址path: /opt/wwwroot # NFS服务器上的共享目录路径# readOnly: true # 可选,设置为只读挂载
- 部署后,容器内/usr/share/nginx/html/index.html内容与 NFS 服务器共享文件一致,跨节点 Pod 可访问同一数据。
2.4 其他常用 Volume 类型
类型 | 定义 | 核心场景 | 优点 |
---|---|---|---|
ConfigMap | 存储配置文件的 Volume | 应用配置注入(如数据库地址、端口) | 配置与代码解耦,支持动态更新 |
Secret | 存储敏感数据的 Volume(Base64 编码) | 密码、Token 等敏感信息挂载 | 避免敏感数据明文暴露在镜像中 |
CephFS/GlusterFS | 分布式文件系统 Volume | 高可用、高扩展的持久化存储 | 支持 RWX(多节点读写),适合大规模集群 |
三、PersistentVolume(PV)与 PersistentVolumeClaim(PVC)
Volume 解决了 Pod 内存储问题,但存在局限性:存储配置依赖底层细节(如 NFS 服务器 IP),普通用户需了解存储技术;且无法管理存储生命周期(如数据回收、访问控制)。PV 和 PVC 通过 “抽象存储资源” 与 “按需申请” 机制解决这些问题。
3.1 PV 与 PVC 的核心作用
-
PV(PersistentVolume):由管理员创建的集群级存储资源,独立于 Pod 生命周期,可配置存储类型、容量、访问模式、回收策略等,底层依赖 NFS、Ceph 等存储后端。
-
PVC(PersistentVolumeClaim):用户对存储资源的申请,声明所需的容量、访问模式、存储类型等,K8s 自动匹配符合条件的 PV 并绑定,用户无需关心底层存储实现。
核心价值:解耦存储 “供给” 与 “使用”—— 管理员负责存储资源配置(PV),用户通过 PVC 申请资源,实现存储使用的标准化与简化。
3.2 PV 关键配置解析
(1)回收策略(数据生命周期管理)
当 PVC 删除后,PV 的处理方式由回收策略定义:
策略 | 行为描述 | 适用场景 |
---|---|---|
Retain | 保留 PV 及数据,需手动回收 | 重要数据(如数据库),避免误删 |
Delete | 自动删除 PV 及底层存储数据 | 临时数据(如日志),自动释放资源 |
Recycle | 清理 PV 数据(rm -rf)后复用 | 已弃用,建议用 Retain + 手动清理替代 |
- 静态 PV 默认策略为Retain,动态 PV 默认策略为Delete。
(2)访问模式(存储权限控制)
定义 PV 允许的访问方式,需底层存储支持:
模式 | 描述 | 支持存储类型示例 |
---|---|---|
ReadWriteOnce(RWO) | 单节点读写访问 | 块存储(如 EBS、Cinder) |
ReadOnlyMany(ROX) | 多节点只读访问 | NFS、CephFS |
ReadWriteMany(RWX) | 多节点读写访问 | CephFS、GlusterFS |
ReadWriteOncePod(RWOP) | 单 Pod 读写访问(1.22+) | 所有存储类型 |
(3)配置方式
-
静态配置:管理员手动创建 PV,明确存储后端参数(如 NFS 路径、Ceph 集群信息)。
-
动态配置:管理员创建 StorageClass 定义存储模板,用户 PVC 指定 StorageClass 后,K8s 自动创建 PV,无需手动配置。
3.3 PV 与 PVC 绑定条件
PVC 需与 PV 满足以下条件才能绑定:
-
访问模式(accessModes)完全匹配;
-
StorageClass 名称一致(storageClassName);
-
PVC 申请容量 ≤ PV 总容量;
-
卷模式(volumeMode,文件系统 / 块存储)一致。
3.4 实践示例:静态 PV 与 PVC 完整流程
(1)创建基于 NFS 的 PV
# nfs-pv.yaml
apiVersion: v1 # PV的API版本为v1
kind: PersistentVolume # 资源类型为PersistentVolume
metadata:name: mypv-nfs # PV名称,唯一标识
spec:capacity: # 存储容量配置storage: 5Gi # 总容量为5GiBaccessModes: # 支持的访问模式- ReadWriteOnce # 支持单节点读写persistentVolumeReclaimPolicy: Retain # 回收策略,PVC删除后保留数据storageClassName: pv-nfs # 存储类名称,用于PVC匹配# 存储类为空表示不指定,PVC也需为空才能匹配# storageClassName: ""nfs: # 底层存储类型为NFSserver: 192.168.10.101 # NFS服务器IPpath: /opt/wwwroot # NFS共享目录# 其他可选配置# claimRef: # 强制绑定到特定PVC,一般不设置# name: mypvc-nfs# namespace: default# nodeAffinity: # 限制PV只能被特定节点使用# required:# nodeSelectorTerms:# - matchExpressions:# - key: kubernetes.io/hostname# operator: In# values:# - node1
kubectl create -f nfs-pv.yaml # 创建PV资源
kubectl get pv # 查看PV状态,刚创建时为Available(待绑定)
(2)创建 PVC 申请存储
# pvc-nfs.yaml
apiVersion: v1 # PVC的API版本为v1
kind: PersistentVolumeClaim # 资源类型为PersistentVolumeClaim
metadata:name: mypvc-nfs # PVC名称
spec:accessModes: # 申请的访问模式,需PV支持- ReadWriteOnceresources: # 资源需求requests:storage: 3Gi # 申请3GiB容量,需≤PV的5GistorageClassName: pv-nfs # 匹配存储类名称,需与PV一致# 可选:指定PV名称强制绑定(一般不推荐)# volumeName: mypv-nfs
kubectl create -f pvc-nfs.yaml # 创建PVC资源
kubectl get pvc # 查看PVC状态,成功后为Bound(已绑定)
(3)Pod 挂载 PVC 使用存储
# pvc-pod.yaml
apiVersion: v1 # Pod的API版本为v1
kind: Pod # 资源类型为Pod
metadata:name: nfs-pvc-pod # Pod名称
spec:containers:- name: nginx # 容器名称image: nginx:1.7.9 # 使用的镜像volumeMounts: # 容器内挂载配置- mountPath: /usr/share/nginx/html # 挂载路径name: nfs-storage # 挂载的Volume名称volumes: # Volume定义- name: nfs-storage # Volume名称persistentVolumeClaim: # 引用PVCclaimName: mypvc-nfs # 要绑定的PVC名称
kubectl create -f pvc-pod.yaml # 创建Pod
# 验证数据共享
kubectl exec -it nfs-pvc-pod -- ls /usr/share/nginx/html
3.5 PV 与 PVC 的优缺点
组件 | 优点 | 缺点 |
---|---|---|
PV | 标准化存储配置,支持复杂策略 | 静态 PV 需手动创建,扩展性有限 |
PVC | 简化存储使用,用户无需懂存储技术 | 依赖管理员提前配置 PV 或 StorageClass |
整体机制 | 解耦存储供给与使用,支持生命周期管理 | 动态配置需额外部署 StorageClass |
四、核心组件关系与总结
4.1 存储组件关系图
底层存储(NFS/Ceph/本地磁盘) → PV(集群级存储资源) ← 绑定 → PVC(用户存储申请) → Volume(Pod挂载) → 容器内目录
4.2 关键结论
-
Volume 是基础:解决 Pod 内数据持久化与共享,支持 emptyDir(临时)、HostPath(节点级)、NFS(跨节点)等类型。
-
PV/PVC 是进阶:通过 “资源抽象” 与 “按需申请” 简化存储管理,适合多用户、大规模集群场景。
-
选型建议:
-
临时共享数据用emptyDir;
-
节点级配置共享用HostPath;
-
跨节点共享用NFS或分布式存储(Ceph);
-
生产环境推荐 PV+PVC,配合动态 StorageClass 实现存储自动化。
通过本章学习,可掌握 K8s 存储从基础到进阶的核心能力,为构建高可用、可扩展的容器存储方案奠定基础。