diff --git a/charts/jupyterlab/Chart.yaml b/charts/jupyterlab/Chart.yaml new file mode 100644 index 0000000..2fa3b1a --- /dev/null +++ b/charts/jupyterlab/Chart.yaml @@ -0,0 +1,21 @@ +apiVersion: v2 +name: jupyterlab +appVersion: "jupyter/datascience-notebook:python-3.9.6" +version: "0.1.0" +description: jupyterlab data science notebook +home: https://github.com/curie-data-factory/helm-charts/tree/master/charts/jupyterlab +icon: https://jupyter.org/assets/homepage/main-logo.svg +sources: + - https://jupyter.org/ +maintainers: + - name: armandleopold + email: armand.leopold@curie.fr +kubeVersion: ">= 1.14.0-0" +keywords: + - jupyter + - lab + - datascience +annotations: + artifacthub.io/images: | + - name: jupyter + image: jupyter/datascience-notebook:python-3.9.6 diff --git a/charts/jupyterlab/README.md b/charts/jupyterlab/README.md new file mode 100644 index 0000000..f84a9ca --- /dev/null +++ b/charts/jupyterlab/README.md @@ -0,0 +1,28 @@ +# Jupyterlab + +Helm chart pour le déploiement des jupyterlab dans l'environnement data-process-jupyter + +# Detect Secrets + +[Detect Secrets](https://github.com/Yelp/detect-secrets) permet d'éviter de commit des secrets dans les répos. + +Il y a 3 commandes à executer pour utiliser l'outil : + +1. `detect-secrets scan --all-files . > .secrets.baseline` + +Cette commande est à executer côté client pour scanner les répo et générer un fichier de baseline. + +2. `detect-secrets audit .secrets.baseline` + +Egalement côté client executer cette commande pour check les mots de passes potentiels. + +**Attention** : Il faut nécéssairement répondre aux questions : + +> Is this a secret that should be committed to this repository? (y)es, (n)o, (s)kip, (b)ack, (q)uit: + +afin de pouvoir passer à l'étape suivante, marquez tous les mots de passe trouvé en définissant si ils peuvent être commit ou non, cela aura une importance dans le passage cd la ci/cd. + +3. `git ls-files -z | xargs -0 detect-secrets-hook --baseline .secrets.baseline` + +Cette commande est executé côté gitlab, elle récupère le fichier `.secrets.baseline` et recheck de répo courant, si il y a des nouveaux mots de passe non marqués ou qu'ils n'ont pas été autorisés à être commits, la ci/cd renverra une erreur. + diff --git a/charts/jupyterlab/templates/ingress.yaml b/charts/jupyterlab/templates/ingress.yaml new file mode 100644 index 0000000..387c111 --- /dev/null +++ b/charts/jupyterlab/templates/ingress.yaml @@ -0,0 +1,33 @@ +{{- if .Values.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + labels: + app: "{{ .Release.Name }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + name: "{{ .Release.Name }}-ingress" + annotations: + nginx.ingress.kubernetes.io/client_max_body_size: 10000m + nginx.ingress.kubernetes.io/proxy-body-size: 10000m + {{- range $key, $value := .Values.ingress.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +spec: + rules: + - host: "{{ .Values.ingress.url }}" + http: + paths: + - path: "/{{ .Values.user }}" + pathType: Prefix + backend: + service: + name: "{{ .Release.Name }}-service" + port: + name: {{ .Values.service.targetPort }}{{ .Values.service.protocol | lower }} + {{- if .Values.ingress.tls }} + tls: +{{ toYaml .Values.ingress.tls | indent 4 }} + {{- end -}} +{{- end -}} diff --git a/charts/jupyterlab/templates/service.yaml b/charts/jupyterlab/templates/service.yaml new file mode 100644 index 0000000..df041df --- /dev/null +++ b/charts/jupyterlab/templates/service.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: "{{ .Release.Name }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + name: "{{ .Release.Name }}-service" +spec: + type: {{ .Values.service.type }} + ports: + - name: {{ .Values.service.targetPort }}{{ .Values.service.protocol | lower }} + port: {{ .Values.service.targetPort }} + protocol: {{ .Values.service.protocol }} + targetPort: {{ .Values.service.targetPort }} + selector: + app: "{{ .Release.Name }}" + release: {{ .Release.Name }} diff --git a/charts/jupyterlab/templates/statefulset.yaml b/charts/jupyterlab/templates/statefulset.yaml new file mode 100644 index 0000000..cb7ed31 --- /dev/null +++ b/charts/jupyterlab/templates/statefulset.yaml @@ -0,0 +1,83 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app: {{ .Release.Name }}-jupyter-{{ .Values.user }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + name: "{{ .Release.Name }}" + namespace: {{ .Release.Namespace }} +spec: + serviceName: "{{ .Release.Name }}" + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: "{{ .Release.Name }}" + release: {{ .Release.Name }} + template: + metadata: + labels: + app: "{{ .Release.Name }}" + release: {{ .Release.Name }} + app.kubernetes.io/name: {{ .Values.user }} + app.kubernetes.io/instance: {{ .Release.Name }} + rollme: {{ randAlphaNum 5 | quote }} + spec: + containers: + - env: + {{- if .Values.gpu.enabled }} + - name: CUDA_VISIBLE_DEVICES + value: 0,1 + - name: LD_LIBRARY_PATH + value: /usr/local/cuda/extras/CUPTI/lib64:/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/usr/local/cuda/lib64 + - name: NVIDIA_DRIVER_CAPABILITIES + value: all + - name: NVIDIA_VISIBLE_DEVICES + value: all + {{- end }} + image: {{ .Values.image.repository }}:{{ .Values.user }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + name: {{ .Release.Name }}-jupyter-{{ .Values.user }} + {{- if .Values.gpu.enabled }} + resources: + limits: + nvidia.com/gpu: "1" + requests: + nvidia.com/gpu: "1" + args: + - bash + - -c + - 'source /etc/bash.bashrc && cp -r /tf/.ssh /tf 2>/dev/null || : && jupyter lab --notebook-dir=/tf --ip 0.0.0.0 --no-browser --allow-root + --allow-root' + {{- else }} + args: + - /bin/bash + - -c + - 'cp -r /home/jovyan/work/.ssh /home/jovyan/ 2>/dev/null || : && jupyter lab --notebook-dir=/home/jovyan/work --ip 0.0.0.0 --no-browser --allow-root' + {{- end }} + ports: + - containerPort: {{ .Values.service.targetPort }} + name: {{ .Values.service.targetPort }}{{ .Values.service.protocol | lower }} + protocol: {{ .Values.service.protocol }} + resources: + requests: + cpu: "1" + memory: 1000Mi + {{- if .Values.resources.enabled }} + limits: + cpu: "{{ .Values.resources.cpu }}" + memory: {{ .Values.resources.memory }} + {{- end }} + volumeMounts: + {{- if .Values.gpu.enabled }} + - mountPath: "/tf" + name: "{{ .Release.Name }}-{{ .Values.user }}-data" + {{- else }} + - mountPath: {{ .Values.persistence.mountPath }} + name: "{{ .Release.Name }}-{{ .Values.user }}-data" + {{- end }} + volumes: + - name: "{{ .Release.Name }}-{{ .Values.user }}-data" + persistentVolumeClaim: + claimName: "{{ .Release.Name }}-{{ .Values.user }}-data" diff --git a/charts/jupyterlab/templates/volume.yaml b/charts/jupyterlab/templates/volume.yaml new file mode 100644 index 0000000..67b977a --- /dev/null +++ b/charts/jupyterlab/templates/volume.yaml @@ -0,0 +1,32 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: "{{ .Release.Name }}-{{ .Values.user }}-data" + namespace: {{ .Release.Namespace }} +{{- with .Values.persistence.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + labels: + app: "{{ .Release.Name }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +{{- if .Values.persistence.replicas }} + storageos.com/replicas: "{{ .Values.persistence.replicas }}" +{{- end }} +spec: + accessModes: + - {{ .Values.persistence.accessMode | quote }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} +{{- if .Values.persistence.storageClass }} +{{- if (eq "-" .Values.persistence.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.persistence.storageClass }}" +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/jupyterlab/values.yaml b/charts/jupyterlab/values.yaml new file mode 100644 index 0000000..08d70e6 --- /dev/null +++ b/charts/jupyterlab/values.yaml @@ -0,0 +1,41 @@ +# Replica count for script runner & website +replicaCount: 1 + +user: master + +gpu: + enabled: false + +resources: + enabled: true + cpu: 20 + memory: 25000Mi + +# Images +image: + repository: jupyter/datascience-notebook:python-3.9.6 + pullPolicy: IfNotPresent + +# Service discovery for Website +service: + type: ClusterIP + targetPort: 8888 + protocol: TCP + +# Load Balancer +ingress: + enabled: true + url: jupyter-data.compagny.net + tls: + - hosts: + - jupyter-data.compagny.net + secretName: jupyter-data + +## Persist data to a persistent volume +persistence: + enabled: true + size: 30Gi + storageClass: storageos-ssd-ext4 + accessMode: "ReadWriteOnce" + replicas: "1" + mountPath: /home/jovyan/work