stateful jupyter notebook in kubernetes

5/11/2020

Trying to deploy a stateful jupyter notebook in Kubernetes, but not able to save the code written in a notebook, whenever the notebook pod is going down all the code is being deleted. I tried to use persistent volume but unable to achieve the expected result.

UPDATE

Changed mount path to "/home/jovyan" as jyputer saves the ipynb in this location. But now getting PermissionError: [Errno 13] Permission denied: '/home/jovyan/.local' while deploying the pod.

kind: Ingress
metadata:
  name: jupyter-ingress
spec:
  backend:
    serviceName: jupyter-notebook-service
    servicePort: 8888

---

kind: Service
apiVersion: v1
metadata:
  name: jupyter-notebook-service
spec:  
  clusterIP: None
  selector:
    app: jupyter-notebook
  ports:
  - protocol: TCP    
    port: 8888
    targetPort: 8888

---

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: jupyter-notebook
  labels:
    app: jupyter-notebook
spec:
  replicas: 1
  serviceName: "jupyter-notebook-service"
  selector:
    matchLabels:
      app: jupyter-notebook
  template:
    metadata:
      labels:
        app: jupyter-notebook
    spec:
      serviceAccountName: dsx-spark
      volumes:
        - name: jupyter-pv-storage
          persistentVolumeClaim:
            claimName: jupyter-pv-claim 
      containers:
      - name: minimal-notebook
        image: jupyter/pyspark-notebook:latest
        ports:
        - containerPort: 8888
        command: ["start-notebook.sh"]
        args: ["--NotebookApp.token=''"]
        volumeMounts:
          - mountPath: "/home/jovyan"
            name: jupyter-pv-storage

---

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: jupyter-pv-claim
spec:
  storageClassName: jupyter-pv-storage
  accessModes:
  - ReadWriteOnce 
  resources:
    requests:
      storage: 1Gi

---
---

apiVersion: v1
kind: PersistentVolume
metadata:
  name: jupyter-pv-volume
  labels:
    type: local
spec:
  storageClassName: jupyter-pv-storage
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce 
  hostPath:
    path: "/home/jovyan"

---

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: jupyternotebook-pv-storage
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
  labels:
provisioner: kubernetes.io/vsphere-volume
parameters:
    diskformat: zeroedthick
    ```
-- Nitin Ashok
jupyter-notebook
kubernetes

2 Answers

5/12/2020

The Pod with jupyter notebook is non-root user so unable to mount the so we are using initContainers to change user/permission of the Persistent Volume Claim before creating the Pod.

kind: StatefulSet
metadata:
  name: jupyter-notebook
  labels:
    app: jupyter-notebook
spec:
  replicas: 1
  serviceName: "jupyter-notebook-service"
  selector:
    matchLabels:
      app: jupyter-notebook
  template:
    metadata:
      labels:
        app: jupyter-notebook
    spec:

      serviceAccountName: dsx-spark
      volumes:
        - name: ci-jupyter-storage-def
          persistentVolumeClaim:
            claimName: my-jupyter-pv-claim 
      containers:
      - name: minimal-notebook
        image: jupyter/pyspark-notebook:latest
        ports:
        - containerPort: 8888
        command: ["start-notebook.sh"]
        args: ["--NotebookApp.token=''"]
        volumeMounts:
          - mountPath: "/home/jovyan/work"
            name: ci-jupyter-storage-def

      initContainers:
      - name: jupyter-data-permission-fix
        image: busybox
        command: ["/bin/chmod","-R","777", "/data"]
        volumeMounts:
        - name: ci-jupyter-storage-def
          mountPath: /data```
-- Nitin Ashok
Source: StackOverflow

5/13/2020

As I have already mentioned in the comments you need to make sure that:

  1. The storage for a given Pod must either be provisioned by a PersistentVolume Provisioner based on the requested storage class, or pre-provisioned by an admin. The volumeClaimTemplates will provide stable storage using PersistentVolumes. PersistentVolumes associated with the Pods’ PersistentVolume Claims are not deleted when the Pods, or StatefulSet are deleted.

  2. The container is running as a user that has the permissions to access that volume. It can be done by changing the permissions to 777 or as you already noticed by using a proper initContainers.

-- OhHiMark
Source: StackOverflow