我应该如何在Kubernetes上为JupyterHub部署持久卷(PV)?

时间:2020-07-02 04:15:18

标签: docker kubernetes jupyterhub

环境信息:

Computer detail: One master node and four slave nodes. All are CentOS Linux release 7.8.2003 (Core).
Kubernetes version: v1.18.0.
Zero to JupyterHub version: 0.9.0.
Helm version: v2.11.0

我最近尝试通过零到JupyterHub在新的实验室服务器中部署在线代码环境(例如Google Colab)。不幸的是,我未能为JupyterHub部署Persistent Volume(PV),并且收到如下失败消息:

Events:
  Type     Reason            Age                From               Message
  ----     ------            ----               ----               -------
  Warning  FailedScheduling  4s (x27 over 35m)  default-scheduler  running "VolumeBinding" filter plugin for pod "hub-7b9cbbcf59-747jl": pod has unbound immediate PersistentVolumeClaims

我遵循tutorial of JupyterHub的安装过程,并使用Helm在k8s上安装JupyterHub。该配置文件如下:

config.yaml

proxy:
  secretToken: "2fdeb3679d666277bdb1c93102a08f5b894774ba796e60af7957cb5677f40706"
singleuser:
  storage:
    dynamic:
      storageClass: local-storage

在这里,我为JupyterHub配置了local-storage,观察到local-storage是k8s:Link。及其yaml文件 这样的:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

然后我使用kubectl get storageclass来检查它是否正常工作,我收到以下消息:

NAME            PROVISIONER                    RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
local-storage   kubernetes.io/no-provisioner   Delete          WaitForFirstConsumer   false                  64m

所以,我以为我为JupyterHub部署了一个存储,但是我很幼稚。我对此感到非常失望,因为我的其他Pods(JupyterHub)都在运行。很久以来,我一直在寻找一些解决方案,但也失败了。

所以现在,我的问题是:

  1. 解决PV问题的真正方法是什么? (最好使用本地存储。)

  2. 本地存储方式是否会使用其他节点的磁盘而不仅仅是主磁盘?

  3. 实际上,我的实验室有一个可能的存储服务,所以如果第二季度答案为否,那么我如何使用我的实验室的存储服务来部署PV?


我已经通过@Arghya Sadhu的解决方案解决了上述问题。但是现在,我遇到了一个新问题,即Pod hub-db-dir也正在等待处理,这导致我的服务proxy-public正在等待处理。

hub-db-dir的描述如下:

Name:           hub-7b9cbbcf59-jv49z
Namespace:      jhub
Priority:       0
Node:           <none>
Labels:         app=jupyterhub
                component=hub
                hub.jupyter.org/network-access-proxy-api=true
                hub.jupyter.org/network-access-proxy-http=true
                hub.jupyter.org/network-access-singleuser=true
                pod-template-hash=7b9cbbcf59
                release=jhub
Annotations:    checksum/config-map: c20a64c7c9475201046ac620b057f0fa65ad6928744f7d265bc8705c959bce2e
                checksum/secret: 1beaebb110d06103988476ec8a3117eee58d97e7dbc70c115c20048ea04e79a4
Status:         Pending
IP:
IPs:            <none>
Controlled By:  ReplicaSet/hub-7b9cbbcf59
Containers:
  hub:
    Image:      jupyterhub/k8s-hub:0.9.0
    Port:       8081/TCP
    Host Port:  0/TCP
    Command:
      jupyterhub
      --config
      /etc/jupyterhub/jupyterhub_config.py
      --upgrade-db
    Requests:
      cpu:      200m
      memory:   512Mi
    Readiness:  http-get http://:hub/hub/health delay=0s timeout=1s period=10s #success=1 #failure=3
    Environment:
      PYTHONUNBUFFERED:        1
      HELM_RELEASE_NAME:       jhub
      POD_NAMESPACE:           jhub (v1:metadata.namespace)
      CONFIGPROXY_AUTH_TOKEN:  <set to the key 'proxy.token' in secret 'hub-secret'>  Optional: false
    Mounts:
      /etc/jupyterhub/config/ from config (rw)
      /etc/jupyterhub/cull_idle_servers.py from config (rw,path="cull_idle_servers.py")
      /etc/jupyterhub/jupyterhub_config.py from config (rw,path="jupyterhub_config.py")
      /etc/jupyterhub/secret/ from secret (rw)
      /etc/jupyterhub/z2jh.py from config (rw,path="z2jh.py")
      /srv/jupyterhub from hub-db-dir (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from hub-token-vlgwz (ro)
Conditions:
  Type           Status
  PodScheduled   False
Volumes:
  config:
    Type:      ConfigMap (a volume populated by a ConfigMap)
    Name:      hub-config
    Optional:  false
  secret:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  hub-secret
    Optional:    false
  hub-db-dir:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  hub-db-dir
    ReadOnly:   false
  hub-token-vlgwz:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  hub-token-vlgwz
    Optional:    false
QoS Class:       Burstable
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason            Age                 From               Message
  ----     ------            ----                ----               -------
  Warning  FailedScheduling  61s (x43 over 56m)  default-scheduler  0/5 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 4 node(s) didn't find available persistent volumes to bind.

带有kubectl get pv,pvc,sc的信息。

NAME                               STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS    AGE
persistentvolumeclaim/hub-db-dir   Pending                                      local-storage   162m

NAME                                                  PROVISIONER                    RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
storageclass.storage.k8s.io/local-storage (default)   kubernetes.io/no-provisioner   Delete          WaitForFirstConsumer   false                  8h

那么,如何解决呢?

2 个答案:

答案 0 :(得分:2)

除了@Arghya Sadhu答案之外,为了使其能够使用local storage进行工作,还必须手动创建一个PersistentVolume

例如:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: hub-db-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: local-storage
  local:
    path: <path_to_local_volume>
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - <name_of_the_node>

然后您可以部署图表:

helm upgrade --install $RELEASE jupyterhub/jupyterhub \
  --namespace $NAMESPACE  \
  --version=0.9.0 \
  --values config.yaml

config.yaml文件可以保留不变:

proxy:
  secretToken: "<token>"
singleuser:
  storage:
    dynamic:
      storageClass: local-storage

答案 1 :(得分:1)

  1. 我认为您需要将local-storage设置为默认存储类

kubectl patch storageclass local-storage -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

  1. 本地存储将使用已安排Pod的节点的本地磁盘存储。

  2. 很难说出更多细节。您可以手动创建PV或使用执行动态卷配置的存储类。