目录
一、 Volume 的概念
二、 Volume 的类型
三、 通过 emptyDir 共享数据
1. EmptyDir 特性
2. EmptyDir 共享数据
四:使用 HostPath 挂载宿主机文件
1. HostPath 特性
2. 挂载宿主机时区文件
五、 挂载 NFS 至容器
1. 前置准备(所有 K8s 节点 + NFS 服务器)
六、PersistentVolume(PV,持久卷)
1. 引入背景
2. 核心特性
3. 回收策略
4. 访问策略
5. 静态配置实践
七、PersistentVolumeClaim(PVC,持久卷声明)
1. 核心作用
2. PVC 配置与绑定
3. PVC 挂载到 Pod
一、 Volume 的概念
对于大多数项目而言,数据文件存储是常见需求(如用户头像、文件、数据库数据)。在 Kubernetes 中,应用部署的高扩展性和编排性,决定了容器内存储数据不可取(无法保障安全)。
应将有状态应用剥离为无状态:数据从应用中分离,存储到云端(如分布式存储、公有云 NAS 服务)。常见方案:
- NFS(生产不建议,单点故障);
- Ceph、GlusterFS、Minio 等分布式存储。
传统架构中,存储需提前在宿主机挂载,新增节点易忘挂载引发问题。Kubernetes 抽象出 Volume 概念,解决数据存储难题。
二、 Volume 的类型
Kubernetes 支持多种 Volume 类型:
- 通用类型:
RBD
、HostPath
等;- 独有类型:
ConfigMap
:存储配置文件;Secret
:存储敏感数据;EmptyDir
:同 Pod 内多容器共享数据;PersistentVolumeClaim
:申请 PersistentVolume。
三、 通过 emptyDir 共享数据
1. EmptyDir 特性
- 特殊 Volume:Pod 删除时,EmptyDir 数据也删除;
- 场景:同 Pod 内容器共享数据(如 Filebeat 收集容器日志)。
2. EmptyDir 共享数据
(1) 编写 Deployment 文件
[root@k8s-master ~]# cat <<EOF>nginx-empty.yaml apiVersion: apps/v1 kind: Deployment metadata:labels:app: nginxname: nginxnamespace: default spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginx01volumeMounts: # 容器1挂载:/opt → share-volume- mountPath: /optname: share-volume- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginx02command: ["sh", "-c", "sleep 3600"] # 保持容器运行volumeMounts: # 容器2挂载:/mnt → share-volume- mountPath: /mntname: share-volumevolumes: # 定义共享卷:share-volume 类型为 emptyDir- name: share-volumeemptyDir: {} # 可添加 medium: Memory 使用 tmpfs(内存存储,节点重启数据清除) EOF
(2) 部署与验证
- 部署:
kubectl create -f nginx-empty.yaml
- 查看 Pod:
kubectl get pod
(示例:nginx-6fffbd7c7b-jrw7f 2/2 Running
)
容器 1 写入数据:
kubectl exec -ti <pod-name> -c nginx01 -- sh # 在 /opt 创建文件(如 touch /opt/test.txt)
容器 2 验证共享:
kubectl exec -ti <pod-name> -c nginx02 -- sh # 查看 /mnt 下是否有 test.txt
- 删除 Pod:
kubectl delete -f nginx-empty.yaml
四:使用 HostPath 挂载宿主机文件
1. HostPath 特性
将宿主机文件 / 目录挂载到 Pod,实现 Pod 与宿主机数据共享(如挂载时区文件解决容器时间偏差)。
2. 挂载宿主机时区文件
(1) 编写 Deployment 文件
[root@k8s-master ~]# cat <<EOF>nginx-hostPath.yaml apiVersion: apps/v1 kind: Deployment metadata:labels:app: nginxname: nginxnamespace: default spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginxvolumeMounts: # 容器内挂载:/etc/localtime → timezone-time- mountPath: /etc/localtimename: timezone-timevolumes: # 定义 HostPath 卷:挂载宿主机 /etc/localtime- name: timezone-timehostPath:path: /etc/localtime # 宿主机路径type: file # 类型:文件必须存在 EOF
(2) 部署与验证
- 部署:
kubectl create -f nginx-hostPath.yaml
验证时间:
kubectl exec -ti <pod-name> -c nginx -- sh date # 检查时区是否为 Asia/Shanghai
HostPath 类型说明:
类型 | 说明 |
---|---|
DirectoryOrCreate | 路径不存在则创建空目录(权限 0755) |
Directory | 路径必须是已存在的目录 |
FileOrCreate | 路径不存在则创建空文件(权限 0644) |
File | 路径必须是已存在的文件 |
Socket /CharDevice /BlockDevice | 对应类型的设备必须存在 |
五、 挂载 NFS 至容器
1. 前置准备(所有 K8s 节点 + NFS 服务器)
- 安装 NFS 工具:
yum -y install nfs-utils
(所有节点);
NFS 服务器配置:
# 创建共享目录 mkdir /opt/wwwroot && echo "NFS Test" > /opt/wwwroot/index.html # 配置共享规则(/etc/exports) echo "/opt/wwwroot 192.168.10.0/24(rw,sync,no_root_squash)" >> /etc/exports # 启动服务 systemctl start nfs && systemctl start rpcbind
2. 编写 Deployment 文件(挂载 NFS)
[root@k8s-master ~]# cat <<EOF>nginx-nfsVolume.yaml apiVersion: apps/v1 kind: Deployment metadata:labels:app: nginxname: nginxnamespace: default spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginxvolumeMounts: # 容器内挂载:/usr/share/nginx/html → nfs-volume- mountPath: /usr/share/nginx/htmlname: nfs-volumevolumes: # 定义 NFS 卷- name: nfs-volumenfs:server: 192.168.10.101 # NFS 服务器IPpath: /opt/wwwroot # NFS 共享目录 EOF
3. 部署与验证
- 部署:
kubectl create -f nginx-nfsVolume.yaml
- 查看 Pod:
kubectl get pod
(示例:nginx-fbd476c4c-zscq9 1/1 Running
)
验证挂载:
kubectl exec -ti <pod-name> -c nginx -- bash cat /usr/share/nginx/html/index.html # 应输出 "NFS Test"
六、PersistentVolume(PV,持久卷)
1. 引入背景
- Volume 无法解决 数据回收、访问模式、单 Pod 挂载 等复杂需求,且非 K8s 管理员难以配置。
- 引入 PV(管理员预配存储) 和 PVC(用户申请 PV),解耦存储管理与使用。
2. 核心特性
- 生命周期独立:不受 Pod 影响,管理员可单独操作。
- 支持存储:NFS、Ceph 等,可配置 访问模式、容量、回收策略。
- 提供方式:静态(预创建)、动态(依赖 StorageClass 自动创建)。
3. 回收策略
策略 | 行为 | 支持存储 |
---|---|---|
Retain | 删除 PVC 后,PV 及数据保留,需手动回收。 | 全类型 |
Recycle | 删除 PVC 后,执行 rm -rf 清理数据(已废弃,仅 NFS/HostPath 支持)。 | NFS、HostPath |
Delete | 删除 PVC 时,自动删除 PV 及数据(动态 PV 默认策略)。 | 云存储(如 AWS EBS) |
4. 访问策略
策略 | 说明 | 存储限制 |
---|---|---|
ReadWriteOnce (RWO) | 单节点读写 | 通用 |
ReadOnlyMany (ROX) | 多节点只读 | 通用 |
ReadWriteMany (RWX) | 多节点读写(块存储多不支持,如 Ceph 块) | NFS、GlusterFS 等 |
ReadWriteOncePod (RWOP) | 单 Pod 读写(K8s 1.22+) | - |
5. 静态配置实践
(1) HostPath 类型 PV
所有 Node 创建目录:mkdir /mnt/data
编写 hostpath-pv.yaml
:
kind: PersistentVolume apiVersion: v1 metadata:name: mypv-hostpath spec:storageClassName: pv-hostpathcapacity: { storage: 10Gi }accessModes: [ReadWriteOnce]hostPath: { path: "/mnt/data" }
(2) NFS 类型 PV(依赖 NFS 服务)
编写 nfs-pv.yaml
:
apiVersion: v1 kind: PersistentVolume metadata: { name: mypv-nfs } spec:storageClassName: pv-nfscapacity: { storage: 5Gi }accessModes: [ReadWriteOnce]persistentVolumeReclaimPolicy: Recyclenfs:path: /opt/wwwrootserver: 192.168.10.101 # NFS 服务器 IP
创建 & 查看:kubectl create -f nfs-pv.yaml && kubectl get pv
七、PersistentVolumeClaim(PVC,持久卷声明)
1. 核心作用
- 用户通过 PVC 声明 容量、访问模式、StorageClass,自动绑定匹配的 PV,无需关心存储细节。
2. PVC 配置与绑定
(1) HostPath PV 的 PVC
kind: PersistentVolumeClaim apiVersion: v1 metadata: { name: mypvc-hostpath } spec:storageClassName: pv-hostpath # 与 PV 一致accessModes: [ReadWriteOnce]resources: { requests: { storage: 10Gi } }
创建 & 查看:kubectl create -f pvc-hostpath.yaml && kubectl get pvc
(状态为 Bound
)
(2) NFS PV 的 PVC
kind: PersistentVolumeClaim apiVersion: v1 metadata: { name: mypvc-nfs } spec:storageClassName: pv-nfs # 与 PV 一致accessModes: [ReadWriteOnce]resources: { requests: { storage: 3Gi } } # ≤ PV 容量(5Gi)
创建 & 查看:kubectl create -f pvc-nfs.yaml && kubectl get pvc
(状态为 Bound
)
3. PVC 挂载到 Pod
kind: Pod apiVersion: v1 metadata: { name: hostpath-pv-pod } spec:volumes:- name: pv-volumepersistentVolumeClaim: { claimName: mypvc-hostpath } # 绑定 PVCcontainers:- name: test-containerimage: nginx:1.7.9volumeMounts:- mountPath: "/data"name: pv-volume
验证:kubectl exec -ti hostpath-pv-pod -- ls /data