首页 > 解决方案 > 将 SMB 或 NFT Azure 文件共享装载到 kubernetes 上的 JupyterHub 以获取共享目录

问题描述

集群信息:

Kubernetes 版本:1.19.11

正在使用的云:Azure

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

主机操作系统:Linux

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

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

我实际上是在尝试在 Kubernetes 上使用 JupyterHub 为大约十几个用户的团队提供一个共享开发环境(我们以后可能会将其扩展到更大/其他团队,但现在我想让它只为我们的团队工作),一个非常有用且看起来可行的功能是拥有一个用于笔记本、文件和数据的共享目录。我想我已经接近完成这个设置了,但是我遇到了一个我无法完全解决的问题。我将先快速解释我的设置,然后再解释问题。我真的很感谢任何人的任何帮助/评论/提示!

设置

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

为了创建 PV,我在 Azure 中设置了一个 NFS 文件共享并创建了相应的 kubernetes secret,如下所示:

 # 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 密码。如果我确实删除了这些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 时,我收到以下错误:

来自 jupyterhub 的错误消息

以防万一,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 讨论帖子,我发现了这个(基于文件的 pod 和 daemon-set - General Discussions - Discuss Kubernetes 之间的数据交换)看起来很有帮助,并且有一个有用的链接到部署 NSF 服务器,但我认为事实是我的 NFS 服务器是一个 Azure 文件共享,这使情况略有不同。

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

PS我之前曾在此处发布过 JupyterHub 讨论(将 SMB 或 NFT Azure 文件共享安装到 kubernetes 上的 JupyterHub 以获取共享目录 - JupyterHub - Jupyter 社区论坛),但有人建议我的问题更多是 k8s 问题而不是一个 JupyterHub 的。我还查看了另一个 stackoverflow 帖子,但是,即使我对 SMB 文件共享开放,它也必须对 VM 做更多的事情,而不是在 kubernetes 上使用 PV/PVC。

谢谢!:)

标签: azuredockerkuberneteskubernetes-helmjupyterhub

解决方案


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

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

在这里,我们主要关注在 AKS 中使用 Azure 文件动态创建 PV的文档. 总体思路是创建一个存储类,该类将定义我们想要创建的 Azure 文件共享类型(高级与标准以及不同的冗余模式),然后创建一个符合该存储类的 PVC(持久卷声明)。因此,当 JupyterHub 尝试挂载我们创建的 PVC 时,它会自动创建一个 PV(持久卷)供 PVC 绑定,然后自动创建一个存储帐户和文件共享,以便 PV 实际存储文件。这都将在支持我们已经使用的资源组中完成(这些通常以“MC_”开头)。在这里,我们将使用带有区域冗余存储的高级存储类。首先,创建要使用的存储类(有关可用标签的更多信息可以在这个存储库中找到) 使用以下 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 和存储类是否已成功创建

kubectl get storageclass
kubectl get pvc

PVC 绑定可能需要几分钟时间。

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

将 PVC 挂载到主目录中的 JupyterHub

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

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

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


推荐阅读