Skip to content

Commit ea9e30d

Browse files
committed
new container service is destructive and mostly read-only
1 parent d2bd9cf commit ea9e30d

File tree

1 file changed

+24
-22
lines changed

1 file changed

+24
-22
lines changed

jupyterhub/README.md

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ the resource manager [Slurm](https://slurm.schedmd.com/). Users can select the
1212
resources for their notebooks from the JupyterHub interface thanks to the
1313
[JupyterHub MOdular Slurm Spawner](https://github.com/silx-kit/jupyterhub_moss),
1414
which leverages [batchspawner](https://github.com/jupyterhub/batchspawner) to
15-
submit jobs to Slurm in user's behalf that will launch the single-user server.
15+
submit jobs to Slurm in user's behalf to launch the single-user server.
1616

1717
The main particularity of our setup is that such jobs are not submitted to
1818
Slurm from the host running JupyterHub, but from the login nodes of the HPC
@@ -24,21 +24,23 @@ installation capable of submitting jobs to the HPC cluster.
2424
## Rootless
2525

2626
JupyterHub is run by a non-root user in a rootless container. Setting up a
27-
rootless container is well described in the [podman rootless
28-
tutorial](https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md).
29-
30-
We use a [system service](host/etc/systemd/system/jupyterhub.service) to
31-
execute `podman` by a non-root user `jupyterhub` (*aka* JupyterHub operator).
32-
This service relies on a [custom shell script](host/usr/local/bin/jupyterhub-init.sh)
33-
to automatically initialize a new image of the rootless container or start an
34-
existing one.
35-
36-
The container [binds a few mounts with sensitive configuration
37-
files](host/usr/local/bin/jupyterhub-init.sh#L59-L66) for JupyterHub, SSL
38-
certificates for the web server and SSH keys to connect to the login nodes.
39-
Provisioning these files in the container through bind-mounts allows to have
40-
secret-free container images and seamlessly deploy updates to the configuration
41-
of the hub.
27+
rootless container is well described in the
28+
[podman rootless tutorial](https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md).
29+
30+
We use a [custom system service](container_host/etc/systemd/system/container-jupyterhub.service)
31+
to start the container with `podman` by the non-root user `jupyterhub` (*aka*
32+
JupyterHub operator).
33+
This service regenerates at (re)start any running container with a new one from
34+
the container image. This approach ensures a clean state of the container and
35+
allows to easily recover from any runtime issues with it.
36+
37+
The root filesystem in the container is read-only. The only writable space is
38+
the home directory of the non-root user running the container. We also [bind a
39+
few read-only mounts](container_host/etc/systemd/system/container-jupyterhub.service#L38)
40+
with sensitive configuration files for JupyterHub, SSL certificates for the web
41+
server and SSH keys to connect to the login nodes. Provisioning these files in
42+
the container through bind-mounts allows to have secret-free container images
43+
and seamlessly deploy updates to the configuration of the hub.
4244

4345
## Network
4446

@@ -70,34 +72,34 @@ from JupyterHub:
7072
* [URLs of the VSC OAuth](container/Dockerfile#L72-L76) are defined in the
7173
environment of the container
7274

73-
* [OAuth secrets](container/.config/jupyterhub_config.py#L40-L45) are
75+
* [OAuth secrets](container/.config/jupyterhub_config.py#L43-L48) are
7476
defined in JupyterHub's configuration file
7577

7678
* local users beyond the non-root user running JupyterHub are **not needed**
7779

7880
## Slurm
7981

8082
Integration with Slurm is leveraged through a custom Spawner called
81-
[VSCSlurmSpawner](container/.config/jupyterhub_config.py#L60) based on
83+
[VSCSlurmSpawner](container/.config/jupyterhub_config.py#L63) based on
8284
[MOSlurmSpawner](https://github.com/silx-kit/jupyterhub_moss).
8385
`VSCSlurmSpawner` allows JupyterHub to generate the user's environment needed
8486
to spawn its single-user server without any local users. All user settings are
8587
taken from `vsc-config`.
8688

87-
We modified the [submission command](container/.config/jupyterhub_config.py#L295)
89+
We modified the [submission command](container/.config/jupyterhub_config.py#L317)
8890
to execute `sbatch` in the login nodes of the HPC cluster through SSH.
8991
The login nodes already run Slurm and are the sole systems handling job
9092
submission in our cluster. Delegating job submission to them avoids having to
9193
install and configure Slurm in the container running JupyterHub. The hub
9294
environment is passed over SSH with a strict control over the variables that
93-
are [sent](container/.ssh/config) and [accepted](slurm_login/etc/ssh/sshd_config)
95+
are [sent](container/.ssh/config) and [accepted](slurm_host/etc/ssh/sshd_config)
9496
on both ends.
9597

9698
The SSH connection is established by the non-root user running JupyterHub (the
9799
hub container does not have other local users). This jupyterhub user has
98100
special `sudo` permissions on the login nodes to submit jobs to Slurm as other
99101
users. The specific group of users and list of commands allowed to the
100-
jupyterhub user are defined in the [sudoers file](slurm_login/etc/sudoers).
102+
jupyterhub user are defined in the [sudoers file](slurm_host/etc/sudoers).
101103

102104
Single-user server spawn process:
103105

@@ -114,7 +116,7 @@ Single-user server spawn process:
114116
hub environment
115117

116118
5. single-user server job script fully [resets the
117-
environment](container/.config/jupyterhub_config.py#L264-L285) before any
119+
environment](container/.config/jupyterhub_config.py#L286-L312) before any
118120
other step is taken to minimize tampering from user's own environment
119121

120122
6. single-user server is launched **without** the mediation of `srun` to be

0 commit comments

Comments
 (0)