K3s 上手 - NFS 存储配置

2021-08-27 [基础设施] #K3s #K8s #Kubernetes #Homelab #NFS
更新日志
2022-01-30 添加 TrueNAS 配置截图; 完善 NFS 使用示例
2022-03-05 更正 TrueNAS 中 NFS 权限配置说明

在上一篇文章《K3s 上手 - 集群搭建》 我有提到容器的所有数据存储均使用 NFS:在我的 TrueNAS 有一块 1T SSD 作为容器数据的专用硬盘,并通过 NFS 共享给 K3s。本文分享下 TrueNAS 的配置及 K3s 使用 NFS 的方式。

创建 NFS 服务

在 TrueNAS 创建 NFS 服务时,需要注意下权限配置,主要有两个方式:

  1. 添加一个专属用户
  2. 使用 ACL 设置 Everyone Read/Write

方式一:专属用户方式

  1. 创建 uid: 1000 和 gid: 1000 的用户,以对应大部分容器默认的 uid:gid

    操作路径: Accounts - Groups & Users

  2. 为 K3s 的 Pool 设置 1000:1000 对应的用户和组

    操作路径: Storage - Pool - 你的DataSet - Edit Permissions - Owner & Group

    stroage_k3s_permissions

  3. 将 DataSet 添加到 NFS 共享

    操作路径: Sharing - Unix Sharing(NFS) - Add - 选择DataSet路径 - Mapall User & Mapall Group 设置为 1000:1000 对应的用户和组

    sharing_nfs_k3s

方式二:ACL 配置

在 Pool 中找到自己指定的 DataSet -> Edit Permissions,添加一个 ACL为:everyone & Allow & Basic & Full Control & Basic & Inherit 的配置。 Permissions 可以是 Full Control 也可以设置为指定的读或写权限,具体看自己这个 DataSet 分享出去的作用。

例如我的音乐文件夹需要映射给 Jellyfin 读/写,则可以添加一个如下配置:

nfs_dataset_acl

K3s 配置 NFS

在 Kubernetes 中使用 NFS 有两种方式:

  1. 使用 nfs-subdir-external-provisioner
  2. 使用 ansible 为每个 Worker mount nfs 作为本地目录,然后 k3s 使用 local-path。

Pod 应该避免依赖宿主,能在 Kubernetes 配置的,应该都在 Kubernetes 中进行,所以建议采用第一种方案。

使用 helm 添加 nfs-subdir-external-provisioner 来为集群提供 NFS 存储支持。

helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
helm repo update

helm install nfs-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
    --set nfs.server=nas \
    --set nfs.path=/mnt/ssd-doc-01/k3s \
    --set "nfs.mountOptions={nfsvers=4.1,rsize=1048576,wsize=1048576}" \
    --set storageClass.name=nfs-ssd-doc-01 \
    --set storageClass.reclaimPolicy=Delete \
    --set storageClass.accessModes=ReadWriteMany \
    --set storageClass.pathPattern="\${.PVC.namespace}/\${.PVC.name}"

执行完成后,可以通过 kubectl get storageclasses.storage.k8s.io 查看目前支持的 PROVISIONER

~ > kubectl get storageclasses.storage.k8s.io
NAME                   PROVISIONER                                                     RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
local-path (default)   rancher.io/local-path                                           Delete          WaitForFirstConsumer   false                  46d
nfs-ssd-doc-01         cluster.local/nfs-provisioner-nfs-subdir-external-provisioner   Delete          Immediate              true                   3d19h

使用 NFS

例如 Gitea 服务,需要使用 NFS 做存储,可以如下定义:

# gitea-pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: gitea-pvc
  namespace: selfhosts
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: nfs-ssd-doc-01 # 上一步定义的 storageClass
  resources:
    requests:
      storage: 80Gi

---

# pod-gitea.yaml
...
    spec:
      containers:
      - name: gitea
        image: gitea/gitea:latest
        ...
        volumeMounts:
        - name: nfs
          mountPath: /data
      volumes:
      - name: nfs
        persistentVolumeClaim:
          claimName: gitea-pvc
# 查看pvc
$ → kubectl get pvc -n selfhosts
NAME            STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS     AGE
gitea-pvc       Bound    pvc-ad30480c-45db-49bf-b3fa-4e730a5bf189   80Gi       RWX            nfs-ssd-doc-01   46h
文章作者:eightpigs
创作时间:2021-08-27
更新时间:2022-01-30
许可协议:CC by-nc-nd 4.0