Kubernetes持久化存储#
在 Kubernetes 中:Pod 是“短暂的”
表现:
- Pod 重建 → IP 变
- Pod 删除 → 数据丢失
使用持久化存储(Persistent Storage)——>Pod 重建后,数据仍然存在
存储发展路径#
阶段1:直接挂载(最原始)#
问题:
阶段2:PV / PVC(标准方案)#
1
| Pod → PVC → PV → 存储(NFS/云盘)
|
✔ 解耦 ✔ 标准 ✔ 可维护
阶段3:StorageClass(企业级)#
1
| Pod → PVC → StorageClass → 自动创建 PV
|
✔ 自动化 ✔ 动态供给
NFS 持久化存储#
Step 1:搭建 NFS 服务端#
使用命令安装nfs
1
| yum install -y nfs-utils
|
首先创建存放数据的目录
配置共享目录
1
2
3
4
| # 打开文件
vim /etc/exports
# 添加如下内容
/data/nfs *(rw,sync,no_root_squash,no_subtree_check)
|
启动服务
1
2
| systemctl start nfs-server
systemctl enable nfs-server
|
生效配置
Step 2:Node 节点准备#
在所有 Node 上执行:
1
| yum install -y nfs-utils
|
Step 3:直接挂载 NFS#
nfs-pod.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| apiVersion: v1
kind: Pod
metadata:
name: nfs-test
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- mountPath: /usr/share/nginx/html
name: web-data
volumes:
- name: web-data
nfs:
server: 192.168.44.134
path: /data/nfs
|
启动nfs服务端
下面我们回到nfs服务端,启动我们的nfs服务
1
2
3
4
| # 启动服务
systemctl start nfs
# 或者使用以下命令进行启动
service nfs-server start
|

通过这个方式,就挂载到了刚刚我们的nfs数据节点下的 /data/nfs 目录
最后就变成了: /usr/share/nginx/html -> 192.168.44.134/data/nfs 内容是对应的
我们通过这个 yaml文件,创建一个pod
1
| kubectl apply -f nfs-nginx.yaml
|
创建完成后,我们也可以查看日志
1
| kubectl describe pod nginx-dep1
|

可以看到,我们的pod已经成功创建出来了,同时下图也是出于Running状态

下面我们就可以进行测试了,比如现在nfs服务节点上添加数据,然后在看数据是否存在 pod中
1
2
3
4
5
| # 进入pod中查看
kubectl exec -it nginx-dep1 bash
# NFS 数据已经挂载
#但这种方式:不推荐(强耦合)
|

PV和PVC#
在 Kubernetes 中,如果将存储(如 NFS 的 IP 和路径)直接写在 Pod 配置中,会导致应用与底层存储强耦合,不利于维护和迁移。为了解决这个问题,Kubernetes 引入了 PV(PersistentVolume)和 PVC(PersistentVolumeClaim)机制,实现存储资源的抽象与解耦。
PV(PersistentVolume)
PV 是对底层存储资源(如 NFS、云盘等)的抽象,由集群管理员创建和维护,属于存储资源的提供者。
PVC(PersistentVolumeClaim)
PVC 是用户对存储资源的请求,描述了所需的容量、访问模式等信息。Pod 通过 PVC 使用存储,而不需要关心底层实现细节。
Step 4:创建 PV#
pv.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
| apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
path: /data/nfs
server: 192.168.44.134
persistentVolumeReclaimPolicy: Retain
|
1
2
| # 创建
kubectl apply -f pv.yaml
|
Step 5:创建 PVC#
pvc.yaml
1
2
3
4
5
6
7
8
9
10
| apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
|
1
2
3
4
5
| # 创建
kubectl apply -f pvc.yaml
# 查看绑定
kubectl get pv,pvc
|
Step 6:Pod 使用 PVC#
deployment.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-pvc
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- mountPath: /usr/share/nginx/html
name: web-data
volumes:
- name: web-data
persistentVolumeClaim:
claimName: nfs-pvc
|
1
2
3
4
5
| # 创建
kubectl apply -f deployment.yaml
# 测试
kubectl exec -it <pod-name> bash
|
访问模式#
| 模式 | 说明 |
|---|
| RWO | 单节点读写 |
| ROX | 多节点只读 |
| RWX | 多节点读写(NFS) |
回收策略#
| 策略 | 说明 |
|---|
| Retain | 保留数据 |
| Delete | 自动删除 |
| Recycle | 清空(已废弃) |
绑定方式#
自动匹配(容量 + 访问模式)
StorageClass#
StorageClass = “自动创建 PV 的模板”
不用每次都手动创建 PV,StorageClass(动态供给)
Pod → PVC → StorageClass → 自动创建 PV
关键组件:Provisioner
常见:
1
2
3
| kubernetes.io/no-provisioner(本地)
nfs-client(NFS)
ceph / aws-ebs / aliyun-disk(云盘)
|
StorageClass YAML#
示例(NFS)
1
2
3
4
5
6
7
| apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storage
provisioner: example.com/nfs
reclaimPolicy: Retain
volumeBindingMode: Immediate
|
provisioner:谁来创建存储
reclaimPolicy:Retain(保留数据) Delete(自动删除)
volumeBindingMode:Immediate(立即绑定) WaitForFirstConsumer(等 Pod 调度)
PVC 使用 StorageClass#
PVC 示例
1
2
3
4
5
6
7
8
9
10
11
| apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-demo
spec:
accessModes:
- ReadWriteOnce
storageClassName: nfs-storage
resources:
requests:
storage: 1Gi
|