自定义用户资源#
注意
有关您可以配置的所有 Helm 图表选项的列表,请参见 配置参考.
用户资源包括 JupyterHub 提供给用户的 CPU、RAM 和存储。大多数可以通过修改 Helm 图表来控制。有关将修改部署到 JupyterHub 部署的信息,请参见 应用配置更改.
由于 JupyterHub 可以为许多不同类型的用户提供服务,因此 JupyterHub 管理员必须能够灵活地 **分配用户资源**,例如内存或计算。例如,Hub 可能为具有大量资源需求的资深用户提供服务,也可能为具有更基本资源需求的初学者用户提供服务。能够根据用户群体的需求自定义 Hub 的资源可以改善所有 Hub 用户的使用体验。
设置用户内存和 CPU 保证/限制#
您 JupyterHub 上的每个用户都获得了一部分内存和 CPU 来使用。有两种方法可以指定用户可以使用多少资源:资源 *保证* 和资源 *限制*。
资源 *保证* 意味着所有用户将始终至少拥有此资源,但如果可用,他们可能会获得更多资源。例如,如果用户 *保证* 1G 的 RAM,用户理论上可以使用超过 1G 的 RAM,前提是这些资源没有被其他用户使用。
资源 *限制* 对可用资源设置了硬性限制。在上面的示例中,如果存在 1G 内存限制,则意味着用户最多可以使用 1G 的 RAM,无论机器上正在使用哪些其他资源。
默认情况下,每个用户 *保证* 1G 的 RAM。所有用户 *至少* 有 1G,但如果可用,他们理论上可以使用更多。您可以轻松更改这些资源的数量,以及它们是 *保证* 还是 *限制*,方法是更改您的 config.yaml
文件。这可以通过以下结构完成。
singleuser:
memory:
limit: 1G
guarantee: 1G
这将设置 1G 的内存限制和保证。Kubernetes 将确保每个用户始终可以访问 1G 的 RAM,并且对更多 RAM 的请求将失败(您的内核通常会崩溃)。您可以将限制设置为高于保证,以允许某些用户在非常短的时间内使用更大的 RAM 量(例如,在运行一个消耗大量内存的单一、短暂函数时)。
类似地,您可以限制 CPU,如下所示
singleuser:
cpu:
limit: .5
guarantee: .5
这将限制您的用户最多使用 0.5 个 CPU(即 1/2 个 CPU 内核),并保证他们使用相同的数量。
注意
请记住在更改 config.yaml
文件后 应用更改!
设置用户 GPU 保证/限制#
可以为您的用户分配 GPU。这对于深度学习等更繁重的负载非常有用,这些负载可以利用 GPU。
例如,要创建一个分配一个 NVIDIA GPU 的配置文件
singleuser:
profileList:
- display_name: "GPU Server"
description: "Spawns a notebook server with access to a GPU"
kubespawner_override:
extra_resource_limits:
nvidia.com/gpu: "1"
这假设您的至少一个 Kubernetes 节点已连接了兼容的 GPU。执行此操作的方法因基础设施提供商而异。以下是一些链接,可以帮助您入门
您还需要按照说明部署 k8s-device-plugin 这里.
要检查您的 GPU 是否可被 Kubernetes 调度,您可以运行以下命令
kubectl get nodes -o=custom-columns=NAME:.metadata.name,GPUs:.status.capacity.'nvidia\.com/gpu'
修改用户存储类型和大小#
有关如何修改用户可以访问的存储类型和大小的信息,请参见 自定义用户存储。
扩展和收缩集群的大小#
您可以轻松地扩展或缩减集群的大小,以满足使用需求或在集群未被使用时节省成本。当您有可预测的使用高峰时,这尤其有用。例如,如果您正在组织和运行研讨会,调整集群大小可以让您节省成本并在活动之前准备 JupyterHub。例如
研讨会前一周:您可以创建集群,设置所有内容,然后将集群调整为零个节点以节省成本。
研讨会当天:您可以将集群扩展到适合研讨会的大小。此工作流程还有助于您避免在研讨会当天争先恐后地设置集群和 JupyterHub。
研讨会结束后:可以删除集群。
以下部分描述了如何在各种云平台上调整集群大小。
Google Cloud Platform#
使用 resize
命令并提供新的集群大小(即节点数)作为命令行选项 --num-nodes
gcloud container clusters resize \
<YOUR-CLUSTER-NAME> \
--num-nodes <NEW-SIZE> \
--zone <YOUR-CLUSTER-ZONE>
要显示集群的名称、区域或当前大小,请使用以下命令
gcloud container clusters list
调整集群大小后,可能需要几分钟才能将新的集群大小报告回来,因为服务正在添加或删除节点。您可以使用 kubectl get node
来查找当前“就绪”节点的真实数量,以报告集群中所有节点的当前 Ready/NotReady
状态。
Microsoft Azure Platform#
使用 scale
命令并提供新的集群大小(即节点数)作为命令行选项 --node-count
az aks scale \
--name <YOUR-CLUSTER-NAME> \
--node-count <NEW-SIZE> \
--resource-group <YOUR-RESOURCE-GROUP>
要显示集群的详细信息,请使用以下命令
az aks show --name <YOUR-CLUSTER-NAME> --resource-group <YOUR-RESOURCE-GROUP>
新的集群节点可能需要一些时间才能就绪。您可以使用 kubectl get node
来报告集群中所有节点的当前 Ready/NotReady
状态。
Amazon Web Services Elastic Kubernetes Service (EKS)#
AWS EKS 是一项 Amazon 服务,提供 AWS 管理的 Kubernetes 控制平面和一组命令行工具 eksctl
,用于创建和管理 Kubernetes 集群。这只是在 AWS 基础设施上部署 Kubernetes 的一种方式,但以下假设您拥有
在 EKS 上部署的 Kubernetes 集群
命令行工具
eksctl
已安装 并配置为指向您的 EKS 集群。
要使用 eksctl
命令行工具扩展现有节点组
eksctl scale nodegroup \
-n <NODEGROUP-NAME> \
--nodes <DESIRED-NUMBER-OF-NODES>\
--nodes-max <MAX-NUMBER-OF-NODES>\
--nodes-min <MIN-NUMBER-OF-NODES>\
--cluster=<YOUR-CLUSTER-NAME>
如果您已设置集群自动扩展器,您也可以使用 eksctl
命令行工具创建自动扩展节点组。
eksctl create nodegroup \
--cluster <YOUR-CLUSTER-NAME> \
--name <NODEGROUP-NAME> \
--node-type <EC2-INSTANCE-TYPE(S)> \
--nodes-max <MAX-NUMBER-OF-NODES>\
--nodes-min <MIN-NUMBER-OF-NODES>\
--ssh-access \
--ssh-public-key <PATH-TO-KEYPAIR-WITH-EKS-PERMISSIONS> \
--node-zones <OPTIONALLY-SPECIFY-AVAILABILIYT-ZONE-FOR-NODES> \
--tags "k8s.io/cluster-autoscaler/node-template/taint/<some-taint-key>=<some-taint-value>:<some-taint-effect>, k8s.io/cluster-autoscaler/node-template/label/<some-node-label-key>=<some-node-label-value>,k8s.io/cluster-autoscaler/<YOUR-CLUSTER-NAME>=true,k8s.io/cluster-autoscaler/enabled=true" \
--node-labels "<some-node-label-key>=<some-node-label-value>,failure-domain.beta.kubernetes.io/zone=<AVAILABILITY-ZONE>,failure-domain.beta.kubernetes.io/region=<AVAILABILITY-REGION>"
为了使 AWS 集群自动扩展器能够自动扩展节点组,必须应用以下标签:k8s.io/cluster-autoscaler/<YOUR-CLUSTER-NAME>=<any-value-only-key-matters>
和 k8s.io/cluster-autoscaler/enabled=true
。
必须添加一个 tag
,它对应于每个 node-labels
,这些标签将在调度 Pod 时用作 nodeSelector
;对于形式为 <some-node-label-key>=<some-node-label-value>
的 node-labels
,这些标签应为 k8s.io/cluster-autoscaler/node-template/label/<some-node-label-key>=<some-node-label-value>
。
也可以使用形式为 k8s.io/cluster-autoscaler/node-template/taint/<some-taint-key>=<some-taint-value>:<some-taint-effect>
的标签将污点应用于节点组中的节点。
最后,可以使用 node-labels
设置 AWS 区域(例如,eu-west-1
)和可用区(例如,eu-west-1a
):failure-domain.beta.kubernetes.io/region=<AVAILABILITY-REGION>
和 failure-domain.beta.kubernetes.io/zone=<AVAILABILITY-ZONE>
;或者使用 --node-zones
标志。设置可用区在单用户 Pod 可能被调度到不同可用区中的节点时很有用;当使用任何不支持跨可用区挂载的 persistentVolume
存储(包括 AWS EKS 中的默认 gp2
存储)时,这种情况会造成问题。在这些情况下,PV
将在用户 Pod 首次调度的节点的可用区中创建,如果将来同一个用户 Pod 被调度到不同的可用区,则会发生错误。通过控制 nodegroups
部署到的区域和/或为 values.yaml
中引用的自定义 StorageClass
中的卷指定可用区来避免这种情况。