概览
本文对常见的容器存储方案进行整理,包括 Docker 本地存储、Kubernetes 常用 Volume(emptyDir、hostPath)以及持久化存储资源对象 PersistentVolume(PV)、PersistentVolumeClaim(PVC)和 StorageClass。并以 NFS 为例,演示静态 PV/PVC 的创建与使用流程。
目录
- 常见存储机制(Docker、Kubernetes)
- Docker 本地存储
- Kubernetes 本地存储:emptyDir、hostPath
- PV / PVC / StorageClass 概念
- NFS 环境准备
- 原生 NFS 挂载示例(Deployment)
- 使用 PV 与 PVC(静态 PV)示例
- 创建 PV 池
- 创建 PVC
- 使用 PVC 的 Deployment
- 清理顺序与注意事项
常见存储机制
Docker 本地存储
- 宿主机目录挂载:
docker run -v /local/path:/container/path ... - 命名卷(volume)挂载:
docker run -v volume_name:/container/path ...
Kubernetes 本地存储
emptyDir
- emptyDir 在 Pod 被调度到 Node 时由 kubelet 在该 Node 上创建目录。
- 初始内容为空;当 Pod 从 Node 上移除后数据会被删除(非持久化)。
- 适用场景:
- 临时缓存、合并排序、短期中间文件
- 容器间共享临时数据(例如临时日志)
- 查看帮助:
kubectl explain pod.spec.volumes.emptyDir kubectl explain pod.spec.containers.volumeMounts
hostPath
- 将宿主机的文件或目录直接映射到 Pod 内。
- 可指定 type(File、Directory、Socket、CharDevice、BlockDevice 等)。
- 适用场景与注意点:
- 适用于特定 Node 上的资源(跨 Node 时可能不一致)。
- 需关注宿主机权限(宿主机目录通常只有 root 写权限)。
- 不会被调度感知(不会计入资源调度决策)。
- 查看帮助:
kubectl explain pod.spec.volumes.hostPath kubectl explain pod.spec.containers.volumeMounts - 示例 Pod(hostPath):
apiVersion: v1 kind: Pod metadata: name: test-pod2 spec: containers: - image: busybox name: test-hostpath command: ["sleep","3600"] volumeMounts: - mountPath: /test-data name: test-volume volumes: - name: test-volume hostPath: path: /data type: Directory
PV / PVC / StorageClass — 核心概念
- PersistentVolume(PV):由管理员创建或动态供应的集群级存储资源抽象(表示具体存储,如 NFS、Ceph、GlusterFS 等)。
- PersistentVolumeClaim(PVC):用户对存储的申请(类似 Pod 对 CPU/内存的请求),PVC 会绑定到合适的 PV。
- StorageClass:描述存储类型与动态供应策略(如快速/慢速、不同 provisioner),供用户在 PVC 中指定。
使用 PV/PVC 可以把存储管理与底层实现解耦,使应用可以通过 PVC 方便地申请持久化存储。
NFS 环境准备(示例)
在 master 节点上安装并配置 NFS:
yum install -y nfs-utils rpcbind
mkdir -p /nfs/data && chmod 755 /nfs/data
# /etc/exports 内容(示例)
# /nfs/data/ *(insecure,rw,sync,no_root_squash)
systemctl enable --now rpcbind.service nfs.service
exportfs -r
exportfs
原生方式数据挂载(直接在 Deployment 中使用 NFS)
示例:直接在 Deployment volumes 中声明 nfs(属于“原生”方式,需提前在 NFS 服务端创建目录)。
nginx-pv-demo.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-pv-demo
name: nginx-pv-demo
spec:
replicas: 2
selector:
matchLabels:
app: nginx-pv-demo
template:
metadata:
labels:
app: nginx-pv-demo
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
nfs:
server: 192.168.5.31 # 填写 NFS 服务器 IP
path: /nfs/data/nginx-pv
示例操作(先在 NFS 上创建目录):
mkdir -p /nfs/data/nginx-pv
kubectl apply -f storage/nginx-pv-demo.yaml
kubectl get deploy
kubectl get pods
# 在宿主机写入文件,Pod 中可读取
echo "success" > /nfs/data/nginx-pv/index.html
kubectl exec -it <pod> -- curl localhost
原生挂载的局限性:
- 需要手动在存储端创建目录。
- 删除 Pod/Deployment 后,存储上的数据不会自动清理。
- 无法通过声明限制或管理存储容量(需要外部管理)。
使用 PV 与 PVC(静态 PV 管理示例)
1) 在 NFS 服务端准备多个目录作为 PV 池
mkdir -p /nfs/data/01
mkdir -p /nfs/data/02
mkdir -p /nfs/data/03
2) 静态 PV 定义(示例文件:nfs-pv.yaml)
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv01-10m
spec:
capacity:
storage: 10M
accessModes:
- ReadWriteMany
storageClassName: nfs
nfs:
path: /nfs/data/01
server: 192.168.5.31
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv02-1gi
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
storageClassName: nfs
nfs:
path: /nfs/data/02
server: 192.168.5.31
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv03-3gi
spec:
capacity:
storage: 3Gi
accessModes:
- ReadWriteMany
storageClassName: nfs
nfs:
path: /nfs/data/03
server: 192.168.5.31
应用并查看:
kubectl apply -f storage/nfs-pv.yaml
kubectl get pv
3) 创建 PVC(示例文件:nfs-pvc.yaml)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 200Mi
storageClassName: nfs
kubectl apply -f storage/nfs-pvc.yaml
kubectl get pvc
kubectl get pv
# PVC 会被调度并绑定到满足条件的 PV(例如上面的 pv02-1gi)
4) 在 Deployment 中使用 PVC(示例:nginx-deploy-pvc.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deploy-pvc
name: nginx-deploy-pvc
spec:
replicas: 2
selector:
matchLabels:
app: nginx-deploy-pvc
template:
metadata:
labels:
app: nginx-deploy-pvc
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
persistentVolumeClaim:
claimName: nginx-pvc
部署后验证:
kubectl apply -f storage/nginx-deploy-pvc.yaml
kubectl get pods
kubectl get pv,pvc
# 在 NFS 上写入 /nfs/data/02/index.html,Pod 内访问应能看到相同内容
注意事项与清理流程(静态 PV)
- 静态 PV:管理员预先创建 PV(如上示例)。PVC 绑定后会使用该 PV。
- 删除静态 PV 的推荐顺序(避免残留问题):
- 删除使用该 PV 的 Pod/Deployment/StatefulSet。
- 在宿主(存储)端清理或移除对应目录的内容。
- 删除 PVC。
- 删除 PV。
- 若使用动态供应(StorageClass + provisioner),则可实现自动创建/回收 PV,便于自动化管理。
参考命令(常用)
kubectl get pv
kubectl get pvc
kubectl get pods
kubectl apply -f <file.yaml>
kubectl delete -f <file.yaml>
kubectl exec -it <pod> -- /bin/bash
kubectl explain pod.spec.volumes
图片示意:

结束。