You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/source/docker.md
+4-2Lines changed: 4 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -71,7 +71,7 @@ Custom kernel images require some support files from the Enterprise Gateway repo
71
71
Enterprise Gateway provides a single [bootstrap-kernel.sh](https://github.com/jupyter/enterprise_gateway/blob/master/etc/kernel-launchers/bootstrap/bootstrap-kernel.sh) script that handles the three kernel languages supported out of the box - Python, R, and Scala. When a kernel image is started by Enterprise Gateway, parameters used within the bootstrap-kernel.sh script are conveyed via environment variables. The bootstrap script is then responsible for validating and converting those parameters to meaningful arguments to the appropriate launcher.
72
72
73
73
##### Kernel Launcher
74
-
The kernel launcher, as discussed [here](system-architecture.html#kernel-launchers) does a number of things. In paricular, it creates the connection ports and conveys that connection information back to Enterprise Gateway via the socket identified by the response address parameter. Although not a requirement for container-based usage, it is recommended that the launcher be written in the same language as the kernel. (This is more of a requirement when used in applications like YARN.)
74
+
The kernel launcher, as discussed [here](system-architecture.html#kernel-launchers) does a number of things. In particular, it creates the connection ports and conveys that connection information back to Enterprise Gateway via the socket identified by the response address parameter. Although not a requirement for container-based usage, it is recommended that the launcher be written in the same language as the kernel. (This is more of a requirement when used in applications like YARN.)
75
75
76
76
#### About Jupyter Docker-stacks Images
77
77
Most of what is presented assumes the base image for your custom image is derived from the [Jupyter Docker-stacks](https://github.com/jupyter/docker-stacks) repository. As a result, it's good to cover what makes up those assumptions so you can build your own image independently from the docker-stacks repository.
Copy file name to clipboardExpand all lines: docs/source/getting-started.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -124,7 +124,7 @@ In that case, the image should ensure the availability of the kernel libraries a
124
124
The launch of containerized kernels via Enterprise Gateway is two-fold.
125
125
126
126
1. First, there's the argv section in the kernelspec that is processed by the server. In these cases, the command that is invoked is a python script using the target container's api (kubernetes, docker, or docker swarm) that is responsible for converting any necessary "parameters" to environment variables, etc. that are used during the actual container creation.
127
-
2. The command that is run in the container is the actual kernel launcher script. This launcher is responsible for taking the response address (which is now an env variable) and returning the kernel's connection information back on that response address to Enterprise Gateway. The kernel launcher does additional things - but primarily listens for interrupt and shutdown requests, which it then passes along to the actual (embedded) kernel.
127
+
2. The command that is run in the container is actually the kernel launcher script. This script is responsible for taking the response address (which is now an env variable) and returning the kernel's connection information back on that response address to Enterprise Gateway. The kernel launcher does additional things - but primarily listens for interrupt and shutdown requests, which it then passes along to the actual (embedded) kernel.
128
128
129
129
So container environments have two launches - one to launch the container itself, the other to launch the kernel (within the container).
Copy file name to clipboardExpand all lines: docs/source/kernel-kubernetes.md
+40-19Lines changed: 40 additions & 19 deletions
Original file line number
Diff line number
Diff line change
@@ -36,6 +36,9 @@ spec:
36
36
- name: http
37
37
port: 8888
38
38
targetPort: 8888
39
+
- name: response
40
+
port: 8877
41
+
targetPort: 8877
39
42
selector:
40
43
gateway-selector: enterprise-gateway
41
44
sessionAffinity: ClientIP
@@ -69,6 +72,12 @@ spec:
69
72
serviceAccountName: enterprise-gateway-sa
70
73
containers:
71
74
- env:
75
+
- name: EG_PORT
76
+
value: "8888"
77
+
78
+
- name: EG_RESPONSE_PORT
79
+
value: "8877"
80
+
72
81
# Created above.
73
82
- name: EG_NAMESPACE
74
83
value: "enterprise-gateway"
@@ -105,6 +114,7 @@ spec:
105
114
args: ["--gateway"]
106
115
ports:
107
116
- containerPort: 8888
117
+
- containerPort: 8877
108
118
```
109
119
#### Namespaces
110
120
A best practice for Kubernetes applications running in an enterprise is to isolate applications via namespaces. Since Enterprise Gateway also requires isolation at the kernel level, it makes sense to use a namespace for each kernel, by default.
@@ -348,41 +358,50 @@ There are essentially two kinds of kernels (independent of language) launched wi
348
358
349
359
When _vanilla_ kernels are launched, Enterprise Gateway is responsible for creating the corresponding pod. On the other hand, _spark-on-kubernetes_ kernels are launched via `spark-submit` with a specific `master` URI - which then creates the corresponding pod(s) (including executor pods). Images can be launched using both forms provided they have the appropriate support for Spark installed.
350
360
351
-
Here's the yaml configuration used when _vanilla_ kernels are launched. As noted in the `KubernetesProcessProxy` section below, this file ([kernel-pod.yaml](https://github.com/jupyter/enterprise_gateway/blob/master/etc/kernel-launchers/kubernetes/scripts/kernel-pod.yaml)) serves as a template where each of the tags surrounded with `${}` represent variables that are substituted at the time of the kernel's launch. All `${kernel_xxx}` parameters correspond to `KERNEL_XXX` environment variables that can be specified from the client in the kernel creation request's json body.
361
+
Here's the yaml configuration used when _vanilla_ kernels are launched. As noted in the `KubernetesProcessProxy` section below, this file ([kernel-pod.yaml.j2](https://github.com/jupyter/enterprise_gateway/blob/master/etc/kernel-launchers/kubernetes/scripts/kernel-pod.yaml.j2)) serves as a template where each of the tags surrounded with `{{` and `}}` represent variables that are substituted at the time of the kernel's launch. All `{{ kernel_xxx }}` parameters correspond to `KERNEL_XXX` environment variables that can be specified from the client in the kernel creation request's json body.
{% if kernel_uid is defined or kernel_gid is defined %}
365
376
securityContext:
366
-
runAsUser: ${kernel_uid}
367
-
runAsGroup: ${kernel_gid}
377
+
{% if kernel_uid is defined %}
378
+
runAsUser: {{ kernel_uid | int }}
379
+
{% endif %}
380
+
{% if kernel_gid is defined %}
381
+
runAsGroup: {{ kernel_gid | int }}
382
+
{% endif %}
383
+
fsGroup: 100
384
+
{% endif %}
368
385
containers:
369
386
- env:
370
387
- name: EG_RESPONSE_ADDRESS
371
-
value: ${eg_response_address}
388
+
value: "{{ eg_response_address }}"
389
+
- name: EG_PUBLIC_KEY
390
+
value: "{{ eg_public_key }}"
372
391
- name: KERNEL_LANGUAGE
373
-
value: ${kernel_language}
392
+
value: "{{ kernel_language }}"
374
393
- name: KERNEL_SPARK_CONTEXT_INIT_MODE
375
-
value: ${kernel_spark_context_init_mode}
394
+
value: "{{ kernel_spark_context_init_mode }}"
376
395
- name: KERNEL_NAME
377
-
value: ${kernel_name}
396
+
value: "{{ kernel_name }}"
378
397
- name: KERNEL_USERNAME
379
-
value: ${kernel_username}
398
+
value: "{{ kernel_username }}"
380
399
- name: KERNEL_ID
381
-
value: ${kernel_id}
400
+
value: "{{ kernel_id }}"
382
401
- name: KERNEL_NAMESPACE
383
-
value: ${kernel_namespace}
384
-
image: ${kernel_image}
385
-
name: ${kernel_username}-${kernel_id}
402
+
value: "{{ kernel_namespace }}"
403
+
image: "{{ kernel_image }}"
404
+
name: "{{ kernel_pod_name }}"
386
405
```
387
406
There are a number of items worth noting:
388
407
1. Kernel pods can be identified in three ways using `kubectl`:
@@ -393,7 +412,7 @@ There are a number of items worth noting:
393
412
Note that since kernels run in isolated namespaces by default, it's often helpful to include the clause `--all-namespaces` on commands that will span namespaces. To isolate commands to a given namespace, you'll need to add the namespace clause `--namespace <namespace-name>`.
394
413
1. Each kernel pod is named by the invoking user (via the `KERNEL_USERNAME` env) and its kernel_id (env `KERNEL_ID`). This identifier also applies to those kernels launched within `spark-on-kubernetes`.
395
414
1. Kernel pods use the specified `securityContext`. If env `KERNEL_UID` is not specified in the kernel creation request a default value of `1000` (the jovyan user) will be used. Similarly for `KERNEL_GID`, whose default is `100` (the users group). In addition, Enterprise Gateway enforces a lists of prohibited UID and GID values. By default, this list is initialized to the 0 (root) UID and GID. Administrators can configure the `EG_PROHIBITED_UIDS` and `EG_PROHIBITED_GIDS` environment variables via the enterprise-gateway.yaml file with comma-separated values to alter the set of user and group ids to be prevented.
396
-
1. As noted above, if `KERNEL_NAMESPACE` is not provided in the request, Enterprise Gateway will create a namespace using the same naming algorithm for the pod. In addition, the `kernel-controller` cluster role will be bound to a namespace-scoped role binding of the same name using the namespace's default service account as its subject. Users wishing to use their own kernel namespaces must provide **both** `KERNEL_NAMESPACE` and `KERNEL_SERVICE_ACCOUNT_NAME` as these are both used in the `kernel-pod.yaml` as `${kernel_namespace}` and `${kernel_service_account_name}`, respectively.
415
+
1. As noted above, if `KERNEL_NAMESPACE` is not provided in the request, Enterprise Gateway will create a namespace using the same naming algorithm for the pod. In addition, the `kernel-controller` cluster role will be bound to a namespace-scoped role binding of the same name using the namespace's default service account as its subject. Users wishing to use their own kernel namespaces must provide **both** `KERNEL_NAMESPACE` and `KERNEL_SERVICE_ACCOUNT_NAME` as these are both used in the `kernel-pod.yaml.j2` as `{{ kernel_namespace }}` and `{{ kernel_service_account_name }}`, respectively.
397
416
1. Kernel pods have restart policies of `Never`. This is because the Jupyter framework already has built-in logic for auto-restarting failed kernels and any other restart policy would likely interfere with the built-in behaviors.
398
417
1. The parameters to the launcher that is built into the image are communicated via environment variables as noted in the `env:` section above.
399
418
@@ -514,8 +533,8 @@ As always, kernels are launched by virtue of the `argv:` stanza in their respect
0 commit comments