在 AWS 上设置 EFS 存储#
ElasticFileSystem 是一个分布式文件系统,它使用 NFS 协议。据说它是在 AWS 幕后使用 GlusterFS 的一个分支。
缺点
在 Kubernetes 规范中,持久卷的权限设置尚未确定。这会带来一些我们将在后面讨论的复杂情况。
一个狡猾的用户可能能够直接联系 EFS 服务器并读取其他用户的文件,具体取决于系统的设置方式。
步骤
设置 EFS 卷
在 AWS 中使用 EFS 设置向导(将来这部分可能会被脚本化)。新的 EFS 卷必须与您的集群位于同一个 VPC 中。这可以在创建后在 AWS 设置中更改。
接下来,为 NFS 流量创建一个新的安全组(目标是该组中的其他实例)。在节点安全组和主安全组中添加一个用于传入 NFS 流量的规则。更改 EFS 卷以使用该安全组。
要验证您的 EFS 卷是否正常工作,请 ssh 登录到其中一个主节点并 su 到 root。接下来,按照 EFS 控制台页面上的步骤挂载您的 NFS 卷。DNS 条目可能需要几分钟才能显示。
挂载成功后,将其卸载并断开与管理节点的连接。
配置 Kubernetes 以了解您的 EFS 卷
创建 test_efs.yaml
apiVersion: v1 kind: PersistentVolume metadata: name: efs-persist spec: capacity: storage: 123Gi accessModes: - ReadWriteMany nfs: server: fs-${EFS_ID}.efs.us-east-1.amazonaws.com path: "/"
创建 test_efs_claim.yaml
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: efs-persist spec: storageClassName: "" accessModes: - ReadWriteMany resources: requests: storage: 11Gi
这些文件中的大小是误导性的。EFS 没有强制执行配额。将来,我们希望将 efs 持久卷大小设置为一个非常大的数字,例如 8EiB,并将持久卷声明设置为 10GB。据我们目前所知,这些大小并不重要。
持久卷定义了一个服务,该服务可以在容器内部执行挂载。持久卷声明是预留持久卷的一部分并可能锁定对其访问的一种方式。
storageClassName 设置看起来很不起眼,但它非常关键。集群中唯一没有存储类别的 PV 是我们上面定义的 PV。将来,我们应该标记不同的 PV,并在 PVC 中使用标签过滤器,而不是依赖于“”。
我们将配置 jupyterhub 以在所有容器之间使用相同的“静态”声明。这意味着我们所有用户都将使用相同的 EFS 共享,该共享应该能够根据我们的需要进行扩展。
这部分与标准指南略有不同。我们需要在我们的应用程序将要所在的命名空间中创建这些 PV 和 PVC。选择一个命名空间(这将与您稍后在 helm install 步骤中使用的命名空间相同)
运行以下命令来设置您的命名空间和存储
kubectl create namespace <your namespace> kubectl --namespace=<your namespace> apply -f test_efs.yaml kubectl --namespace=<your namespace> apply -f test_efs_claim.yaml
我不知道 PV 是否需要在命名空间中,但参数似乎没有造成任何伤害。PVC 必须在命名空间中,否则会以奇怪的方式出错。
配置您的应用程序以使用 EFS 作为其后端存储
现在,我们将以下内容添加到 config.yaml 中
singleuser: image: name: jupyter/base-notebook tag: latest storage: type: "static" static: pvcName: "efs-persist" subPath: "home/{username}" extraEnv: CHOWN_HOME: "yes" uid: 0 fsGid: 0 cmd: "start-singleuser.sh"
image 设置覆盖了默认的固定 jh 基础镜像,因为它尚未更新以包含 CHOWN_HOME 设置。
type static 告诉 jh 不要使用存储类别,而是使用下面定义的 PVC。
pvcName 与我们之前指定的声明名称匹配
subPath 指示挂载点应该位于提供的存储中的哪个位置。在这种情况下,它将是“$EFS_ROOT/home/{username}”
事实证明,jupyterhub 中存在一个错误,导致默认的 subPath 无法正常工作,并将 subPath 设置为“{username}”也会以相同的方式出错。
extraEnv 部分在尝试在用户的容器内启动 jupyterhub 之前设置环境变量。CHOWN_HOME 是强制更改主目录的所有权所需的。
Kubernetes 仍然存在争议,关于是否应该传递 uid 和 gid 来改变目录在容器内的挂载方式。目前,我们在 JupyterHub 启动之前自动更改目录的所有权。
UID/fsGID 是必要的,以强制容器以 root 身份运行 start-singleuser.sh。一旦 start-singleuser.sh 正确地更改了目录的所有权,它就会切换到 jupyterhub 用户。