Skip to content

Commit

Permalink
Merge pull request #145 from GeorgianaElena/traefik-v2-support
Browse files Browse the repository at this point in the history
Traefik v2 support
  • Loading branch information
GeorgianaElena authored Feb 7, 2023
2 parents 07726e4 + f39c1f9 commit e606fcf
Show file tree
Hide file tree
Showing 37 changed files with 1,918 additions and 1,258 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,27 @@ depending on how traefik store its routing configuration.

For **smaller**, single-node deployments:

* TraefikTomlProxy
* TraefikFileProviderProxy

For **distributed** setups:

* TraefikEtcdProxy
* TraefikConsulProxy

## Installation

The [documentation](https://jupyterhub-traefik-proxy.readthedocs.io) contains a
[complete installation
guide](https://jupyterhub-traefik-proxy.readthedocs.io/en/latest/install.html)
with examples for the three different implementations.

* [For TraefikTomlProxy](https://jupyterhub-traefik-proxy.readthedocs.io/en/latest/toml.html#example-setup)
* [For TraefikFileProviderProxy](https://jupyterhub-traefik-proxy.readthedocs.io/en/latest/file.html#example-setup)
* [For TraefikEtcdProxy](https://jupyterhub-traefik-proxy.readthedocs.io/en/latest/etcd.html#example-setup)
* [For TraefikConsulProxy](https://jupyterhub-traefik-proxy.readthedocs.io/en/latest/consul.html#example-setup)


## Running tests

There are some tests that use *etcdctl* command line client for etcd. Make sure
to set environment variable `ETCDCTL_API=3` before running the tests, so that
the v3 API to be used, e.g.:
Expand Down
16 changes: 12 additions & 4 deletions docs/source/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,40 @@ Module: :mod:`jupyterhub_traefik_proxy`

.. automodule:: jupyterhub_traefik_proxy

.. currentmodule:: jupyterhub_traefik_proxy
.. currentmodule:: jupyterhub_traefik_proxy.proxy

:class:`TraefikProxy`
---------------------

.. autoconfigurable:: TraefikProxy
:members:

:class:`TraefikTomlProxy`
-------------------------
.. currentmodule:: jupyterhub_traefik_proxy.fileprovider

:class:`TraefikFileProviderProxy`
---------------------------------

.. autoconfigurable:: TraefikTomlProxy
.. autoconfigurable:: TraefikFileProviderProxy
:members:

.. currentmodule:: jupyterhub_traefik_proxy.kv_proxy

:class:`TKvProxy`
-----------------

.. autoconfigurable:: TKvProxy
:members:

.. currentmodule:: jupyterhub_traefik_proxy.etcd

:class:`TraefikEtcdProxy`
-------------------------

.. autoconfigurable:: TraefikEtcdProxy
:members:

.. currentmodule:: jupyterhub_traefik_proxy.consul

:class:`TraefikConsulProxy`
---------------------------

Expand Down
194 changes: 194 additions & 0 deletions docs/source/file.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
# Using TraefikFileProviderProxy

**jupyterhub-traefik-proxy** can be used with simple toml or yaml configuration files, for smaller, single-node deployments such as
[The Littlest JupyterHub](https://tljh.jupyter.org).

## How-To install TraefikFileProviderProxy

1. Install **jupyterhub**
2. Install **jupyterhub-traefik-proxy**
3. Install **traefik**

* You can find the full installation guide and examples in the [Introduction section](install.html#traefik-proxy-installation)

## How-To enable TraefikFileProviderProxy

You can enable JupyterHub to work with `TraefikFileProviderProxy` in jupyterhub_config.py, using the `proxy_class` configuration option.

You can choose to:

* use the `traefik_file` entrypoint, new in JupyterHub 1.0, e.g.:

```python
c.JupyterHub.proxy_class = "traefik_file"
```

* use the TraefikFileProviderProxy object, in which case, you have to import the module, e.g.:

```python
from jupyterhub_traefik_proxy import TraefikFileProviderProxy
c.JupyterHub.proxy_class = TraefikFileProviderProxy
```


## Traefik configuration

Traefik's configuration is divided into two parts:

* The **static** configuration (loaded only at the beginning)
* The **dynamic** configuration (can be hot-reloaded, without restarting the proxy),
where the routing table will be updated continuously.

Traefik allows us to have one file for the static configuration file (`traefik.toml` or `traefik.yaml`) and one or several files for the routes, that traefik would watch.

```{note}
**TraefikFileProviderProxy**, uses two configuration files: one file for the routes (**rules.toml** or **rules.yaml**), and one for the static configuration (**traefik.toml** or **traefik.yaml**).
```


By **default**, Traefik will search for `traefik.toml` and `rules.toml` in the following places:

* /etc/traefik/
* $HOME/.traefik/
* . the working directory

You can override this in TraefikFileProviderProxy, by modifying the **static_config_file** argument:

```python
c.TraefikFileProviderProxy.static_config_file="/path/to/static_config_filename.toml"
```

Similarly, you can override the dynamic configuration file by modifying the **dynamic_config_file** argument:

```python
c.TraefikFileProviderProxy.dynamic_config_file="/path/to/dynamic_config_filename.toml"
```

```{note}

* **When JupyterHub starts the proxy**, it writes the static config once, then only edits the dynamic config file.

* **When JupyterHub does not start the proxy**, the user is totally responsible for the static config and
JupyterHub is responsible exclusively for the routes.

* **When JupyterHub does not start the proxy**, the user should tell `traefik` to get its dynamic configuration
from a directory. Then, one (or more) dynamic configuration file(s) can be managed externally, and `dynamic_config_file`
will be managed by JupyterHub. This allows e.g., the administrator to configure traefik's API outside of JupyterHub.

```

## Externally managed TraefikFileProviderProxy

When TraefikFileProviderProxy is externally managed, service managers like [systemd](https://www.freedesktop.org/wiki/Software/systemd/)
or [docker](https://www.docker.com/) will be responsible for starting and stopping the proxy.

If TraefikFileProviderProxy is used as an externally managed service, then make sure you follow the steps enumerated below:

1. Let JupyterHub know that the proxy being used is TraefikFileProviderProxy, using the *proxy_class* configuration option:
```python
from jupyterhub_traefik_proxy import TraefikFileProviderProxy
c.JupyterHub.proxy_class = TraefikFileProviderProxy
```

2. Configure `TraefikFileProviderProxy` in **jupyterhub_config.py**

JupyterHub configuration file, *jupyterhub_config.py* must specify at least:
* That the proxy is externally managed
* The traefik api credentials
* The dynamic configuration file,
if different from *rules.toml* or if this file is located
in another place than traefik's default search directories (etc/traefik/, $HOME/.traefik/, the working directory)

Example configuration:
```python
# JupyterHub shouldn't start the proxy, it's already running
c.TraefikFileProviderProxy.should_start = False

# if not the default:
c.TraefikFileProviderProxy.dynamic_config_file = "/path/to/somefile.toml"

# traefik api credentials
c.TraefikFileProviderProxy.traefik_api_username = "abc"
c.TraefikFileProviderProxy.traefik_api_password = "xxx"
```

3. Ensure **traefik.toml** / **traefik.yaml**

The static configuration file, *traefik.toml* (or **traefik.yaml**) must configure at least:
* The default entrypoint
* The api entrypoint (*and authenticate it in a user-managed dynamic configuration file*)
* The websockets protocol
* The dynamic configuration directory to watch
(*make sure this configuration directory exists, even if empty before the proxy is launched*)
* Check `tests/config_files/traefik.toml` for an example.

## Example setup

This is an example setup for using JupyterHub and TraefikFileProviderProxy managed by another service than JupyterHub.

1. Configure the proxy through the JupyterHub configuration file, *jupyterhub_config.py*, e.g.:

```python
from jupyterhub_traefik_proxy import TraefikFileProviderProxy

# mark the proxy as externally managed
c.TraefikFileProviderProxy.should_start = False

# traefik api endpoint login password
c.TraefikFileProviderProxy.traefik_api_password = "admin"

# traefik api endpoint login username
c.TraefikFileProviderProxy.traefik_api_username = "api_admin"

# traefik's dynamic configuration file, which will be managed by JupyterHub
c.TraefikFileProviderProxy.dynamic_config_file = "/var/run/traefik/rules.toml"

# configure JupyterHub to use TraefikFileProviderProxy
c.JupyterHub.proxy_class = TraefikFileProviderProxy
```

2. Create a traefik static configuration file, *traefik.toml*, e.g.:

```
# the api entrypoint
[api]
dashboard = true

# websockets protocol
[wss]
protocol = "http"

# the port on localhost where traefik accepts http requests
[entryPoints.web]
address = ":8000"

# the port on localhost where the traefik api and dashboard can be found
[entryPoints.enter_api]
address = ":8099"

# the dynamic configuration directory
# This must match the directory provided in Step 1. above.
[providers.file]
directory = "/var/run/traefik"
watch = true
```

3. Create a traefik dynamic configuration file in the directory provided in the dynamic configuration above, to provide the api authentication parameters, e.g.

```
# Router configuration for the api service
[http.routers.router-api]
rule = "Host(`localhost`) && PathPrefix(`/api`)"
entryPoints = ["enter_api"]
service = "api@internal"
middlewares = ["auth_api"]

# authenticate the traefik api entrypoint
[http.middlewares.auth_api.basicAuth]
users = [ "api_admin:$apr1$eS/j3kum$q/X2khsIEG/bBGsteP.x./",]
```

4. Start traefik with the configuration specified above, e.g.:
```bash
$ traefik --configfile traefik.toml
```
4 changes: 2 additions & 2 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Moreover it offers *HTTPS* support through a straight-forward `ACME (Let's Encry
There are three versions for the proxy, depending on how traefik stores the routes:

* *for* **smaller**, *single-node deployments*:
* TraefikTomlProxy
* TraefikFileProviderProxy
* *for* **distributed** *setups*:
* TraefikEtcdProxy
* TraefikConsulProxy
Expand All @@ -39,7 +39,7 @@ Getting Started
.. toctree::
:maxdepth: 1

toml
file
etcd
consul

Expand Down
12 changes: 6 additions & 6 deletions docs/source/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
## Enabling traefik-proxy in JupyterHub
[TraefikTomlProxy](https://github.com/jupyterhub/traefik-proxy/blob/HEAD/jupyterhub_traefik_proxy/toml.py), [TraefikEtcdProxy](https://github.com/jupyterhub/traefik-proxy/blob/HEAD/jupyterhub_traefik_proxy/etcd.py) and [TraefikConsulProxy](https://github.com/jupyterhub/traefik-proxy/blob/HEAD/jupyterhub_traefik_proxy/consul.py) are custom proxy implementations that subclass [Proxy](https://github.com/jupyterhub/jupyterhub/blob/HEAD/jupyterhub/proxy.py) and can register in JupyterHub config using `c.JupyterHub.proxy_class` entrypoint.
[TraefikFileProviderProxy](https://github.com/jupyterhub/traefik-proxy/blob/HEAD/jupyterhub_traefik_proxy/fileprovider.py), [TraefikEtcdProxy](https://github.com/jupyterhub/traefik-proxy/blob/HEAD/jupyterhub_traefik_proxy/etcd.py) and [TraefikConsulProxy](https://github.com/jupyterhub/traefik-proxy/blob/HEAD/jupyterhub_traefik_proxy/consul.py) are custom proxy implementations that subclass [Proxy](https://github.com/jupyterhub/jupyterhub/blob/HEAD/jupyterhub/proxy.py) and can register in JupyterHub config using `c.JupyterHub.proxy_class` entrypoint.
On startup, JupyterHub will look by default for a configuration file, *jupyterhub_config.py*, in the current working directory. If the configuration file is not in the current working directory,
you can load a specific config file and start JupyterHub using:
Expand All @@ -83,8 +83,8 @@ There is an example configuration file [here](https://github.com/jupyterhub/trae
In *jupyterhub_config.py*:
```
c.JupyterHub.proxy_class = "traefik_toml"
# will configure JupyterHub to run with TraefikTomlProxy
c.JupyterHub.proxy_class = "traefik_file"
# will configure JupyterHub to run with TraefikFileProviderProxy
```
```
Expand All @@ -110,9 +110,9 @@ c.JupyterHub.proxy_class = "traefik_consul"
The port on which traefik-proxy's api will run, as well as the username and password used for authenticating, can be passed to the proxy through `jupyterhub_config.py`, e.g.:
```
c.TraefikTomlProxy.traefik_api_url = "http://127.0.0.1:8099"
c.TraefikTomlProxy.traefik_api_password = "admin"
c.TraefikTomlProxy.traefik_api_username = "admin"
c.TraefikFileProviderProxy.traefik_api_url = "http://127.0.0.1:8099"
c.TraefikFileProviderProxy.traefik_api_password = "admin"
c.TraefikFileProviderProxy.traefik_api_username = "admin"
```
Check out TraefikProxy's **API Reference** for more configuration options.
<br/><br/>
Expand Down
Loading

0 comments on commit e606fcf

Please sign in to comment.