Skip to content

Commit

Permalink
Add jupyter-web-app component in jupyter pkg
Browse files Browse the repository at this point in the history
Add the jsonnet files in /kubeflow/jupyter. Currently the webapp
is used alongside JupyterHub. The webapp is under the prefix /jupyter.
The image param of the jupyter-web-app must be configured before
deploying.

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
  • Loading branch information
kimwnasptd committed Jan 31, 2019
1 parent 8308576 commit 0617c83
Show file tree
Hide file tree
Showing 5 changed files with 307 additions and 1 deletion.
112 changes: 112 additions & 0 deletions kubeflow/jupyter/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Configuration file for the default JupyterHub Spawner UI
# Each key corresponds to a JupyterHub Spawner UI option
# If a key is missing, the respective Spawner UI option will be left untouched
#
# Each Spawner UI option is configured by two keys: `value` and `readOnly`
# - The `value` key contains the default value
# - The `readOnly` key determines if the option will be available to users
#
# If the 'readOnly' key is present and set to 'true', the respective option
# will be disabled for users and only set by the admin
# If the 'readOnly' key is missing (defaults to 'false'), the respective option
# will be available for users
#
# Please note that some values (e.g. {username}) may be templated
# and expanded according to KubeSpawner's rules
#
# For more information regarding JupyterHub KubeSpawner and its configuration:
# https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html

spawnerFormDefaults:
image:
# The container Image for the user's Jupyter Notebook
# If readonly, this value must be a member of the list below
value: gcr.io/kubeflow-images-public/tensorflow-1.10.1-notebook-cpu:v0.4.0
# The list of available standard container Images
options:
- gcr.io/kubeflow-images-public/tensorflow-1.4.1-notebook-cpu:v0.4.0
- gcr.io/kubeflow-images-public/tensorflow-1.4.1-notebook-gpu:v0.4.0
- gcr.io/kubeflow-images-public/tensorflow-1.5.1-notebook-cpu:v0.4.0
- gcr.io/kubeflow-images-public/tensorflow-1.5.1-notebook-gpu:v0.4.0
- gcr.io/kubeflow-images-public/tensorflow-1.6.0-notebook-cpu:v0.4.0
- gcr.io/kubeflow-images-public/tensorflow-1.6.0-notebook-gpu:v0.4.0
- gcr.io/kubeflow-images-public/tensorflow-1.7.0-notebook-cpu:v0.4.0
- gcr.io/kubeflow-images-public/tensorflow-1.7.0-notebook-gpu:v0.4.0
- gcr.io/kubeflow-images-public/tensorflow-1.8.0-notebook-cpu:v0.4.0
- gcr.io/kubeflow-images-public/tensorflow-1.8.0-notebook-gpu:v0.4.0
- gcr.io/kubeflow-images-public/tensorflow-1.9.0-notebook-cpu:v0.4.0
- gcr.io/kubeflow-images-public/tensorflow-1.9.0-notebook-gpu:v0.4.0
- gcr.io/kubeflow-images-public/tensorflow-1.10.1-notebook-cpu:v0.4.0
- gcr.io/kubeflow-images-public/tensorflow-1.10.1-notebook-gpu:v0.4.0
# By default, custom container Images are allowed
# Uncomment the following line to only enable standard container Images
readOnly: false
cpu:
# CPU for user's Notebook
value: '0.5'
# readOnly: true
memory:
# Memory for user's Notebook
value: 1.0Gi
workspaceVolume:
# Workspace Volume to be attached to user's Notebook
# Each Workspace Volume is declared with the following attributes:
# Type, Name, Size, MountPath and Access Mode
value:
type:
# The Type of the Workspace Volume
# Supported values: 'New', 'Existing'
value: New
name:
# The Name of the Workspace Volume
# Note that this is a templated value
# value: {username}-workspace
value: {username}-workspace
size:
# The Size of the Workspace Volume (in Gi)
value: '10'
mountPath:
# The Path that the Workspace Volume will be mounted
readOnly: true
value: /home/jovyan
accessModes:
# The Access Mode of the Workspace Volume
# Supported values: 'ReadWriteOnce', 'ReadWriteMany', 'ReadOnlyMany'
value: ReadWriteOnce
dataVolumes:
# List of additional Data Volumes to be attached to the user's Notebook
value: []
# Each Data Volume is declared with the following attributes:
# Type, Name, Size, MountPath and Access Mode
#
# For example, a list with 2 Data Volumes:
#value:
# - value:
# type:
# value: New
# name:
# value: {username}-vol-1
# size:
# value: '10'
# mountPath:
# value: /home/jovyan/{username}-vol-1
# accessModes:
# value: ReadWriteOnce
# - value:
# type:
# value: New
# name:
# value: {username}-vol-2
# size:
# value: '5'
# mountPath:
# value: /home/jovyan/{username}-vol-2
# accessModes:
# value: ReadWriteOnce
#
# Uncomment the following line to make the Data Volumes list readonly
#readOnly: true
extraResources:
# Extra Resource Limits for user's Notebook
# Note that braces are escaped
value: "{{}}"
180 changes: 180 additions & 0 deletions kubeflow/jupyter/jupyter-web-app.libsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
{
local k = import "k.libsonnet",
local util = import "kubeflow/common/util.libsonnet",

new(_env, _params):: {
local params = _env + _params,

local defaultSpawnerData = {
// Default JH Spawner UI files
"spawner_ui_config.yaml": importstr "./config.yaml",
},

local jupyterConfig = {
apiVersion: "v1",
kind: "ConfigMap",
metadata: {
name: "jupyter-ui-config",
namespace: params.namespace,
},
data: defaultSpawnerData,
},
jupyterConfig:: jupyterConfig,

serviceAccount:: {
apiVersion: "v1",
kind: "ServiceAccount",
metadata: {
labels: {
app: params.name,
},
name: params.name,
namespace: params.namespace,
},
},

clusterRole:: {
apiVersion: "rbac.authorization.k8s.io/v1",
kind: "ClusterRole",
metadata: {
name: params.name + "-cluster-role",
},
rules: [
{
apiGroups: [""],
resources: ["namespaces"],
verbs: ["get", "list", "create", "delete"]
},
{
apiGroups: ["kubeflow.org"],
resources: ["notebooks"],
verbs: ["get", "list", "create", "delete"],
},
{
apiGroups: [""],
resources: ["persistentvolumeclaims"],
verbs: ["create", "delete", "get", "list"],
},
]
},

clusterRoleBinding:: {
kind: "ClusterRoleBinding",
apiVersion: "rbac.authorization.k8s.io/v1",
metadata: {
name: params.name + "-binding"
},
subjects: [
{
kind: "ServiceAccount",
name: params.name,
namespace: params.namespace
},
],
roleRef: {
kind: "ClusterRole",
name: params.name + "-cluster-role",
apiGroup: "rbac.authorization.k8s.io",
},
},

svc:: {
apiVersion: "v1",
kind: "Service",
metadata: {
name: params.name,
labels: {
run: params.name
},
annotations:{
"getambassador.io/config":
std.join("\n", [
"---",
"apiVersion: ambassador/v0",
"kind: Mapping",
"name: webapp_mapping",
"prefix: /" + params.prefix + "/",
"service: " + params.name + "." + params.namespace,
"add_request_headers: ",
" x-forwarded-prefix: /" + params.prefix
]),
},
},
spec: {
type: "ClusterIP",
ports: [{
port: 80,
targetPort: 5000,
protocol: "TCP",
name: "http",
}],
selector: {
app: params.name
},
},
},

depl :: {
apiVersion: "apps/v1",
kind: "Deployment",
metadata: {
name: params.name,
labels: {
app: params.name,
},
},
spec: {
replicas: 1,
selector: {
matchLabels: {
app: params.name,
},
},
template: {
metadata:{
labels: {
app: params.name,
},
},
spec: {
serviceAccountName: params.name,
containers: [{
name: params.name,
image: params.image,
volumeMounts: [
{
mountPath: "/etc/config",
name: "config-volume",
},
],
ports: [{
containerPort: 5000,
}],
imagePullPolicy: params.policy,
}],
volumes: [
{
configMap: {
name: "jupyter-ui-config",
},
name: "config-volume",
},
],
},
},
},
},

parts:: self,
all:: [
self.svc,
self.depl,
self.jupyterConfig,
self.serviceAccount,
self.clusterRoleBinding,
self.clusterRole,
],

list(obj=self.all):: util.list(obj),
},
}
13 changes: 13 additions & 0 deletions kubeflow/jupyter/prototypes/jupyter-web-app.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// @apiVersion 0.1
// @name io.ksonnet.pkg.jupyter-web-app
// @shortDescription A WebApp that controlls Jupyter Notebooks
// @param name string Name to give to the Jupyter UI
// @optionalParam image string jupyter-web-app/image Docker Image used for the Jupyter UI
// @optionalParam port string 80 Port to expose the UI's Service
// @optionalParam policy string IfNotPresent imagePullPolicy for the UI's image
// @optionalParam prefix string jupyter The prefix under which the app is accessed

