traefik/docs/user-guide/kv-config.md

445 lines
19 KiB
Markdown
Raw Normal View History

2016-07-11 15:32:28 +00:00
# Key-value store configuration
2018-02-06 13:04:03 +00:00
Both [static global configuration](/user-guide/kv-config/#static-configuration-in-key-value-store) and [dynamic](/user-guide/kv-config/#dynamic-configuration-in-key-value-store) configuration can be stored in a Key-value store.
2016-07-11 15:32:28 +00:00
2018-10-17 14:24:04 +00:00
This section explains how to launch Traefik using a configuration loaded from a Key-value store.
2016-07-11 15:32:28 +00:00
2018-10-17 14:24:04 +00:00
Traefik supports several Key-value stores:
2016-07-11 15:32:28 +00:00
- [Consul](https://consul.io)
- [etcd](https://coreos.com/etcd/)
2017-06-08 19:04:50 +00:00
- [ZooKeeper](https://zookeeper.apache.org/)
2016-07-11 15:32:28 +00:00
- [boltdb](https://github.com/boltdb/bolt)
## Static configuration in Key-value store
2016-07-11 15:32:28 +00:00
2017-06-08 19:04:50 +00:00
We will see the steps to set it up with an easy example.
2016-07-11 15:32:28 +00:00
2017-09-11 17:10:04 +00:00
!!! note
We could do the same with any other Key-value Store.
### docker-compose file for Consul
2016-07-11 15:32:28 +00:00
2018-10-17 14:24:04 +00:00
The Traefik global configuration will be retrieved from a [Consul](https://consul.io) store.
2016-07-11 15:32:28 +00:00
2017-06-08 19:04:50 +00:00
First we have to launch Consul in a container.
2017-09-11 17:10:04 +00:00
The [docker-compose file](https://docs.docker.com/compose/compose-file/) allows us to launch Consul and four instances of the trivial app [containous/whoami](https://github.com/containous/whoami) :
2016-07-11 15:32:28 +00:00
2017-04-30 18:17:57 +00:00
```yaml
2016-07-11 15:32:28 +00:00
consul:
image: progrium/consul
command: -server -bootstrap -log-level debug -ui-dir /ui
ports:
- "8400:8400"
- "8500:8500"
- "8600:53/udp"
expose:
- "8300"
- "8301"
- "8301/udp"
- "8302"
2017-09-07 10:02:03 +00:00
- "8302/udp"
2017-06-08 19:04:50 +00:00
2016-07-11 15:32:28 +00:00
whoami1:
image: containous/whoami
2017-06-08 19:04:50 +00:00
2016-07-11 15:32:28 +00:00
whoami2:
image: containous/whoami
2017-06-08 19:04:50 +00:00
2016-07-11 15:32:28 +00:00
whoami3:
image: containous/whoami
2017-06-08 19:04:50 +00:00
2016-07-11 15:32:28 +00:00
whoami4:
image: containous/whoami
2016-07-11 15:32:28 +00:00
```
2017-09-11 17:10:04 +00:00
### Upload the configuration in the Key-value store
2016-07-11 15:32:28 +00:00
2018-10-17 14:24:04 +00:00
We should now fill the store with the Traefik global configuration.
To do that, we can send the Key-value pairs via [curl commands](https://www.consul.io/intro/getting-started/kv.html) or via the [Web UI](https://www.consul.io/intro/getting-started/ui.html).
2016-07-11 15:32:28 +00:00
2018-10-17 14:24:04 +00:00
Fortunately, Traefik allows automation of this process using the `storeconfig` subcommand.
Please refer to the [store Traefik configuration](/user-guide/kv-config/#store-configuration-in-key-value-store) section to get documentation on it.
Here is the toml configuration we would like to store in the Key-value Store :
2016-07-11 15:32:28 +00:00
```toml
logLevel = "DEBUG"
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.api]
address = ":8081"
2016-07-11 15:32:28 +00:00
[entryPoints.http]
address = ":80"
[entryPoints.https]
address = ":443"
2016-07-11 15:32:28 +00:00
[entryPoints.https.tls]
[[entryPoints.https.tls.certificates]]
certFile = "integration/fixtures/https/snitest.com.cert"
keyFile = "integration/fixtures/https/snitest.com.key"
2016-07-11 15:32:28 +00:00
[[entryPoints.https.tls.certificates]]
certFile = """-----BEGIN CERTIFICATE-----
2016-07-11 15:32:28 +00:00
<cert file content>
-----END CERTIFICATE-----"""
keyFile = """-----BEGIN PRIVATE KEY-----
2016-07-11 15:32:28 +00:00
<key file content>
-----END PRIVATE KEY-----"""
[entryPoints.other-https]
address = ":4443"
[entryPoints.other-https.tls]
2016-07-11 15:32:28 +00:00
[consul]
endpoint = "127.0.0.1:8500"
watch = true
prefix = "traefik"
2017-06-08 19:04:50 +00:00
[api]
entrypoint = "api"
2016-07-11 15:32:28 +00:00
```
2017-06-08 19:04:50 +00:00
And there, the same global configuration in the Key-value Store (using `prefix = "traefik"`):
2016-07-11 15:32:28 +00:00
| Key | Value |
|-----------------------------------------------------------|---------------------------------------------------------------|
| `/traefik/loglevel` | `DEBUG` |
| `/traefik/defaultentrypoints/0` | `http` |
| `/traefik/defaultentrypoints/1` | `https` |
| `/traefik/entrypoints/api/address` | `:8081` |
2016-07-11 15:32:28 +00:00
| `/traefik/entrypoints/http/address` | `:80` |
| `/traefik/entrypoints/https/address` | `:443` |
| `/traefik/entrypoints/https/tls/certificates/0/certfile` | `integration/fixtures/https/snitest.com.cert` |
| `/traefik/entrypoints/https/tls/certificates/0/keyfile` | `integration/fixtures/https/snitest.com.key` |
| `/traefik/entrypoints/https/tls/certificates/1/certfile` | `--BEGIN CERTIFICATE--<cert file content>--END CERTIFICATE--` |
| `/traefik/entrypoints/https/tls/certificates/1/keyfile` | `--BEGIN CERTIFICATE--<key file content>--END CERTIFICATE--` |
| `/traefik/entrypoints/other-https/address` | `:4443` |
2016-07-11 15:32:28 +00:00
| `/traefik/consul/endpoint` | `127.0.0.1:8500` |
| `/traefik/consul/watch` | `true` |
| `/traefik/consul/prefix` | `traefik` |
| `/traefik/api/entrypoint` | `api` |
2016-07-11 15:32:28 +00:00
2017-04-30 18:17:57 +00:00
In case you are setting key values manually:
2017-09-05 13:58:03 +00:00
2017-04-30 18:17:57 +00:00
- Remember to specify the indexes (`0`,`1`, `2`, ... ) under prefixes `/traefik/defaultentrypoints/` and `/traefik/entrypoints/https/tls/certificates/` in order to match the global configuration structure.
- Be careful to give the correct IP address and port on the key `/traefik/consul/endpoint`.
2016-07-11 15:32:28 +00:00
Note that we can either give path to certificate file or directly the file content itself.
2018-10-17 14:24:04 +00:00
### Launch Traefik
2016-07-11 15:32:28 +00:00
2018-10-17 14:24:04 +00:00
We will now launch Traefik in a container.
2017-09-11 17:10:04 +00:00
2018-10-17 14:24:04 +00:00
We use CLI flags to setup the connection between Traefik and Consul.
2016-07-11 15:32:28 +00:00
All the rest of the global configuration is stored in Consul.
Here is the [docker-compose file](https://docs.docker.com/compose/compose-file/) :
2016-07-11 15:32:28 +00:00
2017-04-30 18:17:57 +00:00
```yaml
2016-07-11 15:32:28 +00:00
traefik:
image: traefik
command: --consul --consul.endpoint=127.0.0.1:8500
ports:
- "80:80"
- "8080:8080"
```
2017-08-28 12:33:07 +00:00
!!! warning
Be careful to give the correct IP address and port in the flag `--consul.endpoint`.
2016-07-11 15:32:28 +00:00
2017-09-11 17:10:04 +00:00
### Consul ACL Token support
2017-06-08 19:04:50 +00:00
2017-09-11 17:10:04 +00:00
To specify a Consul ACL token for Traefik, we have to set a System Environment variable named `CONSUL_HTTP_TOKEN` prior to starting Traefik.
This variable must be initialized with the ACL token value.
2017-06-08 19:04:50 +00:00
If Traefik is launched into a Docker container, the variable `CONSUL_HTTP_TOKEN` can be initialized with the `-e` Docker option : `-e "CONSUL_HTTP_TOKEN=[consul-acl-token-value]"`
2018-10-17 14:24:04 +00:00
If a Consul ACL is used to restrict Traefik read/write access, one of the following configurations is needed.
2017-11-14 10:38:03 +00:00
- HCL format :
```
key "traefik" {
policy = "write"
},
2017-11-14 10:38:03 +00:00
session "" {
policy = "write"
}
```
- JSON format :
```json
{
"key": {
"traefik": {
"policy": "write"
}
},
"session": {
"": {
"policy": "write"
}
}
}
```
2017-09-11 17:10:04 +00:00
### TLS support
2016-07-11 15:32:28 +00:00
To connect to a Consul endpoint using SSL, simply specify `https://` in the `consul.endpoint` property
- `--consul.endpoint=https://[consul-host]:[consul-ssl-port]`
2017-09-11 17:10:04 +00:00
### TLS support with client certificates
So far, only [Consul](https://consul.io) and [etcd](https://coreos.com/etcd/) support TLS connections with client certificates.
2017-09-11 17:10:04 +00:00
2016-07-11 15:32:28 +00:00
To set it up, we should enable [consul security](https://www.consul.io/docs/internals/security.html) (or [etcd security](https://coreos.com/etcd/docs/latest/security.html)).
2018-10-17 14:24:04 +00:00
Then, we have to provide CA, Cert and Key to Traefik using `consul` flags :
2016-07-11 15:32:28 +00:00
- `--consul.tls`
- `--consul.tls.ca=path/to/the/file`
- `--consul.tls.cert=path/to/the/file`
2017-06-08 19:04:50 +00:00
- `--consul.tls.key=path/to/the/file`
2016-07-11 15:32:28 +00:00
Or etcd flags :
- `--etcd.tls`
- `--etcd.tls.ca=path/to/the/file`
- `--etcd.tls.cert=path/to/the/file`
- `--etcd.tls.key=path/to/the/file`
2017-09-11 17:10:04 +00:00
!! note
We can either give directly directly the file content itself (instead of the path to certificate) in a TOML file configuration.
2016-07-11 15:32:28 +00:00
Remember the command `traefik --help` to display the updated list of flags.
2017-09-11 17:10:04 +00:00
## Dynamic configuration in Key-value store
2017-06-08 19:04:50 +00:00
2018-10-17 14:24:04 +00:00
Following our example, we will provide backends/frontends rules and HTTPS certificates to Traefik.
2016-07-11 15:32:28 +00:00
2017-09-11 17:10:04 +00:00
!!! note
2018-10-17 14:24:04 +00:00
This section is independent of the way Traefik got its static configuration.
2017-09-11 17:10:04 +00:00
It means that the static configuration can either come from the same Key-value store or from any other sources.
2016-07-11 15:32:28 +00:00
2017-09-11 17:10:04 +00:00
### Key-value storage structure
2017-06-08 19:04:50 +00:00
Here is the toml configuration we would like to store in the store :
2016-07-11 15:32:28 +00:00
```toml
[file]
# rules
[backends]
[backends.backend1]
[backends.backend1.circuitbreaker]
2017-09-05 13:58:03 +00:00
expression = "NetworkErrorRatio() > 0.5"
2016-07-11 15:32:28 +00:00
[backends.backend1.servers.server1]
url = "http://172.17.0.2:80"
weight = 10
[backends.backend1.servers.server2]
url = "http://172.17.0.3:80"
weight = 1
[backends.backend2]
[backends.backend1.maxconn]
2017-09-05 13:58:03 +00:00
amount = 10
extractorfunc = "request.host"
2016-07-11 15:32:28 +00:00
[backends.backend2.LoadBalancer]
2017-09-05 13:58:03 +00:00
method = "drr"
2016-07-11 15:32:28 +00:00
[backends.backend2.servers.server1]
url = "http://172.17.0.4:80"
weight = 1
[backends.backend2.servers.server2]
url = "http://172.17.0.5:80"
weight = 2
[frontends]
[frontends.frontend1]
backend = "backend2"
[frontends.frontend1.routes.test_1]
rule = "Host:test.localhost"
[frontends.frontend2]
backend = "backend1"
passHostHeader = true
priority = 10
2018-07-06 14:52:04 +00:00
[frontends.frontend2.auth.basic]
users = [
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
]
2016-07-11 15:32:28 +00:00
entrypoints = ["https"] # overrides defaultEntryPoints
[frontends.frontend2.routes.test_1]
rule = "Host:{subdomain:[a-z]+}.localhost"
[frontends.frontend3]
entrypoints = ["http", "https"] # overrides defaultEntryPoints
backend = "backend2"
2017-09-05 13:58:03 +00:00
rule = "Path:/test"
2018-01-23 15:30:07 +00:00
[[tls]]
[tls.certificate]
certFile = "path/to/your.cert"
keyFile = "path/to/your.key"
2018-01-24 10:57:06 +00:00
2018-01-23 15:30:07 +00:00
[[tls]]
2018-01-24 10:57:06 +00:00
entryPoints = ["https","other-https"]
2018-01-23 15:30:07 +00:00
[tls.certificate]
certFile = """-----BEGIN CERTIFICATE-----
<cert file content>
-----END CERTIFICATE-----"""
keyFile = """-----BEGIN CERTIFICATE-----
<key file content>
-----END CERTIFICATE-----"""
2016-07-11 15:32:28 +00:00
```
2017-06-08 19:04:50 +00:00
And there, the same dynamic configuration in a KV Store (using `prefix = "traefik"`):
2016-07-11 15:32:28 +00:00
- backend 1
| Key | Value |
|--------------------------------------------------------|-----------------------------|
| `/traefik/backends/backend1/circuitbreaker/expression` | `NetworkErrorRatio() > 0.5` |
| `/traefik/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` |
| `/traefik/backends/backend1/servers/server1/weight` | `10` |
| `/traefik/backends/backend1/servers/server2/url` | `http://172.17.0.3:80` |
| `/traefik/backends/backend1/servers/server2/weight` | `1` |
| `/traefik/backends/backend1/servers/server2/tags` | `api,helloworld` |
2016-07-11 15:32:28 +00:00
- backend 2
| Key | Value |
|-----------------------------------------------------|------------------------|
| `/traefik/backends/backend2/maxconn/amount` | `10` |
| `/traefik/backends/backend2/maxconn/extractorfunc` | `request.host` |
| `/traefik/backends/backend2/loadbalancer/method` | `drr` |
| `/traefik/backends/backend2/servers/server1/url` | `http://172.17.0.4:80` |
| `/traefik/backends/backend2/servers/server1/weight` | `1` |
| `/traefik/backends/backend2/servers/server2/url` | `http://172.17.0.5:80` |
| `/traefik/backends/backend2/servers/server2/weight` | `2` |
| `/traefik/backends/backend2/servers/server2/tags` | `web` |
2016-07-11 15:32:28 +00:00
- frontend 1
| Key | Value |
|---------------------------------------------------|-----------------------|
| `/traefik/frontends/frontend1/backend` | `backend2` |
| `/traefik/frontends/frontend1/routes/test_1/rule` | `Host:test.localhost` |
- frontend 2
2018-05-18 15:54:03 +00:00
| Key | Value |
|----------------------------------------------------|-----------------------------------------------|
| `/traefik/frontends/frontend2/backend` | `backend1` |
| `/traefik/frontends/frontend2/passhostheader` | `true` |
| `/traefik/frontends/frontend2/priority` | `10` |
2018-07-06 14:52:04 +00:00
| `/traefik/frontends/frontend2/auth/basic/users/0` | `test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/` |
| `/traefik/frontends/frontend2/auth/basic/users/1` | `test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0` |
2018-05-18 15:54:03 +00:00
| `/traefik/frontends/frontend2/entrypoints` | `http,https` |
| `/traefik/frontends/frontend2/routes/test_2/rule` | `PathPrefix:/test` |
2016-07-11 15:32:28 +00:00
- certificate 1
2018-01-23 15:30:07 +00:00
| Key | Value |
|---------------------------------------|--------------------|
| `/traefik/tls/1/certificate/certfile` | `path/to/your.cert`|
| `/traefik/tls/1/certificate/keyfile` | `path/to/your.key` |
!!! note
2018-01-24 10:57:06 +00:00
As `/traefik/tls/1/entrypoints` is not defined, the certificate will be attached to all `defaulEntryPoints` with a TLS configuration (in the example, the entryPoint `https`)
- certificate 2
2018-01-23 15:30:07 +00:00
| Key | Value |
|---------------------------------------|-----------------------|
| `/traefik/tls/2/entrypoints` | `https,other-https` |
| `/traefik/tls/2/certificate/certfile` | `<cert file content>` |
2018-06-12 06:20:03 +00:00
| `/traefik/tls/2/certificate/keyfile` | `<key file content>` |
2017-09-11 17:10:04 +00:00
### Atomic configuration changes
2016-07-11 15:32:28 +00:00
2018-10-17 14:24:04 +00:00
Traefik can watch the backends/frontends configuration changes and generate its configuration automatically.
2016-07-11 15:32:28 +00:00
2017-09-11 17:10:04 +00:00
!!! note
2018-10-17 14:24:04 +00:00
Only backends/frontends rules are dynamic, the rest of the Traefik configuration stay static.
2016-07-11 15:32:28 +00:00
2017-09-11 17:10:04 +00:00
The [Etcd](https://github.com/coreos/etcd/issues/860) and [Consul](https://github.com/hashicorp/consul/issues/886) backends do not support updating multiple keys atomically.
2018-10-17 14:24:04 +00:00
As a result, it may be possible for Traefik to read an intermediate configuration state despite judicious use of the `--providersThrottleDuration` flag.
To solve this problem, Traefik supports a special key called `/traefik/alias`.
If set, Traefik use the value as an alternative key prefix.
2016-07-11 15:32:28 +00:00
2018-10-17 14:24:04 +00:00
Given the key structure below, Traefik will use the `http://172.17.0.2:80` as its only backend (frontend keys have been omitted for brevity).
2016-07-11 15:32:28 +00:00
| Key | Value |
|-------------------------------------------------------------------------|-----------------------------|
| `/traefik/alias` | `/traefik_configurations/1` |
| `/traefik_configurations/1/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` |
| `/traefik_configurations/1/backends/backend1/servers/server1/weight` | `10` |
2017-09-05 13:58:03 +00:00
When an atomic configuration change is required, you may write a new configuration at an alternative prefix.
2017-09-11 17:10:04 +00:00
2017-09-05 13:58:03 +00:00
Here, although the `/traefik_configurations/2/...` keys have been set, the old configuration is still active because the `/traefik/alias` key still points to `/traefik_configurations/1`:
2016-07-11 15:32:28 +00:00
| Key | Value |
|-------------------------------------------------------------------------|-----------------------------|
| `/traefik/alias` | `/traefik_configurations/1` |
| `/traefik_configurations/1/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` |
| `/traefik_configurations/1/backends/backend1/servers/server1/weight` | `10` |
| `/traefik_configurations/2/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` |
| `/traefik_configurations/2/backends/backend1/servers/server1/weight` | `5` |
2016-07-11 15:32:28 +00:00
| `/traefik_configurations/2/backends/backend1/servers/server2/url` | `http://172.17.0.3:80` |
| `/traefik_configurations/2/backends/backend1/servers/server2/weight` | `5` |
2016-07-11 15:32:28 +00:00
2017-09-05 13:58:03 +00:00
Once the `/traefik/alias` key is updated, the new `/traefik_configurations/2` configuration becomes active atomically.
2017-09-11 17:10:04 +00:00
2017-09-05 13:58:03 +00:00
Here, we have a 50% balance between the `http://172.17.0.3:80` and the `http://172.17.0.4:80` hosts while no traffic is sent to the `172.17.0.2:80` host:
2016-07-11 15:32:28 +00:00
| Key | Value |
|-------------------------------------------------------------------------|-----------------------------|
| `/traefik/alias` | `/traefik_configurations/2` |
| `/traefik_configurations/1/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` |
| `/traefik_configurations/1/backends/backend1/servers/server1/weight` | `10` |
| `/traefik_configurations/2/backends/backend1/servers/server1/url` | `http://172.17.0.3:80` |
| `/traefik_configurations/2/backends/backend1/servers/server1/weight` | `5` |
2016-07-11 15:32:28 +00:00
| `/traefik_configurations/2/backends/backend1/servers/server2/url` | `http://172.17.0.4:80` |
| `/traefik_configurations/2/backends/backend1/servers/server2/weight` | `5` |
2016-07-11 15:32:28 +00:00
2017-09-11 17:10:04 +00:00
!!! note
2018-10-17 14:24:04 +00:00
Traefik *will not watch for key changes in the `/traefik_configurations` prefix*. It will only watch for changes in the `/traefik/alias`.
2017-09-11 17:10:04 +00:00
Further, if the `/traefik/alias` key is set, all other configuration with `/traefik/backends` or `/traefik/frontends` prefix are ignored.
## Store configuration in Key-value store
2017-09-11 17:10:04 +00:00
!!! note
2018-10-17 14:24:04 +00:00
Don't forget to [setup the connection between Traefik and Key-value store](/user-guide/kv-config/#launch-traefik).
2018-10-17 14:24:04 +00:00
The static Traefik configuration in a key-value store can be automatically created and updated, using the [`storeconfig` subcommand](/basics/#commands).
```bash
2017-09-05 13:58:03 +00:00
traefik storeconfig [flags] ...
```
This command is here only to automate the [process which upload the configuration into the Key-value store](/user-guide/kv-config/#upload-the-configuration-in-the-key-value-store).
2018-10-17 14:24:04 +00:00
Traefik will not start but the [static configuration](/basics/#static-traefik-configuration) will be uploaded into the Key-value store.
2017-11-21 09:24:03 +00:00
If you configured ACME (Let's Encrypt), your registration account and your certificates will also be uploaded.
If you configured a file provider `[file]`, all your dynamic configuration (backends, frontends...) will be uploaded to the Key-value store.
2017-11-21 09:24:03 +00:00
2017-09-11 17:10:04 +00:00
To upload your ACME certificates to the KV store, get your Traefik TOML file and add the new `storage` option in the `acme` section:
2017-04-30 18:17:57 +00:00
```toml
[acme]
email = "test@traefik.io"
storage = "traefik/acme/account" # the key where to store your certificates in the KV store
storageFile = "acme.json" # your old certificates store
```
Call `traefik storeconfig` to upload your config in the KV store.
Then remove the line `storageFile = "acme.json"` from your TOML config file.
2017-04-30 18:17:57 +00:00
That's it!
![GIF Magica](https://i.giphy.com/ujUdrdpX7Ok5W.gif)