在上一篇文章《K3s 上手 - 集群搭建》 我有提到容器的所有数据存储均使用 NFS:在我的 TrueNAS 有一块 1T SSD 作为容器数据的专用硬盘,并通过 NFS 共享给 K3s。本文分享下 TrueNAS 的配置及 K3s 使用 NFS 的方式。
在 TrueNAS 创建 NFS 服务时,需要注意下权限配置,主要有两个方式:
创建 uid: 1000 和 gid: 1000 的用户,以对应大部分容器默认的 uid:gid
操作路径: Accounts - Groups & Users
为 K3s 的 Pool 设置 1000:1000 对应的用户和组
操作路径: Storage - Pool - 你的DataSet - Edit Permissions - Owner & Group
将 DataSet 添加到 NFS 共享
操作路径: Sharing - Unix Sharing(NFS) - Add - 选择DataSet路径 - Mapall User & Mapall Group 设置为 1000:1000 对应的用户和组
在 Pool 中找到自己指定的 DataSet -> Edit Permissions,添加一个 ACL为:everyone & Allow & Basic & Full Control & Basic & Inherit
的配置。
Permissions 可以是 Full Control 也可以设置为指定的读或写权限,具体看自己这个 DataSet 分享出去的作用。
例如我的音乐文件夹需要映射给 Jellyfin 读/写,则可以添加一个如下配置:
在 Kubernetes 中使用 NFS 有两种方式:
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}"
nfs.server=nas
: 你的 NFS server 的地址,可以用 ansible 给所有 Worker 配置上 hosts,也可以在路由器层面绑定。nfs.path=/mnt/ssd-doc-01/k3s
: 你的 NFS 服务共享的路径nfs.mountOptions={nfsvers=4.1,rsize=1048576,wsize=1048576}
: NFS 挂载参数storageClass.name=nfs-ssd-doc-01
: 自定义的 storageClass,定义 PVC 时使用storageClass.reclaimPolicy=Delete
: 回收废弃卷的方式,默认为 DeletestorageClass.accessModes=ReadWriteMany
: PV 的访问方式storageClass.pathPattern="\${.PVC.namespace}/\${.PVC.name}"
: 在 NFS 使用时创建路径的规则执行完成后,可以通过 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
例如 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