local jupyter_ui = import "kubeflow/jupyter/jupyter-web-app.libsonnet";

local instance = jupyter_ui.new(env, params);
instance.list(instance.all)
2 changes: 1 addition & 1 deletion scripts/kfctl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ source "${DIR}/gke/util.sh"
source "${DIR}/util-minikube.sh"
INPUT=()
FORMAT=()
export KUBEFLOW_COMPONENTS=${DEFAULT_KUBEFLOW_COMPONENTS:-'"ambassador","jupyter","centraldashboard","tf-job-operator","pytorch-operator","spartakus","argo","pipeline"'}
export KUBEFLOW_COMPONENTS=${DEFAULT_KUBEFLOW_COMPONENTS:-'"ambassador","jupyter","centraldashboard","tf-job-operator","pytorch-operator","spartakus","argo","pipeline","jupyter-web-app","notebooks"'}
export KUBEFLOW_EXTENDEDINFO=${KUBEFLOW_EXTENDEDINFO:-false}

# envsubst alternative if envsubst is not installed
Expand Down
1 change: 1 addition & 0 deletions scripts/util.sh
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ createKsApp() {
ks generate ambassador ambassador
ks generate openvino openvino
ks generate jupyter jupyter
ks generate jupyter-web-app jupyter-web-app
ks generate centraldashboard centraldashboard
ks generate tf-job-operator tf-job-operator
ks generate tensorboard tensorboard
Expand Down

0 comments on commit 0617c83

Please sign in to comment.