将 SMB 或 NFT Azure 文件共享挂载到 kubernetes 上的 JupyterHub 上以获取共享目录

Mounting an SMB or NFT Azure File share onto JupyterHub on kubernetes for a shared directory

集群信息:

Kubernetes 版本:1.19.11

正在使用的云:Azure

安装方式:在线Azure中手动创建UI/Azure CLI

主持人OS:Linux

CNI 和版本:Azure 容器网络接口,最新

大家好!我是 Kubernetes 的新用户,但我认为我已经掌握了基础知识。我主要是想了解一个更复杂的文件共享功能。

我基本上是在尝试在 Kubernetes 上使用 JupyterHub 为大约十几个用户的团队提供共享开发环境(我们稍后可能会将其扩展到 larger/other 个团队,但现在我想得到这个只为我们的团队工作),还有一个非常有用且看起来可行的功能是为笔记本、文件和数据提供一个共享目录。我想我已经非常接近完成此设置了,但是我 运行 遇到了一个我无法完全解决的安装问题。我将首先快速解释我的设置,然后再解释问题。我真的很感激任何人拥有的 help/comments/hints!

设置

目前,所有这些设置都在 Azure 或其他 Azure 托管服务中的 Kubernetes 集群上。我们有一个资源组,其中包含 kubernetes 集群、应用服务域、DNS 区域、虚拟网络、容器注册表(用于我们的自定义 docker 图像)和存储帐户。一切正常,除了在存储帐户中,我有一个 Azure NFS(如果需要的话还有普通的 SMB)文件共享,我尝试通过 PV 和 PVC 将其安装到 JupyterHub 服务器,但无济于事。

为了创建 PV,我在 Azure 中设置了一个 NFS 文件共享并创建了适当的 kubernetes 秘密,如下所示:

 # Get storage account key
STORAGE_KEY=$(az storage account keys list --resource-group $resourceGroupName --account-name $storageAccountName --query "[0].value" -o tsv)

kubectl create secret generic azure-secret \ 
    --from-literal=azurestorageaccountname=$storageAccountName \ 
    --from-literal=azurestorageaccountkey=$STORAGE_KEY

然后我尝试使用此 YAML 文件创建 PV:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: shared-nfs-pv
spec:
  capacity:
    storage: 100Gi
  accessModes:
    - ReadWriteMany
  azureFile:
    secretName: azure-secret
    shareName: aksshare
    readOnly: false
  nfs:
    server: wintermutessd.file.core.windows.net:/wintermutessd/wintermutessdshare
    path: /home/shared
    readOnly: false
  storageClassName: premium-nfs
  mountOptions: 
  - dir_mode=0777
  - file_mode=0777
  - uid=1000
  - gid=1000
  - mfsymlinks
  - nobrl

问题

在创建 PV 的过程中,出现错误 Failed to create the persistentvolume 'shared-nfs-pv'. Error: Invalid (422) : PersistentVolume "shared-nfs-pv" is invalid: spec.azureFile: Forbidden: may not specify more than 1 volume type。删除 azureFile 选项可以解决此错误,但我觉得有必要指定我创建的 kubernetes secret。如果我删除 azureFile 选项,它会成功创建和绑定 PV。然后我用

创建了相应的PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: shared-nfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  # Match name of PV
  volumeName: shared-nfs-pv
  storageClassName: premium-nfs
  resources:
    requests:
      storage: 50Gi

这也绑定成功了。但是,当我使用

将配置添加到 JupyterHub 的 Helm 配置中时
singleuser:
  storage:
    extraVolumes:
      - name: azure
        persistentVolumeClaim:
          claimName: azurefile
    extraVolumeMounts:
      - name: azure
        mountPath: /home/shared

当 jupyterhub 服务器尝试生成和挂载 PVC 时出现以下错误:

以防万一,NFS azure 文件共享只能通过专用端点访问,但这应该没问题,因为我的 kubernetes 集群 运行 在同一个虚拟网络中。事实上,Azure 告诉我,我可以使用

