Commit c690bae6 authored by Will JALLET's avatar Will JALLET 💸

Upgrade jupyterhub chart

parent d1c9fce2
Pipeline #4516 passed with stage
in 13 seconds
appVersion: v0.8.1
appVersion: 0.9.3
description: Multi-user Jupyter installation
home: https://z2jh.jupyter.org
icon: https://jupyter.org/assets/hublogo.svg
......@@ -6,5 +6,5 @@ kubeVersion: '>=1.8.0-0'
name: jupyterhub
sources:
- https://github.com/jupyterhub/zero-to-jupyterhub-k8s
tillerVersion: '>=2.7.0-0'
version: v0.7-560a7cd
tillerVersion: '>=2.9.1-0'
version: 0.8-c0b4dcf
......@@ -9,10 +9,10 @@ properties:
- string
- "null"
description: |
A 64-byte cryptographically secure randomly generated string used to sign values of
A 32-byte cryptographically secure randomly generated string used to sign values of
secure cookies set by the hub. If unset, jupyterhub will generate one on startup and
save it in the file `jupyterhub_cookie_secret` in the `/srv/jupyterhub` directory of
the hub container. Value set here will override the value in `jupyterhub_cookie_secret`.
the hub container. A value set here will make JupyterHub overwrite any previous file.
You do not need to set this at all if you are using the default configuration for
storing databases - sqlite on a persistent volume (with `hub.db.type` set to the
......@@ -20,10 +20,13 @@ properties:
value explicitly - or your users will keep getting logged out each time the hub pod
restarts.
This must be generated with `openssl rand -hex 32`.
Changing this value will all user logins to be invalidated. If this secret leaks,
*immediately* change it to something else, or user data can be compromised
```sh
# to generate a value, run
openssl rand -hex 32
```
imagePullPolicy:
type: string
enum:
......@@ -33,7 +36,7 @@ properties:
description: |
Set the imagePullPolicy on the hub pod.
See [the kubernetes docs](https://kubernetes.io/docs/concepts/containers/images/#updating-images)
See the [Kubernetes docs](https://kubernetes.io/docs/concepts/containers/images/#updating-images)
for more info on what the values mean.
image:
type: object
......@@ -49,15 +52,23 @@ properties:
description: |
Name of the image, without the tag.
Examples:
- yuvipanda/wikimedia-hub
- gcr.io/my-project/my-hub
```
# example names
yuvipanda/wikimedia-hub
gcr.io/my-project/my-hub
```
tag:
type: string
description: |
The tag of the image to pull.
This is the value after the `:` in your full image name.
```
# example tags
v1.11.1
zhy270a
```
db:
type: object
properties:
......@@ -80,9 +91,11 @@ properties:
Use an `sqlite` database kept on a persistent volume attached to the hub.
By default, this disk is dynamically created using the default
[dynamic provisioner]. You can customize how this disk is created / attached
by setting various properties under `hub.db.pvc`.
By default, this disk is created by the cloud provider using
*dynamic provisioning* configured by a [storage
class](https://kubernetes.io/docs/concepts/storage/storage-classes/).
You can customize how this disk is created / attached by
setting various properties under `hub.db.pvc`.
This is the default setting, and should work well for most cloud provider
deployments.
......@@ -99,7 +112,7 @@ properties:
3. **mysql**
Use an externaly hosted mysql database.
Use an externally hosted mysql database.
You have to specify an sqlalchemy connection string for the mysql database you
want to connect to in `hub.db.url` if using this option.
......@@ -116,7 +129,7 @@ properties:
4. **postgres**
Use an externaly hosted postgres database.
Use an externally hosted postgres database.
You have to specify an sqlalchemy connection string for the postgres database you
want to connect to in `hub.db.url` if using this option.
......@@ -132,7 +145,7 @@ properties:
Note that if you use this, you *must* also set `hub.cookieSecret`.
pvc:
type: object
descripton: |
description: |
Customize the Persistent Volume Claim used when `hub.db.type` is `sqlite-pvc`.
properties:
annotations:
......@@ -140,15 +153,21 @@ properties:
description: |
Annotations to apply to the PVC containing the sqlite database.
TODO: Link to pvc annotations
See [the Kubernetes
documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/)
for more details about annotations.
selector:
type: object
description: |
Selectors to set for the PVC containing the sqlite database.
Label selectors to set for the PVC containing the sqlite database.
Useful when you are using a static PVC.
Useful when you are using a specific PV, and want to bind to
that and only that.
TODO: Link to pvc selector docs.
See [the Kubernetes
documentation](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims)
for more details about using a label selector for what PV to
bind to.
storage:
type: string
description: |
......@@ -166,7 +185,7 @@ properties:
description: |
Extra labels to add to the hub pod.
See [the kubernetes documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)
See the [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)
to learn more about labels.
extraEnv:
type: list
......@@ -198,7 +217,7 @@ properties:
[| operator](http://www.yaml.org/spec/1.2/spec.html#id2795688).
For example:
```
```yaml
hub:
extraConfig: |
c.JupyterHub.something = 'something'
......@@ -236,10 +255,13 @@ properties:
secretToken:
type: string
description: |
A 64-byte cryptographically secure randomly generated string used to secure communications
A 32-byte cryptographically secure randomly generated string used to secure communications
between the hub and the configurable-http-proxy.
This must be generated with `openssl rand -hex 32`.
```sh
# to generate a value, run
openssl rand -hex 32
```
Changing this value will cause the proxy and hub pods to restart. It is good security
practice to rotate these values over time. If this secret leaks, *immediately* change
......@@ -247,6 +269,7 @@ properties:
required:
- secretToken
auth:
type: object
properties:
......@@ -265,13 +288,17 @@ properties:
description: |
auth_state will be encrypted and stored in the Hub’s database. This can include things like authentication tokens, etc. to be passed to Spawners as environment variables.
Encrypting auth_state requires the cryptography package.
It must contain one (or more, separated by ;) 32B encryption keys. These can be either base64 or hex-encoded.
It must contain one (or more, separated by ;) 32-byte encryption keys. These can be either base64 or hex-encoded.
The JUPYTERHUB_CRYPT_KEY environment variable for the hub pod is set using this entry.
This can be generated with `openssl rand -hex 32`.
```sh
# to generate a value, run
openssl rand -hex 32
```
If encryption is unavailable, auth_state cannot be persisted.
singleuser:
type: object
description: |
......@@ -285,26 +312,115 @@ properties:
properties:
limit:
type:
- string
- "null"
- string
- "null"
guarantee:
type:
- string
- "null"
- string
- "null"
memory:
type: object
description: |
Set Memory limits & guarantees that are enforced for each user.
See: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
See the [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container)
for more info.
properties:
limit:
type:
- string
- "null"
- string
- "null"
guarantee:
type:
- string
- "null"
- string
- "null"
description: |
Note that this field is referred to as *requests* by the Kubernetes API.
imagePullSecret:
type: object
description: |
Creates an image pull secret for you and makes the user pods utilize
it, allowing them to pull images from private image registries.
Using this configuration option automates the following steps that
normally is required to pull from private image registries.
```sh
# you won't need to run this manually...
kubectl create secret docker-registry singleuser-image-credentials \
--docker-server=<REGISTRY> \
--docker-username=<USERNAME> \
--docker-email=<EMAIL> \
--docker-password=<PASSWORD>
```
```yaml
# you won't need to specify this manually...
spec:
imagePullSecrets:
- name: singleuser-image-credentials
```
To learn the username and password fields to access a gcr.io registry
from a Kubernetes cluster not associated with the same google cloud
credentials, look into [this
guide](http://docs.heptio.com/content/private-registries/pr-gcr.html)
and read the notes about the password.
properties:
enabled:
type: boolean
description: |
Enable the creation of a Kubernetes Secret containing credentials
to access a image registry. By enabling this, user pods and image
puller pods will also be configured to use these credentials when
they pull their container images.
registry:
type: string
description: |
Name of the private registry you want to create a credential set
for. It will default to Docker Hub's image registry.
Examples:
- https://index.docker.io/v1/
- quay.io
- eu.gcr.io
- alexmorreale.privatereg.net
username:
type: string
description: |
Name of the user you want to use to connect to your private
registry. For external gcr.io, you will use the `_json_key`.
Examples:
- alexmorreale
- alex@pfc.com
- _json_key
password:
type: string
description: |
Password of the user you want to use to connect to your private
registry.
Examples:
- plaintextpassword
- abc123SECRETzyx098
For gcr.io registries the password will be a big JSON blob for a
Google cloud service account, it should look something like below.
```yaml
password: |-
{
"type": "service_account",
"project_id": "jupyter-se",
"private_key_id": "f2ba09118a8d3123b3321bd9a7d6d0d9dc6fdb85",
...
}
```
Learn more in [this
guide](http://docs.heptio.com/content/private-registries/pr-gcr.html).
image:
type: object
description: |
......@@ -326,3 +442,218 @@ properties:
The tag of the image to use.
This is the value after the `:` in your full image name.
pullPolicy:
type: string
enum:
- IfNotPresent
- Always
- Never
description: |
Set the imagePullPolicy on the singleuser pods that are spun up by the hub.
See the [Kubernetes docs](https://kubernetes.io/docs/concepts/containers/images/#updating-images)
for more info.
schedulerStrategy:
type:
- string
- "null"
description: |
Deprecated and no longer does anything. Use the user-scheduler instead
in order to accomplish a good packing of the user pods.
extraTolerations:
type: list
description: |
Tolerations allow a pod to be scheduled on nodes with taints. These
are additional tolerations other than the user pods and core pods
default ones `hub.jupyter.org/dedicated=user:NoSchedule` or
`hub.jupyter.org/dedicated=core:NoSchedule`. Note that a duplicate set
of tolerations exist where `/` is replaced with `_` as the Google
cloud does not support the character `/` yet in the toleration.
See the [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/)
for more info.
Pass this field an array of
[`Toleration`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#toleration-v1-core)
objects.
extraNodeAffinity:
type: object
description: |
Affinities describe where pods prefer or require to be scheduled, they
may prefer or require a node where they are to be scheduled to have a
certain label (node affinity). They may also require to be scheduled
in proximity or with a lack of proximity to another pod (pod affinity
and anti pod affinity).
See the [Kubernetes
docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/)
for more info.
properties:
required:
type: list
description: |
Pass this field an array of
[`NodeSelectorTerm`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#nodeselectorterm-v1-core)
objects.
preferred:
type: list
description: |
Pass this field an array of
[`PreferredSchedulingTerm`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#preferredschedulingterm-v1-core)
objects.
extraPodAffinity:
type: object
description: |
See the description of `singleuser.extraNodeAffinity`.
properties:
required:
type: list
description: |
Pass this field an array of
[`PodAffinityTerm`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#podaffinityterm-v1-core)
objects.
preferred:
type: list
description: |
Pass this field an array of
[`WeightedPodAffinityTerm`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#weightedpodaffinityterm-v1-core)
objects.
extraPodAntiAffinity:
type: object
description: |
See the description of `singleuser.extraNodeAffinity`.
properties:
required:
type: list
description: |
Pass this field an array of
[`PodAffinityTerm`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#podaffinityterm-v1-core)
objects.
preferred:
type: list
description: |
Pass this field an array of
[`WeightedPodAffinityTerm`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#weightedpodaffinityterm-v1-core)
objects.
scheduling:
type: object
description: |
Objects for customizing the scheduling of various pods on the nodes and
related labels.
properties:
userScheduler:
type: object
description: |
The user scheduler is making sure that user pods are scheduled
tight on nodes, this is useful for autoscaling of user node pools.
properties:
enabled:
type: boolean
description: |
Enables the user scheduler.
replicas:
type: integer
description: |
You can have multiple schedulers to share the workload or improve
availability on node failure.
image:
type: object
description: |
The image containing the [kube-scheduler
binary](https://console.cloud.google.com/gcr/images/google-containers/GLOBAL/kube-scheduler-amd64).
properties:
name:
type: string
tag:
type:
- string
- "null"
podPriority:
type: object
description: |
Generally available since Kubernetes 1.11, Pod Priority is used to
allow real users evict placeholder pods.
properties:
enabled:
type: bool
description: |
Generally available since Kubernetes 1.11, Pod Priority is used to
allow real users evict placeholder pods.
userPlaceholder:
type: object
description: |
User placeholders simulate users but will thanks to PodPriority be
evicted by the cluster autoscaler if a real user shows up. In this way
placeholders allow you to create a headroom for the real users and
reduce the risk of a user having to wait for a node to be added. Be
sure to use the the continuous image puller as well along with
placeholders, so the images are also available when real users arrive.
To test your setup efficiently, you can adjust the amount of user
placeholders with the following command:
```sh
# Configure to have 3 user placeholders
kubectl scale sts/user-placeholder --replicas=3
```
properties:
enabled:
type: bool
replicas:
type: int
description: |
How many placeholder pods would you like to have?
resources:
type: object
description: |
Unless specified here, the placeholder pods will request the same
resources specified for the real singleuser pods.
corePods:
type: object
description: |
These settings influence the core pods like the hub, proxy and
user-scheduler pods.
properties:
nodeAffinity:
type: object
description: |
Where should pods be scheduled? Perhaps on nodes with a certain
label is preferred or even required?
properties:
matchNodePurpose:
type: string
enum:
- ignore
- prefer
- require
description: |
Decide if core pods *ignore*, *prefer* or *require* to
schedule on nodes with this label:
```
hub.jupyter.org/node-purpose=core
```
userPods:
type: object
description: |
These settings influence the user pods like the user-placeholder,
user-dummy and actual user pods named like jupyter-someusername.
properties:
nodeAffinity:
type: object
description: |
Where should pods be scheduled? Perhaps on nodes with a certain
label is preferred or even required?
properties:
matchNodePurpose:
type: string
enum:
- ignore
- prefer
- require
description: |
Decide if user pods *ignore*, *prefer* or *require* to
schedule on nodes with this label:
```
hub.jupyter.org/node-purpose=user
```
......@@ -9,7 +9,7 @@
generate some output based on one single dictionary of input that we call the
helpers scope. When you are in helm, you access your current scope with a
single a single punctuation (.).
When you ask a helper to render its content, one often forward the current
scope to the helper in order to allow it to access .Release.Name,
.Values.rbac.enabled and similar values.
......@@ -27,7 +27,7 @@
To let a helper access the current scope along with additional values we have
opted to create dictionary containing additional values that is then populated
with additional values from the current scope through a the merge function.
#### Example - Passing a new scope augmented with the old
{{- $_ := merge (dict "appLabel" "kube-lego") . }}
{{- include "jupyterhub.matchLabels" $_ | nindent 6 }}
......@@ -55,7 +55,7 @@
## Example usage
```yaml
# Excerpt from proxy/autohttps/deployment.yaml
apiVersion: apps/v1beta2
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "jupyterhub.nameField" . }}
......@@ -97,7 +97,7 @@
Used by "jupyterhub.labels" and "jupyterhub.nameField".
NOTE: The component label is determined by either...
- 1: The provided scope's .componentLabel
- 1: The provided scope's .componentLabel
- 2: The template's filename if living in the root folder
- 3: The template parent folder's name
- : ...and is combined with .componentPrefix and .componentSuffix
......@@ -163,12 +163,77 @@ component: {{ include "jupyterhub.componentLabel" . }}
{{- /*
jupyterhub.podCullerSelector:
Used to by the pod-culler to select singleuser-server pods. It simply
reformats "jupyterhub.matchLabels" and sets the componentLabel value so
`component=singleuser-server` is output.
jupyterhub.dockerconfigjson:
Creates a base64 encoded docker registry json blob for use in a image pull
secret, just like the `kubectl create secret docker-registry` command does
for the generated secrets data.dockerconfigjson field. The output is
verified to be exactly the same even if you have a password spanning
multiple lines as you may need to use a private GCR registry.
- https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
*/}}
{{- define "jupyterhub.podCullerSelector" -}}
{{- $_ := merge (dict "componentLabel" "singleuser-server") . -}}
{{ include "jupyterhub.matchLabels" $_ | replace ": " "=" | replace "\n" "," | quote }}
{{- define "jupyterhub.dockerconfigjson" -}}
{{ include "jupyterhub.dockerconfigjson.yaml" . | b64enc }}
{{- end }}
{{- define "jupyterhub.dockerconfigjson.yaml" -}}
{{- with .Values.singleuser.imagePullSecret -}}
{
"auths": {
{{ .registry | default "https://index.docker.io/v1/" | quote }}: {
"username": {{ .username | quote }},
"password": {{ .password | quote }},
{{- if .email }}
"email": {{ .email | quote }},
{{- end }}
"auth": {{ (print .username ":" .password) | b64enc | quote }}
}
}
}
{{- end }}
{{- end }}
{{- /*
jupyterhub.resources:
The resource request of a singleuser.
*/}}
{{- define "jupyterhub.resources" -}}
{{- $r1 := .Values.singleuser.cpu.guarantee -}}
{{- $r2 := .Values.singleuser.memory.guarantee -}}
{{- $r3 := .Values.singleuser.extraResource.guarantees -}}
{{- $r := or $r1 $r2 $r3 -}}
{{- $l1 := .Values.singleuser.cpu.limit -}}
{{- $l2 := .Values.singleuser.memory.limit -}}
{{- $l3 := .Values.singleuser.extraResource.limits -}}
{{- $l := or $l1 $l2 $l3 -}}
{{- if $r -}}
requests:
{{- if $r1 }}
cpu: {{ .Values.singleuser.cpu.guarantee }}
{{- end }}
{{- if $r2 }}
memory: {{ .Values.singleuser.memory.guarantee }}
{{- end }}
{{- if $r3 }}
{{- range $key, $value := .Values.singleuser.extraResource.guarantees }}
{{ $key | quote }}: {{ $value | quote }}
{{- end }}
{{- end }}
{{- end }}
{{- if $l }}
limits:
{{- if $l1 }}
cpu: {{ .Values.singleuser.cpu.limit }}
{{- end }}
{{- if $l2 }}
memory: {{ .Values.singleuser.memory.limit }}
{{- end }}
{{- if $l3 }}
{{- range $key, $value := .Values.singleuser.extraResource.limits }}
{{ $key | quote }}: {{ $value | quote }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
......@@ -12,6 +12,7 @@ data:
cull.timeout: {{ .Values.cull.timeout | quote }}
cull.every: {{ .Values.cull.every | quote }}
cull.concurrency: {{ .Values.cull.concurrency | quote }}
cull.max-age: {{ .Values.cull.maxAge | quote }}
{{- end }}
......@@ -67,10 +68,11 @@ data:
auth.gitlab.client-secret: {{ .Values.auth.gitlab.clientSecret | quote }}
auth.gitlab.callback-url: {{ .Values.auth.gitlab.callbackUrl | quote }}
{{- end }}
{{- if eq .Values.auth.type "mediawiki" }}
auth.mediawiki.client-id: {{ .Values.auth.mediawiki.clientId | quote }}
auth.mediawiki.client-secret: {{ .Values.auth.mediawiki.clientSecret | quote }}
auth.mediawiki.callback-url: {{ .Values.auth.mediawiki.callbackUrl | quote }}
auth.mediawiki.index-url: {{ .Values.auth.mediawiki.indexUrl | quote }}
{{- end }}
......@@ -80,7 +82,7 @@ data:
auth.globus.callback-url: {{ .Values.auth.globus.callbackUrl | quote }}
auth.globus.identity-provider: {{ .Values.auth.globus.identityProvider | quote }}
{{- end }}
{{- if eq .Values.auth.type "lti" }}
auth.lti.consumers: |
{{- .Values.auth.lti.consumers | toYaml | trimSuffix "\n" | nindent 4 }}
......@@ -108,7 +110,7 @@ data:
auth.ldap.dn.user.search-base: {{ .Values.auth.ldap.dn.user.searchBase | quote }}