diff --git a/charts/kf-notebooks/.helmignore b/charts/kf-notebooks/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/kf-notebooks/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/kf-notebooks/Chart.yaml b/charts/kf-notebooks/Chart.yaml new file mode 100644 index 0000000..eeef864 --- /dev/null +++ b/charts/kf-notebooks/Chart.yaml @@ -0,0 +1,34 @@ +apiVersion: v2 +name: kf-notebooks +description: Helm chart for deploying KubeFlow Notebooks + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "v1.9.0" + +keywords: + - kubeflow + - notebooks + - ai-apps + - ai-notebooks + - ai-ml + +sources: + - https://github.com/kubeflow/kubeflow diff --git a/charts/kf-notebooks/README.md b/charts/kf-notebooks/README.md new file mode 100644 index 0000000..324fd04 --- /dev/null +++ b/charts/kf-notebooks/README.md @@ -0,0 +1,60 @@ +# KF-Notebooks + +A helm chart to deploy the [Kubeflow Notebooks](https://www.kubeflow.org/docs/components/notebooks/) on a Kubernetes cluster. + +## Setup Helm Repository + +```bash +helm repo add infracloud-charts https://infracloudio.github.io/charts +helm repo update +``` + +See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation. + +## Installing the Chart + +To install the chart with the release name `kf-notebooks`: + +```bash +helm install kf-notebooks infracloud-charts/kf-notebooks +``` + +## Uninstalling the Chart + +To uninstall the `kf-notebooks` deployment: + +```bash +helm uninstall kf-notebooks +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Parameters + +The following table lists the configurable parameters of the KF-Notebooks chart and their default values. + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `global.storageClassName` | Global storage class name | `""` | +| `nameOverride` | String to partially override kf-notebooks.fullname template | `""` | +| `fullnameOverride` | String to fully override kf-notebooks.fullname template | `""` | +| `service.enabled` | Enable service creation | `true` | +| `service.port` | Service port | `80` | +| `service.type` | Service type | `ClusterIP` | +| `notebooks.jupyter.enabled` | Enable Jupyter notebook | `false` | +| `notebooks.jupyter.name` | Jupyter notebook name | `jupyter-pytorch-cuda` | +| `notebooks.jupyter.image.repository` | Jupyter notebook image repository | `kubeflownotebookswg/jupyter-pytorch-cuda-full` | +| `notebooks.jupyter.image.tag` | Jupyter notebook image tag | `v1.9.0` | +| `notebooks.jupyter.image.pullPolicy` | Jupyter notebook image pull policy | `IfNotPresent` | +| `notebooks.jupyter.resources` | Jupyter notebook resources | See `values.yaml` for defaults | +| `notebooks.jupyter.storage.size` | Jupyter notebook storage size | `5Gi` | +| `notebooks.vscode.enabled` | Enable VSCode notebook | `false` | +| `notebooks.vscode.name` | VSCode notebook name | `codeserver-python` | +| `notebooks.vscode.image.repository` | VSCode notebook image repository | `kubeflownotebookswg/codeserver-python` | +| `notebooks.vscode.image.tag` | VSCode notebook image tag | `v1.9.0` | +| `notebooks.vscode.image.pullPolicy` | VSCode notebook image pull policy | `IfNotPresent` | +| `notebooks.vscode.resources` | VSCode notebook resources | See `values.yaml` for defaults | +| `notebooks.vscode.storage.size` | VSCode notebook storage size | `5Gi` | + + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, diff --git a/charts/kf-notebooks/templates/NOTES.txt b/charts/kf-notebooks/templates/NOTES.txt new file mode 100644 index 0000000..8cc0dd9 --- /dev/null +++ b/charts/kf-notebooks/templates/NOTES.txt @@ -0,0 +1,35 @@ +Thank you for installing {{ .Chart.Name }}. + +Your release is named {{ .Release.Name }}. + +To learn more about the release, try: + + $ helm status {{ .Release.Name }} + $ helm get all {{ .Release.Name }} + +{{- if not (.Capabilities.APIVersions.Has "kubeflow.org/v1") }} +WARNING: The Notebook custom resource is not available in your cluster. +Please make sure Kubeflow is installed properly before using this chart. +{{- else }} +The following Notebooks have been created: + +{{- if .Values.notebooks.jupyter.enabled }} +- Jupyter Notebook: {{ include "kf-notebooks.fullname" . }}-{{ .Values.notebooks.jupyter.name }} +{{- end }} +{{- if .Values.notebooks.vscode.enabled }} +- VSCode Notebook: {{ include "kf-notebooks.fullname" . }}-{{ .Values.notebooks.vscode.name }} +{{- end }} + +{{- if .Values.service.enabled }} +To access the notebooks, use port-forwarding: + +{{- if .Values.notebooks.jupyter.enabled }} + $ kubectl port-forward svc/{{ include "kf-notebooks.fullname" . }}-{{ .Values.notebooks.jupyter.name }} {{ .Values.service.port }}:{{ .Values.service.port }} +{{- end }} +{{- if .Values.notebooks.vscode.enabled }} + $ kubectl port-forward svc/{{ include "kf-notebooks.fullname" . }}-{{ .Values.notebooks.vscode.name }} {{ .Values.service.port }}:{{ .Values.service.port }} +{{- end }} + +Then open your browser and navigate to http://localhost:{{ .Values.service.port }} +{{- end }} +{{- end }} diff --git a/charts/kf-notebooks/templates/_helpers.tpl b/charts/kf-notebooks/templates/_helpers.tpl new file mode 100644 index 0000000..c790894 --- /dev/null +++ b/charts/kf-notebooks/templates/_helpers.tpl @@ -0,0 +1,60 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "kf-notebooks.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "kf-notebooks.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "kf-notebooks.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "kf-notebooks.labels" -}} +helm.sh/chart: {{ include "kf-notebooks.chart" . }} +{{ include "kf-notebooks.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "kf-notebooks.selectorLabels" -}} +app.kubernetes.io/name: {{ include "kf-notebooks.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Check if Notebook CRD is installed +*/}} +{{- define "kf-notebooks.checkNotebookCRD" -}} +{{- if not (.Capabilities.APIVersions.Has "kubeflow.org/v1") -}} +{{- fail "Notebook CRD is not installed in the cluster. Please install Kubeflow first." -}} +{{- end -}} +{{- end -}} diff --git a/charts/kf-notebooks/templates/pvc.yaml b/charts/kf-notebooks/templates/pvc.yaml new file mode 100644 index 0000000..842633b --- /dev/null +++ b/charts/kf-notebooks/templates/pvc.yaml @@ -0,0 +1,21 @@ +{{- range $key, $notebook := .Values.notebooks }} +{{- if $notebook.enabled }} +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "kf-notebooks.fullname" $ }}-{{ $notebook.name }}-workspace + labels: + {{- include "kf-notebooks.labels" $ | nindent 4 }} + app: {{ $notebook.name }} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ $notebook.storage.size }} + {{- if $.Values.global.storageClassName }} + storageClassName: {{ $.Values.global.storageClassName }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/kf-notebooks/templates/pytorch-cuda.yaml b/charts/kf-notebooks/templates/pytorch-cuda.yaml new file mode 100644 index 0000000..be424b1 --- /dev/null +++ b/charts/kf-notebooks/templates/pytorch-cuda.yaml @@ -0,0 +1,31 @@ +{{- if .Values.notebooks.jupyter.enabled }} +{{- include "kf-notebooks.checkNotebookCRD" . }} +apiVersion: kubeflow.org/v1 +kind: Notebook +metadata: + name: {{ include "kf-notebooks.fullname" . }}-{{ .Values.notebooks.jupyter.name }} + labels: + {{- include "kf-notebooks.labels" . | nindent 4 }} + app: {{ .Values.notebooks.jupyter.name }} +spec: + template: + spec: + containers: + - name: {{ .Values.notebooks.jupyter.name }} + image: "{{ .Values.notebooks.jupyter.image.repository }}:{{ .Values.notebooks.jupyter.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.notebooks.jupyter.image.pullPolicy }} + resources: + {{- toYaml .Values.notebooks.jupyter.resources | nindent 10 }} + volumeMounts: + - mountPath: /dev/shm + name: dshm + - mountPath: /home/jovyan + name: workspace + volumes: + - emptyDir: + medium: Memory + name: dshm + - name: workspace + persistentVolumeClaim: + claimName: {{ include "kf-notebooks.fullname" . }}-{{ .Values.notebooks.jupyter.name }}-workspace +{{- end }} diff --git a/charts/kf-notebooks/templates/service.yaml b/charts/kf-notebooks/templates/service.yaml new file mode 100644 index 0000000..272a4b5 --- /dev/null +++ b/charts/kf-notebooks/templates/service.yaml @@ -0,0 +1,22 @@ +{{- if .Values.service.enabled }} +{{- range $key, $notebook := .Values.notebooks }} +{{- if $notebook.enabled }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "kf-notebooks.fullname" $ }}-{{ $notebook.name }} + labels: + {{- include "kf-notebooks.labels" $ | nindent 4 }} + app: {{ $notebook.name }} +spec: + type: {{ $.Values.service.type }} + ports: + - port: {{ $.Values.service.port }} + targetPort: 8888 + protocol: TCP + selector: + app: {{ $notebook.name }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/kf-notebooks/templates/vscode.yaml b/charts/kf-notebooks/templates/vscode.yaml new file mode 100644 index 0000000..9030f07 --- /dev/null +++ b/charts/kf-notebooks/templates/vscode.yaml @@ -0,0 +1,31 @@ +{{- if .Values.notebooks.vscode.enabled }} +{{- include "kf-notebooks.checkNotebookCRD" . }} +apiVersion: kubeflow.org/v1 +kind: Notebook +metadata: + name: {{ include "kf-notebooks.fullname" . }}-{{ .Values.notebooks.vscode.name }} + labels: + {{- include "kf-notebooks.labels" . | nindent 4 }} + app: {{ .Values.notebooks.vscode.name }} +spec: + template: + spec: + containers: + - name: {{ .Values.notebooks.vscode.name }} + image: "{{ .Values.notebooks.vscode.image.repository }}:{{ .Values.notebooks.vscode.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.notebooks.vscode.image.pullPolicy }} + resources: + {{- toYaml .Values.notebooks.vscode.resources | nindent 10 }} + volumeMounts: + - mountPath: /dev/shm + name: dshm + - mountPath: /home/jovyan + name: workspace + volumes: + - emptyDir: + medium: Memory + name: dshm + - name: workspace + persistentVolumeClaim: + claimName: {{ include "kf-notebooks.fullname" . }}-{{ .Values.notebooks.vscode.name }}-workspace +{{- end }} diff --git a/charts/kf-notebooks/values.yaml b/charts/kf-notebooks/values.yaml new file mode 100644 index 0000000..61a5b84 --- /dev/null +++ b/charts/kf-notebooks/values.yaml @@ -0,0 +1,52 @@ +# Global settings +global: + storageClassName: "" + +# Common settings +commonLabels: {} +commonAnnotations: {} +nameOverride: "" +fullnameOverride: "" + +# Service settings +service: + enabled: true + port: 80 + type: ClusterIP + +# Notebook settings +notebooks: + jupyter: + enabled: false + name: jupyter-pytorch-cuda + image: + repository: kubeflownotebookswg/jupyter-pytorch-cuda-full + tag: "" + pullPolicy: IfNotPresent + resources: + limits: + cpu: "0.6" + memory: 1.2Gi + nvidia.com/gpu: "1" + requests: + cpu: "0.5" + memory: 1Gi + storage: + size: 5Gi + + vscode: + enabled: false + name: codeserver-python + image: + repository: kubeflownotebookswg/codeserver-python + tag: "" + pullPolicy: IfNotPresent + resources: + limits: + cpu: "0.6" + memory: 1.2Gi + requests: + cpu: "0.5" + memory: 1Gi + storage: + size: 5Gi