在 linux 上挂载这个 NFS 共享
sudo apt-get -y update
sudo apt-get install nfs-common
sudo mkdir -p /mount/wintermutessd/wintermutessdshare
sudo mount -t nfs wintermutessd.file.core.windows.net:/wintermutessd/wintermutessdshare /mount/wintermutessd/wintermutessdshare -o vers=4,minorversion=1,sec=sys

但是,当我将它添加到我的容器中使用的 docker 图像的 Dockerfile 时,构建失败并告诉我未安装 systemctl。尝试通过 apt-get install systemd 添加此内容也无法解决问题。

通过查看其他 K8s 讨论帖子,我发现了这个(File based data exchange between pods and daemon-set - General Discussions - Discuss Kubernetes) which looked helpful and has a useful link 部署 NSF 服务器,但我认为我的 NFS 服务器是一个 Azure 文件共享这一事实使这个场景略有不同。

如果有人有任何想法或建议,我将不胜感激!

P.S。我之前曾在此处发布过 JupyterHub 讨论(Mounting an SMB or NFT Azure File share onto JupyterHub on kubernetes for a shared directory - JupyterHub - Jupyter Community Forum), but it was suggested that my issue is more of a k8s issue rather than a JupyterHub one. I also looked at ,但是,即使我对 SMB 文件共享持开放态度,它也必须与 VM 一起做更多事情,而不是与 kubernetes 上的 PV/PVCs 一起做。

谢谢! :)

所以我实际上设法使用动态分配的 Azure 文件共享解决了这个问题。我正在为此编写内部文档,但我认为我会 post 此处的相关部分。我希望这对人们有所帮助!

通过定义 PVC 和存储动态创建 Azure 文件共享和存储帐户 class

在这里,我们主要遵循 dynamically creating a PV with Azure Files in AKS. The general idea is to create a storage class that will define what kind of Azure file share we want to create (premium vs. standard and the different redundancy modes) and then create a PVC (persistent volume claim) that adheres to that storage class. Consequently, when JupyterHub tries to mount the PVC we created, it will automatically create a PV (persistent volume) for the PVC to bind to, which will then automatically create a storage account and file share for the PV to actually store filese in. This will all be done in the resource group that backs the one we're already using (these generally start with "MC_"). Here, we will be using the premium storage class with zone reduntant storage. First, create the storage class to be used (more info on the available tags here can be found in this repository) 的文档和以下 YAML

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: shared-premium-azurefile
provisioner: kubernetes.io/azure-file
mountOptions:
  - dir_mode=0777
  - file_mode=0777
  - uid=0
  - gid=0
  - mfsymlinks
  - cache=strict
  - actimeo=30
parameters:
  skuName: Premium_ZRS

将此文件命名为 azure-file-sc.yaml 和 运行

kubectl apply -f azure-file-sc.yaml

接下来,我们将创建一个 PVC,它将从我们的 Azure 文件共享中动态配置(它会自动为我们创建一个 PV)。使用以下代码

创建文件azure-file-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: shared-premium-azurefile-pvc
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: shared-premium-azurefile
  resources:
    requests:
      storage: 100Gi

并应用

kubectl apply -f azure-file-pvc.yaml

这将创建文件共享和相应的 PV。我们可以检查我们的 PVC 和存储 class 是否已成功创建

kubectl get storageclass
kubectl get pvc

PVC 可能需要几分钟才能绑定。

在 Azure 端,这就是所有必须要做的,PV 和文件共享的动态分配已为我们处理。

正在将 PVC 挂载到主目录中的 JupyterHub

默认情况下,JupyterHub 为每个新用户创建一个 10Gi 的 PVC,但我们也可以告诉它把现有的 PVC 挂载为外部卷(把这想象成只是将您的计算机插入共享 USB 驱动器)。要将我们之前创建的 PVC 安装到我们所有 JupyterHub 用户的主文件夹中,我们只需将以下内容添加到我们的 config.py Helm 配置中:

singleuser:
  storage:
    extraVolumes:
      - name: azure
        persistentVolumeClaim:
          claimName: shared-premium-azurefile-pvc
    extraVolumeMounts:
      - name: azure
        mountPath: /home/jovyan/shared

现在,当 JupyterHub 启动时,所有用户的主文件夹中都应该有一个具有读写权限的共享目录。