Using TraefikRedisProxy#
Redis is a distributed key-value store. This should be the default choice when using jupyterhub-traefik-proxy in a distributed setup, such as a Kubernetes cluster with multiple traefik instances.
How-To install TraefikRedisProxy#
Install jupyterhub
Install jupyterhub-traefik-proxy and redis Python client
pip install jupyterhub-traefik-proxy[redis]
Install traefik
Install Redis Server
You can find the full installation guide and examples in the installation section
How-To enable TraefikRedisProxy#
You can enable JupyterHub to work with TraefikRedisProxy
in jupyterhub_config.py,
using the proxy_class
configuration option:
c.JupyterHub.proxy_class = "traefik_redis"
Redis configuration#
Depending on the value of the
should_start
proxy flag, you can choose whether or not JupyterHub will manage and start traefik itself.When should_start is True (default), TraefikRedisProxy will generate the static configuration needed to connect to redis and store it in
traefik.toml
file. The traefik process will then be launched using this file.When should_start is False, prior to starting the traefik process, you must create a toml file with the desired traefik static configuration and pass it to traefik. Keep in mind that in order for the routes to be stored in Redis, this toml file must specify redis as the provider.
TraefikRedisProxy searches in the redis key-value store for keys starting with the kv_traefik_prefix prefix to build its static configuration.
Similarly, the dynamic configuration is built by searching for the kv_jupyterhub_prefix.
Note
If you want to change or add to traefik’s dynamic configuration options, you can add them to Redis under this prefix and traefik will pick them up.
The default values of these configuration options are:
kv_traefik_prefix = "/traefik/" kv_jupyterhub_prefix = "/jupyterhub/"
You can override the default values of the prefixes by passing their desired values through
jupyterhub_config.py
e.g.:c.TraefikRedisProxy.kv_traefik_prefix = "/some_dynamic_config_prefix/" c.TraefikRedisProxy.kv_jupyterhub_prefix = "/some_other_config_prefix/"
By default, TraefikRedisProxy assumes Redis accepts client requests on the official default Redis port
6379
for client requests.c.TraefikRedisProxy.redis_url = "redis://127.0.0.1:6379"
If the Redis cluster is deployed differently than using the Redis defaults, then you must pass the Redis url to the proxy using the
redis_url
option in jupyterhub_config.py:c.TraefikRedisProxy.redis_url = "redis://hostname:port"
Note
TraefikRedisProxy does not manage the Redis cluster and assumes it is up and running before the proxy itself starts.
In order for traefik to reliably receive notifications of changes from redis, redis must enable keyspace notifications, e.g. with
--notify-keyspace-events KEA
To avoid losing configuration upon redis restart, the redis server should also enable persistence, e.g. with
--appendonly yes
Note
Based on how Redis is configured and started, TraefikRedisProxy needs to be told about some Redis configuration details, such as:
Redis address where it accepts client requests
c.TraefikRedisProxy.redis_url="scheme://hostname:port"
Redis credentials (if Redis has authentication enabled)
c.TraefikRedisProxy.redis_username="abc" c.TraefikRedisProxy.redis_password="123"
Additional redis client constructor options:
c.TraefikRedisProxy.redis_client_kwargs = {"retry_on_timeout": True}
Externally managed TraefikRedisProxy#
If traefik
is used as an externally managed service, then make sure you follow the steps enumerated below:
Let JupyterHub know that the proxy being used is TraefikRedisProxy, using the proxy_class configuration option:
c.JupyterHub.proxy_class = "traefik_redis"
Configure
TraefikRedisProxy
in jupyterhub_config.pyJupyterHub configuration file, jupyterhub_config.py must specify at least:
That the proxy is externally managed
The traefik api credentials
The Redis credentials (if Redis authentication is enabled)
Example configuration:
# JupyterHub shouldn't start the proxy, it's already running c.TraefikRedisProxy.should_start = False # if not the default: c.TraefikRedisProxy.redis_url = "redis://redis-host:2379" # traefik api credentials c.TraefikRedisProxy.traefik_api_username = "abc" c.TraefikRedisProxy.traefik_api_password = "123" # Redis credentials c.TraefikRedisProxy.redis_username = "def" c.TraefikRedisProxy.redis_password = "456"
Create a toml file with traefik’s desired static configuration
Before starting the traefik process, you must create a toml file with the desired traefik static configuration and pass it to traefik when you launch the process. Keep in mind that in order for the routes to be stored in Redis, this toml file must specify Redis as the provider.
Keep in mind that the static configuration must configure at least:
The default entrypoint
The api entrypoint
The Redis provider
Example:
[api] [entryPoints.http] address = "127.0.0.1:8000" [entryPoints.auth_api] address = "127.0.0.1:8099" [providers.redis] endpoints = [ "127.0.0.1:6379",] rootKey = "traefik" # username, password if needed username = "redisuser" password = "redispass"
Example setup#
This is an example setup for using JupyterHub and TraefikRedisProxy managed by another service than JupyterHub.
Configure the proxy through the JupyterHub configuration file, jupyterhub_config.py, e.g.:
# mark the proxy as externally managed c.TraefikRedisProxy.should_start = False # traefik api endpoint login password c.TraefikRedisProxy.traefik_api_password = "abc" # traefik api endpoint login username c.TraefikRedisProxy.traefik_api_username = "123" # Redis url where it accepts client requests c.TraefikRedisProxy.redis_url = "redis://127.0.0.1:6379" # username, password (if auth enabled) c.TraefikRedisProxy.redis_username = "def" c.TraefikRedisProxy.redis_password = "456" # configure JupyterHub to use TraefikRedisProxy c.JupyterHub.proxy_class = "traefik_redis"
Start a single-node Redis cluster on the default port on localhost. e.g.:
redis-server # if redis-server isn't found on path, and you installed it with snap, you # probably need to do this: # export PATH="/snap/redis/current/usr/bin/:$PATH"
Create a traefik static configuration file, traefik.toml, e.g:.
# enable the api [api] # the public port where traefik accepts http requests [entryPoints.http] address = ":8000" # the port on localhost where the traefik api should be found [entryPoints.auth_api] address = "localhost:8099" [providers.redis] # the Redis username, password (if auth is enabled) username = "def" password = "456" # the Redis address endpoints = ["127.0.0.1:2379"] # the prefix to use for the static configuration rootKey = "traefik"
Start traefik with the configuration specified above, e.g.:
$ traefik -c traefik.toml