在日常 Kubernetes 部署中,大多数生产环境会使用云存储或网络存储(如 EBS、NAS、Ceph)。但对于本地环境、轻量级集群,最快速、最低成本、性能最高的存储方式其实是:本地存储(Local PV)。
然而 Local PV 的一个缺点是——需要手工创建 PV,并指定 nodeAffinity,非常麻烦。
于是,Rancher 开源的 Local Path Provisioner 成为了本地存储的最佳实践:开箱即用、自动创建 PV、自动处理节点路径,无额外依赖。
为了方便后面阅读:Local Path Provisioner 都简写为 LPP。
本文主要内容:
- 如何部署 LPP
- 如何使用 LPP
- 多节点集群中 Pod 会落到哪个节点
- Pod 重启是否会丢数据?
- 哪些情况下会丢数据?如何避免?
1. LPP 是什么?
Local Path Provisioner(LPP)是一个 Kubernetes 本地存储动态卷插件,用于:
- 动态创建 Local PV
- 自动创建与回收节点上的真实目录
- 无需手动写 PV
- 性能接近裸盘
- 各个节点独立提供存储
LPP 基于节点亲和性(Node Affinity)机制和 Kubernetes 调度器的感知能力,确保使用本地存储的 Pod 始终调度到存储所在的特定节点,从而实现本地磁盘的持久化访问。
2. 部署 LPP
项目地址:https://github.com/rancher/local-path-provisioner
一键安装:
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.32/deploy/local-path-storage.yaml
查看状态:
[root@k8s-master ~]# kubectl get po -n local-path-storage
NAME READY STATUS RESTARTS AGE
local-path-provisioner-7d6dddf9dd-mc7r7 1/1 Running 0 8m40s
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
local-path rancher.io/local-path Delete WaitForFirstConsumer false 8m49s
默认 StorageClass 为 local-path。

默认情况下,所有节点都会使用 /opt/local-path-provisioner 作为存储路径,不过可以修改 ConfigMap 来自定义存储路径。这是 云原生 环境下常见的灵活配置方式。
下面为可选操作:
kubectl -n local-path-storage edit configmap local-path-config
修改不同节点使用不同目录作为存储:
{
"nodePathMap": [
{
"node": "node1",
"paths": ["/data/local1"]
},
{
"node": "node2",
"paths": ["/data/local2"]
}
]
}
修改后重启:
kubectl -n local-path-storage rollout restart deploy/local-path-provisioner
3. 创建 PVC
创建 PVC ,动态请求 2Gi 本地卷:
cat > nginx-local-pvc.yaml <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-local-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 2Gi
EOF
执行部署:
[root@k8s-master ~]# kubectl apply -f nginx-local-pvc.yaml
创建后可查看 PVC:
[root@k8s-master ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
nginx-local-pvc Pending local-path <unset> 48s
4. 测试挂载本地存储
下面以 Nginx 为例,测试一下 LPP。
- 使用 PVC 挂载本地卷
- 用 initContainer 写入 index.html
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-local
spec:
replicas: 1
selector:
matchLabels:
app: nginx-local
template:
metadata:
labels:
app: nginx-local
spec:
initContainers:
- name: init-index
image: busybox
command: ["sh", "-c", "echo 'Hello from Local Path Provisioner!' > /data/index.html"]
volumeMounts:
- name: local-storage
mountPath: /data
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
volumeMounts:
- name: local-storage
mountPath: /usr/share/nginx/html
volumes:
- name: local-storage
persistentVolumeClaim:
claimName: nginx-local-pvc
应用:
kubectl apply -f nginx-deploy.yaml
5. 验证效果
查看 Pod 跑在哪个节点:
kubectl get pod -o wide | grep nginx-local
这会告诉你 Pod 为何落到该节点(原理见文末)。
查看 index.html:
kubectl exec -it nginx-local-66bcc5bffb-j45b5 -- cat /usr/share/nginx/html/index.html
你会看到:
Hello from Local Path Provisioner!
查看节点真实目录。进入 Pod 所在节点:
ls /opt/local-path-provisioner/
即可看到对应的 PVC 目录。以上验证都没问题,就说明已经部署好了。

6. Pod 重启后数据会丢吗?
只要你不删除 PVC,Pod 重启、重建、部署更新,都不会导致数据丢失。
理由:
- PVC 与 PV 始终存在
- 对应的节点本地目录也始终存在
- 重启 Pod 后仍挂载同一目录
简单说:Pod 是短暂的,PVC 是持久的。
7. 哪些情况下会导致数据丢失?
以下是实际生产中最需要警惕的点。
7.1 你删除了 PVC
这也是最常见的真实踩坑。
kubectl delete pvc nginx-local-pvc
默认 StorageClass(local-path)保持策略是 Delete,你以为是 Retain,导致删除 PVC 时数据被自动清理。
删除 PVC = 删除 PV + 删除对应节点目录(数据完全消失)。
这是本地存储最常见的数据丢失原因。
7.2 节点磁盘损坏 / 重装系统
Local PV 仅存储在某个节点的本地路径,没有副本:
- 节点重装
- 节点磁盘故障
- 手工格式化目录
都会导致数据永久丢失。
7.3 管理员误删目录
某些管理员不小心执行:
rm -rf /opt/local-path-provisioner/*
直接导致 PV 空指针,这时数据彻底消失。
8. 如何避免数据丢失?
8.1 把 StorageClass 改为 Retain
这在生产环境是强烈建议的,即使删除了 PVC 数据只是解除绑定,并没有删除本地的数据。
kubectl patch sc local-path -p '{"reclaimPolicy":"Retain"}'
8.2 使用 StatefulSet
这种就适合持久化服务。StatefulSet 的 PVC 是一对一的:
- nginx-0 → nginx-local-pvc-nginx-0
- Pod 重建名字不变
- 卷绝不会漂移
更适合数据库,日志、缓存、业务状态等“长期存在的数据”。理解 持久化卷的管理 对于数据安全至关重要。
8.3 使用 nodeAffinity 固定节点
虽然 Local PV 自带 nodeAffinity,但你也可以手动限制 Pod 只在某节点运行,减少误操作。
8.4 定期备份(非常重要)
可使用 CronJob + rsync 组合或使用 Velero 进行备份,生产环境是很有必要备份的。
9. LPP 调度规则
多节点集群中 Pod 为什么会落到某个节点?这一点很多同学不清楚,我们放到最后解释。
9.1 多节点下 Local PV 的调度机制
当你创建 PVC:
- Local Path Provisioner 会从所有可用节点中随机选择一个节点。
- 在该节点创建本地目录。
- 生成 PV,并自动写入 nodeAffinity。
- 调度器在调度 Pod 时,必须把 Pod 调度到 PV 所属节点。
因此:
是 PV 决定 Pod 落在哪个节点,而不是 Pod 自己决定。
9.2 什么情况下会落到你预期节点?
- 你在 ConfigMap 里对某节点配置了独立路径
- 或你使用 nodeSelector/affinity 对 Pod 设定节点偏好
- 或你为 PVC 调整 StorageClass 让某些节点可用某些路径
Local PV 是轻量环境最优的持久化方案,但也有风险。 理解其调度原理与正确的保留策略,是安全使用本地存储的关键,这也是 Kubernetes运维 的核心技能之一。