--- tags: CCNS, python, conda, jupyter --- JupyterHub + LDAPAuth + DockerSpawner Installation note === OS --- ``` Ubuntu Server 18.04.5 ``` Install CUDA --- https://developer.nvidia.com/cuda-downloads? https://www.tensorflow.org/install/gpu ```bash # Add NVIDIA package repositories wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-repo-ubuntu1804_10.0.130-1_amd64.deb sudo dpkg -i cuda-repo-ubuntu1804_10.0.130-1_amd64.deb sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub sudo apt-get update wget http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb sudo apt install ./nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb sudo apt-get update # Install NVIDIA driver sudo apt-get install --no-install-recommends nvidia-driver-410 # Reboot. Check if GPUs are visible using the command: nvidia-smi # Install development and runtime libraries (~4GB) sudo apt-get install --no-install-recommends \ cuda-10-0 \ libcudnn7=7.4.1.5-1+cuda10.0 \ libcudnn7-dev=7.4.1.5-1+cuda10.0 ``` Install Docker --- https://cloud.tencent.com/developer/article/1011087 ```bash curl -fsSL https://get.docker.com/ | sh ``` Change Docker daemon directory --- https://docs.docker.com/config/daemon/ ```bash sudo vim /etc/docker/daemon.json ``` ``` { "data-root": "/data/docker", "runtimes": { "nvidia": { "path": "nvidia-container-runtime", "runtimeArgs": [] } } } ``` Install nvidia-docker --- https://github.com/NVIDIA/nvidia-docker ```bash # Add the package repositories curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - distribution=$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list sudo apt-get update # Install nvidia-docker2 and reload the Docker daemon configuration sudo apt-get install -y nvidia-docker2 sudo systemctl restart docker # Test nvidia-smi with the latest official CUDA image docker run --rm --gpus all nvidia/cuda nvidia-smi ``` ### Enable log file if needed ``` vim /etc/nvidia-container-runtime/config.toml ### Uncomment debug=... ``` Install conda --- https://docs.anaconda.com/anaconda/install/linux/ ```bash wget https://repo.anaconda.com/archive/Anaconda3-2018.12-Linux-x86_64.sh bash Anaconda3-2018.12-Linux-x86_64.sh source ~/.bashrc conda -V ``` Install Jupyter --- https://jupyter.readthedocs.io/en/latest/install.html No need if you have installed Anaconda in the previous setp. Install JupyterHub --- https://jupyterhub.readthedocs.io/en/stable/quickstart.html ```bash conda install -c conda-forge jupyterhub # Install JupyterHub and proxy conda install notebook # Needed if running notebook servers in local jupyterhub -h configurable-http-proxy -h ``` Config options https://jupyterhub.readthedocs.io/en/stable/installation-basics.html - Path suggestions - `/srv/jupyterhub` for all security and runtime files - `/etc/jupyterhub` for all configuration files - `/var/log` for log files - Config planning - Deployment system (Bare metal, Docker) - Authentication (PAM, OAuth, etc.) - Spawner of singleuser notebook servers (Docker, Batch, etc.) - Services (nbgrader, etc.) - JupyterHub database (default SQLite; traditional RDBMS such as PostgreSQL,) MySQL, or other databases supported by SQLAlchemy) Generate config file for JupyterHub --- https://jupyterhub.readthedocs.io/en/stable/getting-started/config-basics.html ```bash mkdir -p /etc/jupyterhub cd /etc/jupyterhub jupyterhub --generate-config jupyterhub -f /etc/jupyterhub/jupyterhub_config.py ``` Config LDAP Authentication --- https://jupyterhub.readthedocs.io/en/stable/reference/authenticators.html https://github.com/jupyterhub/ldapauthenticator ```bash conda install -c conda-forge jupyterhub-ldapauthenticator ``` Edit `/etc/jupyterhub/jupyterhub_config.py` ``` c.JupyterHub.authenticator_class = 'ldapauthenticator.LDAPAuthenticator' c.LDAPAuthenticator.server_address = '<server_address>' c.LDAPAuthenticator.bind_dn_template = 'uid={username},cn=users,dc=example,dc=com' c.LDAPAuthenticator.use_ssl = True ``` Config Docker spawner --- https://jupyterhub.readthedocs.io/en/stable/reference/spawners.html https://github.com/jupyterhub/dockerspawner ```bash conda install -c conda-forge dockerspawner ``` Edit `/etc/jupyterhub/jupyterhub_config.py` ```python c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner' c.DockerSpawner.image_whitelist = { "deepdetect-gpu (Tensorflow+PyTorch)": "jolibrain/jupyter-dd-notebook-gpu", "tensorflow-2-gpu (Tensorflow 2.0)": "d4n1el/tensorflow-2-notebook-gpu", "datascience-gpu (Python+Julia+R)": "d4n1el/datascience-notebook-gpu", "tensorflow-cpu (Tensorflow)": "jupyter/tensorflow-notebook", "datascience-cpu (Python+Julia+R)": "jupyter/datascience-notebook", } c.DockerSpawner.remove_containers = True c.DockerSpawner.extra_create_kwargs = {'user': 'root'} c.DockerSpawner.extra_host_config = {'runtime': 'nvidia'} c.Spawner.environment = {'GRANT_SUDO': 'yes'} from jupyter_client.localinterfaces import public_ips c.JupyterHub.hub_ip = public_ips()[0] ``` Good notebook image list ``` docker pull jupyter/tensorflow-notebook docker pull jupyter/datascience-notebook ``` w/ GPU supports: https://github.com/d4n1elchen/docker-stacks ``` docker pull jolibrain/jupyter-dd-notebook-gpu docker pull d4n1el/tensorflow-2-notebook-gpu docker pull d4n1el/datascience-notebook-gpu docker run --runtime=nvidia --rm jolibrain/jupyter-dd-notebook-gpu nvidia-smi ``` Automatically add and mount remote folder for persistence data for each user and bind to the container ```python import os, shutil def create_dir_hook(spawner): """ Create directory """ username = spawner.user.name # get the username home_path = os.path.join('/home/', username) volume_path = os.path.join(home_path, 'net') net_path = os.path.join('/net/eugeo-home/', username) if not os.path.exists(volume_path): os.mkdir(home_path) shutil.chown(home_path, user=username, group='users') c.Spawner.pre_spawn_hook = create_dir_hook c.DockerSpawner.volumes = { '/net/eugeo-home/{username}': '/home/{username}/net', '/net/eugeo-home/{username}/sortiliena-home': '/home/{username}/net/sortiliena-home', '/net/eugeo-home/{username}/yuuki-home': '/home/{username}/net/yuuki-home' } ``` [sftp Settings](https://hackmd.io/GkvAp8HMTMGhUTqELgf_pQ?both) Config domain and ssl for jupyterhub --- https://jupyterhub.readthedocs.io/en/stable/getting-started/security-basics.html Sign a certificate ``` openssl req -x509 -nodes -days 3650 -newkey rsa:1024 -keyout /etc/jupyterhub/certificate/key.pem -out /etc/jupyterhub/certificate/cert.pem ``` Edit config ```python c.JupyterHub.ssl_cert = '/etc/jupyterhub/certificate/cert.pem' c.JupyterHub.ssl_key = '/etc/jupyterhub/certificate/key.pem' ``` Setup jupyterhub as system service --- https://github.com/jupyterhub/jupyterhub/wiki/Run-jupyterhub-as-a-system-service Add `/etc/systemd/system/jupyterhub.service` ``` [Unit] Description=Jupyterhub After=syslog.target network.target [Service] User=root Environment="PATH=/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/anaconda3/bin" ExecStart=/root/anaconda3/bin/jupyterhub -f /etc/jupyterhub/jupyterhub_config.py [Install] WantedBy=multi-user.target ``` ```bash sudo systemctl daemon-reload sudo systemctl start jupyterhub sudo systemctl status jupyterhub sudo systemctl enable jupyterhub ```