NAS(网络附加存储)通过 Kubernetes 存储插件 可无缝对接 K8s 集群,为容器提供 共享存储服务(支持多 Pod 并发读写),核心是将 NAS 的文件共享能力转化为 K8s 原生的 PersistentVolume(PV) 和 PersistentVolumeClaim(PVC),让容器像使用本地存储一样访问 NAS。

一、核心原理:NAS 与 K8s 的对接逻辑

K8s 本身不直接管理 NAS,需通过 存储插件(CSI 或 FlexVolume) 实现 “NAS 资源抽象”:

  1. 存储插件:作为中间层,负责与 NAS 设备通信(如创建共享目录、挂载权限配置),并将 NAS 共享目录转化为 K8s 可识别的 PV;
  2. PV/PVC:PV 是对 NAS 共享目录的 “K8s 化描述”(如容量、访问模式),PVC 是 Pod 对 PV 的 “申请请求”,二者通过 storageClassName 绑定;
  3. Pod 挂载:Pod 通过 PVC 绑定 PV 后,NAS 共享目录会被挂载到 Pod 的指定路径,容器内可直接读写该路径下的文件(支持多 Pod 同时挂载)。

二、常见 NAS 类型与 K8s 对接方案

不同厂商的 NAS(如开源 OpenMediaVault、商业群晖 / 威联通、云厂商阿里云 NAS/ AWS EFS)对接 K8s 的核心逻辑一致,但插件选择略有差异,以下分 通用协议(NFS/SMB) 和 云厂商 NAS 两类说明。

方案 1:通用 NAS(支持 NFS/SMB 协议,如群晖、OpenMediaVault)

通用 NAS 通常支持 NFS(Linux 首选)或 SMB(Windows/Linux 兼容)协议,K8s 可通过 NFS CSI 插件 或 原生 NFS PV 对接,推荐用 CSI 插件(功能更丰富,支持动态 PV 创建)。

步骤 1:NAS 端配置(以 NFS 为例)
  1. 在 NAS 管理界面(如群晖 DSM)中,创建一个共享目录(如 k8s-nas-share);
  2. 开启 NFS 服务,设置 NFS 共享权限:允许 K8s 所有节点的 IP 访问(如 K8s 节点网段为 192.168.1.0/24),权限设为 “读写”;
  3. 记录 NAS 的 NFS 共享路径(如 192.168.1.200:/volume1/k8s-nas-share192.168.1.200 是 NAS 的 IP)。
步骤 2:K8s 端部署 NFS CSI 插件(动态 PV 方案)

CSI(Container Storage Interface)是 K8s 官方推荐的存储插件标准,支持动态创建 PV(无需手动定义 PV),以下以 nfs-subdir-external-provisioner(开源 NFS CSI 插件)为例:

2.1 安装插件(基于 Helm,推荐)

Helm 是 K8s 包管理工具,可快速部署插件:

# 1. 添加 Helm 仓库
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/

# 2. 安装插件,指定 NAS 的 NFS 共享路径和服务器 IP
helm install nfs-csi nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
  --set nfs.server=192.168.1.200 \  # NAS 的 IP
  --set nfs.path=/volume1/k8s-nas-share \  # NAS 的 NFS 共享路径
  --set storageClass.name=nfs-sc \  # 自定义存储类名称(后续 PVC 会引用)
  --set storageClass.defaultClass=false  # 是否设为默认存储类(按需选择)

2.2 验证插件部署

# 查看 CSI 控制器和节点端 Pod(均需为 Running 状态)
kubectl get pods -l app=nfs-subdir-external-provisioner
# 查看创建的存储类(storageClass)
kubectl get sc | grep nfs-sc
步骤 3:创建 PVC 并挂载到 Pod

通过 PVC 申请 NAS 存储,Pod 引用 PVC 即可使用 NAS 共享目录:

3.1 创建 PVC(申请存储)

创建 nfs-pvc.yaml 文件:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc  # PVC 名称
spec:
  accessModes:
    - ReadWriteMany  # 访问模式:多 Pod 读写(NAS 核心优势)
  resources:
    requests:
      storage: 10Gi  # 申请的存储容量(需 ≤ NAS 共享目录剩余容量)
  storageClassName: nfs-sc  # 关联之前创建的 NFS 存储类

执行创建命令:

kubectl apply -f nfs-pvc.yaml
# 验证 PVC 状态(需为 Bound,表示已绑定 PV)
kubectl get pvc nfs-pvc
3.2 创建 Pod 挂载 PVC

创建 nfs-pod.yaml 文件,将 PVC 挂载到 Pod 的 /data 路径:

apiVersion: v1
kind: Pod
metadata:
  name: nfs-pod
spec:
  containers:
  - name: test-container
    image: nginx:alpine  # 用 Nginx 镜像示例
    volumeMounts:
    - name: nfs-volume  # 卷名称,与下方 volumes 对应
      mountPath: /data  # 容器内挂载路径
  volumes:
  - name: nfs-volume
    persistentVolumeClaim:
      claimName: nfs-pvc  # 引用之前创建的 PVC

执行创建命令并验证:

kubectl apply -f nfs-pod.yaml
# 进入 Pod,验证 NAS 挂载
kubectl exec -it nfs-pod -- /bin/sh
# 在 Pod 内创建文件,查看 NAS 端是否同步
echo "test from k8s pod" > /data/test.txt

此时在 NAS 的 k8s-nas-share 目录下,会看到 test.txt 文件,说明挂载成功。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