NFS 存储
学习目标
- 理解 NFS 在 Kubernetes 中的使用方式
- 掌握 NFS Volume 和 NFS Provisioner 的配置
- 了解 NFS 存储的优缺点和适用场景
核心概念
NFS 是什么
NFS (Network File System):
┌─────────────────────────────────────────┐
│ NFS Server │
│ /exports/k8s-data │
└─────────────────┬───────────────────────┘
│ 网络共享
┌─────────┼─────────┐
▼ ▼ ▼
┌──────┐ ┌──────┐ ┌──────┐
│Node A│ │Node B│ │Node C│
│ Pod1 │ │ Pod2 │ │ Pod3 │
└──────┘ └──────┘ └──────┘
特点:
- 所有节点/Pod 可同时读写同一目录
- 数据集中在 NFS 服务器
- 适合多 Pod 共享数据
方式一:直接使用 NFS Volume
apiVersion: v1
kind: Pod
metadata:
name: nfs-pod
spec:
containers:
- name: app
image: nginx
volumeMounts:
- mountPath: /data
name: nfs-volume
volumes:
- name: nfs-volume
nfs:
server: 192.168.1.100 # NFS 服务器地址
path: /exports/data # NFS 共享路径
readOnly: false
优点:简单直接
缺点:
- 不支持动态供给
- 需要预先知道 NFS 服务器信息
- 无法通过 PVC 申请
方式二:NFS + PV/PVC(静态)
# PV
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany # NFS 支持多节点读写
nfs:
server: 192.168.1.100
path: /exports/data
persistentVolumeReclaimPolicy: Retain
---
# PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
方式三:NFS Subdir External Provisioner(动态供给)
动态供给架构:
┌─────────────────────────────────────────┐
│ NFS Subdir External Provisioner │
│ (Deployment) │
└─────────────────┬───────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ NFS Server │
│ /exports/k8s-data │
│ ├── pvc-uuid-1/ │
│ ├── pvc-uuid-2/ │
│ └── pvc-uuid-3/ │
└─────────────────────────────────────────┘
每创建一个 PVC,自动在 NFS 上创建子目录
安装 Provisioner
# 使用 Helm 安装
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner
helm install nfs-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
--set nfs.server=192.168.1.100 \
--set nfs.path=/exports/k8s-data \
--set storageClass.name=nfs-client
StorageClass 定义
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
pathPattern: "${.PVC.namespace}-${.PVC.name}" # 目录命名模式
onDelete: delete # PVC 删除时行为
reclaimPolicy: Delete
volumeBindingMode: Immediate
使用动态 NFS
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-dynamic-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-client
resources:
requests:
storage: 5Gi
NFS 上自动创建:/exports/k8s-data/default-nfs-dynamic-pvc/
NFS 访问模式
| 模式 | NFS 支持 | 说明 |
|---|---|---|
| ReadWriteOnce | 是 | 单节点读写 |
| ReadOnlyMany | 是 | 多节点只读 |
| ReadWriteMany | 是 | 多节点读写 |
NFS 的优势:
- 完整支持所有访问模式
- 特别适合 ReadWriteMany 场景
- 多个 Pod 可同时读写同一目录
NFS 子目录命名
# 常用 pathPattern 模式
parameters:
# 默认:pvc-{uuid}
pathPattern: ""
# 按命名空间和 PVC 名
pathPattern: "${.PVC.namespace}-${.PVC.name}"
# 按命名空间分目录
pathPattern: "${.PVC.namespace}/${.PVC.name}"
# 自定义前缀
pathPattern: "k8s-volumes/${.PVC.namespace}-${.PVC.name}"
实践练习
练习 1:搭建测试 NFS
# 在 NFS 服务器上(或使用容器模拟)
# 创建共享目录
sudo mkdir -p /exports/k8s-data
sudo chmod 777 /exports/k8s-data
# 配置 /etc/exports
echo "/exports/k8s-data *(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports
sudo exportfs -ra
练习 2:使用 NFS Volume
# nfs-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nfs-test
spec:
containers:
- name: writer
image: busybox
command: ["sh", "-c", "echo 'Hello NFS' > /data/test.txt && sleep 3600"]
volumeMounts:
- mountPath: /data
name: nfs-vol
volumes:
- name: nfs-vol
nfs:
server: 192.168.1.100 # 替换为实际地址
path: /exports/k8s-data
kubectl apply -f nfs-pod.yaml
kubectl exec nfs-test -- cat /data/test.txt
练习 3:验证多 Pod 共享
# 创建两个 Pod 共享同一 NFS
apiVersion: v1
kind: Pod
metadata:
name: nfs-reader
spec:
containers:
- name: reader
image: busybox
command: ["sh", "-c", "cat /data/test.txt && sleep 3600"]
volumeMounts:
- mountPath: /data
name: nfs-vol
volumes:
- name: nfs-vol
nfs:
server: 192.168.1.100
path: /exports/k8s-data
kubectl apply -f nfs-reader.yaml
kubectl exec nfs-reader -- cat /data/test.txt
常见误解
1. NFS 性能不是最优的
NFS 是网络存储,性能不如本地磁盘
高 IOPS 场景(数据库)应使用块存储
NFS 适合文件共享、日志、配置等场景
2. NFS 不是高可用的
NFS 服务器是单点
生产环境需要:
- NFS 高可用方案(如 GlusterFS、Ceph)
- 或使用云厂商的托管文件存储(EFS、Azure Files)
小结
| 要点 | 说明 |
|---|---|
| NFS | 网络文件系统,支持多节点共享 |
| 访问模式 | 完整支持 RWO/ROX/RWX |
| 静态使用 | 直接指定 NFS 服务器和路径 |
| 动态供给 | 使用 nfs-subdir-external-provisioner |
| 适用场景 | 文件共享、日志、配置 |
| 注意事项 | 性能有限、单点风险 |
练习编辑器
bash
Loading...