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
traefik-proxy uses the [Traefik API](https://doc.traefik.io/traefik/operations/api/) to monitor routes and configurations.
6
+
7
+
Because of **security** concerns, in traefik-proxy implementation, traefik api endpoint isn't exposed on the public http endpoint. Instead, it runs on a dedicated **authenticated endpoint** that's on localhost by default.
8
+
9
+
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.:
Check out TraefikProxy's [API Reference](TraefikProxy) for more configuration options.
18
+
19
+
## Class structure
20
+
21
+
A JupyterHub Proxy implementation must implement these methods:
22
+
23
+
-`start` / `stop` (starting and stopping the proxy)
24
+
-`add_route`
25
+
-`delete_route`
26
+
-`get_all_routes`
27
+
-`get_route` (a default implementation is provided by the base class, based on get_all_routes)
28
+
29
+
Additionally, for traefik we need to set up the separate "static config" (API access and where routes will be stored) and "dynamic config" (the routing table itself, which changes as servers start and stop).
30
+
Where and how dynamic_config is stored is the ~only difference between TraefikProxy subclasses.
31
+
32
+
Setting up traefik configuration is in these methods:
33
+
34
+
-`_setup_traefik_static_config` - must be extended by subclasses to add any provider-specific configuration to `self.static_config`
35
+
-`_setup_traefik_dynamic_config` - usually not modified
36
+
37
+
TraefikProxy is organized into three levels:
38
+
39
+
First, is [](TraefikProxy). This class is responsible for everything traefik-specific.
40
+
It implements talking to the traefik API, and computing _what_ dynamic configuration is needed for each step.
41
+
This base class provides implementations of `start`, `stop`, `add_route`, `delete_route`, and `get_all_routes`.
42
+
43
+
TraefikProxy subclasses must implement _how_ dynamic config is stored, and set the appropriate static config to tell traefik how to load the dynamic config.
44
+
Specifically, the generic methods:
45
+
46
+
-`_setup_traefik_static_config` should extend `self.static_config` to configure the traefik [configuration discovery provider](https://doc.traefik.io/traefik/providers/overview/)
47
+
-`_apply_dynamic_config` stores a given dynamic config dictionary in the appropriate config store
48
+
-`_delete_dynamic_config` removes keys from the dynamic config store
49
+
-`_get_jupyterhub_dynamic_config` reads the whole jupyterhub part (not read by traefik itself)
50
+
51
+
We have two classes at this level:
52
+
53
+
- TraefikFileProviderProxy, which stores dynamic config in a toml or yaml file, and
54
+
- TKvProxy - another base class, which implements the above, based on a generic notion of a key-value store
55
+
56
+
TKvProxy is an adapter layer, implementing all of the above methods, based on a few basic actions on key-value stores:
57
+
58
+
-`_kv_atomic_set` should take a _flat dictionary_ of key _paths_ and string values, and store them.
59
+
-`_kv_atomic_delete` should delete a number of keys in a single transaction
60
+
-`_kv_get_tree` should recursively read everything in the key-value store under a prefix (returning the _flattened_ dictionary)
61
+
62
+
TKvProxy is responsible for translating between key-value-friendly "flat" dictionaries and the 'true' nested dictionary format of the configuration (i.e. the nested dictionary `{"a": {"b": 5}}` will be flattened to `{"a/b": "5"}`).
63
+
64
+
Finally, we have our specific key-value store implementations: [](TraefikEtcdProxy) and [](TraefikConsulProxy).
65
+
These classes only need to implement:
66
+
67
+
1. configuration necessary to connect to the key-value provider
68
+
2.`_setup_traefik_static_config` to tell traefik how to talk to the same key-value provider
69
+
3. the above three `_kv_` methods for reading, writing, and deleting keys
70
+
71
+
## Testing jupyterhub-traefik-proxy
72
+
73
+
You can then run the all the test suite from the _traefik-proxy_ directory with:
# will configure JupyterHub to run with TraefikEtcdProxy
99
-
100
99
```
101
100
102
101
```
103
102
c.JupyterHub.proxy_class = "traefik_consul"
104
103
# will configure JupyterHub to run with TraefikConsulProxy
105
-
106
-
```
107
-
108
-
## Implementation details
109
-
110
-
1. **Traefik API**
111
-
112
-
traefik-proxy uses the [Traefik API](https://doc.traefik.io/traefik/operations/api/) to monitor routes and configurations.
113
-
114
-
Because of **security** concerns, in traefik-proxy implementation, traefik api endpoint isn't exposed on the public http endpoint. Instead, it runs on a dedicated **authenticated endpoint** that's on localhost by default.
115
-
116
-
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.:
0 commit comments