在 K8S 中配置 NFS 服务

NFS(Network File System)是一种分布式文件系统协议,允许在网络上共享文件和目录。
在K8S中可以用于:

  1. 共享存储卷: NFS 可以用作共享存储卷的后端,允许多个 Pod 共享相同的存储。这在需要多个 Pod 之间共享数据或状态时非常有用,例如,一些应用可能需要多个副本协同工作并共享相同的数据。

  2. 持久化存储: NFS 可以用作 Kubernetes 集群中的持久化存储解决方案,确保 Pod 中的数据在 Pod 重启或迁移时得以保留。这对于需要数据持久性的应用程序(如数据库)是至关重要的。


1. NFS 服务端配置

1.1 安装 NFS 服务端

{.line-numbers}
1
sudo apt install rpcbind nfs-kernel-server -y

1.2 创建共享目录

{.line-numbers}
1
2
3
mkdir /srv/nfs
chmod -R 777 /srv/nfs
#chown -R nobody:nogroup /srv/nfs

1.3 配置 NFS 共享

1.3.1 编辑NFS服务主配置文件

{.line-numbers}
1
vim /etc/exports

末行加入

{.line-numbers}
1
2
/srv/nfs *(rw,sync,no_subtree_check,no_root_squash) #自行选择参数
#如需限制ip访问 /srv/nfs 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
参数名称参数用途
rw 读写权限
ro 只读权限
sync 请求或写入数据时,数据同步写入到NFS Server的硬盘后才返回。优点:数据安全不会丢;缺点:性能比不启动该参数要差
async 写入时数据会先写入到内存缓冲区,直到硬盘有空档才会再写入磁盘,这样可以提升写入效率!风险为若服务器宕机或不正常关机,不会缓冲未写入磁盘的数据(解决办法:服务器主板电池或UPS不间断电源)
no_root_squash 访问NFS Server共享目录的用户如果是root的话,它对该共享目录具有root权限。这个配置原本是为无盘客户端准备的。用户应避免使用。
root_squash 如果访问NFS Server共享目录的用户时root,则它的权限将被压缩成匿名用户,同时它的UID和GID通常会变成nfsnobody账号身份。
all_squash 不管访问NFS Server共享目录的用户身份如何,它的权限都将被压缩成匿名用户,同时它的UID和GID都会变成nfsnobody帐号身份。在早期多个NFS 客户端同时读写NFS Server数据时,这个参数很有用。 在生产中配置NFS 的重要技巧: l)确保所有客户端服务器对NFS共享目录具备相同的用户访问权限 a.all_squash 把所有客户端都压缩成固定的匿名用户(UID相同) b.就是anonuid,anongid 指定的UID和GID的用户。 2)所有的客户端和服务端都需要有一个相同的UID和GID的用户,即nfsnobody(UID必须相同)。
anonuid 参数以anon*开头即指anonymous匿名用户,这个用户的UID设置值通常为nfsnobody的UID值,当然也可以自行设置这个UID值。但是,UID必须存在于/etc/passwd 中。在多NFS Clients时,如多台Web Server共享一个NFS目录,通过这个参数可以使得不同的NFS Clients写入的数据对所有NFS Clients保持同样的用户权限,即为配置的匿名UID对应用户权限,这个参数很有用,一般默认即可。
anongid 同anonuid,区别就是把uid(用户id)换成gid(组id)。

1.3.2 重启服务sudo systemctl restart nfs-kernel-server

1.3.3 验证共享exportfs -vshowmount -e localhost


2. NFS客户端挂载

2.1 安装 NFS 客户端

{.line-numbers}
1
sudo apt install nfs-common

2.2 创建本地挂载目录

{.line-numbers}
1
sudo mkdir -p /mnt/nfs

2.3 将 NFS 服务器上的/data目录,挂载到本地的/mnt/目录下

{.line-numbers}
1
sudo mount -t nfs <NFS-SERVER-IP>:/srv/nfs /mnt/nfs

3. K8S挂载

想要 Kubernetes 支持 NFS 存储,可以选择安装 nfs-subdir-external-provisioner ,它是一个存储资源自动调配器,它可将现有的 NFS 服务器通过持久卷声明来支持 Kubernetes 持久卷的动态分配。该组件是对 Kubernetes NFS-Client Provisioner 的扩展, nfs-client-provisioner 已经不提供更新,已经迁移到 nfs-subdir-external-provisioner仓库。

3.1 helm 方式安装

{.line-numbers}
1
2
3
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner
kubectl create ns nfs-system
helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner -n nfs-system --set storageClass.name=nfs-sc --set nfs.server=<NFS-SERVER-IP> --set nfs.path=/srv/nfs --set storageClass.defaultClass=true

参数:

  • nfs.server NFS 服务器的 IP 地址
  • nfs.path NFS 服务器上的共享目录
  • storageClass.name 存储类的名称
  • storageClass.defaultClass 是否设置为默认存储类
  • image.repository: 自定义 nfs-subdir-external-provisioner 镜像拉取地址

3.2 验证

  • 检查storageClass kubectl get sc nfs-sc -o wide

3.2.1 创建PVC资源申请测试

  • 编写yaml
    {.line-numbers}
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
    name: test-nfs-pvc
    spec:
    storageClassName: nfs-sc
    accessModes:
    - ReadWriteMany
    resources:
    requests:
    storage: 1Gi
  • 创建PVC kubectl apply -f test-nfs-pvc.yaml
  • 查看PVC kubectl get pvc -n nfs-system -o wide

3.2.2 创建测试Pod

  • 编写yaml
    {.line-numbers}
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    kind: Pod
    apiVersion: v1
    metadata:
    name: test-nfs-pod
    spec:
    containers:
    - name: test-nfs-pod
    image: busybox:latest
    command:
    - "/bin/sh"
    args:
    - "-c"
    - "touch /mnt/SUCCESS && sleep 3600"
    volumeMounts:
    - name: nfs-pvc
    mountPath: "/mnt"
    restartPolicy: "Never"
    volumes:
    - name: nfs-pvc
    persistentVolumeClaim:
    claimName: test-nfs-pvc
  • 创建Pod kubectl apply -f test-nfs-pod.yaml -n nfs-system
  • 查看Pod kubectl get pods -n nfs-system -o wide

3.2.3 清理测试资源

{.line-numbers}
1
2
kubectl delete -f test-nfs-pod.yaml -n nfs-system
kubectl delete -f test-nfs-pvc.yaml -n nfs-system

参考文章

  1. ubuntu22.04安装NFS及配置
  2. K8S集群中部署NFS之一:配置NFS服务
  3. 30分钟玩转Kubernetes持久化存储之 NFS 实战入门

在 K8S 中配置 NFS 服务
https://heeteve-blog.pages.dev/2024/03/在K8S中配置NFS服务/
作者
Heeteve
发布于
2024年3月10日
许可协议