K8S 之 存储卷 NFS

摘要

存储卷 NFS 介绍

  • 在 Kubernetes 中,NFS (Network File System) 是一种通过网络将远程存储挂载到 Pod 的方式。它允许多个 Pod 跨节点共享相同的存储目录,常用于 ReadWriteMany(RWX) 场景。

  • 我们需要准备一个NFS 服务器,并配置 NFS 存储卷。具体可以参考 Linux 安装 NFS

  • k8s中每个worker节点都需要安装 NFS 客户端,但是不需要挂载 NFS 存储卷,这个会在pod中进行。

示例

  • 一个使用 NFS 存储卷的 pod 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# nfs-direct-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nfs-direct-pod
spec:
containers:
- name: busybox
image: busybox
command: ["sh", "-c", "sleep 3600"]
volumeMounts:
- name: nfs-volume
mountPath: /data # 容器内挂载点
volumes:
- name: nfs-volume
nfs:
server: 10.211.55.88 # NFS 服务端地址
path: /nfs-server/data # NFS 服务端共享目录
readOnly: false # 是否只读挂载,false 表示可读写
  • 创建 Pod

1
kubectl apply -f nfs-direct-pod.yaml
  • 查看 Pod 挂载点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 查看pod部署到哪个节点
$ kubectl get pod nfs-direct-pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nfs-direct-pod 1/1 Running 0 12m 10.244.194.115 k8s-worker1 <none> <none>

# 登录 k8s-worker1 节点,查看 nfs 挂载点,也就是说 创建 pod时会自动在宿主机上挂载 nfs
$ df -t nfs4
Filesystem 1K-blocks Used Available Use% Mounted on
10.211.55.88:/nfs-server/data 42872832 3630080 39242752 9% /var/lib/kubelet/pods/e44786a9-fbd9-4ee8-bb28-84eb074fb7d9/volumes/kubernetes.io~nfs/nfs-volume

# 查看pod挂载的目录
$ k exec -it nfs-direct-pod -- df -t nfs4
Filesystem 1K-blocks Used Available Use% Mounted on
10.211.55.88:/nfs-server/data
42872832 3630080 39242752 8% /data

# 向nfs挂载目录中写入数据
k exec -it nfs-direct-pod -- sh -c 'echo "hello world" > /data/test.txt'
  • 删除pod

1
2
3
4
5
k delete pod nfs-direct-pod

# 再次登录 宿主机节点,发现 nfs 挂载点也被卸载了,但是 nfs-server 中的文件仍然存在
$ df -t nfs4
df: no file systems processed

存储卷类型 emptyDir、hostPath、NFS 的对比表

特性 emptyDir hostPath nfs
数据生命周期 Pod 生命周期内有效,Pod 删除数据丢失 绑定节点上的目录,Pod 删了数据仍保留 存储在远程 NFS Server,Pod 删除数据不丢失
共享范围 同一个 Pod 的多个容器可共享 同一节点上多个 Pod 可共享 集群内多个 Pod 跨节点可共享
持久化能力 ❌ 不持久化,随 Pod 生命周期结束消失 ✅ 持久化,只要宿主机目录存在数据就在 ✅ 持久化,NFS 存储独立于 Pod 存在
跨节点共享 ❌ 不能 ❌ 不能 ✅ 支持跨节点共享
适用场景 临时缓存、进程间共享数据 宿主机特定目录挂载,日志存储、宿主机插件对接 多副本服务共享存储、持久化数据、共享配置文件
数据安全性 随 Pod 删除,数据易丢失 容器有权限可修改宿主机文件,存在风险 依赖 NFS Server 稳定性,配置不当可能被所有节点读写
典型用例 Redis 缓存目录、Sidecar 容器共享日志 挂载宿主机 docker.sock、宿主机日志目录 跨 Pod 文件共享、Web 静态资源、Tensorflow 多副本训练共享数据

为什么已经有 NFS,还推荐用 PV/PVC?

  • ✅ 简短回答:PV/PVC 是对底层存储(如 NFS)的抽象和标准化管理。

原因 说明
Kubernetes 标准资源 用 PVC 声明存储需求,由 K8s 统一调度和管理。
存储与 Pod 解耦 Pod 专注于应用逻辑,PVC 专注于声明“我要一个 10Gi 的 RWX 存储”,背后是 NFS、Ceph 还是别的,开发者无需关心。
动态供应 搭配 StorageClass 可以实现 自动创建 PV,不需要手动维护 PV。
生命周期管理 PVC 被删除时可触发 PV 回收、保留或删除策略(RetainRecycleDelete)。直接挂载 NFS 没有这些机制。
权限隔离 PV/PVC 可以通过 accessModes 控制访问级别,比如只允许特定 Pod 访问。直接挂载 NFS 容易权限混乱。
更好兼容性 某些工作负载(如 StatefulSet)只能用 PVC,不支持直接 nfs 卷。
更灵活的切换存储方案 后期如果换成 Ceph、EBS、GlusterFS,只需改 PV/PVC,不需要改 Pod 配置。