Skip to content

Instantly share code, notes, and snippets.

@luong-komorebi
Created October 26, 2022 15:07
Show Gist options
  • Save luong-komorebi/f64bb955e0528c44611af0882d858629 to your computer and use it in GitHub Desktop.
Save luong-komorebi/f64bb955e0528c44611af0882d858629 to your computer and use it in GitHub Desktop.
jupyterhub schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"additionalProperties": false,
"required": [
"imagePullSecrets",
"hub",
"proxy",
"singleuser",
"ingress",
"prePuller",
"custom",
"cull",
"debug",
"rbac",
"global"
],
"properties": {
"fullnameOverride": {
"type": [
"string",
"null"
],
"description": "fullnameOverride and nameOverride allow you to adjust how the resources\npart of the Helm chart are named.\n\nName format | Resource types | fullnameOverride | nameOverride | Note\n------------------------- | -------------- | ---------------- | ------------ | -\ncomponent | namespaced | `\"\"` | * | Default\nrelease-component | cluster wide | `\"\"` | * | Default\nfullname-component | * | str | * | -\nrelease-component | * | null | `\"\"` | -\nrelease-(name-)component | * | null | str | omitted if contained in release\nrelease-(chart-)component | * | null | null | omitted if contained in release\n\n```{admonition} Warning!\n:class: warning\nChanging fullnameOverride or nameOverride after the initial installation\nof the chart isn't supported. Changing their values likely leads to a\nreset of non-external JupyterHub databases, abandonment of users' storage,\nand severed couplings to currently running user pods.\n```\n\nIf you are a developer of a chart depending on this chart, you should\navoid hardcoding names. If you want to reference the name of a resource in\nthis chart from a parent helm chart's template, you can make use of the\nglobal named templates instead.\n\n```yaml\n# some pod definition of a parent chart helm template\nschedulerName: {{ include \"jupyterhub.user-scheduler.fullname\" . }}\n```\n\nTo access them from a container, you can also rely on the hub ConfigMap\nthat contains entries of all the resource names.\n\n```yaml\n# some container definition in a parent chart helm template\nenv:\n - name: SCHEDULER_NAME\n valueFrom:\n configMapKeyRef:\n name: {{ include \"jupyterhub.user-scheduler.fullname\" . }}\n key: user-scheduler\n```\n"
},
"nameOverride": {
"type": [
"string",
"null"
],
"description": "See the documentation under [`fullnameOverride`](schema_fullnameOverride).\n"
},
"imagePullSecret": {
"type": "object",
"required": [
"create"
],
"if": {
"properties": {
"create": {
"const": true
}
}
},
"then": {
"additionalProperties": false,
"required": [
"registry",
"username",
"password"
],
"description": "This is configuration to create a k8s Secret resource of `type:\nkubernetes.io/dockerconfigjson`, with credentials to pull images from a\nprivate image registry. If you opt to do so, it will be available for use\nby all pods in their respective `spec.imagePullSecrets` alongside other\nk8s Secrets defined in `imagePullSecrets` or the pod respective\n`...image.pullSecrets` configuration.\n\nIn other words, using this configuration option can automate both the\notherwise manual creation of a k8s Secret and the otherwise manual\nconfiguration to reference this k8s Secret in all the pods of the Helm\nchart.\n\n```sh\n# you won't need to create a k8s Secret manually...\nkubectl create secret docker-registry image-pull-secret \\\n --docker-server=<REGISTRY> \\\n --docker-username=<USERNAME> \\\n --docker-email=<EMAIL> \\\n --docker-password=<PASSWORD>\n```\n\nIf you just want to let all Pods reference an existing secret, use the\n[`imagePullSecrets`](schema_imagePullSecrets) configuration instead.\n",
"properties": {
"create": {
"type": "boolean",
"description": "Toggle the creation of the k8s Secret with provided credentials to\naccess a private image registry.\n"
},
"automaticReferenceInjection": {
"type": "boolean",
"description": "Toggle the automatic reference injection of the created Secret to all\npods' `spec.imagePullSecrets` configuration.\n"
},
"registry": {
"type": "string",
"description": "Name of the private registry you want to create a credential set for.\nIt will default to Docker Hub's image registry.\n\nExamples:\n - https://index.docker.io/v1/\n - quay.io\n - eu.gcr.io\n - alexmorreale.privatereg.net\n"
},
"username": {
"type": "string",
"description": "Name of the user you want to use to connect to your private registry.\n\nFor external gcr.io, you will use the `_json_key`.\n\nExamples:\n - alexmorreale\n - alex@pfc.com\n - _json_key\n"
},
"password": {
"type": "string",
"description": "Password for the private image registry's user.\n\nExamples:\n - plaintextpassword\n - abc123SECRETzyx098\n\nFor gcr.io registries the password will be a big JSON blob for a\nGoogle cloud service account, it should look something like below.\n\n```yaml\npassword: |-\n {\n \"type\": \"service_account\",\n \"project_id\": \"jupyter-se\",\n \"private_key_id\": \"f2ba09118a8d3123b3321bd9a7d6d0d9dc6fdb85\",\n ...\n }\n```\n"
},
"email": {
"type": [
"string",
"null"
],
"description": "Specification of an email is most often not required, but it is\nsupported.\n"
}
}
}
},
"imagePullSecrets": {
"type": "array",
"description": "Chart wide configuration to _append_ k8s Secret references to all its\npod's `spec.imagePullSecrets` configuration.\n\nThis will not override or get overridden by pod specific configuration,\nbut instead augment the pod specific configuration.\n\nYou can use both the k8s native syntax, where each list element is like\n`{\"name\": \"my-secret-name\"}`, or you can let list elements be strings\nnaming the secrets directly.\n"
},
"hub": {
"type": "object",
"additionalProperties": false,
"required": [
"baseUrl"
],
"properties": {
"revisionHistoryLimit": {
"type": [
"integer",
"null"
],
"minimum": 0,
"description": "Configures the resource's `spec.revisionHistoryLimit`. This is\navailable for Deployment, StatefulSet, and DaemonSet resources.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#revision-history-limit)\nfor more info.\n"
},
"config": {
"type": "object",
"additionalProperties": true,
"description": "JupyterHub and its components (authenticators, spawners, etc), are\nPython classes that expose its configuration through\n[_traitlets_](https://traitlets.readthedocs.io/en/stable/). With this\nHelm chart configuration (`hub.config`), you can directly configure\nthe Python classes through _static_ YAML values. To _dynamically_ set\nvalues, you need to use [`hub.extraConfig`](schema_hub.extraConfig)\ninstead.\n\n```{admonition} Currently intended only for auth config\n:class: warning\nThis config _currently_ (0.11.0) only influence the software in the\n`hub` Pod, but some Helm chart config options such as\n[`hub.baseUrl`](schema_hub.baseUrl) is used to set\n`JupyterHub.base_url` in the `hub` Pod _and_ influence how other Helm\ntemplates are rendered.\n\nAs we have not yet mapped out all the potential configuration\nconflicts except for the authentication related configuration options,\nplease accept that using it for something else at this point can lead\nto issues.\n```\n\n__Example__\n\nIf you inspect documentation or some `jupyterhub_config.py` to contain\nthe following section:\n\n```python\nc.JupyterHub.admin_access = true\nc.JupyterHub.admin_users = [\"jovyan1\", \"jovyan2\"]\n```\n\nThen, you would be able to represent it with this configuration like:\n\n```yaml\nhub:\n config:\n JupyterHub:\n admin_access: true\n admin_users:\n - jovyan1\n - jovyan2\n```\n\n```{admonition} YAML limitations\n:class: tip\nYou can't represent Python `Bytes` or `Set` objects in YAML directly.\n```\n\n```{admonition} Helm value merging\n:class: tip\n`helm` merges a Helm chart's default values with values passed with\nthe `--values` or `-f` flag. During merging, lists are replaced while\ndictionaries are updated.\n```\n"
},
"extraFiles": {
"type": "object",
"additionalProperties": false,
"description": "A dictionary with extra files to be injected into the pod's container\non startup. This can for example be used to inject: configuration\nfiles, custom user interface templates, images, and more.\n\n```yaml\n# NOTE: \"hub\" is used in this example, but the configuration is the\n# same for \"singleuser\".\nhub:\n extraFiles:\n # The file key is just a reference that doesn't influence the\n # actual file name.\n <file key>:\n # mountPath is required and must be the absolute file path.\n mountPath: <full file path>\n\n # Choose one out of the three ways to represent the actual file\n # content: data, stringData, or binaryData.\n #\n # data should be set to a mapping (dictionary). It will in the\n # end be rendered to either YAML, JSON, or TOML based on the\n # filename extension that are required to be either .yaml, .yml,\n # .json, or .toml.\n #\n # If your content is YAML, JSON, or TOML, it can make sense to\n # use data to represent it over stringData as data can be merged\n # instead of replaced if set partially from separate Helm\n # configuration files.\n #\n # Both stringData and binaryData should be set to a string\n # representing the content, where binaryData should be the\n # base64 encoding of the actual file content.\n #\n data:\n myConfig:\n myMap:\n number: 123\n string: \"hi\"\n myList:\n - 1\n - 2\n stringData: |\n hello world!\n binaryData: aGVsbG8gd29ybGQhCg==\n\n # mode is by default 0644 and you can optionally override it\n # either by octal notation (example: 0400) or decimal notation\n # (example: 256).\n mode: <file system permissions>\n```\n\n**Using --set-file**\n\nTo avoid embedding entire files in the Helm chart configuration, you\ncan use the `--set-file` flag during `helm upgrade` to set the\nstringData or binaryData field.\n\n```yaml\nhub:\n extraFiles:\n my_image:\n mountPath: /usr/local/share/jupyterhub/static/my_image.png\n\n # Files in /usr/local/etc/jupyterhub/jupyterhub_config.d are\n # automatically loaded in alphabetical order of the final file\n # name when JupyterHub starts.\n my_config:\n mountPath: /usr/local/etc/jupyterhub/jupyterhub_config.d/my_jupyterhub_config.py\n```\n\n```bash\n# --set-file expects a text based file, so you need to base64 encode\n# it manually first.\nbase64 my_image.png > my_image.png.b64\n\nhelm upgrade <...> \\\n --set-file hub.extraFiles.my_image.binaryData=./my_image.png.b64 \\\n --set-file hub.extraFiles.my_config.stringData=./my_jupyterhub_config.py\n```\n\n**Common uses**\n\n1. **JupyterHub template customization**\n\n You can replace the default JupyterHub user interface templates in\n the hub pod by injecting new ones to\n `/usr/local/share/jupyterhub/templates`. These can in turn\n reference custom images injected to\n `/usr/local/share/jupyterhub/static`.\n\n1. **JupyterHub standalone file config**\n\n Instead of embedding JupyterHub python configuration as a string\n within a YAML file through\n [`hub.extraConfig`](schema_hub.extraConfig), you can inject a\n standalone .py file into\n `/usr/local/etc/jupyterhub/jupyterhub_config.d` that is\n automatically loaded.\n\n1. **Flexible configuration**\n\n By injecting files, you don't have to embed them in a docker image\n that you have to rebuild.\n\n If your configuration file is a YAML/JSON/TOML file, you can also\n use `data` instead of `stringData` which allow you to set various\n configuration in separate Helm config files. This can be useful to\n help dependent charts override only some configuration part of the\n file, or to allow for the configuration be set through multiple\n Helm configuration files.\n\n**Limitations**\n\n1. File size\n\n The files in `hub.extraFiles` and `singleuser.extraFiles` are\n respectively stored in their own k8s Secret resource. As k8s\n Secret's are limited, typically to 1MB, you will be limited to a\n total file size of less than 1MB as there is also base64 encoding\n that takes place reducing available capacity to 75%.\n\n2. File updates\n\n The files that are mounted are only set during container startup.\n This is [because we use\n `subPath`](https://kubernetes.io/docs/concepts/storage/volumes/#secret)\n as is required to avoid replacing the content of the entire\n directory we mount in.\n",
"patternProperties": {
".*": {
"type": "object",
"additionalProperties": false,
"required": [
"mountPath"
],
"oneOf": [
{
"required": [
"data"
]
},
{
"required": [
"stringData"
]
},
{
"required": [
"binaryData"
]
}
],
"properties": {
"mountPath": {
"type": "string"
},
"data": {
"type": "object",
"additionalProperties": true
},
"stringData": {
"type": "string"
},
"binaryData": {
"type": "string"
},
"mode": {
"type": "number"
}
}
}
}
},
"baseUrl": {
"type": "string",
"description": "This is the equivalent of c.JupyterHub.base_url, but it is also needed\nby the Helm chart in general. So, instead of setting\nc.JupyterHub.base_url, use this configuration.\n"
},
"command": {
"type": "array",
"description": "A list of strings to be used to replace the JupyterHub image's\n`ENTRYPOINT` entry. Note that in k8s lingo, the Dockerfile's\n`ENTRYPOINT` is called `command`. The list of strings will be expanded\nwith Helm's template function `tpl` which can render Helm template\nlogic inside curly braces (`{{... }}`).\n\nThis could be useful to wrap the invocation of JupyterHub itself in\nsome custom way.\n\nFor more details, see the [Kubernetes\ndocumentation](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/).\n"
},
"args": {
"type": "array",
"description": "A list of strings to be used to replace the JupyterHub image's `CMD`\nentry as well as the Helm chart's default way to start JupyterHub.\nNote that in k8s lingo, the Dockerfile's `CMD` is called `args`. The\nlist of strings will be expanded with Helm's template function `tpl`\nwhich can render Helm template logic inside curly braces (`{{... }}`).\n\n```{warning}\nBy replacing the entire configuration file, which is mounted to\n`/usr/local/etc/jupyterhub/jupyterhub_config.py` by the Helm chart,\ninstead of appending to it with `hub.extraConfig`, you expose your\ndeployment for issues stemming from getting out of sync with the Helm\nchart's config file.\n\nThese kind of issues will be significantly harder to debug and\ndiagnose, and can due to this could cause a lot of time expenditure\nfor both the community maintaining the Helm chart as well as yourself,\neven if this wasn't the reason for the issue.\n\nDue to this, we ask that you do your _absolute best to avoid replacing\nthe default provided `jupyterhub_config.py` file. It can often be\npossible. For example, if your goal is to have a dedicated .py file\nfor more extensive additions that you can syntax highlight and such\nand feel limited by passing code in `hub.extraConfig` which is part of\na YAML file, you can use [this\ntrick](https://github.com/jupyterhub/zero-to-jupyterhub-k8s/issues/1580#issuecomment-707776237)\ninstead.\n```\n\n```yaml\nhub:\n args:\n - \"jupyterhub\"\n - \"--config\"\n - \"/usr/local/etc/jupyterhub/jupyterhub_config.py\"\n - \"--debug\"\n - \"--upgrade-db\"\n```\n\nFor more details, see the [Kubernetes\ndocumentation](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/).\n"
},
"cookieSecret": {
"type": [
"string",
"null"
],
"description": "```{note}\nAs of version 1.0.0 this will automatically be generated and there is\nno need to set it manually.\n\nIf you wish to reset a generated key, you can use `kubectl edit` on\nthe k8s Secret typically named `hub` and remove the\n`hub.config.JupyterHub.cookie_secret` entry in the k8s Secret, then\nperform a new `helm upgrade`.\n```\n\nA 32-byte cryptographically secure randomly generated string used to sign values of\nsecure cookies set by the hub. If unset, jupyterhub will generate one on startup and\nsave it in the file `jupyterhub_cookie_secret` in the `/srv/jupyterhub` directory of\nthe hub container. A value set here will make JupyterHub overwrite any previous file.\n\nYou do not need to set this at all if you are using the default configuration for\nstoring databases - sqlite on a persistent volume (with `hub.db.type` set to the\ndefault `sqlite-pvc`). If you are using an external database, then you must set this\nvalue explicitly - or your users will keep getting logged out each time the hub pod\nrestarts.\n\nChanging this value will all user logins to be invalidated. If this secret leaks,\n*immediately* change it to something else, or user data can be compromised\n\n```sh\n# to generate a value, run\nopenssl rand -hex 32\n```\n"
},
"image": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"tag"
],
"description": "Set custom image name, tag, pullPolicy, or pullSecrets for the pod.\n",
"properties": {
"name": {
"type": "string",
"description": "The name of the image, without the tag.\n\n```\n# example name\ngcr.io/my-project/my-image\n```\n"
},
"tag": {
"type": "string",
"description": "The tag of the image to pull. This is the value following `:` in\ncomplete image specifications.\n\n```\n# example tags\nv1.11.1\nzhy270a\n```\n"
},
"pullPolicy": {
"enum": [
null,
"",
"IfNotPresent",
"Always",
"Never"
],
"description": "Configures the Pod's `spec.imagePullPolicy`.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/containers/images/#updating-images)\nfor more info.\n"
},
"pullSecrets": {
"type": "array",
"description": "A list of references to existing Kubernetes Secrets with\ncredentials to pull the image.\n\nThis Pod's final `imagePullSecrets` k8s specification will be a\ncombination of:\n\n1. This list of k8s Secrets, specific for this pod.\n2. The list of k8s Secrets, for use by all pods in the Helm chart,\n declared in this Helm charts configuration called\n `imagePullSecrets`.\n3. A k8s Secret, for use by all pods in the Helm chart, if\n conditionally created from image registry credentials provided\n under `imagePullSecret` if `imagePullSecret.create` is set to\n true.\n\n```yaml\n# example - k8s native syntax\npullSecrets:\n - name: my-k8s-secret-with-image-registry-credentials\n\n# example - simplified syntax\npullSecrets:\n - my-k8s-secret-with-image-registry-credentials\n```\n"
}
}
},
"networkPolicy": {
"type": "object",
"additionalProperties": false,
"description": "This configuration regards the creation and configuration of a k8s\n_NetworkPolicy resource_.\n",
"properties": {
"enabled": {
"type": "boolean",
"description": "Toggle the creation of the NetworkPolicy resource targeting this\npod, and by doing so, restricting its communication to only what\nis explicitly allowed in the NetworkPolicy.\n"
},
"ingress": {
"type": "array",
"description": "Additional ingress rules to add besides those that are required\nfor core functionality.\n"
},
"egress": {
"type": "array",
"description": "Additional egress rules to add besides those that are required for\ncore functionality and those added via\n[`.egressAllowRules`](schema_hub.networkPolicy.egressAllowRules).\n\n```{versionchanged} 2.0.0\nThe default value changed from providing one very permissive rule\nallowing all egress to providing no rule. The permissive rule is\nstill provided via\n[`.egressAllowRules`](schema_hub.networkPolicy.egressAllowRules)\nset to true though.\n```\n\nAs an example, below is a configuration that disables the more\nbroadly permissive `.privateIPs` egress allow rule for the hub\npod, and instead provides tightly scoped permissions to access a\nspecific k8s local service as identified by pod labels.\n\n```yaml\nhub:\n networkPolicy:\n egressAllowRules:\n privateIPs: false\n egress:\n - to:\n - podSelector:\n matchLabels:\n app: my-k8s-local-service\n ports:\n - protocol: TCP\n port: 5978\n```\n"
},
"egressAllowRules": {
"type": "object",
"additionalProperties": false,
"description": "This is a set of predefined rules that when enabled will be added\nto the NetworkPolicy list of egress rules.\n\nThe resulting egress rules will be a composition of:\n- rules specific for the respective pod(s) function within the\n Helm chart\n- rules based on enabled `egressAllowRules` flags\n- rules explicitly specified by the user\n\n```{note}\nEach flag under this configuration will not render into a\ndedicated rule in the NetworkPolicy resource, but instead combine\nwith the other flags to a reduced set of rules to avoid a\nperformance penalty.\n```\n\n```{versionadded} 2.0.0\nAll `egressAllowRules` are new in JupyterHub Helm chart 2.0.0.\n```\n",
"properties": {
"cloudMetadataServer": {
"type": "boolean",
"description": "Defaults to `false` for singleuser servers, but to `true` for\nall other network policies.\n\nWhen enabled this rule allows the respective pod(s) to\nestablish outbound connections to the cloud metadata server.\n\nNote that the `nonPrivateIPs` rule is allowing all non Private\nIP ranges but makes an exception for the cloud metadata\nserver, leaving this as the definitive configuration to allow\naccess to the cloud metadata server.\n"
},
"dnsPortsPrivateIPs": {
"type": "boolean",
"description": "Defaults to `true` for all network policies.\n\nWhen enabled this rule allows the respective pod(s) to\nestablish outbound connections to private IPs via port 53.\n\nNote that we can't reliably identify the k8s internal DNS\nserver due to variations between k8s clusters. Due to that,\nthis rule which is critical for core functionality, can be\ndisabled for a more refined custom rule.\n"
},
"nonPrivateIPs": {
"type": "boolean",
"description": "Defaults to `true` for all network policies.\n\nWhen enabled this rule allows the respective pod(s) to\nestablish outbound connections to the non-private IP ranges\nwith the exception of the cloud metadata server. This means\nrespective pod(s) can establish connections to the internet\nbut not (say) an unsecured prometheus server running in the\nsame cluster.\n"
},
"privateIPs": {
"type": "boolean",
"description": "Defaults to `false` for singleuser servers, but to `true` for\nall other network policies.\n\nPrivate IPs refer to the IP ranges `10.0.0.0/8`,\n`172.16.0.0/12`, `192.168.0.0/16`.\n\nWhen enabled this rule allows the respective pod(s) to\nestablish outbound connections to the internal k8s cluster.\nThis means users can access the internet but not (say) an\nunsecured prometheus server running in the same cluster.\n\nSince not all workloads in the k8s cluster may have\nNetworkPolicies setup to restrict their incoming connections,\nhaving this set to false can be a good defense against\nmalicious intent from someone in control of software in these\npods.\n\nIf possible, try to avoid setting this to true as it gives\nbroad permissions that could be specified more directly via\nthe [`.egress`](schema_singleuser.networkPolicy.egress).\n"
}
}
},
"interNamespaceAccessLabels": {
"enum": [
"accept",
"ignore"
],
"description": "This configuration option determines if both namespaces and pods\nin other namespaces, that have specific access labels, should be\naccepted to allow ingress (set to `accept`), or, if the labels are\nto be ignored when applied outside the local namespace (set to\n`ignore`).\n\nThe available access labels for respective NetworkPolicy resources\nare:\n\n- `hub.jupyter.org/network-access-hub: \"true\"` (hub)\n- `hub.jupyter.org/network-access-proxy-http: \"true\"` (proxy.chp, proxy.traefik)\n- `hub.jupyter.org/network-access-proxy-api: \"true\"` (proxy.chp)\n- `hub.jupyter.org/network-access-singleuser: \"true\"` (singleuser)\n"
},
"allowedIngressPorts": {
"type": "array",
"description": "A rule to allow ingress on these ports will be added no matter\nwhat the origin of the request is. The default setting for\n`proxy.chp` and `proxy.traefik`'s networkPolicy configuration is\n`[http, https]`, while it is `[]` for other networkPolicies.\n\nNote that these port names or numbers target a Pod's port name or\nnumber, not a k8s Service's port name or number.\n"
}
}
},
"db": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"enum": [
"sqlite-pvc",
"sqlite-memory",
"mysql",
"postgres",
"other"
],
"description": "Type of database backend to use for the hub database.\n\nThe Hub requires a persistent database to function, and this lets you specify\nwhere it should be stored.\n\nThe various options are:\n\n1. **sqlite-pvc**\n\n Use an `sqlite` database kept on a persistent volume attached to the hub.\n\n By default, this disk is created by the cloud provider using\n *dynamic provisioning* configured by a [storage\n class](https://kubernetes.io/docs/concepts/storage/storage-classes/).\n You can customize how this disk is created / attached by\n setting various properties under `hub.db.pvc`.\n\n This is the default setting, and should work well for most cloud provider\n deployments.\n\n2. **sqlite-memory**\n\n Use an in-memory `sqlite` database. This should only be used for testing,\n since the database is erased whenever the hub pod restarts - causing the hub\n to lose all memory of users who had logged in before.\n\n When using this for testing, make sure you delete all other objects that the\n hub has created (such as user pods, user PVCs, etc) every time the hub restarts.\n Otherwise you might run into errors about duplicate resources.\n\n3. **mysql**\n\n Use an externally hosted mysql database.\n\n You have to specify an sqlalchemy connection string for the mysql database you\n want to connect to in `hub.db.url` if using this option.\n\n The general format of the connection string is:\n ```\n mysql+pymysql://<db-username>:<db-password>@<db-hostname>:<db-port>/<db-name>\n ```\n\n The user specified in the connection string must have the rights to create\n tables in the database specified.\n\n4. **postgres**\n\n Use an externally hosted postgres database.\n\n You have to specify an sqlalchemy connection string for the postgres database you\n want to connect to in `hub.db.url` if using this option.\n\n The general format of the connection string is:\n ```\n postgresql+psycopg2://<db-username>:<db-password>@<db-hostname>:<db-port>/<db-name>\n ```\n\n The user specified in the connection string must have the rights to create\n tables in the database specified.\n\n5. **other**\n\n Use an externally hosted database of some kind other than mysql\n or postgres.\n\n When using _other_, the database password must be passed as\n part of [hub.db.url](schema_hub.db.url) as\n [hub.db.password](schema_hub.db.password) will be ignored.\n"
},
"pvc": {
"type": "object",
"additionalProperties": false,
"required": [
"storage"
],
"description": "Customize the Persistent Volume Claim used when `hub.db.type` is `sqlite-pvc`.\n",
"properties": {
"annotations": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Annotations to apply to the PVC containing the sqlite database.\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/)\nfor more details about annotations.\n"
},
"selector": {
"type": "object",
"additionalProperties": true,
"description": "Label selectors to set for the PVC containing the sqlite database.\n\nUseful when you are using a specific PV, and want to bind to\nthat and only that.\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims)\nfor more details about using a label selector for what PV to\nbind to.\n"
},
"storage": {
"type": "string",
"description": "Size of disk to request for the database disk.\n"
},
"accessModes": {
"type": "array",
"items": {
"type": [
"string",
"null"
]
},
"description": "AccessModes contains the desired access modes the volume\nshould have. See [the k8s\ndocumentation](https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1)\nfor more information.\n"
},
"storageClassName": {
"type": [
"string",
"null"
],
"description": "Name of the StorageClass required by the claim.\n\nIf this is a blank string it will be set to a blank string,\nwhile if it is null, it will not be set at all.\n"
},
"subPath": {
"type": [
"string",
"null"
],
"description": "Path within the volume from which the container's volume\nshould be mounted. Defaults to \"\" (volume's root).\n"
}
}
},
"upgrade": {
"type": [
"boolean",
"null"
],
"description": "Users with external databases need to opt-in for upgrades of the\nJupyterHub specific database schema if needed as part of a\nJupyterHub version upgrade.\n"
},
"url": {
"type": [
"string",
"null"
],
"description": "Connection string when `hub.db.type` is mysql or postgres.\n\nSee documentation for `hub.db.type` for more details on the format of this property.\n"
},
"password": {
"type": [
"string",
"null"
],
"description": "Password for the database when `hub.db.type` is mysql or postgres.\n"
}
}
},
"labels": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Extra labels to add to the hub pod.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)\nto learn more about labels.\n"
},
"initContainers": {
"type": "array",
"description": "list of initContainers to be run with hub pod. See [Kubernetes Docs](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/)\n\n```yaml\nhub:\n initContainers:\n - name: init-myservice\n image: busybox:1.28\n command: ['sh', '-c', 'command1']\n - name: init-mydb\n image: busybox:1.28\n command: ['sh', '-c', 'command2']\n```\n"
},
"extraEnv": {
"type": [
"object",
"array"
],
"additionalProperties": true,
"description": "Extra environment variables that should be set for the hub pod.\n\nEnvironment variables are usually used to:\n - Pass parameters to some custom code in `hub.extraConfig`.\n - Configure code running in the hub pod, such as an authenticator or\n spawner.\n\nString literals with `$(ENV_VAR_NAME)` will be expanded by Kubelet which\nis a part of Kubernetes.\n\n```yaml\nhub:\n extraEnv:\n # basic notation (for literal values only)\n MY_ENV_VARS_NAME1: \"my env var value 1\"\n\n # explicit notation (the \"name\" field takes precedence)\n HUB_NAMESPACE:\n name: HUB_NAMESPACE\n valueFrom:\n fieldRef:\n fieldPath: metadata.namespace\n\n # implicit notation (the \"name\" field is implied)\n PREFIXED_HUB_NAMESPACE:\n value: \"my-prefix-$(HUB_NAMESPACE)\"\n SECRET_VALUE:\n valueFrom:\n secretKeyRef:\n name: my-k8s-secret\n key: password\n```\n\nFor more information, see the [Kubernetes EnvVar\nspecification](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#envvar-v1-core).\n"
},
"extraConfig": {
"type": "object",
"additionalProperties": true,
"description": "Arbitrary extra python based configuration that should be in `jupyterhub_config.py`.\n\nThis is the *escape hatch* - if you want to configure JupyterHub to do something specific\nthat is not present here as an option, you can write the raw Python to do it here.\n\nextraConfig is a *dict*, so there can be multiple configuration\nsnippets under different names. The configuration sections are run in\nalphabetical order based on the keys.\n\nNon-exhaustive examples of things you can do here:\n - Subclass authenticator / spawner to do a custom thing\n - Dynamically launch different images for different sets of images\n - Inject an auth token from GitHub authenticator into user pod\n - Anything else you can think of!\n\nSince this is usually a multi-line string, you want to format it using YAML's\n[| operator](https://yaml.org/spec/1.2.2/#23-scalars).\n\nFor example:\n\n```yaml\nhub:\n extraConfig:\n myConfig.py: |\n c.JupyterHub.something = 'something'\n c.Spawner.something_else = 'something else'\n```\n\n```{note}\nNo code validation is performed until JupyterHub loads it! If you make\na typo here, it will probably manifest itself as the hub pod failing\nto start up and instead entering an `Error` state or the subsequent\n`CrashLoopBackoff` state.\n\nTo make use of your own programs linters etc, it would be useful to\nnot embed Python code inside a YAML file. To do that, consider using\n[`hub.extraFiles`](schema_hub.extraFiles) and mounting a file to\n`/usr/local/etc/jupyterhub/jupyterhub_config.d` in order to load your\nextra configuration logic.\n```\n"
},
"fsGid": {
"type": [
"integer",
"null"
],
"minimum": 0,
"description": "```{note}\nRemoved in version 2.0.0. Use\n[`hub.podSecurityContext`](schema_hub.podSecurityContext) and specify\n`fsGroup` instead.\n```\n"
},
"service": {
"type": "object",
"additionalProperties": false,
"description": "Object to configure the service the JupyterHub will be exposed on by the Kubernetes server.\n",
"properties": {
"type": {
"enum": [
"ClusterIP",
"NodePort",
"LoadBalancer",
"ExternalName"
],
"description": "The Kubernetes ServiceType to be used.\n\nThe default type is `ClusterIP`.\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types)\nto learn more about service types.\n"
},
"ports": {
"type": "object",
"additionalProperties": false,
"description": "Object to configure the ports the hub service will be deployed on.\n",
"properties": {
"nodePort": {
"type": [
"integer",
"null"
],
"minimum": 0,
"description": "The nodePort to deploy the hub service on.\n"
}
}
},
"annotations": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Kubernetes annotations to apply to the hub service.\n"
},
"extraPorts": {
"type": "array",
"description": "Extra ports to add to the Hub Service object besides `hub` / `8081`.\nThis should be an array that includes `name`, `port`, and `targetPort`.\nSee [Multi-port Services](https://kubernetes.io/docs/concepts/services-networking/service/#multi-port-services) for more details.\n"
},
"loadBalancerIP": {
"type": [
"string",
"null"
],
"description": "A public IP address the hub Kubernetes service should be exposed\non. To expose the hub directly is not recommended. Instead route\ntraffic through the proxy-public service towards the hub.\n"
}
}
},
"pdb": {
"type": "object",
"additionalProperties": false,
"description": "Configure a PodDisruptionBudget for this Deployment.\n\nThese are disabled by default for our deployments that don't support\nbeing run in parallel with multiple replicas. Only the user-scheduler\ncurrently supports being run in parallel with multiple replicas. If\nthey are enabled for a Deployment with only one replica, they will\nblock `kubectl drain` of a node for example.\n\nNote that if you aim to block scaling down a node with the\nhub/proxy/autohttps pod that would cause disruptions of the\ndeployment, then you should instead annotate the pods of the\nDeployment [as described\nhere](https://github.com/kubernetes/autoscaler/blob/HEAD/cluster-autoscaler/FAQ.md#what-types-of-pods-can-prevent-ca-from-removing-a-node).\n\n \"cluster-autoscaler.kubernetes.io/safe-to-evict\": \"false\"\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/)\nfor more details about disruptions.\n",
"properties": {
"enabled": {
"type": "boolean",
"description": "Decides if a PodDisruptionBudget is created targeting the\nDeployment's pods.\n"
},
"maxUnavailable": {
"type": [
"integer",
"null"
],
"description": "The maximum number of pods that can be unavailable during\nvoluntary disruptions.\n"
},
"minAvailable": {
"type": [
"integer",
"null"
],
"description": "The minimum number of pods required to be available during\nvoluntary disruptions.\n"
}
}
},
"existingSecret": {
"type": [
"string",
"null"
],
"description": "This option allow you to provide the name of an existing k8s Secret to\nuse alongside of the chart managed k8s Secret. The content of this k8s\nSecret will be merged with the chart managed k8s Secret, giving\npriority to the self-managed k8s Secret.\n\n```{warning}\n1. The self managed k8s Secret must mirror the structure in the chart\n managed secret.\n2. [`proxy.secretToken`](schema_proxy.secretToken) (aka.\n `hub.config.ConfigurableHTTPProxy.auth_token`) is only read from\n the chart managed k8s Secret.\n```\n"
},
"nodeSelector": {
"type": "object",
"additionalProperties": true,
"description": "An object with key value pairs representing labels. K8s Nodes are\nrequired to have match all these labels for this Pod to scheduled on\nthem.\n\n```yaml\ndisktype: ssd\nnodetype: awesome\n```\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector)\nfor more details.\n"
},
"tolerations": {
"type": "array",
"description": "Tolerations allow a pod to be scheduled on nodes with taints. These\ntolerations are additional tolerations to the tolerations common to\nall pods of a their respective kind\n([scheduling.corePods.tolerations](schema_scheduling.corePods.tolerations),\n[scheduling.userPods.tolerations](schema_scheduling.userPods.tolerations)).\n\nPass this field an array of\n[`Toleration`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#toleration-v1-core)\nobjects.\n\nSee the [Kubernetes\ndocs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)\nfor more info.\n"
},
"activeServerLimit": {
"type": [
"integer",
"null"
],
"description": "JupyterHub native configuration, see the [JupyterHub\ndocumentation](https://jupyterhub.readthedocs.io/en/stable/api/app.html)\nfor more information.\n"
},
"allowNamedServers": {
"type": [
"boolean",
"null"
],
"description": "JupyterHub native configuration, see the [JupyterHub\ndocumentation](https://jupyterhub.readthedocs.io/en/stable/api/app.html)\nfor more information.\n"
},
"annotations": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "K8s annotations for the hub pod.\n"
},
"authenticatePrometheus": {
"type": [
"boolean",
"null"
],
"description": "JupyterHub native configuration, see the [JupyterHub\ndocumentation](https://jupyterhub.readthedocs.io/en/stable/api/app.html)\nfor more information.\n"
},
"concurrentSpawnLimit": {
"type": [
"integer",
"null"
],
"description": "JupyterHub native configuration, see the [JupyterHub\ndocumentation](https://jupyterhub.readthedocs.io/en/stable/api/app.html)\nfor more information.\n"
},
"consecutiveFailureLimit": {
"type": [
"integer",
"null"
],
"description": "JupyterHub native configuration, see the [JupyterHub\ndocumentation](https://jupyterhub.readthedocs.io/en/stable/api/app.html)\nfor more information.\n"
},
"podSecurityContext": {
"additionalProperties": true,
"description": "A k8s native specification of the pod's security context, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core)\nfor details.\n"
},
"containerSecurityContext": {
"type": "object",
"additionalProperties": true,
"description": "A k8s native specification of the container's security context, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core)\nfor details.\n"
},
"deploymentStrategy": {
"type": "object",
"additionalProperties": false,
"properties": {
"rollingUpdate": {
"type": [
"string",
"null"
]
},
"type": {
"type": [
"string",
"null"
],
"description": "JupyterHub does not support running in parallel, due to this we\ndefault to using a deployment strategy of Recreate.\n"
}
}
},
"extraContainers": {
"type": "array",
"description": "Additional containers for the Pod. Use a k8s native syntax.\n"
},
"extraVolumeMounts": {
"type": "array",
"description": "Additional volume mounts for the Container. Use a k8s native syntax.\n"
},
"extraVolumes": {
"type": "array",
"description": "Additional volumes for the Pod. Use a k8s native syntax.\n"
},
"livenessProbe": {
"type": "object",
"additionalProperties": true,
"required": [
"enabled"
],
"if": {
"properties": {
"enabled": {
"const": true
}
}
},
"then": {
"description": "This config option is like the k8s native specification of a\ncontainer probe, except that it also supports an `enabled` boolean\nflag.\n\nSee [the k8s\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#probe-v1-core)\nfor more details.\n"
}
},
"readinessProbe": {
"type": "object",
"additionalProperties": true,
"required": [
"enabled"
],
"if": {
"properties": {
"enabled": {
"const": true
}
}
},
"then": {
"description": "This config option is like the k8s native specification of a\ncontainer probe, except that it also supports an `enabled` boolean\nflag.\n\nSee [the k8s\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#probe-v1-core)\nfor more details.\n"
}
},
"namedServerLimitPerUser": {
"type": [
"integer",
"null"
],
"description": "JupyterHub native configuration, see the [JupyterHub\ndocumentation](https://jupyterhub.readthedocs.io/en/stable/api/app.html)\nfor more information.\n"
},
"redirectToServer": {
"type": [
"boolean",
"null"
],
"description": "JupyterHub native configuration, see the [JupyterHub\ndocumentation](https://jupyterhub.readthedocs.io/en/stable/api/app.html)\nfor more information.\n"
},
"resources": {
"type": "object",
"additionalProperties": true,
"description": "A k8s native specification of resources, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#resourcerequirements-v1-core).\n"
},
"lifecycle": {
"type": "object",
"additionalProperties": false,
"description": "A k8s native specification of lifecycle hooks on the container, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#lifecycle-v1-core).\n",
"properties": {
"postStart": {
"type": "object",
"additionalProperties": true
},
"preStop": {
"type": "object",
"additionalProperties": true
}
}
},
"services": {
"type": "object",
"additionalProperties": true,
"description": "This is where you register JupyterHub services. For details on how to\nconfigure these services in this Helm chart just keep reading but for\ndetails on services themselves instead read [JupyterHub's\ndocumentation](https://jupyterhub.readthedocs.io/en/stable/api/service.html).\n\n```{note}\nOnly a selection of JupyterHub's configuration options that can be\nconfigured for a service are documented below. All configuration set\nhere will be applied even if this Helm chart doesn't recognize it.\n```\n\nJupyterHub's native configuration accepts a list of service objects,\nthis Helm chart only accept a dictionary where each key represents the\nname of a service and the value is the actual service objects.\n\nWhen configuring JupyterHub services via this Helm chart, the `name`\nfield can be omitted as it can be implied by the dictionary key.\nFurther, the `api_token` field can be omitted as it will be\nautomatically generated as of version 1.1.0 of this Helm chart.\n\nIf you have an external service that needs to access the automatically\ngenerated api_token for the service, you can access it from the `hub`\nk8s Secret part of this Helm chart under the key\n`hub.services.my-service-config-key.apiToken`.\n\nHere is an example configuration of two services where the first\nexplicitly sets a name and api_token, while the second omits those and\nlets the name be implied from the key name and the api_token be\nautomatically generated.\n\n```yaml\nhub:\n services:\n my-service-1:\n admin: true\n name: my-explicitly-set-service-name\n api_token: my-explicitly-set-api_token\n\n # the name of the following service will be my-service-2\n # the api_token of the following service will be generated\n my-service-2: {}\n```\n\nIf you develop a Helm chart depending on the JupyterHub Helm chart and\nwant to let some Pod's environment variable be populated with the\napi_token of a service registered like above, then do something along\nthese lines.\n\n```yaml\n# ... container specification of a pod ...\nenv:\n - name: MY_SERVICE_1_API_TOKEN\n valueFrom:\n secretKeyRef:\n # Don't hardcode the name, use the globally accessible\n # named templates part of the JupyterHub Helm chart.\n name: {{ include \"jupyterhub.hub.fullname\" . }}\n # Note below the use of the configuration key my-service-1\n # rather than the explicitly set service name.\n key: hub.services.my-service-1.apiToken\n```\n",
"properties": {
"name": {
"type": "string",
"description": "The name can be implied via the key name under which this\nservice is configured, and is due to that allowed to be\nomitted in this Helm chart configuration of JupyterHub.\n"
},
"admin": {
"type": "boolean"
},
"command": {
"type": [
"string",
"array"
]
},
"url": {
"type": "string"
},
"api_token": {
"type": [
"string",
"null"
],
"description": "The api_token will be automatically generated if not\nexplicitly set. It will also be exposed in via a k8s Secret\npart of this Helm chart under a specific key.\n\nSee the documentation under\n[`hub.services`](schema_hub.services) for details about this.\n"
},
"apiToken": {
"type": [
"string",
"null"
],
"description": "An alias for api_token provided for backward compatibility by\nthe JupyterHub Helm chart that will be transformed to\napi_token.\n"
}
}
},
"loadRoles": {
"type": "object",
"additionalProperties": true,
"description": "This is where you should define JupyterHub roles and apply them to\nJupyterHub users, groups, and services to grant them additional\npermissions as defined in JupyterHub's RBAC system.\n\nComplement this documentation with [JupyterHub's\ndocumentation](https://jupyterhub.readthedocs.io/en/latest/rbac/roles.html#defining-roles)\nabout `load_roles`.\n\nNote that while JupyterHub's native configuration `load_roles` accepts\na list of role objects, this Helm chart only accepts a dictionary where\neach key represents the name of a role and the value is the actual\nrole object.\n\n```yaml\nhub:\n loadRoles:\n teacher:\n description: Access to users' information and group membership\n\n # this role provides permissions to...\n scopes: [users, groups]\n\n # this role will be assigned to...\n users: [erik]\n services: [grading-service]\n groups: [teachers]\n```\n\nWhen configuring JupyterHub roles via this Helm chart, the `name`\nfield can be omitted as it can be implied by the dictionary key.\n"
},
"shutdownOnLogout": {
"type": [
"boolean",
"null"
],
"description": "JupyterHub native configuration, see the [JupyterHub\ndocumentation](https://jupyterhub.readthedocs.io/en/stable/api/app.html)\nfor more information.\n"
},
"templatePaths": {
"type": "array",
"description": "JupyterHub native configuration, see the [JupyterHub\ndocumentation](https://jupyterhub.readthedocs.io/en/stable/api/app.html)\nfor more information.\n"
},
"templateVars": {
"type": "object",
"additionalProperties": true,
"description": "JupyterHub native configuration, see the [JupyterHub\ndocumentation](https://jupyterhub.readthedocs.io/en/stable/api/app.html)\nfor more information.\n"
},
"serviceAccount": {
"type": "object",
"required": [
"create"
],
"additionalProperties": false,
"description": "Configuration for a k8s ServiceAccount dedicated for use by the\nspecific pod which this configuration is nested under.\n",
"properties": {
"create": {
"type": "boolean",
"description": "Whether or not to create the `ServiceAccount` resource.\n"
},
"name": {
"type": [
"string",
"null"
],
"description": "This configuration serves multiple purposes:\n\n- It will be the `serviceAccountName` referenced by related Pods.\n- If `create` is set, the created ServiceAccount resource will be named like this.\n- If [`rbac.create`](schema_rbac.create) is set, the associated (Cluster)RoleBindings will bind to this name.\n\nIf not explicitly provided, a default name will be used.\n"
},
"annotations": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Kubernetes annotations to apply to the k8s ServiceAccount.\n"
}
}
},
"extraPodSpec": {
"type": "object",
"additionalProperties": true,
"description": "Arbitrary extra k8s pod specification as a YAML object. The default\nvalue of this setting is an empty object, i.e. no extra configuration.\nThe value of this property is augmented to the pod specification as-is.\n\nThis is a powerful tool for expert k8s administrators with advanced\nconfiguration requirements. This setting should only be used for\nconfiguration that cannot be accomplished through the other settings.\nMisusing this setting can break your deployment and/or compromise\nyour system security.\n\nThis is one of four related settings for inserting arbitrary pod\nspecification:\n\n1. hub.extraPodSpec\n2. proxy.chp.extraPodSpec\n3. proxy.traefik.extraPodSpec\n4. scheduling.userScheduler.extraPodSpec\n\nOne real-world use of these settings is to enable host networking. For\nexample, to configure host networking for the hub pod, add the\nfollowing to your helm configuration values:\n\n```yaml\nhub:\n extraPodSpec:\n hostNetwork: true\n dnsPolicy: ClusterFirstWithHostNet\n```\n\nLikewise, to configure host networking for the proxy pod, add the\nfollowing:\n\n```yaml\nproxy:\n chp:\n extraPodSpec:\n hostNetwork: true\n dnsPolicy: ClusterFirstWithHostNet\n```\n\nN.B. Host networking has special security implications and can easily\nbreak your deployment. This is an example—not an endorsement.\n\nSee [PodSpec](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec)\nfor the latest pod resource specification.\n"
}
}
},
"proxy": {
"type": "object",
"additionalProperties": false,
"properties": {
"chp": {
"type": "object",
"additionalProperties": false,
"description": "Configure the configurable-http-proxy (chp) pod managed by jupyterhub to route traffic\nboth to itself and to user pods.\n",
"properties": {
"revisionHistoryLimit": {
"type": [
"integer",
"null"
],
"minimum": 0,
"description": "Configures the resource's `spec.revisionHistoryLimit`. This is\navailable for Deployment, StatefulSet, and DaemonSet resources.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#revision-history-limit)\nfor more info.\n"
},
"networkPolicy": {
"type": "object",
"additionalProperties": false,
"description": "This configuration regards the creation and configuration of a k8s\n_NetworkPolicy resource_.\n",
"properties": {
"enabled": {
"type": "boolean",
"description": "Toggle the creation of the NetworkPolicy resource targeting this\npod, and by doing so, restricting its communication to only what\nis explicitly allowed in the NetworkPolicy.\n"
},
"ingress": {
"type": "array",
"description": "Additional ingress rules to add besides those that are required\nfor core functionality.\n"
},
"egress": {
"type": "array",
"description": "Additional egress rules to add besides those that are required for\ncore functionality and those added via\n[`.egressAllowRules`](schema_hub.networkPolicy.egressAllowRules).\n\n```{versionchanged} 2.0.0\nThe default value changed from providing one very permissive rule\nallowing all egress to providing no rule. The permissive rule is\nstill provided via\n[`.egressAllowRules`](schema_hub.networkPolicy.egressAllowRules)\nset to true though.\n```\n\nAs an example, below is a configuration that disables the more\nbroadly permissive `.privateIPs` egress allow rule for the hub\npod, and instead provides tightly scoped permissions to access a\nspecific k8s local service as identified by pod labels.\n\n```yaml\nhub:\n networkPolicy:\n egressAllowRules:\n privateIPs: false\n egress:\n - to:\n - podSelector:\n matchLabels:\n app: my-k8s-local-service\n ports:\n - protocol: TCP\n port: 5978\n```\n"
},
"egressAllowRules": {
"type": "object",
"additionalProperties": false,
"description": "This is a set of predefined rules that when enabled will be added\nto the NetworkPolicy list of egress rules.\n\nThe resulting egress rules will be a composition of:\n- rules specific for the respective pod(s) function within the\n Helm chart\n- rules based on enabled `egressAllowRules` flags\n- rules explicitly specified by the user\n\n```{note}\nEach flag under this configuration will not render into a\ndedicated rule in the NetworkPolicy resource, but instead combine\nwith the other flags to a reduced set of rules to avoid a\nperformance penalty.\n```\n\n```{versionadded} 2.0.0\nAll `egressAllowRules` are new in JupyterHub Helm chart 2.0.0.\n```\n",
"properties": {
"cloudMetadataServer": {
"type": "boolean",
"description": "Defaults to `false` for singleuser servers, but to `true` for\nall other network policies.\n\nWhen enabled this rule allows the respective pod(s) to\nestablish outbound connections to the cloud metadata server.\n\nNote that the `nonPrivateIPs` rule is allowing all non Private\nIP ranges but makes an exception for the cloud metadata\nserver, leaving this as the definitive configuration to allow\naccess to the cloud metadata server.\n"
},
"dnsPortsPrivateIPs": {
"type": "boolean",
"description": "Defaults to `true` for all network policies.\n\nWhen enabled this rule allows the respective pod(s) to\nestablish outbound connections to private IPs via port 53.\n\nNote that we can't reliably identify the k8s internal DNS\nserver due to variations between k8s clusters. Due to that,\nthis rule which is critical for core functionality, can be\ndisabled for a more refined custom rule.\n"
},
"nonPrivateIPs": {
"type": "boolean",
"description": "Defaults to `true` for all network policies.\n\nWhen enabled this rule allows the respective pod(s) to\nestablish outbound connections to the non-private IP ranges\nwith the exception of the cloud metadata server. This means\nrespective pod(s) can establish connections to the internet\nbut not (say) an unsecured prometheus server running in the\nsame cluster.\n"
},
"privateIPs": {
"type": "boolean",
"description": "Defaults to `false` for singleuser servers, but to `true` for\nall other network policies.\n\nPrivate IPs refer to the IP ranges `10.0.0.0/8`,\n`172.16.0.0/12`, `192.168.0.0/16`.\n\nWhen enabled this rule allows the respective pod(s) to\nestablish outbound connections to the internal k8s cluster.\nThis means users can access the internet but not (say) an\nunsecured prometheus server running in the same cluster.\n\nSince not all workloads in the k8s cluster may have\nNetworkPolicies setup to restrict their incoming connections,\nhaving this set to false can be a good defense against\nmalicious intent from someone in control of software in these\npods.\n\nIf possible, try to avoid setting this to true as it gives\nbroad permissions that could be specified more directly via\nthe [`.egress`](schema_singleuser.networkPolicy.egress).\n"
}
}
},
"interNamespaceAccessLabels": {
"enum": [
"accept",
"ignore"
],
"description": "This configuration option determines if both namespaces and pods\nin other namespaces, that have specific access labels, should be\naccepted to allow ingress (set to `accept`), or, if the labels are\nto be ignored when applied outside the local namespace (set to\n`ignore`).\n\nThe available access labels for respective NetworkPolicy resources\nare:\n\n- `hub.jupyter.org/network-access-hub: \"true\"` (hub)\n- `hub.jupyter.org/network-access-proxy-http: \"true\"` (proxy.chp, proxy.traefik)\n- `hub.jupyter.org/network-access-proxy-api: \"true\"` (proxy.chp)\n- `hub.jupyter.org/network-access-singleuser: \"true\"` (singleuser)\n"
},
"allowedIngressPorts": {
"type": "array",
"description": "A rule to allow ingress on these ports will be added no matter\nwhat the origin of the request is. The default setting for\n`proxy.chp` and `proxy.traefik`'s networkPolicy configuration is\n`[http, https]`, while it is `[]` for other networkPolicies.\n\nNote that these port names or numbers target a Pod's port name or\nnumber, not a k8s Service's port name or number.\n"
}
}
},
"extraCommandLineFlags": {
"type": "array",
"description": "A list of strings to be added as command line options when\nstarting\n[configurable-http-proxy](https://github.com/jupyterhub/configurable-http-proxy#command-line-options)\nthat will be expanded with Helm's template function `tpl` which\ncan render Helm template logic inside curly braces (`{{ ... }}`).\n\n```yaml\nproxy:\n chp:\n extraCommandLineFlags:\n - \"--auto-rewrite\"\n - \"--custom-header {{ .Values.myCustomStuff }}\"\n```\n\nNote that these will be appended last, and if you provide the same\nflag twice, the last flag will be used, which mean you can\noverride the default flag values as well.\n"
},
"extraEnv": {
"type": [
"object",
"array"
],
"additionalProperties": true,
"description": "Extra environment variables that should be set for the chp pod.\n\nEnvironment variables are usually used here to:\n - override HUB_SERVICE_PORT or HUB_SERVICE_HOST default values\n - set CONFIGPROXY_SSL_KEY_PASSPHRASE for setting passphrase of SSL keys\n\nString literals with `$(ENV_VAR_NAME)` will be expanded by Kubelet which\nis a part of Kubernetes.\n\n```yaml\nproxy:\n chp:\n extraEnv:\n # basic notation (for literal values only)\n MY_ENV_VARS_NAME1: \"my env var value 1\"\n\n # explicit notation (the \"name\" field takes precedence)\n CHP_NAMESPACE:\n name: CHP_NAMESPACE\n valueFrom:\n fieldRef:\n fieldPath: metadata.namespace\n\n # implicit notation (the \"name\" field is implied)\n PREFIXED_CHP_NAMESPACE:\n value: \"my-prefix-$(CHP_NAMESPACE)\"\n SECRET_VALUE:\n valueFrom:\n secretKeyRef:\n name: my-k8s-secret\n key: password\n```\n\nFor more information, see the [Kubernetes EnvVar\nspecification](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#envvar-v1-core).\n"
},
"pdb": {
"type": "object",
"additionalProperties": false,
"description": "Configure a PodDisruptionBudget for this Deployment.\n\nThese are disabled by default for our deployments that don't support\nbeing run in parallel with multiple replicas. Only the user-scheduler\ncurrently supports being run in parallel with multiple replicas. If\nthey are enabled for a Deployment with only one replica, they will\nblock `kubectl drain` of a node for example.\n\nNote that if you aim to block scaling down a node with the\nhub/proxy/autohttps pod that would cause disruptions of the\ndeployment, then you should instead annotate the pods of the\nDeployment [as described\nhere](https://github.com/kubernetes/autoscaler/blob/HEAD/cluster-autoscaler/FAQ.md#what-types-of-pods-can-prevent-ca-from-removing-a-node).\n\n \"cluster-autoscaler.kubernetes.io/safe-to-evict\": \"false\"\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/)\nfor more details about disruptions.\n",
"properties": {
"enabled": {
"type": "boolean",
"description": "Decides if a PodDisruptionBudget is created targeting the\nDeployment's pods.\n"
},
"maxUnavailable": {
"type": [
"integer",
"null"
],
"description": "The maximum number of pods that can be unavailable during\nvoluntary disruptions.\n"
},
"minAvailable": {
"type": [
"integer",
"null"
],
"description": "The minimum number of pods required to be available during\nvoluntary disruptions.\n"
}
}
},
"nodeSelector": {
"type": "object",
"additionalProperties": true,
"description": "An object with key value pairs representing labels. K8s Nodes are\nrequired to have match all these labels for this Pod to scheduled on\nthem.\n\n```yaml\ndisktype: ssd\nnodetype: awesome\n```\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector)\nfor more details.\n"
},
"tolerations": {
"type": "array",
"description": "Tolerations allow a pod to be scheduled on nodes with taints. These\ntolerations are additional tolerations to the tolerations common to\nall pods of a their respective kind\n([scheduling.corePods.tolerations](schema_scheduling.corePods.tolerations),\n[scheduling.userPods.tolerations](schema_scheduling.userPods.tolerations)).\n\nPass this field an array of\n[`Toleration`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#toleration-v1-core)\nobjects.\n\nSee the [Kubernetes\ndocs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)\nfor more info.\n"
},
"containerSecurityContext": {
"type": "object",
"additionalProperties": true,
"description": "A k8s native specification of the container's security context, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core)\nfor details.\n"
},
"image": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"tag"
],
"description": "Set custom image name, tag, pullPolicy, or pullSecrets for the pod.\n",
"properties": {
"name": {
"type": "string",
"description": "The name of the image, without the tag.\n\n```\n# example name\ngcr.io/my-project/my-image\n```\n"
},
"tag": {
"type": "string",
"description": "The tag of the image to pull. This is the value following `:` in\ncomplete image specifications.\n\n```\n# example tags\nv1.11.1\nzhy270a\n```\n"
},
"pullPolicy": {
"enum": [
null,
"",
"IfNotPresent",
"Always",
"Never"
],
"description": "Configures the Pod's `spec.imagePullPolicy`.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/containers/images/#updating-images)\nfor more info.\n"
},
"pullSecrets": {
"type": "array",
"description": "A list of references to existing Kubernetes Secrets with\ncredentials to pull the image.\n\nThis Pod's final `imagePullSecrets` k8s specification will be a\ncombination of:\n\n1. This list of k8s Secrets, specific for this pod.\n2. The list of k8s Secrets, for use by all pods in the Helm chart,\n declared in this Helm charts configuration called\n `imagePullSecrets`.\n3. A k8s Secret, for use by all pods in the Helm chart, if\n conditionally created from image registry credentials provided\n under `imagePullSecret` if `imagePullSecret.create` is set to\n true.\n\n```yaml\n# example - k8s native syntax\npullSecrets:\n - name: my-k8s-secret-with-image-registry-credentials\n\n# example - simplified syntax\npullSecrets:\n - my-k8s-secret-with-image-registry-credentials\n```\n"
}
}
},
"livenessProbe": {
"type": "object",
"additionalProperties": true,
"required": [
"enabled"
],
"if": {
"properties": {
"enabled": {
"const": true
}
}
},
"then": {
"description": "This config option is like the k8s native specification of a\ncontainer probe, except that it also supports an `enabled` boolean\nflag.\n\nSee [the k8s\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#probe-v1-core)\nfor more details.\n"
}
},
"readinessProbe": {
"type": "object",
"additionalProperties": true,
"required": [
"enabled"
],
"if": {
"properties": {
"enabled": {
"const": true
}
}
},
"then": {
"description": "This config option is like the k8s native specification of a\ncontainer probe, except that it also supports an `enabled` boolean\nflag.\n\nSee [the k8s\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#probe-v1-core)\nfor more details.\n"
}
},
"resources": {
"type": "object",
"additionalProperties": true,
"description": "A k8s native specification of resources, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#resourcerequirements-v1-core).\n"
},
"defaultTarget": {
"type": [
"string",
"null"
],
"description": "Override the URL for the default routing target for the proxy.\nDefaults to JupyterHub itself.\nThis will generally only have an effect while JupyterHub is not running,\nas JupyterHub adds itself as the default target after it starts.\n"
},
"errorTarget": {
"type": [
"string",
"null"
],
"description": "Override the URL for the error target for the proxy.\nDefaults to JupyterHub itself.\nUseful to reduce load on the Hub\nor produce more informative error messages than the Hub's default,\ne.g. in highly customized deployments such as BinderHub.\nSee Configurable HTTP Proxy for details on implementing an error target.\n"
},
"extraPodSpec": {
"type": "object",
"additionalProperties": true,
"description": "Arbitrary extra k8s pod specification as a YAML object. The default\nvalue of this setting is an empty object, i.e. no extra configuration.\nThe value of this property is augmented to the pod specification as-is.\n\nThis is a powerful tool for expert k8s administrators with advanced\nconfiguration requirements. This setting should only be used for\nconfiguration that cannot be accomplished through the other settings.\nMisusing this setting can break your deployment and/or compromise\nyour system security.\n\nThis is one of four related settings for inserting arbitrary pod\nspecification:\n\n1. hub.extraPodSpec\n2. proxy.chp.extraPodSpec\n3. proxy.traefik.extraPodSpec\n4. scheduling.userScheduler.extraPodSpec\n\nOne real-world use of these settings is to enable host networking. For\nexample, to configure host networking for the hub pod, add the\nfollowing to your helm configuration values:\n\n```yaml\nhub:\n extraPodSpec:\n hostNetwork: true\n dnsPolicy: ClusterFirstWithHostNet\n```\n\nLikewise, to configure host networking for the proxy pod, add the\nfollowing:\n\n```yaml\nproxy:\n chp:\n extraPodSpec:\n hostNetwork: true\n dnsPolicy: ClusterFirstWithHostNet\n```\n\nN.B. Host networking has special security implications and can easily\nbreak your deployment. This is an example—not an endorsement.\n\nSee [PodSpec](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec)\nfor the latest pod resource specification.\n"
}
}
},
"secretToken": {
"type": [
"string",
"null"
],
"description": "```{note}\nAs of version 1.0.0 this will automatically be generated and there is\nno need to set it manually.\n\nIf you wish to reset a generated key, you can use `kubectl edit` on\nthe k8s Secret typically named `hub` and remove the\n`hub.config.ConfigurableHTTPProxy.auth_token` entry in the k8s Secret,\nthen perform a new `helm upgrade`.\n```\n\nA 32-byte cryptographically secure randomly generated string used to\nsecure communications between the hub pod and the proxy pod running a\n[configurable-http-proxy](https://github.com/jupyterhub/configurable-http-proxy)\ninstance.\n\n```sh\n# to generate a value, run\nopenssl rand -hex 32\n```\n\nChanging this value will cause the proxy and hub pods to restart. It is good security\npractice to rotate these values over time. If this secret leaks, *immediately* change\nit to something else, or user data can be compromised.\n"
},
"service": {
"type": "object",
"additionalProperties": false,
"description": "Configuration of the k8s Service `proxy-public` which either will\npoint to the `autohttps` pod running Traefik for TLS termination, or\nthe `proxy` pod running ConfigurableHTTPProxy. Incoming traffic from\nusers on the internet should always go through this k8s Service.\n\nWhen this service targets the `autohttps` pod which then routes to the\n`proxy` pod, a k8s Service named `proxy-http` will be added targeting\nthe `proxy` pod and only accepting HTTP traffic on port 80.\n",
"properties": {
"type": {
"enum": [
"ClusterIP",
"NodePort",
"LoadBalancer",
"ExternalName"
],
"description": "Default `LoadBalancer`.\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types)\nto learn more about service types.\n"
},
"labels": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Extra labels to add to the proxy service.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)\nto learn more about labels.\n"
},
"annotations": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Annotations to apply to the service that is exposing the proxy.\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/)\nfor more details about annotations.\n"
},
"nodePorts": {
"type": "object",
"additionalProperties": false,
"description": "Object to set NodePorts to expose the service on for http and https.\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport)\nfor more details about NodePorts.\n",
"properties": {
"http": {
"type": [
"integer",
"null"
],
"description": "The HTTP port the proxy-public service should be exposed on.\n"
},
"https": {
"type": [
"integer",
"null"
],
"description": "The HTTPS port the proxy-public service should be exposed on.\n"
}
}
},
"disableHttpPort": {
"type": "boolean",
"description": "Default `false`.\n\nIf `true`, port 80 for incoming HTTP traffic will no longer be exposed. This should not be used with `proxy.https.type=letsencrypt` or `proxy.https.enabled=false` as it would remove the only exposed port.\n"
},
"extraPorts": {
"type": "array",
"description": "Extra ports the k8s Service should accept incoming traffic on,\nwhich will be redirected to either the `autohttps` pod (treafik)\nor the `proxy` pod (chp).\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#serviceport-v1-core)\nfor the structure of the items in this list.\n"
},
"loadBalancerIP": {
"type": [
"string",
"null"
],
"description": "The public IP address the proxy-public Kubernetes service should\nbe exposed on. This entry will end up at the configurable proxy\nserver that JupyterHub manages, which will direct traffic to user\npods at the `/user` path and the hub pod at the `/hub` path.\n\nSet this if you want to use a fixed external IP address instead of\na dynamically acquired one. This is relevant if you have a domain\nname that you want to point to a specific IP and want to ensure it\ndoesn't change.\n"
},
"loadBalancerSourceRanges": {
"type": "array",
"description": "A list of IP CIDR ranges that are allowed to access the load balancer service.\nDefaults to allowing everyone to access it.\n"
}
}
},
"https": {
"type": "object",
"additionalProperties": false,
"description": "Object for customizing the settings for HTTPS used by the JupyterHub's proxy.\nFor more information on configuring HTTPS for your JupyterHub, see the [HTTPS section in our security guide](https)\n",
"properties": {
"enabled": {
"type": [
"boolean",
"null"
],
"description": "Indicator to set whether HTTPS should be enabled or not on the proxy. Defaults to `true` if the https object is provided.\n"
},
"type": {
"enum": [
null,
"",
"letsencrypt",
"manual",
"offload",
"secret"
],
"description": "The type of HTTPS encryption that is used.\nDecides on which ports and network policies are used for communication via HTTPS. Setting this to `secret` sets the type to manual HTTPS with a secret that has to be provided in the `https.secret` object.\nDefaults to `letsencrypt`.\n"
},
"letsencrypt": {
"type": "object",
"additionalProperties": false,
"properties": {
"contactEmail": {
"type": [
"string",
"null"
],
"description": "The contact email to be used for automatically provisioned HTTPS certificates by Let's Encrypt. For more information see [Set up automatic HTTPS](setup-automatic-https).\nRequired for automatic HTTPS.\n"
},
"acmeServer": {
"type": [
"string",
"null"
],
"description": "Let's Encrypt is one of various ACME servers that can provide\na certificate, and by default their production server is used.\n\nLet's Encrypt staging: https://acme-staging-v02.api.letsencrypt.org/directory\nLet's Encrypt production: acmeServer: https://acme-v02.api.letsencrypt.org/directory\n"
}
}
},
"manual": {
"type": "object",
"additionalProperties": false,
"description": "Object for providing own certificates for manual HTTPS configuration. To be provided when setting `https.type` to `manual`.\nSee [Set up manual HTTPS](setup-manual-https)\n",
"properties": {
"key": {
"type": [
"string",
"null"
],
"description": "The RSA private key to be used for HTTPS.\nTo be provided in the form of\n\n```\nkey: |\n -----BEGIN RSA PRIVATE KEY-----\n ...\n -----END RSA PRIVATE KEY-----\n```\n"
},
"cert": {
"type": [
"string",
"null"
],
"description": "The certificate to be used for HTTPS.\nTo be provided in the form of\n\n```\ncert: |\n -----BEGIN CERTIFICATE-----\n ...\n -----END CERTIFICATE-----\n```\n"
}
}
},
"secret": {
"type": "object",
"additionalProperties": false,
"description": "Secret to be provided when setting `https.type` to `secret`.\n",
"properties": {
"name": {
"type": [
"string",
"null"
],
"description": "Name of the secret\n"
},
"key": {
"type": [
"string",
"null"
],
"description": "Path to the private key to be used for HTTPS.\nExample: `'tls.key'`\n"
},
"crt": {
"type": [
"string",
"null"
],
"description": "Path to the certificate to be used for HTTPS.\nExample: `'tls.crt'`\n"
}
}
},
"hosts": {
"type": "array",
"description": "You domain in list form.\nRequired for automatic HTTPS. See [Set up automatic HTTPS](setup-automatic-https).\nTo be provided like:\n```\nhosts:\n - <your-domain-name>\n```\n"
}
}
},
"traefik": {
"type": "object",
"additionalProperties": false,
"description": "Configure the traefik proxy used to terminate TLS when 'autohttps' is enabled\n",
"properties": {
"revisionHistoryLimit": {
"type": [
"integer",
"null"
],
"minimum": 0,
"description": "Configures the resource's `spec.revisionHistoryLimit`. This is\navailable for Deployment, StatefulSet, and DaemonSet resources.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#revision-history-limit)\nfor more info.\n"
},
"labels": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Extra labels to add to the traefik pod.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)\nto learn more about labels.\n"
},
"networkPolicy": {
"type": "object",
"additionalProperties": false,
"description": "This configuration regards the creation and configuration of a k8s\n_NetworkPolicy resource_.\n",
"properties": {
"enabled": {
"type": "boolean",
"description": "Toggle the creation of the NetworkPolicy resource targeting this\npod, and by doing so, restricting its communication to only what\nis explicitly allowed in the NetworkPolicy.\n"
},
"ingress": {
"type": "array",
"description": "Additional ingress rules to add besides those that are required\nfor core functionality.\n"
},
"egress": {
"type": "array",
"description": "Additional egress rules to add besides those that are required for\ncore functionality and those added via\n[`.egressAllowRules`](schema_hub.networkPolicy.egressAllowRules).\n\n```{versionchanged} 2.0.0\nThe default value changed from providing one very permissive rule\nallowing all egress to providing no rule. The permissive rule is\nstill provided via\n[`.egressAllowRules`](schema_hub.networkPolicy.egressAllowRules)\nset to true though.\n```\n\nAs an example, below is a configuration that disables the more\nbroadly permissive `.privateIPs` egress allow rule for the hub\npod, and instead provides tightly scoped permissions to access a\nspecific k8s local service as identified by pod labels.\n\n```yaml\nhub:\n networkPolicy:\n egressAllowRules:\n privateIPs: false\n egress:\n - to:\n - podSelector:\n matchLabels:\n app: my-k8s-local-service\n ports:\n - protocol: TCP\n port: 5978\n```\n"
},
"egressAllowRules": {
"type": "object",
"additionalProperties": false,
"description": "This is a set of predefined rules that when enabled will be added\nto the NetworkPolicy list of egress rules.\n\nThe resulting egress rules will be a composition of:\n- rules specific for the respective pod(s) function within the\n Helm chart\n- rules based on enabled `egressAllowRules` flags\n- rules explicitly specified by the user\n\n```{note}\nEach flag under this configuration will not render into a\ndedicated rule in the NetworkPolicy resource, but instead combine\nwith the other flags to a reduced set of rules to avoid a\nperformance penalty.\n```\n\n```{versionadded} 2.0.0\nAll `egressAllowRules` are new in JupyterHub Helm chart 2.0.0.\n```\n",
"properties": {
"cloudMetadataServer": {
"type": "boolean",
"description": "Defaults to `false` for singleuser servers, but to `true` for\nall other network policies.\n\nWhen enabled this rule allows the respective pod(s) to\nestablish outbound connections to the cloud metadata server.\n\nNote that the `nonPrivateIPs` rule is allowing all non Private\nIP ranges but makes an exception for the cloud metadata\nserver, leaving this as the definitive configuration to allow\naccess to the cloud metadata server.\n"
},
"dnsPortsPrivateIPs": {
"type": "boolean",
"description": "Defaults to `true` for all network policies.\n\nWhen enabled this rule allows the respective pod(s) to\nestablish outbound connections to private IPs via port 53.\n\nNote that we can't reliably identify the k8s internal DNS\nserver due to variations between k8s clusters. Due to that,\nthis rule which is critical for core functionality, can be\ndisabled for a more refined custom rule.\n"
},
"nonPrivateIPs": {
"type": "boolean",
"description": "Defaults to `true` for all network policies.\n\nWhen enabled this rule allows the respective pod(s) to\nestablish outbound connections to the non-private IP ranges\nwith the exception of the cloud metadata server. This means\nrespective pod(s) can establish connections to the internet\nbut not (say) an unsecured prometheus server running in the\nsame cluster.\n"
},
"privateIPs": {
"type": "boolean",
"description": "Defaults to `false` for singleuser servers, but to `true` for\nall other network policies.\n\nPrivate IPs refer to the IP ranges `10.0.0.0/8`,\n`172.16.0.0/12`, `192.168.0.0/16`.\n\nWhen enabled this rule allows the respective pod(s) to\nestablish outbound connections to the internal k8s cluster.\nThis means users can access the internet but not (say) an\nunsecured prometheus server running in the same cluster.\n\nSince not all workloads in the k8s cluster may have\nNetworkPolicies setup to restrict their incoming connections,\nhaving this set to false can be a good defense against\nmalicious intent from someone in control of software in these\npods.\n\nIf possible, try to avoid setting this to true as it gives\nbroad permissions that could be specified more directly via\nthe [`.egress`](schema_singleuser.networkPolicy.egress).\n"
}
}
},
"interNamespaceAccessLabels": {
"enum": [
"accept",
"ignore"
],
"description": "This configuration option determines if both namespaces and pods\nin other namespaces, that have specific access labels, should be\naccepted to allow ingress (set to `accept`), or, if the labels are\nto be ignored when applied outside the local namespace (set to\n`ignore`).\n\nThe available access labels for respective NetworkPolicy resources\nare:\n\n- `hub.jupyter.org/network-access-hub: \"true\"` (hub)\n- `hub.jupyter.org/network-access-proxy-http: \"true\"` (proxy.chp, proxy.traefik)\n- `hub.jupyter.org/network-access-proxy-api: \"true\"` (proxy.chp)\n- `hub.jupyter.org/network-access-singleuser: \"true\"` (singleuser)\n"
},
"allowedIngressPorts": {
"type": "array",
"description": "A rule to allow ingress on these ports will be added no matter\nwhat the origin of the request is. The default setting for\n`proxy.chp` and `proxy.traefik`'s networkPolicy configuration is\n`[http, https]`, while it is `[]` for other networkPolicies.\n\nNote that these port names or numbers target a Pod's port name or\nnumber, not a k8s Service's port name or number.\n"
}
}
},
"extraInitContainers": {
"type": "array",
"description": "list of extraInitContainers to be run with traefik pod, after the containers set in the chart. See [Kubernetes Docs](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/)\n\n```yaml\nproxy:\n traefik:\n extraInitContainers:\n - name: init-myservice\n image: busybox:1.28\n command: ['sh', '-c', 'command1']\n - name: init-mydb\n image: busybox:1.28\n command: ['sh', '-c', 'command2']\n```\n"
},
"extraEnv": {
"type": [
"object",
"array"
],
"additionalProperties": true,
"description": "Extra environment variables that should be set for the traefik pod.\n\nEnvironment Variables here may be used to configure traefik.\n\nString literals with `$(ENV_VAR_NAME)` will be expanded by Kubelet which\nis a part of Kubernetes.\n\n```yaml\nproxy:\n traefik:\n extraEnv:\n # basic notation (for literal values only)\n MY_ENV_VARS_NAME1: \"my env var value 1\"\n\n # explicit notation (the \"name\" field takes precedence)\n TRAEFIK_NAMESPACE:\n name: TRAEFIK_NAMESPACE\n valueFrom:\n fieldRef:\n fieldPath: metadata.namespace\n\n # implicit notation (the \"name\" field is implied)\n PREFIXED_TRAEFIK_NAMESPACE:\n value: \"my-prefix-$(TRAEFIK_NAMESPACE)\"\n SECRET_VALUE:\n valueFrom:\n secretKeyRef:\n name: my-k8s-secret\n key: password\n```\n\nFor more information, see the [Kubernetes EnvVar\nspecification](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#envvar-v1-core).\n"
},
"pdb": {
"type": "object",
"additionalProperties": false,
"description": "Configure a PodDisruptionBudget for this Deployment.\n\nThese are disabled by default for our deployments that don't support\nbeing run in parallel with multiple replicas. Only the user-scheduler\ncurrently supports being run in parallel with multiple replicas. If\nthey are enabled for a Deployment with only one replica, they will\nblock `kubectl drain` of a node for example.\n\nNote that if you aim to block scaling down a node with the\nhub/proxy/autohttps pod that would cause disruptions of the\ndeployment, then you should instead annotate the pods of the\nDeployment [as described\nhere](https://github.com/kubernetes/autoscaler/blob/HEAD/cluster-autoscaler/FAQ.md#what-types-of-pods-can-prevent-ca-from-removing-a-node).\n\n \"cluster-autoscaler.kubernetes.io/safe-to-evict\": \"false\"\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/)\nfor more details about disruptions.\n",
"properties": {
"enabled": {
"type": "boolean",
"description": "Decides if a PodDisruptionBudget is created targeting the\nDeployment's pods.\n"
},
"maxUnavailable": {
"type": [
"integer",
"null"
],
"description": "The maximum number of pods that can be unavailable during\nvoluntary disruptions.\n"
},
"minAvailable": {
"type": [
"integer",
"null"
],
"description": "The minimum number of pods required to be available during\nvoluntary disruptions.\n"
}
}
},
"nodeSelector": {
"type": "object",
"additionalProperties": true,
"description": "An object with key value pairs representing labels. K8s Nodes are\nrequired to have match all these labels for this Pod to scheduled on\nthem.\n\n```yaml\ndisktype: ssd\nnodetype: awesome\n```\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector)\nfor more details.\n"
},
"tolerations": {
"type": "array",
"description": "Tolerations allow a pod to be scheduled on nodes with taints. These\ntolerations are additional tolerations to the tolerations common to\nall pods of a their respective kind\n([scheduling.corePods.tolerations](schema_scheduling.corePods.tolerations),\n[scheduling.userPods.tolerations](schema_scheduling.userPods.tolerations)).\n\nPass this field an array of\n[`Toleration`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#toleration-v1-core)\nobjects.\n\nSee the [Kubernetes\ndocs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)\nfor more info.\n"
},
"containerSecurityContext": {
"type": "object",
"additionalProperties": true,
"description": "A k8s native specification of the container's security context, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core)\nfor details.\n"
},
"extraDynamicConfig": {
"type": "object",
"additionalProperties": true,
"description": "This refers to traefik's post-startup configuration.\n\nThis Helm chart already provide such configuration, so this is a\nplace where you can merge in additional configuration. If you are\nabout to use this configuration, you may want to inspect the\ndefault configuration declared\n[here](https://github.com/jupyterhub/zero-to-jupyterhub-k8s/blob/HEAD/jupyterhub/templates/proxy/autohttps/_configmap-dynamic.yaml).\n"
},
"extraPorts": {
"type": "array",
"description": "Extra ports for the traefik container within the autohttps pod\nthat you would like to expose, formatted in a k8s native way.\n"
},
"extraStaticConfig": {
"type": "object",
"additionalProperties": true,
"description": "This refers to traefik's startup configuration.\n\nThis Helm chart already provide such configuration, so this is a\nplace where you can merge in additional configuration. If you are\nabout to use this configuration, you may want to inspect the\ndefault configuration declared\n[here](https://github.com/jupyterhub/zero-to-jupyterhub-k8s/blob/HEAD/jupyterhub/templates/proxy/autohttps/_configmap-traefik.yaml).\n"
},
"extraVolumes": {
"type": "array",
"description": "Additional volumes for the Pod. Use a k8s native syntax.\n"
},
"extraVolumeMounts": {
"type": "array",
"description": "Additional volume mounts for the Container. Use a k8s native syntax.\n"
},
"hsts": {
"type": "object",
"additionalProperties": false,
"required": [
"includeSubdomains",
"maxAge",
"preload"
],
"description": "This section regards a HTTP Strict-Transport-Security (HSTS)\nresponse header. It can act as a request for a visiting web\nbrowsers to enforce HTTPS on their end in for a given time into\nthe future, and optionally also for future requests to subdomains.\n\nThese settings relate to traefik configuration which we use as a\nTLS termination proxy.\n\nSee [Mozilla's\ndocumentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security)\nfor more information.\n",
"properties": {
"includeSubdomains": {
"type": "boolean"
},
"maxAge": {
"type": "integer"
},
"preload": {
"type": "boolean"
}
}
},
"image": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"tag"
],
"description": "Set custom image name, tag, pullPolicy, or pullSecrets for the pod.\n",
"properties": {
"name": {
"type": "string",
"description": "The name of the image, without the tag.\n\n```\n# example name\ngcr.io/my-project/my-image\n```\n"
},
"tag": {
"type": "string",
"description": "The tag of the image to pull. This is the value following `:` in\ncomplete image specifications.\n\n```\n# example tags\nv1.11.1\nzhy270a\n```\n"
},
"pullPolicy": {
"enum": [
null,
"",
"IfNotPresent",
"Always",
"Never"
],
"description": "Configures the Pod's `spec.imagePullPolicy`.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/containers/images/#updating-images)\nfor more info.\n"
},
"pullSecrets": {
"type": "array",
"description": "A list of references to existing Kubernetes Secrets with\ncredentials to pull the image.\n\nThis Pod's final `imagePullSecrets` k8s specification will be a\ncombination of:\n\n1. This list of k8s Secrets, specific for this pod.\n2. The list of k8s Secrets, for use by all pods in the Helm chart,\n declared in this Helm charts configuration called\n `imagePullSecrets`.\n3. A k8s Secret, for use by all pods in the Helm chart, if\n conditionally created from image registry credentials provided\n under `imagePullSecret` if `imagePullSecret.create` is set to\n true.\n\n```yaml\n# example - k8s native syntax\npullSecrets:\n - name: my-k8s-secret-with-image-registry-credentials\n\n# example - simplified syntax\npullSecrets:\n - my-k8s-secret-with-image-registry-credentials\n```\n"
}
}
},
"resources": {
"type": "object",
"additionalProperties": true,
"description": "A k8s native specification of resources, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#resourcerequirements-v1-core).\n"
},
"serviceAccount": {
"type": "object",
"required": [
"create"
],
"additionalProperties": false,
"description": "Configuration for a k8s ServiceAccount dedicated for use by the\nspecific pod which this configuration is nested under.\n",
"properties": {
"create": {
"type": "boolean",
"description": "Whether or not to create the `ServiceAccount` resource.\n"
},
"name": {
"type": [
"string",
"null"
],
"description": "This configuration serves multiple purposes:\n\n- It will be the `serviceAccountName` referenced by related Pods.\n- If `create` is set, the created ServiceAccount resource will be named like this.\n- If [`rbac.create`](schema_rbac.create) is set, the associated (Cluster)RoleBindings will bind to this name.\n\nIf not explicitly provided, a default name will be used.\n"
},
"annotations": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Kubernetes annotations to apply to the k8s ServiceAccount.\n"
}
}
},
"extraPodSpec": {
"type": "object",
"additionalProperties": true,
"description": "Arbitrary extra k8s pod specification as a YAML object. The default\nvalue of this setting is an empty object, i.e. no extra configuration.\nThe value of this property is augmented to the pod specification as-is.\n\nThis is a powerful tool for expert k8s administrators with advanced\nconfiguration requirements. This setting should only be used for\nconfiguration that cannot be accomplished through the other settings.\nMisusing this setting can break your deployment and/or compromise\nyour system security.\n\nThis is one of four related settings for inserting arbitrary pod\nspecification:\n\n1. hub.extraPodSpec\n2. proxy.chp.extraPodSpec\n3. proxy.traefik.extraPodSpec\n4. scheduling.userScheduler.extraPodSpec\n\nOne real-world use of these settings is to enable host networking. For\nexample, to configure host networking for the hub pod, add the\nfollowing to your helm configuration values:\n\n```yaml\nhub:\n extraPodSpec:\n hostNetwork: true\n dnsPolicy: ClusterFirstWithHostNet\n```\n\nLikewise, to configure host networking for the proxy pod, add the\nfollowing:\n\n```yaml\nproxy:\n chp:\n extraPodSpec:\n hostNetwork: true\n dnsPolicy: ClusterFirstWithHostNet\n```\n\nN.B. Host networking has special security implications and can easily\nbreak your deployment. This is an example—not an endorsement.\n\nSee [PodSpec](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec)\nfor the latest pod resource specification.\n"
}
}
},
"labels": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "K8s labels for the proxy pod.\n\n```{note}\nFor consistency, this should really be located under\nproxy.chp.labels but isn't for historical reasons.\n```\n"
},
"annotations": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "K8s annotations for the proxy pod.\n\n```{note}\nFor consistency, this should really be located under\nproxy.chp.annotations but isn't for historical reasons.\n```\n"
},
"deploymentStrategy": {
"type": "object",
"additionalProperties": false,
"properties": {
"rollingUpdate": {
"type": [
"string",
"null"
]
},
"type": {
"type": [
"string",
"null"
],
"description": "While the proxy pod running\n[configurable-http-proxy](https://github.com/jupyterhub/configurable-http-proxy)\ncould run in parallel, two instances running in parallel wouldn't\nboth receive updates from JupyterHub regarding how it should route\ntraffic. Due to this we default to using a deployment strategy of\nRecreate instead of RollingUpdate.\n"
}
}
},
"secretSync": {
"type": "object",
"additionalProperties": false,
"description": "This configuration section refers to configuration of the sidecar\ncontainer in the autohttps pod running next to its traefik container\nresponsible for TLS termination.\n\nThe purpose of this container is to store away and load TLS\ncertificates from a k8s Secret. The TLS certificates are acquired by\nthe ACME client (LEGO) that is running within the traefik container,\nwhere traefik is using them for TLS termination.\n",
"properties": {
"containerSecurityContext": {
"type": "object",
"additionalProperties": true,
"description": "A k8s native specification of the container's security context, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core)\nfor details.\n"
},
"image": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"tag"
],
"description": "Set custom image name, tag, pullPolicy, or pullSecrets for the pod.\n",
"properties": {
"name": {
"type": "string",
"description": "The name of the image, without the tag.\n\n```\n# example name\ngcr.io/my-project/my-image\n```\n"
},
"tag": {
"type": "string",
"description": "The tag of the image to pull. This is the value following `:` in\ncomplete image specifications.\n\n```\n# example tags\nv1.11.1\nzhy270a\n```\n"
},
"pullPolicy": {
"enum": [
null,
"",
"IfNotPresent",
"Always",
"Never"
],
"description": "Configures the Pod's `spec.imagePullPolicy`.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/containers/images/#updating-images)\nfor more info.\n"
},
"pullSecrets": {
"type": "array",
"description": "A list of references to existing Kubernetes Secrets with\ncredentials to pull the image.\n\nThis Pod's final `imagePullSecrets` k8s specification will be a\ncombination of:\n\n1. This list of k8s Secrets, specific for this pod.\n2. The list of k8s Secrets, for use by all pods in the Helm chart,\n declared in this Helm charts configuration called\n `imagePullSecrets`.\n3. A k8s Secret, for use by all pods in the Helm chart, if\n conditionally created from image registry credentials provided\n under `imagePullSecret` if `imagePullSecret.create` is set to\n true.\n\n```yaml\n# example - k8s native syntax\npullSecrets:\n - name: my-k8s-secret-with-image-registry-credentials\n\n# example - simplified syntax\npullSecrets:\n - my-k8s-secret-with-image-registry-credentials\n```\n"
}
}
},
"resources": {
"type": "object",
"additionalProperties": true,
"description": "A k8s native specification of resources, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#resourcerequirements-v1-core).\n"
}
}
}
}
},
"singleuser": {
"type": "object",
"additionalProperties": false,
"description": "Options for customizing the environment that is provided to the users after they log in.\n",
"properties": {
"networkPolicy": {
"type": "object",
"additionalProperties": false,
"description": "This configuration regards the creation and configuration of a k8s\n_NetworkPolicy resource_.\n",
"properties": {
"enabled": {
"type": "boolean",
"description": "Toggle the creation of the NetworkPolicy resource targeting this\npod, and by doing so, restricting its communication to only what\nis explicitly allowed in the NetworkPolicy.\n"
},
"ingress": {
"type": "array",
"description": "Additional ingress rules to add besides those that are required\nfor core functionality.\n"
},
"egress": {
"type": "array",
"description": "Additional egress rules to add besides those that are required for\ncore functionality and those added via\n[`.egressAllowRules`](schema_hub.networkPolicy.egressAllowRules).\n\n```{versionchanged} 2.0.0\nThe default value changed from providing one very permissive rule\nallowing all egress to providing no rule. The permissive rule is\nstill provided via\n[`.egressAllowRules`](schema_hub.networkPolicy.egressAllowRules)\nset to true though.\n```\n\nAs an example, below is a configuration that disables the more\nbroadly permissive `.privateIPs` egress allow rule for the hub\npod, and instead provides tightly scoped permissions to access a\nspecific k8s local service as identified by pod labels.\n\n```yaml\nhub:\n networkPolicy:\n egressAllowRules:\n privateIPs: false\n egress:\n - to:\n - podSelector:\n matchLabels:\n app: my-k8s-local-service\n ports:\n - protocol: TCP\n port: 5978\n```\n"
},
"egressAllowRules": {
"type": "object",
"additionalProperties": false,
"description": "This is a set of predefined rules that when enabled will be added\nto the NetworkPolicy list of egress rules.\n\nThe resulting egress rules will be a composition of:\n- rules specific for the respective pod(s) function within the\n Helm chart\n- rules based on enabled `egressAllowRules` flags\n- rules explicitly specified by the user\n\n```{note}\nEach flag under this configuration will not render into a\ndedicated rule in the NetworkPolicy resource, but instead combine\nwith the other flags to a reduced set of rules to avoid a\nperformance penalty.\n```\n\n```{versionadded} 2.0.0\nAll `egressAllowRules` are new in JupyterHub Helm chart 2.0.0.\n```\n",
"properties": {
"cloudMetadataServer": {
"type": "boolean",
"description": "Defaults to `false` for singleuser servers, but to `true` for\nall other network policies.\n\nWhen enabled this rule allows the respective pod(s) to\nestablish outbound connections to the cloud metadata server.\n\nNote that the `nonPrivateIPs` rule is allowing all non Private\nIP ranges but makes an exception for the cloud metadata\nserver, leaving this as the definitive configuration to allow\naccess to the cloud metadata server.\n"
},
"dnsPortsPrivateIPs": {
"type": "boolean",
"description": "Defaults to `true` for all network policies.\n\nWhen enabled this rule allows the respective pod(s) to\nestablish outbound connections to private IPs via port 53.\n\nNote that we can't reliably identify the k8s internal DNS\nserver due to variations between k8s clusters. Due to that,\nthis rule which is critical for core functionality, can be\ndisabled for a more refined custom rule.\n"
},
"nonPrivateIPs": {
"type": "boolean",
"description": "Defaults to `true` for all network policies.\n\nWhen enabled this rule allows the respective pod(s) to\nestablish outbound connections to the non-private IP ranges\nwith the exception of the cloud metadata server. This means\nrespective pod(s) can establish connections to the internet\nbut not (say) an unsecured prometheus server running in the\nsame cluster.\n"
},
"privateIPs": {
"type": "boolean",
"description": "Defaults to `false` for singleuser servers, but to `true` for\nall other network policies.\n\nPrivate IPs refer to the IP ranges `10.0.0.0/8`,\n`172.16.0.0/12`, `192.168.0.0/16`.\n\nWhen enabled this rule allows the respective pod(s) to\nestablish outbound connections to the internal k8s cluster.\nThis means users can access the internet but not (say) an\nunsecured prometheus server running in the same cluster.\n\nSince not all workloads in the k8s cluster may have\nNetworkPolicies setup to restrict their incoming connections,\nhaving this set to false can be a good defense against\nmalicious intent from someone in control of software in these\npods.\n\nIf possible, try to avoid setting this to true as it gives\nbroad permissions that could be specified more directly via\nthe [`.egress`](schema_singleuser.networkPolicy.egress).\n"
}
}
},
"interNamespaceAccessLabels": {
"enum": [
"accept",
"ignore"
],
"description": "This configuration option determines if both namespaces and pods\nin other namespaces, that have specific access labels, should be\naccepted to allow ingress (set to `accept`), or, if the labels are\nto be ignored when applied outside the local namespace (set to\n`ignore`).\n\nThe available access labels for respective NetworkPolicy resources\nare:\n\n- `hub.jupyter.org/network-access-hub: \"true\"` (hub)\n- `hub.jupyter.org/network-access-proxy-http: \"true\"` (proxy.chp, proxy.traefik)\n- `hub.jupyter.org/network-access-proxy-api: \"true\"` (proxy.chp)\n- `hub.jupyter.org/network-access-singleuser: \"true\"` (singleuser)\n"
},
"allowedIngressPorts": {
"type": "array",
"description": "A rule to allow ingress on these ports will be added no matter\nwhat the origin of the request is. The default setting for\n`proxy.chp` and `proxy.traefik`'s networkPolicy configuration is\n`[http, https]`, while it is `[]` for other networkPolicies.\n\nNote that these port names or numbers target a Pod's port name or\nnumber, not a k8s Service's port name or number.\n"
}
}
},
"podNameTemplate": {
"type": [
"string",
"null"
],
"description": "Passthrough configuration for\n[KubeSpawner.pod_name_template](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html#kubespawner.KubeSpawner.pod_name_template).\n"
},
"cpu": {
"type": "object",
"additionalProperties": false,
"description": "Set CPU limits & guarantees that are enforced for each user.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/)\nfor more info.\n",
"properties": {
"limit": {
"type": [
"number",
"null"
]
},
"guarantee": {
"type": [
"number",
"null"
]
}
}
},
"memory": {
"type": "object",
"additionalProperties": false,
"description": "Set Memory limits & guarantees that are enforced for each user.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/)\nfor more info.\n",
"properties": {
"limit": {
"type": [
"number",
"string",
"null"
]
},
"guarantee": {
"type": [
"number",
"string",
"null"
],
"description": "Note that this field is referred to as *requests* by the Kubernetes API.\n"
}
}
},
"image": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"tag"
],
"description": "Set custom image name, tag, pullPolicy, or pullSecrets for the pod.\n",
"properties": {
"name": {
"type": "string",
"description": "The name of the image, without the tag.\n\n```\n# example name\ngcr.io/my-project/my-image\n```\n"
},
"tag": {
"type": "string",
"description": "The tag of the image to pull. This is the value following `:` in\ncomplete image specifications.\n\n```\n# example tags\nv1.11.1\nzhy270a\n```\n"
},
"pullPolicy": {
"enum": [
null,
"",
"IfNotPresent",
"Always",
"Never"
],
"description": "Configures the Pod's `spec.imagePullPolicy`.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/containers/images/#updating-images)\nfor more info.\n"
},
"pullSecrets": {
"type": "array",
"description": "A list of references to existing Kubernetes Secrets with\ncredentials to pull the image.\n\nThis Pod's final `imagePullSecrets` k8s specification will be a\ncombination of:\n\n1. This list of k8s Secrets, specific for this pod.\n2. The list of k8s Secrets, for use by all pods in the Helm chart,\n declared in this Helm charts configuration called\n `imagePullSecrets`.\n3. A k8s Secret, for use by all pods in the Helm chart, if\n conditionally created from image registry credentials provided\n under `imagePullSecret` if `imagePullSecret.create` is set to\n true.\n\n```yaml\n# example - k8s native syntax\npullSecrets:\n - name: my-k8s-secret-with-image-registry-credentials\n\n# example - simplified syntax\npullSecrets:\n - my-k8s-secret-with-image-registry-credentials\n```\n"
}
}
},
"initContainers": {
"type": "array",
"description": "list of initContainers to be run every singleuser pod. See [Kubernetes Docs](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/)\n\n```yaml\nsingleuser:\n initContainers:\n - name: init-myservice\n image: busybox:1.28\n command: ['sh', '-c', 'command1']\n - name: init-mydb\n image: busybox:1.28\n command: ['sh', '-c', 'command2']\n```\n"
},
"profileList": {
"type": "array",
"description": "For more information about the profile list, see [KubeSpawner's\ndocumentation](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html#kubespawner.KubeSpawner)\nas this is simply a passthrough to that configuration.\n\n```{note}\nThe image-pullers are aware of the overrides of images in\n`singleuser.profileList` but they won't be if you configure it in\nJupyterHub's configuration of '`c.KubeSpawner.profile_list`.\n```\n\n```yaml\nsingleuser:\n profileList:\n - display_name: \"Default: Shared, 8 CPU cores\"\n description: \"Your code will run on a shared machine with CPU only.\"\n default: True\n - display_name: \"Personal, 4 CPU cores & 26GB RAM, 1 NVIDIA Tesla K80 GPU\"\n description: \"Your code will run a personal machine with a GPU.\"\n kubespawner_override:\n extra_resource_limits:\n nvidia.com/gpu: \"1\"\n```\n"
},
"extraFiles": {
"type": "object",
"additionalProperties": false,
"description": "A dictionary with extra files to be injected into the pod's container\non startup. This can for example be used to inject: configuration\nfiles, custom user interface templates, images, and more.\n\n```yaml\n# NOTE: \"hub\" is used in this example, but the configuration is the\n# same for \"singleuser\".\nhub:\n extraFiles:\n # The file key is just a reference that doesn't influence the\n # actual file name.\n <file key>:\n # mountPath is required and must be the absolute file path.\n mountPath: <full file path>\n\n # Choose one out of the three ways to represent the actual file\n # content: data, stringData, or binaryData.\n #\n # data should be set to a mapping (dictionary). It will in the\n # end be rendered to either YAML, JSON, or TOML based on the\n # filename extension that are required to be either .yaml, .yml,\n # .json, or .toml.\n #\n # If your content is YAML, JSON, or TOML, it can make sense to\n # use data to represent it over stringData as data can be merged\n # instead of replaced if set partially from separate Helm\n # configuration files.\n #\n # Both stringData and binaryData should be set to a string\n # representing the content, where binaryData should be the\n # base64 encoding of the actual file content.\n #\n data:\n myConfig:\n myMap:\n number: 123\n string: \"hi\"\n myList:\n - 1\n - 2\n stringData: |\n hello world!\n binaryData: aGVsbG8gd29ybGQhCg==\n\n # mode is by default 0644 and you can optionally override it\n # either by octal notation (example: 0400) or decimal notation\n # (example: 256).\n mode: <file system permissions>\n```\n\n**Using --set-file**\n\nTo avoid embedding entire files in the Helm chart configuration, you\ncan use the `--set-file` flag during `helm upgrade` to set the\nstringData or binaryData field.\n\n```yaml\nhub:\n extraFiles:\n my_image:\n mountPath: /usr/local/share/jupyterhub/static/my_image.png\n\n # Files in /usr/local/etc/jupyterhub/jupyterhub_config.d are\n # automatically loaded in alphabetical order of the final file\n # name when JupyterHub starts.\n my_config:\n mountPath: /usr/local/etc/jupyterhub/jupyterhub_config.d/my_jupyterhub_config.py\n```\n\n```bash\n# --set-file expects a text based file, so you need to base64 encode\n# it manually first.\nbase64 my_image.png > my_image.png.b64\n\nhelm upgrade <...> \\\n --set-file hub.extraFiles.my_image.binaryData=./my_image.png.b64 \\\n --set-file hub.extraFiles.my_config.stringData=./my_jupyterhub_config.py\n```\n\n**Common uses**\n\n1. **JupyterHub template customization**\n\n You can replace the default JupyterHub user interface templates in\n the hub pod by injecting new ones to\n `/usr/local/share/jupyterhub/templates`. These can in turn\n reference custom images injected to\n `/usr/local/share/jupyterhub/static`.\n\n1. **JupyterHub standalone file config**\n\n Instead of embedding JupyterHub python configuration as a string\n within a YAML file through\n [`hub.extraConfig`](schema_hub.extraConfig), you can inject a\n standalone .py file into\n `/usr/local/etc/jupyterhub/jupyterhub_config.d` that is\n automatically loaded.\n\n1. **Flexible configuration**\n\n By injecting files, you don't have to embed them in a docker image\n that you have to rebuild.\n\n If your configuration file is a YAML/JSON/TOML file, you can also\n use `data` instead of `stringData` which allow you to set various\n configuration in separate Helm config files. This can be useful to\n help dependent charts override only some configuration part of the\n file, or to allow for the configuration be set through multiple\n Helm configuration files.\n\n**Limitations**\n\n1. File size\n\n The files in `hub.extraFiles` and `singleuser.extraFiles` are\n respectively stored in their own k8s Secret resource. As k8s\n Secret's are limited, typically to 1MB, you will be limited to a\n total file size of less than 1MB as there is also base64 encoding\n that takes place reducing available capacity to 75%.\n\n2. File updates\n\n The files that are mounted are only set during container startup.\n This is [because we use\n `subPath`](https://kubernetes.io/docs/concepts/storage/volumes/#secret)\n as is required to avoid replacing the content of the entire\n directory we mount in.\n",
"patternProperties": {
".*": {
"type": "object",
"additionalProperties": false,
"required": [
"mountPath"
],
"oneOf": [
{
"required": [
"data"
]
},
{
"required": [
"stringData"
]
},
{
"required": [
"binaryData"
]
}
],
"properties": {
"mountPath": {
"type": "string"
},
"data": {
"type": "object",
"additionalProperties": true
},
"stringData": {
"type": "string"
},
"binaryData": {
"type": "string"
},
"mode": {
"type": "number"
}
}
}
}
},
"extraEnv": {
"type": [
"object",
"array"
],
"additionalProperties": true,
"description": "Extra environment variables that should be set for the user pods.\n\nString literals with `$(ENV_VAR_NAME)` will be expanded by Kubelet which\nis a part of Kubernetes. Note that the user pods will already have\naccess to a set of environment variables that you can use, like\n`JUPYTERHUB_USER` and `JUPYTERHUB_HOST`. For more information about these\ninspect [this source\ncode](https://github.com/jupyterhub/jupyterhub/blob/cc8e7806530466dce8968567d1bbd2b39a7afa26/jupyterhub/spawner.py#L763).\n\n```yaml\nsingleuser:\n extraEnv:\n # basic notation (for literal values only)\n MY_ENV_VARS_NAME1: \"my env var value 1\"\n\n # explicit notation (the \"name\" field takes precedence)\n USER_NAMESPACE:\n name: USER_NAMESPACE\n valueFrom:\n fieldRef:\n fieldPath: metadata.namespace\n\n # implicit notation (the \"name\" field is implied)\n PREFIXED_USER_NAMESPACE:\n value: \"my-prefix-$(USER_NAMESPACE)\"\n SECRET_VALUE:\n valueFrom:\n secretKeyRef:\n name: my-k8s-secret\n key: password\n```\n\nFor more information, see the [Kubernetes EnvVar\nspecification](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#envvar-v1-core).\n"
},
"nodeSelector": {
"type": "object",
"additionalProperties": true,
"description": "An object with key value pairs representing labels. K8s Nodes are\nrequired to have match all these labels for this Pod to scheduled on\nthem.\n\n```yaml\ndisktype: ssd\nnodetype: awesome\n```\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector)\nfor more details.\n"
},
"extraTolerations": {
"type": "array",
"description": "Tolerations allow a pod to be scheduled on nodes with taints. These\ntolerations are additional tolerations to the tolerations common to\nall pods of a their respective kind\n([scheduling.corePods.tolerations](schema_scheduling.corePods.tolerations),\n[scheduling.userPods.tolerations](schema_scheduling.userPods.tolerations)).\n\nPass this field an array of\n[`Toleration`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#toleration-v1-core)\nobjects.\n\nSee the [Kubernetes\ndocs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)\nfor more info.\n"
},
"extraNodeAffinity": {
"type": "object",
"additionalProperties": false,
"description": "Affinities describe where pods prefer or require to be scheduled, they\nmay prefer or require a node where they are to be scheduled to have a\ncertain label (node affinity). They may also require to be scheduled\nin proximity or with a lack of proximity to another pod (pod affinity\nand anti pod affinity).\n\nSee the [Kubernetes\ndocs](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/)\nfor more info.\n",
"properties": {
"required": {
"type": "array",
"description": "Pass this field an array of\n[`NodeSelectorTerm`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#nodeselectorterm-v1-core)\nobjects.\n"
},
"preferred": {
"type": "array",
"description": "Pass this field an array of\n[`PreferredSchedulingTerm`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#preferredschedulingterm-v1-core)\nobjects.\n"
}
}
},
"extraPodAffinity": {
"type": "object",
"additionalProperties": false,
"description": "See the description of `singleuser.extraNodeAffinity`.\n",
"properties": {
"required": {
"type": "array",
"description": "Pass this field an array of\n[`PodAffinityTerm`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podaffinityterm-v1-core)\nobjects.\n"
},
"preferred": {
"type": "array",
"description": "Pass this field an array of\n[`WeightedPodAffinityTerm`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#weightedpodaffinityterm-v1-core)\nobjects.\n"
}
}
},
"extraPodAntiAffinity": {
"type": "object",
"additionalProperties": false,
"description": "See the description of `singleuser.extraNodeAffinity`.\n",
"properties": {
"required": {
"type": "array",
"description": "Pass this field an array of\n[`PodAffinityTerm`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podaffinityterm-v1-core)\nobjects.\n"
},
"preferred": {
"type": "array",
"description": "Pass this field an array of\n[`WeightedPodAffinityTerm`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#weightedpodaffinityterm-v1-core)\nobjects.\n"
}
}
},
"cloudMetadata": {
"type": "object",
"additionalProperties": false,
"description": "Please refer to dedicated section in [the Helm chart\ndocumentation](block-metadata-iptables) for more information about\nthis.\n",
"properties": {
"blockWithIptables": {
"type": "boolean"
},
"ip": {
"type": "string"
}
}
},
"cmd": {
"type": [
"array",
"string",
"null"
],
"description": "Passthrough configuration for\n[KubeSpawner.cmd](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html#kubespawner.KubeSpawner.cmd).\nThe default is \"jupyterhub-singleuser\".\nUse `cmd: null` to launch a custom CMD from the image,\nwhich must launch jupyterhub-singleuser or an equivalent process eventually.\nFor example: Jupyter's docker-stacks images.\n"
},
"defaultUrl": {
"type": [
"string",
"null"
],
"description": "Passthrough configuration for\n[KubeSpawner.default_url](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html#kubespawner.KubeSpawner.default_url).\n"
},
"events": {
"type": [
"boolean",
"null"
],
"description": "Passthrough configuration for\n[KubeSpawner.events_enabled](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html#kubespawner.KubeSpawner.events_enabled).\n"
},
"extraAnnotations": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Passthrough configuration for\n[KubeSpawner.extra_annotations](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html#kubespawner.KubeSpawner.extra_annotations).\n"
},
"extraContainers": {
"type": "array",
"description": "Passthrough configuration for\n[KubeSpawner.extra_containers](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html#kubespawner.KubeSpawner.extra_containers).\n"
},
"extraLabels": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Passthrough configuration for\n[KubeSpawner.extra_labels](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html#kubespawner.KubeSpawner.extra_labels).\n"
},
"extraPodConfig": {
"type": "object",
"additionalProperties": true,
"description": "Passthrough configuration for\n[KubeSpawner.extra_pod_config](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html#kubespawner.KubeSpawner.extra_pod_config).\n"
},
"extraResource": {
"type": "object",
"additionalProperties": false,
"properties": {
"guarantees": {
"type": "object",
"additionalProperties": true,
"description": "Passthrough configuration for\n[KubeSpawner.extra_resource_guarantees](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html#kubespawner.KubeSpawner.extra_resource_guarantees).\n"
},
"limits": {
"type": "object",
"additionalProperties": true,
"description": "Passthrough configuration for\n[KubeSpawner.extra_resource_limits](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html#kubespawner.KubeSpawner.extra_resource_limits).\n"
}
}
},
"fsGid": {
"type": [
"integer",
"null"
],
"description": "Passthrough configuration for\n[KubeSpawner.fs_gid](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html#kubespawner.KubeSpawner.fs_gid).\n"
},
"lifecycleHooks": {
"type": "object",
"additionalProperties": false,
"description": "Passthrough configuration for\n[KubeSpawner.lifecycle_hooks](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html#kubespawner.KubeSpawner.lifecycle_hooks).\n",
"properties": {
"postStart": {
"type": "object",
"additionalProperties": true
},
"preStop": {
"type": "object",
"additionalProperties": true
}
}
},
"networkTools": {
"type": "object",
"additionalProperties": false,
"description": "This configuration section refers to configuration of a conditionally\ncreated initContainer for the user pods with a purpose to block a\nspecific IP address.\n\nThis initContainer will be created if\n[`singleuser.cloudMetadata.blockWithIptables`](schema_singleuser.cloudMetadata.blockWithIptables)\nis set to true.\n",
"properties": {
"image": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"tag"
],
"description": "Set custom image name, tag, pullPolicy, or pullSecrets for the pod.\n",
"properties": {
"name": {
"type": "string",
"description": "The name of the image, without the tag.\n\n```\n# example name\ngcr.io/my-project/my-image\n```\n"
},
"tag": {
"type": "string",
"description": "The tag of the image to pull. This is the value following `:` in\ncomplete image specifications.\n\n```\n# example tags\nv1.11.1\nzhy270a\n```\n"
},
"pullPolicy": {
"enum": [
null,
"",
"IfNotPresent",
"Always",
"Never"
],
"description": "Configures the Pod's `spec.imagePullPolicy`.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/containers/images/#updating-images)\nfor more info.\n"
},
"pullSecrets": {
"type": "array",
"description": "A list of references to existing Kubernetes Secrets with\ncredentials to pull the image.\n\nThis Pod's final `imagePullSecrets` k8s specification will be a\ncombination of:\n\n1. This list of k8s Secrets, specific for this pod.\n2. The list of k8s Secrets, for use by all pods in the Helm chart,\n declared in this Helm charts configuration called\n `imagePullSecrets`.\n3. A k8s Secret, for use by all pods in the Helm chart, if\n conditionally created from image registry credentials provided\n under `imagePullSecret` if `imagePullSecret.create` is set to\n true.\n\n```yaml\n# example - k8s native syntax\npullSecrets:\n - name: my-k8s-secret-with-image-registry-credentials\n\n# example - simplified syntax\npullSecrets:\n - my-k8s-secret-with-image-registry-credentials\n```\n"
}
}
},
"resources": {
"type": "object",
"additionalProperties": true,
"description": "A k8s native specification of resources, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#resourcerequirements-v1-core).\n"
}
}
},
"serviceAccountName": {
"type": [
"string",
"null"
],
"description": "Passthrough configuration for\n[KubeSpawner.service_account](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html#kubespawner.KubeSpawner.service_account).\n"
},
"startTimeout": {
"type": [
"integer",
"null"
],
"description": "Passthrough configuration for\n[KubeSpawner.start_timeout](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html#kubespawner.KubeSpawner.start_timeout).\n"
},
"storage": {
"type": "object",
"additionalProperties": false,
"required": [
"type",
"homeMountPath"
],
"description": "This section configures KubeSpawner directly to some extent but also\nindirectly through Helm chart specific configuration options such as\n[`singleuser.storage.type`](schema_singleuser.storage.type).\n",
"properties": {
"capacity": {
"type": [
"string",
"null"
],
"description": "Configures `KubeSpawner.storage_capacity`.\n\nSee the [KubeSpawner\ndocumentation](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html)\nfor more information.\n"
},
"dynamic": {
"type": "object",
"additionalProperties": false,
"properties": {
"pvcNameTemplate": {
"type": [
"string",
"null"
],
"description": "Configures `KubeSpawner.pvc_name_template` which will be the\nresource name of the PVC created by KubeSpawner for each user\nif needed.\n"
},
"storageAccessModes": {
"type": "array",
"items": {
"type": [
"string",
"null"
]
},
"description": "Configures `KubeSpawner.storage_access_modes`.\n\nSee KubeSpawners documentation and [the k8s\ndocumentation](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes)\nfor more information.\n"
},
"storageClass": {
"type": [
"string",
"null"
],
"description": "Configures `KubeSpawner.storage_class`, which can be an\nexplicit StorageClass to dynamically provision storage for the\nPVC that KubeSpawner will create.\n\nThere is of a default StorageClass available in k8s clusters\nfor use if this is unspecified.\n"
},
"volumeNameTemplate": {
"type": [
"string",
"null"
],
"description": "Configures `KubeSpawner.volume_name_template`, which is the\nname to reference from the containers volumeMounts section.\n"
}
}
},
"extraLabels": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Configures `KubeSpawner.storage_extra_labels`. Note that these\nlabels are set on the PVC during creation only and won't be\nupdated after creation.\n"
},
"extraVolumeMounts": {
"type": "array",
"description": "Additional volume mounts for the Container. Use a k8s native syntax.\n"
},
"extraVolumes": {
"type": "array",
"description": "Additional volumes for the Pod. Use a k8s native syntax.\n"
},
"homeMountPath": {
"type": "string",
"description": "The location within the container where the home folder storage\nshould be mounted.\n"
},
"static": {
"type": "object",
"additionalProperties": false,
"properties": {
"pvcName": {
"type": [
"string",
"null"
],
"description": "Configures `KubeSpawner.pvc_claim_name` to reference\npre-existing storage.\n"
},
"subPath": {
"type": [
"string",
"null"
],
"description": "Configures the `subPath` field of a\n`KubeSpawner.volume_mounts` entry added by the Helm chart.\n\nPath within the volume from which the container's volume\nshould be mounted.\n"
}
}
},
"type": {
"enum": [
"dynamic",
"static",
"none"
],
"description": "Decide if you want storage to be provisioned dynamically\n(dynamic), or if you want to attach existing storage (static), or\ndon't want any storage to be attached (none).\n"
}
}
},
"allowPrivilegeEscalation": {
"type": [
"boolean",
"null"
],
"description": "Passthrough configuration for\n[KubeSpawner.allow_privilege_escalation](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html#kubespawner.KubeSpawner.allow_privilege_escalation).\n"
},
"uid": {
"type": [
"integer",
"null"
],
"description": "Passthrough configuration for\n[KubeSpawner.uid](https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html#kubespawner.KubeSpawner.uid).\n\nThis dictates as what user the main container will start up as.\n\nAs an example of when this is needed, consider if you want to enable\nsudo rights for some of your users. This can be done by starting up as\nroot, enabling it from the container in a startup script, and then\ntransitioning to the normal user.\n"
}
}
},
"scheduling": {
"type": "object",
"additionalProperties": false,
"description": "Objects for customizing the scheduling of various pods on the nodes and\nrelated labels.\n",
"properties": {
"userScheduler": {
"type": "object",
"additionalProperties": false,
"required": [
"enabled",
"plugins",
"pluginConfig",
"logLevel"
],
"description": "The user scheduler is making sure that user pods are scheduled\ntight on nodes, this is useful for autoscaling of user node pools.\n",
"properties": {
"enabled": {
"type": "boolean",
"description": "Enables the user scheduler.\n"
},
"revisionHistoryLimit": {
"type": [
"integer",
"null"
],
"minimum": 0,
"description": "Configures the resource's `spec.revisionHistoryLimit`. This is\navailable for Deployment, StatefulSet, and DaemonSet resources.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#revision-history-limit)\nfor more info.\n"
},
"replicas": {
"type": "integer",
"description": "You can have multiple schedulers to share the workload or improve\navailability on node failure.\n"
},
"image": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"tag"
],
"description": "Set custom image name, tag, pullPolicy, or pullSecrets for the pod.\n",
"properties": {
"name": {
"type": "string",
"description": "The name of the image, without the tag.\n\n```\n# example name\ngcr.io/my-project/my-image\n```\n"
},
"tag": {
"type": "string",
"description": "The tag of the image to pull. This is the value following `:` in\ncomplete image specifications.\n\n```\n# example tags\nv1.11.1\nzhy270a\n```\n"
},
"pullPolicy": {
"enum": [
null,
"",
"IfNotPresent",
"Always",
"Never"
],
"description": "Configures the Pod's `spec.imagePullPolicy`.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/containers/images/#updating-images)\nfor more info.\n"
},
"pullSecrets": {
"type": "array",
"description": "A list of references to existing Kubernetes Secrets with\ncredentials to pull the image.\n\nThis Pod's final `imagePullSecrets` k8s specification will be a\ncombination of:\n\n1. This list of k8s Secrets, specific for this pod.\n2. The list of k8s Secrets, for use by all pods in the Helm chart,\n declared in this Helm charts configuration called\n `imagePullSecrets`.\n3. A k8s Secret, for use by all pods in the Helm chart, if\n conditionally created from image registry credentials provided\n under `imagePullSecret` if `imagePullSecret.create` is set to\n true.\n\n```yaml\n# example - k8s native syntax\npullSecrets:\n - name: my-k8s-secret-with-image-registry-credentials\n\n# example - simplified syntax\npullSecrets:\n - my-k8s-secret-with-image-registry-credentials\n```\n"
}
}
},
"pdb": {
"type": "object",
"additionalProperties": false,
"description": "Configure a PodDisruptionBudget for this Deployment.\n\nThese are disabled by default for our deployments that don't support\nbeing run in parallel with multiple replicas. Only the user-scheduler\ncurrently supports being run in parallel with multiple replicas. If\nthey are enabled for a Deployment with only one replica, they will\nblock `kubectl drain` of a node for example.\n\nNote that if you aim to block scaling down a node with the\nhub/proxy/autohttps pod that would cause disruptions of the\ndeployment, then you should instead annotate the pods of the\nDeployment [as described\nhere](https://github.com/kubernetes/autoscaler/blob/HEAD/cluster-autoscaler/FAQ.md#what-types-of-pods-can-prevent-ca-from-removing-a-node).\n\n \"cluster-autoscaler.kubernetes.io/safe-to-evict\": \"false\"\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/)\nfor more details about disruptions.\n",
"properties": {
"enabled": {
"type": "boolean",
"description": "Decides if a PodDisruptionBudget is created targeting the\nDeployment's pods.\n"
},
"maxUnavailable": {
"type": [
"integer",
"null"
],
"description": "The maximum number of pods that can be unavailable during\nvoluntary disruptions.\n"
},
"minAvailable": {
"type": [
"integer",
"null"
],
"description": "The minimum number of pods required to be available during\nvoluntary disruptions.\n"
}
}
},
"nodeSelector": {
"type": "object",
"additionalProperties": true,
"description": "An object with key value pairs representing labels. K8s Nodes are\nrequired to have match all these labels for this Pod to scheduled on\nthem.\n\n```yaml\ndisktype: ssd\nnodetype: awesome\n```\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector)\nfor more details.\n"
},
"tolerations": {
"type": "array",
"description": "Tolerations allow a pod to be scheduled on nodes with taints. These\ntolerations are additional tolerations to the tolerations common to\nall pods of a their respective kind\n([scheduling.corePods.tolerations](schema_scheduling.corePods.tolerations),\n[scheduling.userPods.tolerations](schema_scheduling.userPods.tolerations)).\n\nPass this field an array of\n[`Toleration`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#toleration-v1-core)\nobjects.\n\nSee the [Kubernetes\ndocs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)\nfor more info.\n"
},
"labels": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Extra labels to add to the userScheduler pods.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)\nto learn more about labels.\n"
},
"annotations": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Extra annotations to add to the user-scheduler pods.\n"
},
"containerSecurityContext": {
"type": "object",
"additionalProperties": true,
"description": "A k8s native specification of the container's security context, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core)\nfor details.\n"
},
"logLevel": {
"type": "integer",
"description": "Corresponds to the verbosity level of logging made by the\nkube-scheduler binary running within the user-scheduler pod.\n"
},
"plugins": {
"type": "object",
"additionalProperties": true,
"description": "These plugins refers to kube-scheduler plugins as documented\n[here](https://kubernetes.io/docs/reference/scheduling/config/).\n\nThe user-scheduler is really just a kube-scheduler configured in a\nway to pack users tight on nodes using these plugins. See\nvalues.yaml for information about the default plugins.\n"
},
"pluginConfig": {
"type": "array",
"description": "Individually activated plugins can be configured further.\n"
},
"resources": {
"type": "object",
"additionalProperties": true,
"description": "A k8s native specification of resources, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#resourcerequirements-v1-core).\n"
},
"serviceAccount": {
"type": "object",
"required": [
"create"
],
"additionalProperties": false,
"description": "Configuration for a k8s ServiceAccount dedicated for use by the\nspecific pod which this configuration is nested under.\n",
"properties": {
"create": {
"type": "boolean",
"description": "Whether or not to create the `ServiceAccount` resource.\n"
},
"name": {
"type": [
"string",
"null"
],
"description": "This configuration serves multiple purposes:\n\n- It will be the `serviceAccountName` referenced by related Pods.\n- If `create` is set, the created ServiceAccount resource will be named like this.\n- If [`rbac.create`](schema_rbac.create) is set, the associated (Cluster)RoleBindings will bind to this name.\n\nIf not explicitly provided, a default name will be used.\n"
},
"annotations": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Kubernetes annotations to apply to the k8s ServiceAccount.\n"
}
}
},
"extraPodSpec": {
"type": "object",
"additionalProperties": true,
"description": "Arbitrary extra k8s pod specification as a YAML object. The default\nvalue of this setting is an empty object, i.e. no extra configuration.\nThe value of this property is augmented to the pod specification as-is.\n\nThis is a powerful tool for expert k8s administrators with advanced\nconfiguration requirements. This setting should only be used for\nconfiguration that cannot be accomplished through the other settings.\nMisusing this setting can break your deployment and/or compromise\nyour system security.\n\nThis is one of four related settings for inserting arbitrary pod\nspecification:\n\n1. hub.extraPodSpec\n2. proxy.chp.extraPodSpec\n3. proxy.traefik.extraPodSpec\n4. scheduling.userScheduler.extraPodSpec\n\nOne real-world use of these settings is to enable host networking. For\nexample, to configure host networking for the hub pod, add the\nfollowing to your helm configuration values:\n\n```yaml\nhub:\n extraPodSpec:\n hostNetwork: true\n dnsPolicy: ClusterFirstWithHostNet\n```\n\nLikewise, to configure host networking for the proxy pod, add the\nfollowing:\n\n```yaml\nproxy:\n chp:\n extraPodSpec:\n hostNetwork: true\n dnsPolicy: ClusterFirstWithHostNet\n```\n\nN.B. Host networking has special security implications and can easily\nbreak your deployment. This is an example—not an endorsement.\n\nSee [PodSpec](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec)\nfor the latest pod resource specification.\n"
}
}
},
"podPriority": {
"type": "object",
"additionalProperties": false,
"description": "Pod Priority is used to allow real users evict user placeholder pods\nthat in turn by entering a Pending state can trigger a scale up by a\ncluster autoscaler.\n\nHaving this option enabled only make sense if the following conditions\nare met:\n\n1. A cluster autoscaler is installed.\n2. user-placeholer pods are configured to have a priority equal or\n higher than the cluster autoscaler's \"priority cutoff\" so that the\n cluster autoscaler scales up a node in advance for a pending user\n placeholder pod.\n3. Normal user pods have a higher priority than the user-placeholder\n pods.\n4. Image puller pods have a priority between normal user pods and\n user-placeholder pods.\n\nNote that if the default priority cutoff if not configured on cluster\nautoscaler, it will currently default to 0, and that in the future\nthis is meant to be lowered. If your cloud provider is installing the\ncluster autoscaler for you, they may also configure this specifically.\n\nRecommended settings for a cluster autoscaler...\n\n... with a priority cutoff of -10 (GKE):\n\n```yaml\npodPriority:\n enabled: true\n globalDefault: false\n defaultPriority: 0\n imagePullerPriority: -5\n userPlaceholderPriority: -10\n```\n\n... with a priority cutoff of 0:\n\n```yaml\npodPriority:\n enabled: true\n globalDefault: true\n defaultPriority: 10\n imagePullerPriority: 5\n userPlaceholderPriority: 0\n```\n",
"properties": {
"enabled": {
"type": "boolean"
},
"globalDefault": {
"type": "boolean",
"description": "Warning! This will influence all pods in the cluster.\n\nThe priority a pod usually get is 0. But this can be overridden\nwith a PriorityClass resource if it is declared to be the global\ndefault. This configuration option allows for the creation of such\nglobal default.\n"
},
"defaultPriority": {
"type": "integer",
"description": "The actual value for the default pod priority.\n"
},
"imagePullerPriority": {
"type": "integer",
"description": "The actual value for the [hook|continuous]-image-puller pods' priority.\n"
},
"userPlaceholderPriority": {
"type": "integer",
"description": "The actual value for the user-placeholder pods' priority.\n"
}
}
},
"userPlaceholder": {
"type": "object",
"additionalProperties": false,
"description": "User placeholders simulate users but will thanks to PodPriority be\nevicted by the cluster autoscaler if a real user shows up. In this way\nplaceholders allow you to create a headroom for the real users and\nreduce the risk of a user having to wait for a node to be added. Be\nsure to use the the continuous image puller as well along with\nplaceholders, so the images are also available when real users arrive.\n\nTo test your setup efficiently, you can adjust the amount of user\nplaceholders with the following command:\n```sh\n# Configure to have 3 user placeholders\nkubectl scale sts/user-placeholder --replicas=3\n```\n",
"properties": {
"enabled": {
"type": "boolean"
},
"image": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"tag"
],
"description": "Set custom image name, tag, pullPolicy, or pullSecrets for the pod.\n",
"properties": {
"name": {
"type": "string",
"description": "The name of the image, without the tag.\n\n```\n# example name\ngcr.io/my-project/my-image\n```\n"
},
"tag": {
"type": "string",
"description": "The tag of the image to pull. This is the value following `:` in\ncomplete image specifications.\n\n```\n# example tags\nv1.11.1\nzhy270a\n```\n"
},
"pullPolicy": {
"enum": [
null,
"",
"IfNotPresent",
"Always",
"Never"
],
"description": "Configures the Pod's `spec.imagePullPolicy`.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/containers/images/#updating-images)\nfor more info.\n"
},
"pullSecrets": {
"type": "array",
"description": "A list of references to existing Kubernetes Secrets with\ncredentials to pull the image.\n\nThis Pod's final `imagePullSecrets` k8s specification will be a\ncombination of:\n\n1. This list of k8s Secrets, specific for this pod.\n2. The list of k8s Secrets, for use by all pods in the Helm chart,\n declared in this Helm charts configuration called\n `imagePullSecrets`.\n3. A k8s Secret, for use by all pods in the Helm chart, if\n conditionally created from image registry credentials provided\n under `imagePullSecret` if `imagePullSecret.create` is set to\n true.\n\n```yaml\n# example - k8s native syntax\npullSecrets:\n - name: my-k8s-secret-with-image-registry-credentials\n\n# example - simplified syntax\npullSecrets:\n - my-k8s-secret-with-image-registry-credentials\n```\n"
}
}
},
"revisionHistoryLimit": {
"type": [
"integer",
"null"
],
"minimum": 0,
"description": "Configures the resource's `spec.revisionHistoryLimit`. This is\navailable for Deployment, StatefulSet, and DaemonSet resources.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#revision-history-limit)\nfor more info.\n"
},
"replicas": {
"type": "integer",
"description": "How many placeholder pods would you like to have?\n"
},
"labels": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Extra labels to add to the userPlaceholder pods.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)\nto learn more about labels.\n"
},
"annotations": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Extra annotations to add to the placeholder pods.\n"
},
"resources": {
"type": "object",
"additionalProperties": true,
"description": "Unless specified here, the placeholder pods will request the same\nresources specified for the real singleuser pods.\n"
},
"containerSecurityContext": {
"type": "object",
"additionalProperties": true,
"description": "A k8s native specification of the container's security context, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core)\nfor details.\n"
}
}
},
"corePods": {
"type": "object",
"additionalProperties": false,
"description": "These settings influence the core pods like the hub, proxy and\nuser-scheduler pods.\nThese settings influence all pods considered core pods, namely:\n\n- hub\n- proxy\n- autohttps\n- hook-image-awaiter\n- user-scheduler\n\nBy defaults, the tolerations are:\n\n- hub.jupyter.org/dedicated=core:NoSchedule\n- hub.jupyter.org_dedicated=core:NoSchedule\n\nNote that tolerations set here are combined with the respective\ncomponents dedicated tolerations, and that `_` is available in case\n`/` isn't allowed in the clouds tolerations.\n",
"properties": {
"tolerations": {
"type": "array",
"description": "Tolerations allow a pod to be scheduled on nodes with taints. These\ntolerations are additional tolerations to the tolerations common to\nall pods of a their respective kind\n([scheduling.corePods.tolerations](schema_scheduling.corePods.tolerations),\n[scheduling.userPods.tolerations](schema_scheduling.userPods.tolerations)).\n\nPass this field an array of\n[`Toleration`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#toleration-v1-core)\nobjects.\n\nSee the [Kubernetes\ndocs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)\nfor more info.\n"
},
"nodeAffinity": {
"type": "object",
"additionalProperties": false,
"description": "Where should pods be scheduled? Perhaps on nodes with a certain\nlabel is preferred or even required?\n",
"properties": {
"matchNodePurpose": {
"enum": [
"ignore",
"prefer",
"require"
],
"description": "Decide if core pods *ignore*, *prefer* or *require* to\nschedule on nodes with this label:\n```\nhub.jupyter.org/node-purpose=core\n```\n"
}
}
}
}
},
"userPods": {
"type": "object",
"additionalProperties": false,
"description": "These settings influence all pods considered user pods, namely:\n\n- user-placeholder\n- hook-image-puller\n- continuous-image-puller\n- jupyter-<username>\n\nBy defaults, the tolerations are:\n\n- hub.jupyter.org/dedicated=core:NoSchedule\n- hub.jupyter.org_dedicated=core:NoSchedule\n\nNote that tolerations set here are combined with the respective\ncomponents dedicated tolerations, and that `_` is available in case\n`/` isn't allowed in the clouds tolerations.\n",
"properties": {
"tolerations": {
"type": "array",
"description": "Tolerations allow a pod to be scheduled on nodes with taints. These\ntolerations are additional tolerations to the tolerations common to\nall pods of a their respective kind\n([scheduling.corePods.tolerations](schema_scheduling.corePods.tolerations),\n[scheduling.userPods.tolerations](schema_scheduling.userPods.tolerations)).\n\nPass this field an array of\n[`Toleration`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#toleration-v1-core)\nobjects.\n\nSee the [Kubernetes\ndocs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)\nfor more info.\n"
},
"nodeAffinity": {
"type": "object",
"additionalProperties": false,
"description": "Where should pods be scheduled? Perhaps on nodes with a certain\nlabel is preferred or even required?\n",
"properties": {
"matchNodePurpose": {
"enum": [
"ignore",
"prefer",
"require"
],
"description": "Decide if user pods *ignore*, *prefer* or *require* to\nschedule on nodes with this label:\n```\nhub.jupyter.org/node-purpose=user\n```\n"
}
}
}
}
}
}
},
"ingress": {
"type": "object",
"additionalProperties": false,
"required": [
"enabled"
],
"properties": {
"enabled": {
"type": "boolean",
"description": "Enable the creation of a Kubernetes Ingress to proxy-public service.\n\nSee [Advanced Topics — Zero to JupyterHub with Kubernetes\n0.7.0 documentation](ingress)\nfor more details.\n"
},
"annotations": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Annotations to apply to the Ingress resource.\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/)\nfor more details about annotations.\n"
},
"ingressClassName": {
"type": [
"string",
"null"
],
"description": "Maps directly to the Ingress resource's `spec.ingressClassName``.\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class)\nfor more details.\n"
},
"hosts": {
"type": "array",
"description": "List of hosts to route requests to the proxy.\n"
},
"pathSuffix": {
"type": [
"string",
"null"
],
"description": "Suffix added to Ingress's routing path pattern.\n\nSpecify `*` if your ingress matches path by glob pattern.\n"
},
"pathType": {
"enum": [
"Prefix",
"Exact",
"ImplementationSpecific"
],
"description": "The path type to use. The default value is 'Prefix'.\n\nSee [the Kubernetes documentation](https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types)\nfor more details about path types.\n"
},
"tls": {
"type": "array",
"description": "TLS configurations for Ingress.\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls)\nfor more details about annotations.\n"
}
}
},
"prePuller": {
"type": "object",
"additionalProperties": false,
"required": [
"hook",
"continuous"
],
"properties": {
"revisionHistoryLimit": {
"type": [
"integer",
"null"
],
"minimum": 0,
"description": "Configures the resource's `spec.revisionHistoryLimit`. This is\navailable for Deployment, StatefulSet, and DaemonSet resources.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#revision-history-limit)\nfor more info.\n"
},
"labels": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Extra labels to add to the pre puller job pods.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)\nto learn more about labels.\n"
},
"annotations": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Annotations to apply to the hook and continous image puller pods. One example use case is to\ndisable istio sidecars which could interfere with the image pulling.\n"
},
"resources": {
"type": "object",
"additionalProperties": true,
"description": "These are standard Kubernetes resources with requests and limits for\ncpu and memory. They will be used on the containers in the pods\npulling images. These should be set extremely low as the containers\nshut down directly or is a pause container that just idles.\n\nThey were made configurable as usage of ResourceQuota may require\ncontainers in the namespace to have explicit resources set.\n"
},
"extraTolerations": {
"type": "array",
"description": "Tolerations allow a pod to be scheduled on nodes with taints. These\ntolerations are additional tolerations to the tolerations common to\nall pods of a their respective kind\n([scheduling.corePods.tolerations](schema_scheduling.corePods.tolerations),\n[scheduling.userPods.tolerations](schema_scheduling.userPods.tolerations)).\n\nPass this field an array of\n[`Toleration`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#toleration-v1-core)\nobjects.\n\nSee the [Kubernetes\ndocs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)\nfor more info.\n"
},
"hook": {
"type": "object",
"additionalProperties": false,
"required": [
"enabled"
],
"description": "See the [*optimization\nsection*](pulling-images-before-users-arrive)\nfor more details.\n",
"properties": {
"enabled": {
"type": "boolean"
},
"pullOnlyOnChanges": {
"type": "boolean",
"description": "Pull only if changes have been made to the images to pull, or more\naccurately if the hook-image-puller daemonset has changed in any\nway.\n"
},
"podSchedulingWaitDuration": {
"description": "The `hook-image-awaiter` has a criteria to await all the\n`hook-image-puller` DaemonSet's pods to both schedule and finish\ntheir image pulling. This flag can be used to relax this criteria\nto instead only await the pods that _has already scheduled_ to\nfinish image pulling after a certain duration.\n\nThe value of this is that sometimes the newly created\n`hook-image-puller` pods cannot be scheduled because nodes are\nfull, and then it probably won't make sense to block a `helm\nupgrade`.\n\nAn infinite duration to wait for pods to schedule can be\nrepresented by `-1`. This was the default behavior of version\n0.9.0 and earlier.\n",
"type": "integer"
},
"nodeSelector": {
"type": "object",
"additionalProperties": true,
"description": "An object with key value pairs representing labels. K8s Nodes are\nrequired to have match all these labels for this Pod to scheduled on\nthem.\n\n```yaml\ndisktype: ssd\nnodetype: awesome\n```\n\nSee [the Kubernetes\ndocumentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector)\nfor more details.\n"
},
"tolerations": {
"type": "array",
"description": "Tolerations allow a pod to be scheduled on nodes with taints. These\ntolerations are additional tolerations to the tolerations common to\nall pods of a their respective kind\n([scheduling.corePods.tolerations](schema_scheduling.corePods.tolerations),\n[scheduling.userPods.tolerations](schema_scheduling.userPods.tolerations)).\n\nPass this field an array of\n[`Toleration`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#toleration-v1-core)\nobjects.\n\nSee the [Kubernetes\ndocs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)\nfor more info.\n"
},
"containerSecurityContext": {
"type": "object",
"additionalProperties": true,
"description": "A k8s native specification of the container's security context, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core)\nfor details.\n"
},
"image": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"tag"
],
"description": "Set custom image name, tag, pullPolicy, or pullSecrets for the pod.\n",
"properties": {
"name": {
"type": "string",
"description": "The name of the image, without the tag.\n\n```\n# example name\ngcr.io/my-project/my-image\n```\n"
},
"tag": {
"type": "string",
"description": "The tag of the image to pull. This is the value following `:` in\ncomplete image specifications.\n\n```\n# example tags\nv1.11.1\nzhy270a\n```\n"
},
"pullPolicy": {
"enum": [
null,
"",
"IfNotPresent",
"Always",
"Never"
],
"description": "Configures the Pod's `spec.imagePullPolicy`.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/containers/images/#updating-images)\nfor more info.\n"
},
"pullSecrets": {
"type": "array",
"description": "A list of references to existing Kubernetes Secrets with\ncredentials to pull the image.\n\nThis Pod's final `imagePullSecrets` k8s specification will be a\ncombination of:\n\n1. This list of k8s Secrets, specific for this pod.\n2. The list of k8s Secrets, for use by all pods in the Helm chart,\n declared in this Helm charts configuration called\n `imagePullSecrets`.\n3. A k8s Secret, for use by all pods in the Helm chart, if\n conditionally created from image registry credentials provided\n under `imagePullSecret` if `imagePullSecret.create` is set to\n true.\n\n```yaml\n# example - k8s native syntax\npullSecrets:\n - name: my-k8s-secret-with-image-registry-credentials\n\n# example - simplified syntax\npullSecrets:\n - my-k8s-secret-with-image-registry-credentials\n```\n"
}
}
},
"resources": {
"type": "object",
"additionalProperties": true,
"description": "A k8s native specification of resources, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#resourcerequirements-v1-core).\n"
},
"serviceAccount": {
"type": "object",
"required": [
"create"
],
"additionalProperties": false,
"description": "Configuration for a k8s ServiceAccount dedicated for use by the\nspecific pod which this configuration is nested under.\n",
"properties": {
"create": {
"type": "boolean",
"description": "Whether or not to create the `ServiceAccount` resource.\n"
},
"name": {
"type": [
"string",
"null"
],
"description": "This configuration serves multiple purposes:\n\n- It will be the `serviceAccountName` referenced by related Pods.\n- If `create` is set, the created ServiceAccount resource will be named like this.\n- If [`rbac.create`](schema_rbac.create) is set, the associated (Cluster)RoleBindings will bind to this name.\n\nIf not explicitly provided, a default name will be used.\n"
},
"annotations": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
".*": {
"type": "string"
}
},
"description": "Kubernetes annotations to apply to the k8s ServiceAccount.\n"
}
}
}
}
},
"continuous": {
"type": "object",
"additionalProperties": false,
"required": [
"enabled"
],
"description": "See the [*optimization\nsection*](pulling-images-before-users-arrive)\nfor more details.\n\n```{note}\nIf used with a Cluster Autoscaler (an autoscaling node pool), also add\nuser-placeholders and enable pod priority.\n```\n",
"properties": {
"enabled": {
"type": "boolean"
}
}
},
"pullProfileListImages": {
"type": "boolean",
"description": "The singleuser.profileList configuration can let the user choose an\nimage through the selection of a profile. This option determines if\nthose images will be pulled, both by the hook and continuous pullers.\n\nThe reason to disable this, is that if you have for example 10 images\nwhich start pulling in order from 1 to 10, a user that arrives and\nwants to start a pod with image number 10 will need to wait for all\nimages to be pulled, and then it may be preferable to just let the\nuser arriving wait for a single image to be pulled on arrival.\n"
},
"extraImages": {
"type": "object",
"additionalProperties": false,
"description": "See the [*optimization section*](images-that-will-be-pulled) for more\ndetails.\n\n```yaml\nprePuller:\n extraImages:\n myExtraImageIWantPulled:\n name: jupyter/all-spark-notebook\n tag: 2343e33dec46\n```\n",
"patternProperties": {
".*": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"tag"
],
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
}
}
}
}
},
"containerSecurityContext": {
"type": "object",
"additionalProperties": true,
"description": "A k8s native specification of the container's security context, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core)\nfor details.\n"
},
"pause": {
"type": "object",
"additionalProperties": false,
"description": "The image-puller pods rely on initContainer to pull all images, and\ntheir actual container when they are done is just running a `pause`\ncontainer. These are settings for that pause container.\n",
"properties": {
"containerSecurityContext": {
"type": "object",
"additionalProperties": true,
"description": "A k8s native specification of the container's security context, see [the\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core)\nfor details.\n"
},
"image": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"tag"
],
"description": "Set custom image name, tag, pullPolicy, or pullSecrets for the pod.\n",
"properties": {
"name": {
"type": "string",
"description": "The name of the image, without the tag.\n\n```\n# example name\ngcr.io/my-project/my-image\n```\n"
},
"tag": {
"type": "string",
"description": "The tag of the image to pull. This is the value following `:` in\ncomplete image specifications.\n\n```\n# example tags\nv1.11.1\nzhy270a\n```\n"
},
"pullPolicy": {
"enum": [
null,
"",
"IfNotPresent",
"Always",
"Never"
],
"description": "Configures the Pod's `spec.imagePullPolicy`.\n\nSee the [Kubernetes docs](https://kubernetes.io/docs/concepts/containers/images/#updating-images)\nfor more info.\n"
},
"pullSecrets": {
"type": "array",
"description": "A list of references to existing Kubernetes Secrets with\ncredentials to pull the image.\n\nThis Pod's final `imagePullSecrets` k8s specification will be a\ncombination of:\n\n1. This list of k8s Secrets, specific for this pod.\n2. The list of k8s Secrets, for use by all pods in the Helm chart,\n declared in this Helm charts configuration called\n `imagePullSecrets`.\n3. A k8s Secret, for use by all pods in the Helm chart, if\n conditionally created from image registry credentials provided\n under `imagePullSecret` if `imagePullSecret.create` is set to\n true.\n\n```yaml\n# example - k8s native syntax\npullSecrets:\n - name: my-k8s-secret-with-image-registry-credentials\n\n# example - simplified syntax\npullSecrets:\n - my-k8s-secret-with-image-registry-credentials\n```\n"
}
}
}
}
}
}
},
"custom": {
"type": "object",
"additionalProperties": true,
"description": "Additional values to pass to the Hub.\nJupyterHub will not itself look at these,\nbut you can read values in your own custom config via `hub.extraConfig`.\nFor example:\n\n```yaml\ncustom:\n myHost: \"https://example.horse\"\nhub:\n extraConfig:\n myConfig.py: |\n c.MyAuthenticator.host = get_config(\"custom.myHost\")\n```\n"
},
"cull": {
"type": "object",
"additionalProperties": false,
"required": [
"enabled"
],
"description": "The\n[jupyterhub-idle-culler](https://github.com/jupyterhub/jupyterhub-idle-culler)\ncan run as a JupyterHub managed service to _cull_ running servers.\n",
"properties": {
"enabled": {
"type": "boolean",
"description": "Enable/disable use of jupyter-idle-culler.\n"
},
"users": {
"type": [
"boolean",
"null"
],
"description": "See the `--cull-users` flag."
},
"adminUsers": {
"type": [
"boolean",
"null"
],
"description": "See the `--cull-admin-users` flag."
},
"removeNamedServers": {
"type": [
"boolean",
"null"
],
"description": "See the `--remove-named-servers` flag."
},
"timeout": {
"type": [
"integer",
"null"
],
"description": "See the `--timeout` flag."
},
"every": {
"type": [
"integer",
"null"
],
"description": "See the `--cull-every` flag."
},
"concurrency": {
"type": [
"integer",
"null"
],
"description": "See the `--concurrency` flag."
},
"maxAge": {
"type": [
"integer",
"null"
],
"description": "See the `--max-age` flag."
}
}
},
"debug": {
"type": "object",
"additionalProperties": false,
"required": [
"enabled"
],
"properties": {
"enabled": {
"type": "boolean",
"description": "Increases the loglevel throughout the resources in the Helm chart.\n"
}
}
},
"rbac": {
"type": "object",
"additionalProperties": false,
"required": [
"create"
],
"properties": {
"enabled": {
"type": "boolean",
"description": "````{note}\nRemoved in version 2.0.0. If you have been using `rbac.enable=false`\n(strongly discouraged), then the equivalent configuration would be:\n\n```yaml\nrbac:\n create: false\nhub:\n serviceAccount:\n create: false\nproxy:\n traefik:\n serviceAccount:\n create: false\nscheduling:\n userScheduler:\n serviceAccount:\n create: false\nprePuller:\n hook:\n serviceAccount:\n create: false\n```\n````\n"
},
"create": {
"type": "boolean",
"description": "Decides if (Cluster)Role and (Cluster)RoleBinding resources are\ncreated and bound to the configured serviceAccounts.\n"
}
}
},
"global": {
"type": "object",
"additionalProperties": true,
"properties": {
"safeToShowValues": {
"type": "boolean",
"description": "A flag that should only be set to true temporarily when experiencing a\ndeprecation message that contain censored content that you wish to\nreveal."
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment