From 7c2ba62b560e3312f6b6e43bdf45fa08a674f6bd Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic Date: Sat, 26 Aug 2017 12:12:44 +0200 Subject: [PATCH] doc: structural review - user-guide review. - add DataDog and StatD configuration. - sync sample.toml and doc. - split entry points doc. - Deprecated. --- docs/backends/marathon.md | 166 ----------- docs/backends/rancher.md | 117 -------- docs/basics.md | 51 ++-- docs/{ => configuration}/backends/boltdb.md | 7 +- docs/{ => configuration}/backends/consul.md | 23 +- docs/{ => configuration}/backends/docker.md | 74 ++++- docs/{ => configuration}/backends/dynamodb.md | 19 +- docs/{ => configuration}/backends/ecs.md | 33 ++- docs/{ => configuration}/backends/etcd.md | 5 +- docs/{ => configuration}/backends/eureka.md | 6 +- docs/{ => configuration}/backends/file.md | 14 +- .../backends/kubernetes.md | 6 +- docs/configuration/backends/marathon.md | 167 ++++++++++++ docs/{ => configuration}/backends/mesos.md | 6 +- docs/configuration/backends/rancher.md | 122 +++++++++ .../api.md => configuration/backends/web.md} | 95 ++++--- .../{ => configuration}/backends/zookeeper.md | 5 +- docs/configuration/{toml.md => commons.md} | 257 ++++++++++-------- docs/img/traefik-health.png | Bin 102955 -> 53776 bytes docs/index.md | 2 +- docs/user-guide/cluster.md | 3 +- docs/user-guide/examples.md | 1 - ...ng-started-with-docker-and-lets-encrypt.md | 66 +++-- docs/user-guide/kubernetes.md | 79 ++---- docs/user-guide/kv-config.md | 3 +- docs/user-guide/marathon.md | 1 - docs/user-guide/swarm-mode.md | 37 +-- mkdocs.yml | 47 ++-- provider/consul/consul_catalog.go | 2 +- provider/kubernetes/client.go | 2 +- traefik.sample.toml | 125 +++++++-- types/types.go | 2 +- 32 files changed, 848 insertions(+), 695 deletions(-) delete mode 100644 docs/backends/marathon.md delete mode 100644 docs/backends/rancher.md rename docs/{ => configuration}/backends/boltdb.md (90%) rename docs/{ => configuration}/backends/consul.md (91%) rename docs/{ => configuration}/backends/docker.md (91%) rename docs/{ => configuration}/backends/dynamodb.md (65%) rename docs/{ => configuration}/backends/ecs.md (55%) rename docs/{ => configuration}/backends/etcd.md (97%) rename docs/{ => configuration}/backends/eureka.md (95%) rename docs/{ => configuration}/backends/file.md (94%) rename docs/{ => configuration}/backends/kubernetes.md (98%) create mode 100644 docs/configuration/backends/marathon.md rename docs/{ => configuration}/backends/mesos.md (97%) create mode 100644 docs/configuration/backends/rancher.md rename docs/{backends/api.md => configuration/backends/web.md} (80%) rename docs/{ => configuration}/backends/zookeeper.md (95%) rename docs/configuration/{toml.md => commons.md} (73%) diff --git a/docs/backends/marathon.md b/docs/backends/marathon.md deleted file mode 100644 index 9475b7d8b..000000000 --- a/docs/backends/marathon.md +++ /dev/null @@ -1,166 +0,0 @@ -# Marathon backend - -Træfik can be configured to use Marathon as a backend configuration: - - -```toml -################################################################ -# Mesos/Marathon configuration backend -################################################################ - -# Enable Marathon configuration backend -# -# Optional -# -[marathon] - -# Marathon server endpoint. -# You can also specify multiple endpoint for Marathon: -# endpoint := "http://10.241.1.71:8080,10.241.1.72:8080,10.241.1.73:8080" -# -# Required -# -endpoint = "http://127.0.0.1:8080" - -# Enable watch Marathon changes -# -# Optional -# -watch = true - -# Default domain used. -# -# Required -# -domain = "marathon.localhost" - -# Override default configuration template. For advanced users :) -# -# Optional -# -# filename = "marathon.tmpl" - -# Expose Marathon apps by default in traefik -# -# Optional -# Default: true -# -# exposedByDefault = true - -# Convert Marathon groups to subdomains -# Default behavior: /foo/bar/myapp => foo-bar-myapp.{defaultDomain} -# with groupsAsSubDomains enabled: /foo/bar/myapp => myapp.bar.foo.{defaultDomain} -# -# Optional -# Default: false -# -# groupsAsSubDomains = true - -# Enable compatibility with marathon-lb labels -# -# Optional -# Default: false -# -# marathonLBCompatibility = true - -# Enable Marathon basic authentication -# -# Optional -# -# [marathon.basic] -# httpBasicAuthUser = "foo" -# httpBasicPassword = "bar" - -# TLS client configuration. https://golang.org/pkg/crypto/tls/#Config -# -# Optional -# -# [marathon.TLS] -# CA = "/etc/ssl/ca.crt" -# Cert = "/etc/ssl/marathon.cert" -# Key = "/etc/ssl/marathon.key" -# InsecureSkipVerify = true - -# DCOSToken for DCOS environment, This will override the Authorization header -# -# Optional -# -# dcosToken = "xxxxxx" - -# Override DialerTimeout -# Amount of time to allow the Marathon provider to wait to open a TCP connection -# to a Marathon master. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw -# values (digits). If no units are provided, the value is parsed assuming -# seconds. -# -# Optional -# Default: "60s" -# dialerTimeout = "60s" - -# Set the TCP Keep Alive interval for the Marathon HTTP Client. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw -# values (digits). If no units are provided, the value is parsed assuming -# seconds. -# -# Optional -# Default: "10s" -# -# keepAlive = "10s" - -# By default, a task's IP address (as returned by the Marathon API) is used as -# backend server if an IP-per-task configuration can be found; otherwise, the -# name of the host running the task is used. -# The latter behavior can be enforced by enabling this switch. -# -# Optional -# Default: false -# -# forceTaskHostname = false - -# Applications may define readiness checks which are probed by Marathon during -# deployments periodically and the results exposed via the API. Enabling the -# following parameter causes Traefik to filter out tasks whose readiness checks -# have not succeeded. -# Note that the checks are only valid at deployment times. See the Marathon -# guide for details. -# -# Optional -# Default: false -# -# respectReadinessChecks = false -``` - -Labels can be used on containers to override default behaviour: - -- `traefik.backend=foo`: assign the application to `foo` backend -- `traefik.backend.maxconn.amount=10`: set a maximum number of connections to the backend. Must be used in conjunction with the below label to take effect. -- `traefik.backend.maxconn.extractorfunc=client.ip`: set the function to be used against the request to determine what to limit maximum connections to the backend by. Must be used in conjunction with the above label to take effect. -- `traefik.backend.loadbalancer.method=drr`: override the default `wrr` load balancer algorithm -- `traefik.backend.loadbalancer.sticky=true`: enable backend sticky sessions -- `traefik.backend.circuitbreaker.expression=NetworkErrorRatio() > 0.5`: create a [circuit breaker](/basics/#backends) to be used against the backend -- `traefik.backend.healthcheck.path=/health`: set the Traefik health check path [default: no health checks] -- `traefik.backend.healthcheck.interval=5s`: sets a custom health check interval in Go-parseable (`time.ParseDuration`) format [default: 30s] -- `traefik.portIndex=1`: register port by index in the application's ports array. Useful when the application exposes multiple ports. -- `traefik.port=80`: register the explicit application port value. Cannot be used alongside `traefik.portIndex`. -- `traefik.protocol=https`: override the default `http` protocol -- `traefik.weight=10`: assign this weight to the application -- `traefik.enable=false`: disable this application in Træfik -- `traefik.frontend.rule=Host:test.traefik.io`: override the default frontend rule (Default: `Host:{containerName}.{domain}`). -- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend. -- `traefik.frontend.priority=10`: override default frontend priority -- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. -- `traefik.frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0`: Sets basic authentication for that frontend with the usernames and passwords test:test and test2:test2, respectively - -If several ports need to be exposed from a container, the services labels can be used - -- `traefik..port=443`: create a service binding with frontend/backend using this port. Overrides `traefik.port`. -- `traefik..portIndex=1`: create a service binding with frontend/backend using this port index. Overrides `traefik.portIndex`. -- `traefik..protocol=https`: assign `https` protocol. Overrides `traefik.protocol`. -- `traefik..weight=10`: assign this service weight. Overrides `traefik.weight`. -- `traefik..frontend.backend=fooBackend`: assign this service frontend to `foobackend`. Default is to assign to the service backend. -- `traefik..frontend.entryPoints=http`: assign this service entrypoints. Overrides `traefik.frontend.entrypoints`. -- `traefik..frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0` Sets a Basic Auth for that frontend with the users test:test and test2:test2. -- `traefik..frontend.passHostHeader=true`: Forward client `Host` header to the backend. Overrides `traefik.frontend.passHostHeader`. -- `traefik..frontend.priority=10`: assign the service frontend priority. Overrides `traefik.frontend.priority`. -- `traefik..frontend.rule=Path:/foo`: assign the service frontend rule. Overrides `traefik.frontend.rule`. \ No newline at end of file diff --git a/docs/backends/rancher.md b/docs/backends/rancher.md deleted file mode 100644 index 8f34eca51..000000000 --- a/docs/backends/rancher.md +++ /dev/null @@ -1,117 +0,0 @@ -# Rancher backend - -Træfik can be configured to use Rancher as a backend configuration: - - -```toml -################################################################ -# Rancher configuration backend -################################################################ - -# Enable Rancher configuration backend -# -# Optional -# -[rancher] - -# Default domain used. -# Can be overridden by setting the "traefik.domain" label on an service. -# -# Required -# -domain = "rancher.localhost" - -# Enable watch Rancher changes -# -# Optional -# Default: true -# -Watch = true - -# Polling interval (in seconds) -# -# Optional -# -RefreshSeconds = 15 - -# Expose Rancher services by default in traefik -# -# Optional -# Default: true -# -ExposedByDefault = false - -# Filter services with unhealthy states and inactive states -# -# Optional -# Default: false -# -EnableServiceHealthFilter = true -``` - -```toml -# Enable Rancher metadata service configuration backend instead of the API -# configuration backend -# -# Optional -# Default: false -# -[rancher.metadata] - -# Poll the Rancher metadata service for changes every `rancher.RefreshSeconds` -# NOTE: this is less accurate than the default long polling technique which -# will provide near instantaneous updates to Traefik -# -# Optional -# Default: false -# -IntervalPoll = true - -# Prefix used for accessing the Rancher metadata service -# -# Optional -# Default: "/latest" -# -Prefix = "/2016-07-29" -``` - -```toml -# Enable Rancher API configuration backend -# -# Optional -# Default: true -# -[rancher.api] - -# Endpoint to use when connecting to the Rancher API -# -# Required -Endpoint = "http://rancherserver.example.com/v1" - -# AccessKey to use when connecting to the Rancher API -# -# Required -AccessKey = "XXXXXXXXXXXXXXXXXXXX" - -# SecretKey to use when connecting to the Rancher API -# -# Required -SecretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -``` - -If Traefik needs access to the Rancher API, you need to set the `endpoint`, `accesskey` and `secretkey` parameters. - -To enable traefik to fetch information about the Environment it's deployed in only, you need to create an `Environment API Key`. -This can be found within the API Key advanced options. - -Labels can be used on task containers to override default behaviour: - -- `traefik.protocol=https`: override the default `http` protocol -- `traefik.weight=10`: assign this weight to the container -- `traefik.enable=false`: disable this container in Træfik -- `traefik.frontend.rule=Host:test.traefik.io`: override the default frontend rule (Default: `Host:{containerName}.{domain}`). -- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend. -- `traefik.frontend.priority=10`: override default frontend priority -- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. -- `traefik.frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0`: Sets basic authentication for that frontend with the usernames and passwords test:test and test2:test2, respectively - diff --git a/docs/basics.md b/docs/basics.md index 0094065f9..5b0e584f6 100644 --- a/docs/basics.md +++ b/docs/basics.md @@ -1,5 +1,6 @@ +# Basics -# Concepts +## Concepts Let's take our example from the [overview](https://docs.traefik.io/#overview) again: @@ -24,7 +25,7 @@ Routes are created using requests fields (`Host`, `Path`, `Headers`...) and can - The [frontend](#frontends) will then send the request to a [backend](#backends). A backend can be composed by one or more [servers](#servers), and by a load-balancing strategy. - Finally, the [server](#servers) will forward the request to the corresponding microservice in the private network. -## Entrypoints +### Entrypoints Entrypoints are the network entry points into Træfik. They can be defined using: @@ -71,13 +72,13 @@ And here is another example with client certificate authentication: - One or several files containing Certificate Authorities in PEM format are added. - It is possible to have multiple CA:s in the same file or keep them in separate files. -## Frontends +### Frontends A frontend consists of a set of rules that determine how incoming requests are forwarded from an entrypoint to a backend. Rules may be classified in one of two groups: Modifiers and matchers. -### Modifiers +#### Modifiers Modifier rules only modify the request. They do not have any impact on routing decisions being made. @@ -86,7 +87,7 @@ Following is the list of existing modifier rules: - `AddPrefix: /products`: Add path prefix to the existing request path prior to forwarding the request to the backend. - `ReplacePath: /serverless-path`: Replaces the path and adds the old path to the `X-Replaced-Path` header. Useful for mapping to AWS Lambda or Google Cloud Functions. -### Matchers +#### Matchers Matcher rules determine if a particular request should be forwarded to a backend. @@ -115,7 +116,7 @@ In order to use regular expressions with Host and Path matchers, you must declar (Note that the variable has no special meaning; however, it is required by the gorilla/mux dependency which embeds the regular expression and defines the syntax.) -#### Path Matcher Usage Guidelines +##### Path Matcher Usage Guidelines This section explains when to use the various path matchers. @@ -128,7 +129,7 @@ If your backend is serving assets (e.g., images or Javascript files), chances ar Instead of distinguishing your backends by path only, you can add a Host matcher to the mix. That way, namespacing of your backends happens on the basis of hosts in addition to paths. -### Examples +#### Examples Here is an example of frontends definition: @@ -157,7 +158,7 @@ Here is an example of frontends definition: - `frontend2` will forward the traffic to the `backend1` if the rule `Host:localhost,{subdomain:[a-z]+}.localhost` is matched (forwarding client `Host` header to the backend) - `frontend3` will forward the traffic to the `backend2` if the rules `Host:test3.localhost` **AND** `Path:/test` are matched -### Combining multiple rules +#### Combining multiple rules As seen in the previous example, you can combine multiple rules. In TOML file, you can use multiple routes: @@ -193,7 +194,7 @@ Finally, you can create a rule to bind multiple domains or Path to a frontend, u rule = "Path:/test1,/test2" ``` -### Rules Order +#### Rules Order When combining `Modifier` rules with `Matcher` rules, it is important to remember that `Modifier` rules **ALWAYS** apply after the `Matcher` rules. The following rules are both `Matchers` and `Modifiers`, so the `Matcher` portion of the rule will apply first, and the `Modifier` will apply later. @@ -212,7 +213,7 @@ The following rules are both `Matchers` and `Modifiers`, so the `Matcher` portio 5. `AddPrefix` 6. `ReplacePath` -### Priorities +#### Priorities By default, routes will be sorted (in descending order) using rules length (to avoid path overlap): `PathPrefix:/12345` will be matched before `PathPrefix:/1234` that will be matched before `PathPrefix:/1`. @@ -237,7 +238,7 @@ You can customize priority by frontend: Here, `frontend1` will be matched before `frontend2` (`10 > 5`). -### Custom headers +#### Custom headers Custom headers can be configured through the frontends, to add headers to either requests or responses that match the frontend's rules. This allows for setting headers such as `X-Script-Name` to be added to the request, or custom headers to be added to the response: @@ -255,7 +256,7 @@ Custom headers can be configured through the frontends, to add headers to either In this example, all matches to the path `/cheese` will have the `X-Script-Name` header added to the proxied request, and the `X-Custom-Response-Header` added to the response. -### Security headers +#### Security headers Security related headers (HSTS headers, SSL redirection, Browser XSS filter, etc) can be added and configured per frontend in a similar manner to the custom headers above. This functionality allows for some easy security features to quickly be set. An example of some of the security headers: @@ -277,7 +278,7 @@ Security related headers (HSTS headers, SSL redirection, Browser XSS filter, etc In this example, traffic routed through the first frontend will have the `X-Frame-Options` header set to `DENY`, and the second will only allow HTTPS request through, otherwise will return a 301 HTTPS redirect. -## Backends +### Backends A backend is responsible to load-balance the traffic coming from one or more frontends to a set of http servers. Various methods of load-balancing are supported: @@ -364,7 +365,7 @@ To use a different port for the healthcheck: port = 8080 ``` -## Servers +### Servers Servers are simply defined using a `URL`. You can also apply a custom `weight` to each server (this will be used by load-balancing). @@ -397,7 +398,7 @@ Here is an example of backends and servers definition: - `backend2` will forward the traffic to two servers: `http://172.17.0.4:80"` with weight `1` and `http://172.17.0.5:80` with weight `2` using `drr` load-balancing strategy. - a circuit breaker is added on `backend1` using the expression `NetworkErrorRatio() > 0.5`: watch error ratio over 10 second sliding window -## Custom Error pages +### Custom Error pages Custom error pages can be returned, in lieu of the default, according to frontend-configured ranges of HTTP Status codes. In the example below, if a 503 status is returned from the frontend "website", the custom error page at http://2.3.4.5/503.html is returned with the actual status code set in the HTTP header. @@ -430,7 +431,7 @@ Instead, the query parameter can also be set to some generic error page like so: Now the 500s.html error page is returned for the configured code range. The configured status code ranges are inclusive; that is, in the above example, the 500s.html page will be returned for status codes 500 through, and including, 599. -# Configuration +## Configuration Træfik's configuration has two parts: @@ -438,7 +439,7 @@ Træfik's configuration has two parts: - The [dynamic Træfik configuration](/basics#dynamic-trfk-configuration) which can be hot-reloaded (no need to restart the process). -## Static Træfik configuration +### Static Træfik configuration The static configuration is the global configuration which is setting up connections to configuration backends and entrypoints. @@ -454,7 +455,7 @@ It means that arguments override configuration file, and key-value store overrid Note that the provider-enabling argument parameters (e.g., `--docker`) set all default values for the specific provider. It must not be used if a configuration source with less precedence wants to set a non-default provider value. -### Configuration file +#### Configuration file By default, Træfik will try to find a `traefik.toml` in the following places: @@ -470,7 +471,7 @@ $ traefik --configFile=foo/bar/myconfigfile.toml Please refer to the [global configuration](/toml/#global-configuration) section to get documentation on it. -### Arguments +#### Arguments Each argument (and command) is described in the help section: @@ -480,7 +481,7 @@ $ traefik --help Note that all default values will be displayed as well. -### Key-value stores +#### Key-value stores Træfik supports several Key-value stores: @@ -491,7 +492,7 @@ Træfik supports several Key-value stores: Please refer to the [User Guide Key-value store configuration](/user-guide/kv-config/) section to get documentation on it. -## Dynamic Træfik configuration +### Dynamic Træfik configuration The dynamic configuration concerns : @@ -506,7 +507,7 @@ Routes to services will be created and updated instantly at any changes. Please refer to the [configuration backends](/toml/#configuration-backends) section to get documentation on it. -# Commands +## Commands Usage: `traefik [command] [--flag=flag_argument]` @@ -530,7 +531,7 @@ Note that each command is described at the beginning of the help section: $ traefik --help ``` -## Command: bug +### Command: bug Here is the easiest way to submit a pre-filled issue on [Træfik GitHub](https://github.com/containous/traefik). @@ -540,7 +541,7 @@ $ traefik bug See https://www.youtube.com/watch?v=Lyz62L8m93I. -## Command: healthcheck +### Command: healthcheck This command allows to check the health of Traefik. Its exit status is `0` if Traefik is healthy and `1` if it is unhealthy. This can be used with Docker [HEALTHCHECK](https://docs.docker.com/engine/reference/builder/#healthcheck) instruction or any other health check orchestration mechanism. @@ -552,7 +553,7 @@ $ traefik healthcheck OK: http://:8082/ping ``` -# Log Rotation +## Log Rotation Traefik will close and reopen its log files, assuming they're configured, on receipt of a USR1 signal. This allows the logs to be rotated and processed by an external program, such as `logrotate`. diff --git a/docs/backends/boltdb.md b/docs/configuration/backends/boltdb.md similarity index 90% rename from docs/backends/boltdb.md rename to docs/configuration/backends/boltdb.md index 1a872b4d3..ce44ea67e 100644 --- a/docs/backends/boltdb.md +++ b/docs/configuration/backends/boltdb.md @@ -1,4 +1,4 @@ -# BoltDB backend +# BoltDB Backend Træfik can be configured to use BoltDB as a backend configuration: @@ -8,9 +8,6 @@ Træfik can be configured to use BoltDB as a backend configuration: ################################################################ # Enable BoltDB configuration backend -# -# Optional -# [boltdb] # BoltDB file @@ -35,5 +32,5 @@ prefix = "/traefik" # # Optional # -# filename = "boltdb.tmpl" +filename = "boltdb.tmpl" ``` \ No newline at end of file diff --git a/docs/backends/consul.md b/docs/configuration/backends/consul.md similarity index 91% rename from docs/backends/consul.md rename to docs/configuration/backends/consul.md index 8aac5cea4..c92fd59e4 100644 --- a/docs/backends/consul.md +++ b/docs/configuration/backends/consul.md @@ -1,4 +1,5 @@ -# Consul backend +# Consul Backend + ## Consul Key-Value backend Træfik can be configured to use Consul as a backend configuration: @@ -9,9 +10,6 @@ Træfik can be configured to use Consul as a backend configuration: ################################################################ # Enable Consul KV configuration backend -# -# Optional -# [consul] # Consul server endpoint @@ -61,9 +59,6 @@ Træfik can be configured to use service discovery catalog of Consul as a backen ################################################################ # Enable Consul Catalog configuration backend -# -# Optional -# [consulCatalog] # Consul server endpoint @@ -81,7 +76,6 @@ domain = "consul.localhost" # Expose Consul catalog services by default in traefik # # Optional -# Default: true # exposedByDefault = false @@ -92,17 +86,18 @@ exposedByDefault = false prefix = "traefik" # Default frontEnd Rule for Consul services -# The format is a Go Template with ".ServiceName", ".Domain" and ".Attributes" available -# "getTag(name, tags, defaultValue)", "hasTag(name, tags)" and "getAttribute(name, tags, defaultValue)" functions are available -# "getAttribute(...)" function uses prefixed tag names based on "prefix" value +# +# The format is a Go Template with: +# - ".ServiceName", ".Domain" and ".Attributes" available +# - "getTag(name, tags, defaultValue)", "hasTag(name, tags)" and "getAttribute(name, tags, defaultValue)" functions are available +# - "getAttribute(...)" function uses prefixed tag names based on "prefix" value # # Optional # -frontEndRule = "Host:{{.ServiceName}}.{{Domain}}" +#frontEndRule = "Host:{{.ServiceName}}.{{Domain}}" ``` -This backend will create routes matching on hostname based on the service name -used in consul. +This backend will create routes matching on hostname based on the service name used in consul. Additional settings can be defined using Consul Catalog tags: diff --git a/docs/backends/docker.md b/docs/configuration/backends/docker.md similarity index 91% rename from docs/backends/docker.md rename to docs/configuration/backends/docker.md index cfc5d541d..e29b451ec 100644 --- a/docs/backends/docker.md +++ b/docs/configuration/backends/docker.md @@ -1,6 +1,8 @@ -# Docker backend +# Docker Backend -Træfik can be configured to use Docker as a backend configuration: +Træfik can be configured to use Docker as a backend configuration. + +## Docker ```toml ################################################################ @@ -8,9 +10,6 @@ Træfik can be configured to use Docker as a backend configuration: ################################################################ # Enable Docker configuration backend -# -# Optional -# [docker] # Docker server endpoint. Can be a tcp or a unix socket endpoint. @@ -47,12 +46,12 @@ watch = true exposedbydefault = true # Use the IP address from the binded port instead of the inner network one. For specific use-case :) - # # Optional # Default: false # usebindportip = true + # Use Swarm Mode services as data provider # # Optional @@ -60,9 +59,10 @@ usebindportip = true # swarmmode = false - # Enable docker TLS connection # +# Optional +# # [docker.tls] # ca = "/etc/ssl/ca.crt" # cert = "/etc/ssl/docker.crt" @@ -70,7 +70,65 @@ swarmmode = false # insecureskipverify = true ``` -### Labels can be used on containers to override default behaviour +## Docker Swarm Mode + +```toml +################################################################ +# Docker Swarmmode configuration backend +################################################################ + +# Enable Docker configuration backend +[docker] + +# Docker server endpoint. Can be a tcp or a unix socket endpoint. +# +# Required +# Default: "unix:///var/run/docker.sock" +# +endpoint = "tcp://127.0.0.1:2375" + +# Default domain used. +# Can be overridden by setting the "traefik.domain" label on a services. +# +# Optional +# Default: "" +# +domain = "docker.localhost" + +# Enable watch docker changes +# +# Optional +# +watch = true + +# Use Docker Swarm Mode as data provider +swarmmode = true + +# Override default configuration template. For advanced users :) +# +# Optional +# +# filename = "docker.tmpl" + +# Expose services by default in traefik +# +# Optional +# Default: true +# +exposedbydefault = false + +# Enable docker TLS connection +# +# Optional +# +# [swarm.tls] +# ca = "/etc/ssl/ca.crt" +# cert = "/etc/ssl/docker.crt" +# key = "/etc/ssl/docker.key" +# insecureskipverify = true +``` + +## Labels can be used on containers to override default behaviour | Label | Description | |---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| diff --git a/docs/backends/dynamodb.md b/docs/configuration/backends/dynamodb.md similarity index 65% rename from docs/backends/dynamodb.md rename to docs/configuration/backends/dynamodb.md index 17d9a9d5a..65065a33f 100644 --- a/docs/backends/dynamodb.md +++ b/docs/configuration/backends/dynamodb.md @@ -1,17 +1,13 @@ -# DynamoDB backend +# DynamoDB Backend Træfik can be configured to use Amazon DynamoDB as a backend configuration: - ```toml ################################################################ # DynamoDB configuration backend ################################################################ # Enable DynamoDB configuration backend -# -# Optional -# [dynamodb] # DyanmoDB Table Name @@ -55,14 +51,13 @@ SecretAccessKey = "123" # Optional # Endpoint = "http://localhost:8080" - ``` Items in the `dynamodb` table must have three attributes: -- `id` : string - - The id is the primary key. -- `name` : string - - The name is used as the name of the frontend or backend. -- `frontend` or `backend` : map - - This attribute's structure matches exactly the structure of a Frontend or Backend type in traefik. See `types/types.go` for details. The presence or absence of this attribute determines its type. So an item should never have both a `frontend` and a `backend` attribute. \ No newline at end of file +- `id` (string): The id is the primary key. +- `name`(string): The name is used as the name of the frontend or backend. +- `frontend` or `backend` (map): This attribute's structure matches exactly the structure of a Frontend or Backend type in traefik. + See `types/types.go` for details. + The presence or absence of this attribute determines its type. + So an item should never have both a `frontend` and a `backend` attribute. diff --git a/docs/backends/ecs.md b/docs/configuration/backends/ecs.md similarity index 55% rename from docs/backends/ecs.md rename to docs/configuration/backends/ecs.md index 0501ce0e8..72c7768bc 100644 --- a/docs/backends/ecs.md +++ b/docs/configuration/backends/ecs.md @@ -1,22 +1,18 @@ -# ECS backend +# ECS Backend Træfik can be configured to use Amazon ECS as a backend configuration: - ```toml ################################################################ # ECS configuration backend ################################################################ # Enable ECS configuration backend -# -# Optional -# [ecs] # ECS Cluster Name # -# Deprecated - Please use Clusters +# DEPRECATED - Please use Clusters # Cluster = "default" @@ -73,19 +69,26 @@ AccessKeyID = "abc" # SecretAccessKey = "123" +# Override default configuration template. For advanced users :) +# +# Optional +# +# filename = "ecs.tmpl" ``` Labels can be used on task containers to override default behaviour: -- `traefik.protocol=https`: override the default `http` protocol -- `traefik.weight=10`: assign this weight to the container -- `traefik.enable=false`: disable this container in Træfik -- `traefik.backend.loadbalancer.method=drr`: override the default `wrr` load balancer algorithm -- `traefik.backend.loadbalancer.sticky=true`: enable backend sticky sessions -- `traefik.frontend.rule=Host:test.traefik.io`: override the default frontend rule (Default: `Host:{containerName}.{domain}`). -- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend. -- `traefik.frontend.priority=10`: override default frontend priority -- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. +| Label | Description | +|----------------------------------------------|------------------------------------------------------------------------------------------| +| `traefik.protocol=https` | override the default `http` protocol | +| `traefik.weight=10` | assign this weight to the container | +| `traefik.enable=false` | disable this container in Træfik | +| `traefik.backend.loadbalancer.method=drr` | override the default `wrr` load balancer algorithm | +| `traefik.backend.loadbalancer.sticky=true` | enable backend sticky sessions | +| `traefik.frontend.rule=Host:test.traefik.io` | override the default frontend rule (Default: `Host:{containerName}.{domain}`). | +| `traefik.frontend.passHostHeader=true` | forward client `Host` header to the backend. | +| `traefik.frontend.priority=10` | override default frontend priority | +| `traefik.frontend.entryPoints=http,https` | assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. | If `AccessKeyID`/`SecretAccessKey` is not given credentials will be resolved in the following order: diff --git a/docs/backends/etcd.md b/docs/configuration/backends/etcd.md similarity index 97% rename from docs/backends/etcd.md rename to docs/configuration/backends/etcd.md index e621739e4..568bcfb94 100644 --- a/docs/backends/etcd.md +++ b/docs/configuration/backends/etcd.md @@ -1,4 +1,4 @@ -# Etcd backend +# Etcd Backend Træfik can be configured to use Etcd as a backend configuration: @@ -8,9 +8,6 @@ Træfik can be configured to use Etcd as a backend configuration: ################################################################ # Enable Etcd configuration backend -# -# Optional -# [etcd] # Etcd server endpoint diff --git a/docs/backends/eureka.md b/docs/configuration/backends/eureka.md similarity index 95% rename from docs/backends/eureka.md rename to docs/configuration/backends/eureka.md index 25e5053fc..2cf2c9d33 100644 --- a/docs/backends/eureka.md +++ b/docs/configuration/backends/eureka.md @@ -1,17 +1,13 @@ -# Eureka backend +# Eureka Backend Træfik can be configured to use Eureka as a backend configuration: - ```toml ################################################################ # Eureka configuration backend ################################################################ # Enable Eureka configuration backend -# -# Optional -# [eureka] # Eureka server endpoint. diff --git a/docs/backends/file.md b/docs/configuration/backends/file.md similarity index 94% rename from docs/backends/file.md rename to docs/configuration/backends/file.md index 06ad47dda..3ba267922 100644 --- a/docs/backends/file.md +++ b/docs/configuration/backends/file.md @@ -1,8 +1,10 @@ -# File backends +# File Backends Like any other reverse proxy, Træfik can be configured with a file. You have three choices: -- simply add your configuration at the end of the global configuration file `traefik.toml`: +## Simple + +Add your configuration at the end of the global configuration file `traefik.toml`: ```toml # traefik.toml @@ -74,7 +76,9 @@ defaultEntryPoints = ["http", "https"] rule = "Path:/test" ``` -- or put your rules in a separate file, for example `rules.toml`: +## Rules in a Separate File + +Put your rules in a separate file, for example `rules.toml`: ```toml # traefik.toml @@ -141,7 +145,9 @@ filename = "rules.toml" rule = "Path:/test" ``` -- or you could have multiple .toml files in a directory: +## Multiple .toml Files + +You could have multiple `.toml` files in a directory: ```toml [file] diff --git a/docs/backends/kubernetes.md b/docs/configuration/backends/kubernetes.md similarity index 98% rename from docs/backends/kubernetes.md rename to docs/configuration/backends/kubernetes.md index 23392a242..822d14f4a 100644 --- a/docs/backends/kubernetes.md +++ b/docs/configuration/backends/kubernetes.md @@ -1,5 +1,4 @@ -# Kubernetes Ingress backend - +# Kubernetes Ingress Backend Træfik can be configured to use Kubernetes Ingress as a backend configuration: @@ -8,9 +7,6 @@ Træfik can be configured to use Kubernetes Ingress as a backend configuration: # Kubernetes Ingress configuration backend ################################################################ # Enable Kubernetes Ingress configuration backend -# -# Optional -# [kubernetes] # Kubernetes server endpoint diff --git a/docs/configuration/backends/marathon.md b/docs/configuration/backends/marathon.md new file mode 100644 index 000000000..3f0599f99 --- /dev/null +++ b/docs/configuration/backends/marathon.md @@ -0,0 +1,167 @@ +# Marathon Backend + +Træfik can be configured to use Marathon as a backend configuration: + +```toml +################################################################ +# Mesos/Marathon configuration backend +################################################################ + +# Enable Marathon configuration backend +[marathon] + +# Marathon server endpoint. +# You can also specify multiple endpoint for Marathon: +# endpoint := "http://10.241.1.71:8080,10.241.1.72:8080,10.241.1.73:8080" +# +# Required +# +endpoint = "http://127.0.0.1:8080" + +# Enable watch Marathon changes +# +# Optional +# +watch = true + +# Default domain used. +# Can be overridden by setting the "traefik.domain" label on an application. +# +# Required +# +domain = "marathon.localhost" + +# Override default configuration template. For advanced users :) +# +# Optional +# +# filename = "marathon.tmpl" + +# Expose Marathon apps by default in traefik +# +# Optional +# Default: true +# +# exposedByDefault = true + +# Convert Marathon groups to subdomains +# Default behavior: /foo/bar/myapp => foo-bar-myapp.{defaultDomain} +# with groupsAsSubDomains enabled: /foo/bar/myapp => myapp.bar.foo.{defaultDomain} +# +# Optional +# Default: false +# +# groupsAsSubDomains = true + +# Enable compatibility with marathon-lb labels +# +# Optional +# Default: false +# +# marathonLBCompatibility = true + +# Enable Marathon basic authentication +# +# Optional +# +# [marathon.basic] +# httpBasicAuthUser = "foo" +# httpBasicPassword = "bar" + +# TLS client configuration. https://golang.org/pkg/crypto/tls/#Config +# +# Optional +# +# [marathon.TLS] +# CA = "/etc/ssl/ca.crt" +# Cert = "/etc/ssl/marathon.cert" +# Key = "/etc/ssl/marathon.key" +# InsecureSkipVerify = true + +# DCOSToken for DCOS environment, This will override the Authorization header +# +# Optional +# +# dcosToken = "xxxxxx" + +# Override DialerTimeout +# Amount of time to allow the Marathon provider to wait to open a TCP connection +# to a Marathon master. +# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw +# values (digits). If no units are provided, the value is parsed assuming +# seconds. +# +# Optional +# Default: "60s" +# dialerTimeout = "60s" + +# Set the TCP Keep Alive interval for the Marathon HTTP Client. +# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw +# values (digits). If no units are provided, the value is parsed assuming +# seconds. +# +# Optional +# Default: "10s" +# +# keepAlive = "10s" + +# By default, a task's IP address (as returned by the Marathon API) is used as +# backend server if an IP-per-task configuration can be found; otherwise, the +# name of the host running the task is used. +# The latter behavior can be enforced by enabling this switch. +# +# Optional +# Default: false +# +# forceTaskHostname = false + +# Applications may define readiness checks which are probed by Marathon during +# deployments periodically and the results exposed via the API. Enabling the +# following parameter causes Traefik to filter out tasks whose readiness checks +# have not succeeded. +# Note that the checks are only valid at deployment times. See the Marathon +# guide for details. +# +# Optional +# Default: false +# +# respectReadinessChecks = false +``` + +Labels can be used on containers to override default behaviour: + +| Label | Description | +|----------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `traefik.backend=foo` | assign the application to `foo` backend | +| `traefik.backend.maxconn.amount=10` | set a maximum number of connections to the backend. Must be used in conjunction with the below label to take effect. | +| `traefik.backend.maxconn.extractorfunc=client.ip` | set the function to be used against the request to determine what to limit maximum connections to the backend by. Must be used in conjunction with the above label to take effect. | +| `traefik.backend.loadbalancer.method=drr` | override the default `wrr` load balancer algorithm | +| `traefik.backend.loadbalancer.sticky=true` | enable backend sticky sessions | +| `traefik.backend.circuitbreaker.expression=NetworkErrorRatio() > 0.5` | create a [circuit breaker](/basics/#backends) to be used against the backend | +| `traefik.backend.healthcheck.path=/health` | set the Traefik health check path [default: no health checks] | +| `traefik.backend.healthcheck.interval=5s` | sets a custom health check interval in Go-parseable (`time.ParseDuration`) format [default: 30s] | +| `traefik.portIndex=1` | register port by index in the application's ports array. Useful when the application exposes multiple ports. | +| `traefik.port=80` | register the explicit application port value. Cannot be used alongside `traefik.portIndex`. | +| `traefik.protocol=https` | override the default `http` protocol | +| `traefik.weight=10` | assign this weight to the application | +| `traefik.enable=false` | disable this application in Træfik | +| `traefik.frontend.rule=Host:test.traefik.io` | override the default frontend rule (Default: `Host:{containerName}.{domain}`). | +| `traefik.frontend.passHostHeader=true` | forward client `Host` header to the backend. | +| `traefik.frontend.priority=10` | override default frontend priority | +| `traefik.frontend.entryPoints=http,https` | assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. | +| `traefik.frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0` | Sets basic authentication for that frontend with the usernames and passwords test:test and test2:test2, respectively | + +If several ports need to be exposed from a container, the services labels can be used: + +| Label | Description | +|-------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------| +| `traefik..port=443` | create a service binding with frontend/backend using this port. Overrides `traefik.port`. | +| `traefik..portIndex=1` | create a service binding with frontend/backend using this port index. Overrides `traefik.portIndex`. | +| `traefik..protocol=https` | assign `https` protocol. Overrides `traefik.protocol`. | +| `traefik..weight=10` | assign this service weight. Overrides `traefik.weight`. | +| `traefik..frontend.backend=fooBackend` | assign this service frontend to `foobackend`. Default is to assign to the service backend. | +| `traefik..frontend.entryPoints=http` | assign this service entrypoints. Overrides `traefik.frontend.entrypoints`. | +| `traefik..frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0` | Sets a Basic Auth for that frontend with the users test:test and test2:test2. | +| `traefik..frontend.passHostHeader=true` | Forward client `Host` header to the backend. Overrides `traefik.frontend.passHostHeader`. | +| `traefik..frontend.priority=10` | assign the service frontend priority. Overrides `traefik.frontend.priority`. | +| `traefik..frontend.rule=Path:/foo` | assign the service frontend rule. Overrides `traefik.frontend.rule`. | diff --git a/docs/backends/mesos.md b/docs/configuration/backends/mesos.md similarity index 97% rename from docs/backends/mesos.md rename to docs/configuration/backends/mesos.md index 17aa1e7e1..86484b80d 100644 --- a/docs/backends/mesos.md +++ b/docs/configuration/backends/mesos.md @@ -1,17 +1,13 @@ -# Mesos generic backend +# Mesos Generic Backend Træfik can be configured to use Mesos as a backend configuration: - ```toml ################################################################ # Mesos configuration backend ################################################################ # Enable Mesos configuration backend -# -# Optional -# [mesos] # Mesos server endpoint. diff --git a/docs/configuration/backends/rancher.md b/docs/configuration/backends/rancher.md new file mode 100644 index 000000000..786000d95 --- /dev/null +++ b/docs/configuration/backends/rancher.md @@ -0,0 +1,122 @@ +# Rancher Backend + +Træfik can be configured to use Rancher as a backend configuration: + +```toml +################################################################ +# Rancher configuration backend +################################################################ + +# Enable Rancher configuration backend +[rancher] + +# Default domain used. +# Can be overridden by setting the "traefik.domain" label on an service. +# +# Required +# +domain = "rancher.localhost" + +# Enable watch Rancher changes +# +# Optional +# Default: true +# +Watch = true + +# Polling interval (in seconds) +# +# Optional +# +RefreshSeconds = 15 + +# Expose Rancher services by default in traefik +# +# Optional +# Default: true +# +ExposedByDefault = false + +# Filter services with unhealthy states and inactive states +# +# Optional +# Default: false +# +EnableServiceHealthFilter = true +``` + +## Rancher Metadata Service + +```toml +# Enable Rancher metadata service configuration backend instead of the API +# configuration backend +# +# Optional +# Default: false +# +[rancher.metadata] + +# Poll the Rancher metadata service for changes every `rancher.RefreshSeconds` +# NOTE: this is less accurate than the default long polling technique which +# will provide near instantaneous updates to Traefik +# +# Optional +# Default: false +# +IntervalPoll = true + +# Prefix used for accessing the Rancher metadata service +# +# Optional +# Default: "/latest" +# +Prefix = "/2016-07-29" +``` + +## Rancher API + +```toml +# Enable Rancher API configuration backend +# +# Optional +# Default: true +# +[rancher.api] + +# Endpoint to use when connecting to the Rancher API +# +# Required +Endpoint = "http://rancherserver.example.com/v1" + +# AccessKey to use when connecting to the Rancher API +# +# Required +AccessKey = "XXXXXXXXXXXXXXXXXXXX" + +# SecretKey to use when connecting to the Rancher API +# +# Required +SecretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +``` + +## Notes + +If Traefik needs access to the Rancher API, you need to set the `endpoint`, `accesskey` and `secretkey` parameters. + +To enable traefik to fetch information about the Environment it's deployed in only, you need to create an `Environment API Key`. +This can be found within the API Key advanced options. + +## Labels + +Labels can be used on task containers to override default behaviour: + +| Label | Description | +|----------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------| +| `traefik.protocol=https` | override the default `http` protocol | +| `traefik.weight=10` | assign this weight to the container | +| `traefik.enable=false` | disable this container in Træfik | +| `traefik.frontend.rule=Host:test.traefik.io` | override the default frontend rule (Default: `Host:{containerName}.{domain}`). | +| `traefik.frontend.passHostHeader=true` | forward client `Host` header to the backend. | +| `traefik.frontend.priority=10` | override default frontend priority | +| `traefik.frontend.entryPoints=http,https` | assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. | +| `traefik.frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0` | Sets basic authentication for that frontend with the usernames and passwords test:test and test2:test2, respectively | diff --git a/docs/backends/api.md b/docs/configuration/backends/web.md similarity index 80% rename from docs/backends/api.md rename to docs/configuration/backends/web.md index c9f5001ec..5a7d1d3f0 100644 --- a/docs/backends/api.md +++ b/docs/configuration/backends/web.md @@ -1,66 +1,38 @@ -# API backend +# Web Backend -Træfik can be configured using a RESTful api. +Træfik can be configured: + +- using a RESTful api. +- to use a metric system (like Prometheus, DataDog or StatD, ...). +- to expose a Web Dashboard. ## Configuration -### CLI - -| Flag | Description | Default | -|------------------------------------|----------------------------------|---------------------| -| `--web` | Enable Web backend | `"true"` | -| `--web.address` | Web administration port | `":8080"` | -| `--web.certfile` | SSL certificate | | -| `--web.keyfile` | SSL key | | -| `--web.metrics` | Enable a metrics exporter | `"true"` | -| `--web.metrics.prometheus` | Prometheus metrics exporter type | `"true"` | -| `--web.metrics.prometheus.buckets` | Buckets for latency metrics | `"[0.1 0.3 1.2 5]"` | -| `--web.path` | Root path for dashboard and API | | -| `--web.readonly` | Enable read only API | `"false"` | -| `--web.statistics` | Enable more detailed statistics | `"false"` | -| `--web.statistics.recenterrors` | Number of recent errors logged | `"10"` | - -### traefik.toml: ```toml [web] + +# Web administration port +# +# Required +# address = ":8080" -# Set the root path for webui and API -# -# Optional -# -# path = "/mypath" -# # SSL certificate and key used # # Optional # # CertFile = "traefik.crt" # KeyFile = "traefik.key" -# + # Set REST API to read-only mode # # Optional # ReadOnly = false -# -# To enable more detailed statistics + +# Enable more detailed statistics # [web.statistics] # RecentErrors = 10 -# -# To enable Traefik to export internal metrics to Prometheus -# [web.metrics.prometheus] -# Buckets=[0.1,0.3,1.2,5.0] -# -# To enable Traefik to export internal metics to DataDog -# [web.metrics.datadog] -# Address = localhost:8125 -# PushInterval = "10s" -# -# To enable Traefik to export internal metics to StatsD -# [web.metrics.statsd] -# Address = localhost:8125 -# PushInterval = "10s" -# + # To enable basic auth on the webui # with 2 user/pass: test:test and test2:test2 # Passwords can be encoded in MD5, SHA1 and BCrypt: you can use htpasswd to generate those ones @@ -78,10 +50,31 @@ address = ":8080" ``` ## Web UI + ![Web UI Providers](/img/web.frontend.png) ![Web UI Health](/img/traefik-health.png) +## Metrics + +You can enable Traefik to export internal metrics to different monitoring systems. + +```toml +# To enable Traefik to export internal metrics to Prometheus +# [web.metrics.prometheus] +# Buckets=[0.1,0.3,1.2,5.0] + +# DataDog metrics exporter type +# [web.metrics.datadog] +# Address = "localhost:8125" +# Pushinterval = "10s" + +# StatsD metrics exporter type +# [web.metrics.statsd] +# Address = "localhost:8125" +# Pushinterval = "10s" +``` + ## API | Path | Method | Description | @@ -102,16 +95,14 @@ address = ":8080" | `/api/providers/{provider}/frontends/{frontend}/routes/{route}` | `GET` | Get a route in a frontend | | `/metrics` | `GET` | Export internal metrics | -> You can enable Traefik to export internal metrics to different monitoring systems (Only Prometheus is supported at the moment). - ->```bash ->$ traefik --web.metrics.prometheus --web.metrics.prometheus.buckets="0.1,0.3,1.2,5.0" ->``` - ### Example + #### Ping + ```shell $ curl -sv "http://localhost:8080/ping" +``` +```shell * Trying ::1... * Connected to localhost (::1) port 8080 (#0) > GET /ping HTTP/1.1 @@ -129,8 +120,11 @@ OK ``` #### Health + ```shell $ curl -s "http://localhost:8080/health" | jq . +``` +```json { // Træfik PID "pid": 2458, @@ -187,8 +181,11 @@ $ curl -s "http://localhost:8080/health" | jq . ``` #### Provider configurations + ```shell $ curl -s "http://localhost:8080/api" | jq . +``` +```json { "file": { "frontends": { diff --git a/docs/backends/zookeeper.md b/docs/configuration/backends/zookeeper.md similarity index 95% rename from docs/backends/zookeeper.md rename to docs/configuration/backends/zookeeper.md index 51a6a698c..c35e3e37e 100644 --- a/docs/backends/zookeeper.md +++ b/docs/configuration/backends/zookeeper.md @@ -1,4 +1,4 @@ -# Zookeeper backend +# Zookeeper Backend Træfik can be configured to use Zookeeper as a backend configuration: @@ -8,9 +8,6 @@ Træfik can be configured to use Zookeeper as a backend configuration: ################################################################ # Enable Zookeeperconfiguration backend -# -# Optional -# [zookeeper] # Zookeeper server endpoint diff --git a/docs/configuration/toml.md b/docs/configuration/commons.md similarity index 73% rename from docs/configuration/toml.md rename to docs/configuration/commons.md index af11da7ff..bacc24e40 100644 --- a/docs/configuration/toml.md +++ b/docs/configuration/commons.md @@ -1,10 +1,8 @@ +# Global Configuration -# Global configuration - -## Main section +## Main Section ```toml -# traefik.toml ################################################################ # Global configuration ################################################################ @@ -42,7 +40,7 @@ # Access logs file # -# Deprecated - see [accessLog] lower down +# DEPRECATED - see [accessLog] lower down # Optional # # accessLogsFile = "log/access.log" @@ -70,7 +68,7 @@ # IdleTimeout # -# Deprecated - see [respondingTimeouts] section. In the case both settings are configured, the deprecated option will +# DEPRECATED - see [respondingTimeouts] section. In the case both settings are configured, the deprecated option will # be overwritten. # # IdleTimeout is the maximum amount of time an idle (keep-alive) connection will remain idle before closing itself. @@ -145,28 +143,29 @@ Supported filters: # # Simple matching constraint # constraints = ["tag==api"] -# + # Simple mismatching constraint # constraints = ["tag!=api"] -# + # Globbing # constraints = ["tag==us-*"] -# -# Backend-specific constraint -# [consulCatalog] -# endpoint = 127.0.0.1:8500 -# constraints = ["tag==api"] -# + # Multiple constraints # - "tag==" must match with at least one tag # - "tag!=" must match with none of tags # constraints = ["tag!=us-*", "tag!=asia-*"] + +# Backend-specific constraint +# [consulCatalog] +# endpoint = 127.0.0.1:8500 +# constraints = ["tag==api"] + # [consulCatalog] # endpoint = 127.0.0.1:8500 # constraints = ["tag==api", "tag!=v*-beta"] ``` -## Access log definition +## Access Log Definition Access logs are written when `[accessLog]` is defined. By default it will write to stdout and produce logs in the textual Common Log Format (CLF), extended with additional fields. @@ -189,41 +188,57 @@ To write JSON format logs, specify `json` as the format: format = "json" ``` -## Entrypoints definition +## Entry Points Definition ```toml # Entrypoints definition # -# Optional # Default: # [entryPoints] # [entryPoints.http] # address = ":80" # +[entryPoints] + [entryPoints.http] + address = ":80" +``` + +### Redirect HTTP to HTTPS + +```toml # To redirect an http entrypoint to an https entrypoint (with SNI support): -# [entryPoints] -# [entryPoints.http] -# address = ":80" -# [entryPoints.http.redirect] -# entryPoint = "https" -# [entryPoints.https] -# address = ":443" -# [entryPoints.https.tls] -# [[entryPoints.https.tls.certificates]] -# CertFile = "integration/fixtures/https/snitest.com.cert" -# KeyFile = "integration/fixtures/https/snitest.com.key" -# [[entryPoints.https.tls.certificates]] -# CertFile = "integration/fixtures/https/snitest.org.cert" -# KeyFile = "integration/fixtures/https/snitest.org.key" # +[entryPoints] + [entryPoints.http] + address = ":80" + [entryPoints.http.redirect] + entryPoint = "https" + [entryPoints.https] + address = ":443" + [entryPoints.https.tls] + [[entryPoints.https.tls.certificates]] + CertFile = "integration/fixtures/https/snitest.com.cert" + KeyFile = "integration/fixtures/https/snitest.com.key" + [[entryPoints.https.tls.certificates]] + CertFile = "integration/fixtures/https/snitest.org.cert" + KeyFile = "integration/fixtures/https/snitest.org.key" +``` + +### Rewriting URL + +```toml # To redirect an entrypoint rewriting the URL: -# [entryPoints] -# [entryPoints.http] -# address = ":80" -# [entryPoints.http.redirect] -# regex = "^http://localhost/(.*)" -# replacement = "http://mydomain/$1" -# +[entryPoints] + [entryPoints.http] + address = ":80" + [entryPoints.http.redirect] + regex = "^http://localhost/(.*)" + replacement = "http://mydomain/$1" +``` + +### TLS Mutual Authentication + +```toml # Only accept clients that present a certificate signed by a specified # Certificate Authority (CA) # ClientCAFiles can be configured with multiple CA:s in the same file or @@ -232,78 +247,101 @@ To write JSON format logs, specify `json` as the format: # The requirement will apply to all server certs in the entrypoint # In the example below both snitest.com and snitest.org will require client certs # -# [entryPoints] -# [entryPoints.https] -# address = ":443" -# [entryPoints.https.tls] -# ClientCAFiles = ["tests/clientca1.crt", "tests/clientca2.crt"] -# [[entryPoints.https.tls.certificates]] -# CertFile = "integration/fixtures/https/snitest.com.cert" -# KeyFile = "integration/fixtures/https/snitest.com.key" -# [[entryPoints.https.tls.certificates]] -# CertFile = "integration/fixtures/https/snitest.org.cert" -# KeyFile = "integration/fixtures/https/snitest.org.key" -# +[entryPoints] + [entryPoints.https] + address = ":443" + [entryPoints.https.tls] + ClientCAFiles = ["tests/clientca1.crt", "tests/clientca2.crt"] + [[entryPoints.https.tls.certificates]] + CertFile = "integration/fixtures/https/snitest.com.cert" + KeyFile = "integration/fixtures/https/snitest.com.key" + [[entryPoints.https.tls.certificates]] + CertFile = "integration/fixtures/https/snitest.org.cert" + KeyFile = "integration/fixtures/https/snitest.org.key" +``` + +### Basic & Digest Authentication + +```toml # To enable basic auth on an entrypoint +# # with 2 user/pass: test:test and test2:test2 -# Passwords can be encoded in MD5, SHA1 and BCrypt: you can use htpasswd to generate those ones -# Users can be specified directly in the toml file, or indirectly by referencing an external file; if both are provided, the two are merged, with external file contents having precedence -# [entryPoints] -# [entryPoints.http] -# address = ":80" -# [entryPoints.http.auth.basic] -# users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"] -# usersFile = "/path/to/.htpasswd" -# -# To enable digest auth on an entrypoint -# with 2 user/realm/pass: test:traefik:test and test2:traefik:test2 -# You can use htdigest to generate those ones -# Users can be specified directly in the toml file, or indirectly by referencing an external file; if both are provided, the two are merged, with external file contents having precedence -# [entryPoints] -# [entryPoints.http] -# address = ":80" -# [entryPoints.http.auth.basic] -# users = ["test:traefik:a2688e031edb4be6a3797f3882655c05 ", "test2:traefik:518845800f9e2bfb1f1f740ec24f074e"] -# usersFile = "/path/to/.htdigest" -# -# To specify an https entrypoint with a minimum TLS version, and specifying an array of cipher suites (from crypto/tls): -# [entryPoints] -# [entryPoints.https] -# address = ":443" -# [entryPoints.https.tls] -# MinVersion = "VersionTLS12" -# CipherSuites = ["TLS_RSA_WITH_AES_256_GCM_SHA384"] -# [[entryPoints.https.tls.certificates]] -# CertFile = "integration/fixtures/https/snitest.com.cert" -# KeyFile = "integration/fixtures/https/snitest.com.key" -# [[entryPoints.https.tls.certificates]] -# CertFile = "integration/fixtures/https/snitest.org.cert" -# KeyFile = "integration/fixtures/https/snitest.org.key" - -# To enable compression support using gzip format: -# [entryPoints] -# [entryPoints.http] -# address = ":80" -# compress = true - -# To enable IP whitelisting at the entrypoint level: -# [entryPoints] -# [entryPoints.http] -# address = ":80" -# whiteListSourceRange = ["127.0.0.1/32"] - -# To enable ProxyProtocol support (https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt): -# [entryPoints] -# [entryPoints.http] -# address = ":80" -# proxyprotocol = true - +# Passwords can be encoded in MD5, SHA1 and BCrypt: you can use htpasswd to generate those ones. +# Users can be specified directly in the toml file, or indirectly by referencing an external file; +# if both are provided, the two are merged, with external file contents having precedence. [entryPoints] [entryPoints.http] address = ":80" + [entryPoints.http.auth.basic] + users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"] + usersFile = "/path/to/.htpasswd" ``` -## Retry configuration +```toml +# To enable digest auth on an entrypoint +# +# with 2 user/realm/pass: test:traefik:test and test2:traefik:test2 +# You can use htdigest to generate those ones +# Users can be specified directly in the toml file, or indirectly by referencing an external file; +# if both are provided, the two are merged, with external file contents having precedence +[entryPoints] + [entryPoints.http] + address = ":80" + [entryPoints.http.auth.basic] + users = ["test:traefik:a2688e031edb4be6a3797f3882655c05 ", "test2:traefik:518845800f9e2bfb1f1f740ec24f074e"] + usersFile = "/path/to/.htdigest" +``` + +### Specify Minimum TLS Version + +```toml +# To specify an https entrypoint with a minimum TLS version, +# and specifying an array of cipher suites (from crypto/tls): +[entryPoints] + [entryPoints.https] + address = ":443" + [entryPoints.https.tls] + MinVersion = "VersionTLS12" + CipherSuites = ["TLS_RSA_WITH_AES_256_GCM_SHA384"] + [[entryPoints.https.tls.certificates]] + CertFile = "integration/fixtures/https/snitest.com.cert" + KeyFile = "integration/fixtures/https/snitest.com.key" + [[entryPoints.https.tls.certificates]] + CertFile = "integration/fixtures/https/snitest.org.cert" + KeyFile = "integration/fixtures/https/snitest.org.key" +``` + +### Compression + +```toml +# To enable compression support using gzip format: +[entryPoints] + [entryPoints.http] + address = ":80" + compress = true +``` + +### Whitelisting + +```toml +# To enable IP whitelisting at the entrypoint level: +[entryPoints] + [entryPoints.http] + address = ":80" + whiteListSourceRange = ["127.0.0.1/32"] +``` + +### ProxyProtocol Support + +```toml +# To enable ProxyProtocol support (https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt): +[entryPoints] + [entryPoints.http] + address = ":80" + proxyprotocol = true +``` + +## Retry Configuration ```toml # Enable retry sending request if network error @@ -320,7 +358,8 @@ To write JSON format logs, specify `json` as the format: # attempts = 3 ``` -## Health check configuration +## Health Check Configuration + ```toml # Enable custom health check options. # @@ -341,8 +380,9 @@ To write JSON format logs, specify `json` as the format: # interval = "30s" ``` -## Responding timeouts -``` +## Responding Timeouts + +```toml # respondingTimeouts are timeouts for incoming requests to the Traefik instance. # # Optional @@ -382,8 +422,9 @@ To write JSON format logs, specify `json` as the format: ``` -## Forwarding timeouts -``` +## Forwarding Timeouts + +```toml # forwardingTimeouts are timeouts for requests forwarded to the backend servers. # # Optional diff --git a/docs/img/traefik-health.png b/docs/img/traefik-health.png index bfcf2799f093dfa54371280dc3fcaf8d9ccafc8f..608174ac713302eb6afbaa5cbb7f9a82993a9aee 100644 GIT binary patch literal 53776 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 E09o}Rp8x;= literal 102955 zcmZ^K19T=`@^>aSCZ0H%*mg3pZQHgzv2AN6wyh_&%_p|~&Aa>lwYy)R+voJHs^2a3 z>8^9TI$T~>3<35VEC>h)f`quRA_xdLGzbW&1vKOz3gHgO76=F|l!cIxyo8Vtp}eD= zsfD!(2#9!iaEhBc+9AeJclvpB)7_?5HJtdRj3;`s$?=5AZ(@wNJkSVYV$g`Zd@3v$ z)`&0)3h*xwH0D17{T(MXkW*FP$#a4|xtBJ8pe0vz~#moFH-9$I_;_<6u9$ z1)0XidNsKS8N|P_gH8K`KY@G^pT?Gurba?i^B*9%zr6MZ{c(DqGt{=^xA~ddi-VCf z00MIJBW*~(E&+uvtVT|g$tk-O8E8f%Lo}{?I9v^1xWwrk6x>~PeO)J@jt9b%E^8(N z`lE=b&6$ei>opN1VMR7FMz;S|TQ?_31b)aBNZ$#H1LZMvx0W6%K{wcp#0@lc=*J-Q zjonAS-^<)_yq}}DHtgQxqb5I!qkCXAyP`-u8WhS8)PVrBIK-kas5L!^!r`Jx_WNg_ zuY9XZK5WC1WXs`aVUY2Ju-{2u&p&q$-WMpbi@tExk>M(6$B&u5bK9!dUHZBN3%hq) zXuN<}kM7!YWN)!F3xjCtl3X%9$tW#;@qc9i0lSYvQ#}c3^1TBA3-iah0z)B$+4pCf z25IX-P6L(Fhsp}zzWNfNkE2icK18BZ93UMB;V8hz0W0gzBo8wgz-5o34SBu|+k$8t zAiw}R)N90m0PK-_Sa=bdMVsgf7L)ZxI3e6FypV4DLi{cPP zFbZ_&1J@^Jv`EvIhADxZi)anU28{qj1G& zkLuqMwzuS9&f<=Vks3PKmEED+uG$&0cWOa$|EddH9oYJAMHjvB~K6jhTbFU}!%M7&Nqj-ndgAxv6;Jrjy0G)|oIH8YGoTxp>B`&Wq+W9ggk zB8d<2k`k%nU`5!oVoU@Y$<{)MWTkPjaaJR|`=R^IXs{yjh7vFZ-<4wIPbk?bmDu z?Yiy8?o1ta5A%;tVQiyLV_u<(V^UzYP%+SkeN{$t{u+f!gVsUALG∾̳uYnp?wr5 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 diff --git a/docs/index.md b/docs/index.md index 2d61e8926..fc52c7b4b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,7 +2,7 @@ Træfik

-[![Build Status SemaphoreCI](https://semaphoreci.com/api/v1/containous/traefik/branches/add-ldez-maintainers/shields_badge.svg)](https://semaphoreci.com/containous/traefik) +[![Build Status SemaphoreCI](https://semaphoreci.com/api/v1/containous/traefik/branches/master/shields_badge.svg)](https://semaphoreci.com/containous/traefik) [![Docs](https://img.shields.io/badge/docs-current-brightgreen.svg)](https://docs.traefik.io) [![Go Report Card](https://goreportcard.com/badge/kubernetes/helm)](http://goreportcard.com/report/containous/traefik) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/containous/traefik/blob/master/LICENSE.md) diff --git a/docs/user-guide/cluster.md b/docs/user-guide/cluster.md index 99769cb63..6d21a6b0a 100644 --- a/docs/user-guide/cluster.md +++ b/docs/user-guide/cluster.md @@ -16,5 +16,6 @@ Please refer to [this section](/user-guide/kv-config/#store-configuration-in-key Once your Træfik configuration is uploaded on your KV store, you can start each Træfik instance. A Træfik cluster is based on a manager/worker model. -When starting, Træfik will elect a manager. If this instance fails, another manager will be automatically elected. +When starting, Træfik will elect a manager. +If this instance fails, another manager will be automatically elected. diff --git a/docs/user-guide/examples.md b/docs/user-guide/examples.md index 8089a8ec4..f07cdbc12 100644 --- a/docs/user-guide/examples.md +++ b/docs/user-guide/examples.md @@ -1,4 +1,3 @@ - # Examples You will find here some configuration examples of Træfik. diff --git a/docs/user-guide/getting-started-with-docker-and-lets-encrypt.md b/docs/user-guide/getting-started-with-docker-and-lets-encrypt.md index 5bf7893bd..ca57997fe 100644 --- a/docs/user-guide/getting-started-with-docker-and-lets-encrypt.md +++ b/docs/user-guide/getting-started-with-docker-and-lets-encrypt.md @@ -1,11 +1,20 @@ # Docker & Traefik -In this use case, we want to use Traefik as a *layer-7* load balancer with SSL termination for a set of microservices used to run a webapplication. We also want to automatically *discover any services* on the Docker host and let Traefik reconfigure itself automatically when containers get created (or shut down) so HTTP traffic can be routed accordingly. In addition, we want to use Let's Encrypt to automatically generate and renew SSL certificates per hostname. -## Setting up -In order for this to work, you'll need a server with a public IP address, with Docker installed on it. In this example, we're using the fictitious domain *my-awesome-app.org*. In real-life, you'll want to use your own domain and have the DNS configured accordingly so the hostname records you'll want to use point to the aforementioned public IP address. +In this use case, we want to use Traefik as a _layer-7_ load balancer with SSL termination for a set of micro-services used to run a web application. +We also want to automatically _discover any services_ on the Docker host and let Traefik reconfigure itself automatically when containers get created (or shut down) so HTTP traffic can be routed accordingly. +In addition, we want to use Let's Encrypt to automatically generate and renew SSL certificates per hostname. + +## Setting Up + +In order for this to work, you'll need a server with a public IP address, with Docker installed on it. +In this example, we're using the fictitious domain _my-awesome-app.org_. +In real-life, you'll want to use your own domain and have the DNS configured accordingly so the hostname records you'll want to use point to the aforementioned public IP address. ## Networking -Docker containers can only communicate with each other over TCP when they share at least one network. This makes sense from a topological point of view in the context of networking, since Docker under the hood creates IPTable rules so containers can't reach other containers *unless you'd want to*. In this example, we're going to use a single network called `web` where all containers that are handling HTTP traffic (including Traefik) will reside in. + +Docker containers can only communicate with each other over TCP when they share at least one network. +This makes sense from a topological point of view in the context of networking, since Docker under the hood creates IPTable rules so containers can't reach other containers _unless you'd want to_. +In this example, we're going to use a single network called `web` where all containers that are handling HTTP traffic (including Traefik) will reside in. On the Docker host, run the following command: @@ -23,7 +32,8 @@ $ touch /opt/traefik/acme.json && chmod 600 /opt/traefik/acme.json $ touch /opt/traefik/traefik.toml ``` -The `docker-compose.yml` file will provide us with a simple, consistent and more importantly, a deterministic way to create Traefik. The contents of the file is as follows: +The `docker-compose.yml` file will provide us with a simple, consistent and more importantly, a deterministic way to create Traefik. +The contents of the file is as follows: ```yaml version: '2' @@ -48,8 +58,11 @@ networks: external: true ``` -As you can see, we're mounting the `traefik.toml` file as well as the (empty) `acme.json` file in the container. Also, we're mounting the `/var/run/docker.sock` Docker socket in the container as well, so Traefik can listen to Docker events and reconfigure it's own internal configuration when containers are created (or shut down). -Also, we're making sure the container is automatically restarted by the Docker engine in case of problems (or: if the server is rebooted). We're publishing the default HTTP ports `80` and `443` on the host, and making sure the container is placed within the `web` network we've created earlier on. Finally, we're giving this container a static name called `traefik`. +As you can see, we're mounting the `traefik.toml` file as well as the (empty) `acme.json` file in the container. +Also, we're mounting the `/var/run/docker.sock` Docker socket in the container as well, so Traefik can listen to Docker events and reconfigure it's own internal configuration when containers are created (or shut down). +Also, we're making sure the container is automatically restarted by the Docker engine in case of problems (or: if the server is rebooted). +We're publishing the default HTTP ports `80` and `443` on the host, and making sure the container is placed within the `web` network we've created earlier on. +Finally, we're giving this container a static name called `traefik`. Let's take a look at a simply `traefik.toml` configuration as well before we'll create the Traefik container: @@ -87,16 +100,17 @@ This is the minimum configuration required to do the following: - Log `ERROR`-level messages (or more severe) to the console, but silence `DEBUG`-level messagse - Check for new versions of Traefik periodically -- Create two entrypoints, namely an `HTTP` endpoint on port `80`, and an `HTTPS` endpoint on port `443` where all incoming traffic on port `80` will immediately get redirected to `HTTPS`. +- Create two entry points, namely an `HTTP` endpoint on port `80`, and an `HTTPS` endpoint on port `443` where all incoming traffic on port `80` will immediately get redirected to `HTTPS`. - Enable the Docker configuration backend and listen for container events on the Docker unix socket we've mounted earlier. However, **new containers will not be exposed by Traefik by default, we'll get into this in a bit!** - Enable automatic request and configuration of SSL certificates using Let's Encrypt. These certificates will be stored in the `acme.json` file, which you can back-up yourself and store off-premises. Alright, let's boot the container. From the `/opt/traefik` directory, run `$ docker-compose up -d` which will create and start the Traefik container. -## Exposing your webservices to the outside world +## Exposing Web Services to the Outside World + Now that we've fully configured and started Traefik, it's time to get our applications running! -Let's take a simple example of a microservice project consisting of various services, where some will be exposed to the outside world and some will not. The `docker-compose.yml` of our project looks like this: +Let's take a simple example of a micro-service project consisting of various services, where some will be exposed to the outside world and some will not. The `docker-compose.yml` of our project looks like this: ```yaml version: "2.1" @@ -155,10 +169,17 @@ networks: external: true ``` -Here, we can see a set of services with two applications that we're actually exposing to the outside world. Notice how there isn't a single container that has any published ports to the host -- everything is routed through Docker networks. Also, only the containers that we want traffic to get routed to are attached to the `web` network we created at the start of this document. Since the `traefik` container we've created and started earlier is also attached to this network, HTTP requests can now get routed to these containers. +Here, we can see a set of services with two applications that we're actually exposing to the outside world. +Notice how there isn't a single container that has any published ports to the host -- everything is routed through Docker networks. +Also, only the containers that we want traffic to get routed to are attached to the `web` network we created at the start of this document. +Since the `traefik` container we've created and started earlier is also attached to this network, HTTP requests can now get routed to these containers. ### Labels -As mentioned earlier, we don't want containers exposed automatically by Traefik. The reason behind this is simple: we want to have control over this process ourselves. Thanks to Docker labels, we can tell Traefik how to create it's internal routing configuration. Let's take a look at the labels themselves for the `app` service, which is a HTTP webservice listing on port 9000: + +As mentioned earlier, we don't want containers exposed automatically by Traefik. +The reason behind this is simple: we want to have control over this process ourselves. +Thanks to Docker labels, we can tell Traefik how to create it's internal routing configuration. +Let's take a look at the labels themselves for the `app` service, which is a HTTP webservice listing on port 9000: ```yaml - "traefik.backend=my-awesome-app-app" @@ -168,14 +189,25 @@ As mentioned earlier, we don't want containers exposed automatically by Traefik. - "traefik.port=9000" ``` -First, we specify the `backend` name which corresponds to the actual service we're routing **to**. We also tell Traefik to use the `web` network to route HTTP traffic to this container. With the `frontend.rule` label, we tell Traefik that we want to route to this container if the incoming HTTP request contains the `Host` `app.my-awesome-app.org`. Essentially, this is the actual rule used for Layer-7 load balancing. With the `traefik.enable` label, we tell Traefik to include this container in it's internal configuration. Finally but not unimportantly, we tell Traefik to route **to** port `9000`, since that is the actual TCP/IP port the container actually listens on. +First, we specify the `backend` name which corresponds to the actual service we're routing **to**. +We also tell Traefik to use the `web` network to route HTTP traffic to this container. With the `frontend.rule` label, we tell Traefik that we want to route to this container if the incoming HTTP request contains the `Host` `app.my-awesome-app.org`. +Essentially, this is the actual rule used for Layer-7 load balancing. +With the `traefik.enable` label, we tell Traefik to include this container in it's internal configuration. +Finally but not unimportantly, we tell Traefik to route **to** port `9000`, since that is the actual TCP/IP port the container actually listens on. #### Gotchas and tips -- Always specify the correct port where the container expects HTTP traffic using `traefik.port` label. If a container exposes multiple ports, Traefik may forward traffic to the wrong port. Even if a container only exposes one port, you should always write configuration defensively and explicitly. -- Should you choose to enable the `exposedbydefault` flag in the `traefik.toml` configuration, be aware that all containers that are placed in the same network as Traefik will automatically be reachable from the outside world, for everyone and everyone to see. Usually, this is a bad idea. + +- Always specify the correct port where the container expects HTTP traffic using `traefik.port` label. + If a container exposes multiple ports, Traefik may forward traffic to the wrong port. + Even if a container only exposes one port, you should always write configuration defensively and explicitly. +- Should you choose to enable the `exposedbydefault` flag in the `traefik.toml` configuration, be aware that all containers that are placed in the same network as Traefik will automatically be reachable from the outside world, for everyone and everyone to see. + Usually, this is a bad idea. - With the `traefik.frontend.auth.basic` label, it's possible for Traefik to provide a HTTP basic-auth challenge for the endpoints you provide the label for. - Traefik has built-in support to automatically export [Prometheus](https://prometheus.io) metrics -- Traefik supports websockets out of the box. In the example above, the `events`-service could be a NodeJS-based application which allows clients to connect using websocket protocol. Thanks to the fact that HTTPS in our example is enforced, these websockets are automatically secure as well (WSS) +- Traefik supports websockets out of the box. In the example above, the `events`-service could be a NodeJS-based application which allows clients to connect using websocket protocol. + Thanks to the fact that HTTPS in our example is enforced, these websockets are automatically secure as well (WSS) ### Final thoughts -Using Traefik as a Layer-7 load balancer in combination with both Docker and Let's Encrypt provides you with an extremely flexible, performant and self-configuring solution for your projects. With Let's Encrypt, your endpoints are automatically secured with production-ready SSL certificates that are renewed automatically as well. + +Using Traefik as a Layer-7 load balancer in combination with both Docker and Let's Encrypt provides you with an extremely flexible, performant and self-configuring solution for your projects. +With Let's Encrypt, your endpoints are automatically secured with production-ready SSL certificates that are renewed automatically as well. diff --git a/docs/user-guide/kubernetes.md b/docs/user-guide/kubernetes.md index 523e94f1c..44f73efcd 100644 --- a/docs/user-guide/kubernetes.md +++ b/docs/user-guide/kubernetes.md @@ -14,11 +14,9 @@ on your machine, as it is the quickest way to get a local Kubernetes cluster set ### Role Based Access Control configuration (Kubernetes 1.6+ only) -Kubernetes introduces [Role Based Access Control (RBAC)](https://kubernetes.io/docs/admin/authorization/rbac/) in 1.6+ to allow fine-grained control -of Kubernetes resources and api. +Kubernetes introduces [Role Based Access Control (RBAC)](https://kubernetes.io/docs/admin/authorization/rbac/) in 1.6+ to allow fine-grained control of Kubernetes resources and api. -If your cluster is configured with RBAC, you may need to authorize Træfik to use the -Kubernetes API using ClusterRole and ClusterRoleBinding resources: +If your cluster is configured with RBAC, you may need to authorize Træfik to use the Kubernetes API using ClusterRole and ClusterRoleBinding resources: _Note: your cluster may have suitable ClusterRoles already setup, but the following should work everywhere_ @@ -71,20 +69,15 @@ kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/exa ## Deploy Træfik using a Deployment or DaemonSet -It is possible to use Træfik with a -[Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) -or a [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) -object, whereas both options have their own pros and cons: The scalability is much better when -using a Deployment, because you will have a Single-Pod-per-Node model when using -the DeaemonSet. It is possible to exclusively run a Service on a dedicated -set of machines using taints and tolerations with a DaemonSet. On the other hand the -DaemonSet allows you to access any Node directly on Port 80 and 443, where you have to setup a -[Service](https://kubernetes.io/docs/concepts/services-networking/service/) object -with a Deployment. +It is possible to use Træfik with a [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) or a [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) object, + whereas both options have their own pros and cons: + The scalability is much better when using a Deployment, because you will have a Single-Pod-per-Node model when using the DeaemonSet. +It is possible to exclusively run a Service on a dedicated set of machines using taints and tolerations with a DaemonSet. +On the other hand the DaemonSet allows you to access any Node directly on Port 80 and 443, where you have to setup a [Service](https://kubernetes.io/docs/concepts/services-networking/service/) object with a Deployment. The Deployment objects looks like this: -```yaml +```yml --- apiVersion: v1 kind: ServiceAccount @@ -207,10 +200,11 @@ $ kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/e $ kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-ds.yaml ``` -There are some significant differences between using Deployments and DaemonSets. The Deployment has easier -up and down scaling possibilities. It can implement full pod lifecycle and supports rolling updates from -Kubernetes 1.2. At least one Pod is needed to run the Deployment. The DaemonSet automatically scales to all nodes that -meets a specific selector and guarantees to fill nodes one at a time. Rolling updates are fully supported from Kubernetes 1.7 for DaemonSets as well. +There are some significant differences between using Deployments and DaemonSets. +The Deployment has easier up and down scaling possibilities. It can implement full pod lifecycle and supports rolling updates from Kubernetes 1.2. +At least one Pod is needed to run the Deployment. +The DaemonSet automatically scales to all nodes that meets a specific selector and guarantees to fill nodes one at a time. +Rolling updates are fully supported from Kubernetes 1.7 for DaemonSets as well. @@ -229,24 +223,21 @@ kubernetes-dashboard-s8krj 1/1 Running 0 4h traefik-ingress-controller-678226159-eqseo 1/1 Running 0 7m ``` -You should see that after submitting the Deployment or DaemonSet to Kubernetes it has launched -a Pod, and it is now running. _It might take a few moments for kubernetes to pull -the Træfik image and start the container._ +You should see that after submitting the Deployment or DaemonSet to Kubernetes it has launched a Pod, and it is now running. +_It might take a few moments for kubernetes to pull the Træfik image and start the container._ > You could also check the deployment with the Kubernetes dashboard, run > `minikube dashboard` to open it in your browser, then choose the `kube-system` > namespace from the menu at the top right of the screen. -You should now be able to access Træfik on port 80 of your Minikube instance when using -the DaemonSet: +You should now be able to access Træfik on port 80 of your Minikube instance when using the DaemonSet: ```sh curl $(minikube ip) 404 page not found ``` -If you decided to use the deployment, then you need to target the correct NodePort, which can -be seen then you execute `kubectl get services --namespace=kube-system`. +If you decided to use the deployment, then you need to target the correct NodePort, which can be seen then you execute `kubectl get services --namespace=kube-system`. ```sh curl $(minikube ip): @@ -257,10 +248,8 @@ curl $(minikube ip): ## Deploy Træfik using Helm Chart -Instead of installing Træfik via an own object, you can also use the Træfik Helm chart. This -allows more complex configuration via Kubernetes -[ConfigMap](https://kubernetes.io/docs/tasks/configure-pod-container/configmap/) and enabled -TLS certificates. +Instead of installing Træfik via an own object, you can also use the Træfik Helm chart. +This allows more complex configuration via Kubernetes [ConfigMap](https://kubernetes.io/docs/tasks/configure-pod-container/configmap/) and enabled TLS certificates. Install Træfik chart by: @@ -272,8 +261,7 @@ For more information, check out [the doc](https://github.com/kubernetes/charts/t ## Submitting An Ingress to the cluster. -Lets start by creating a Service and an Ingress that will expose the -[Træfik Web UI](https://github.com/containous/traefik#web-ui). +Lets start by creating a Service and an Ingress that will expose the [Træfik Web UI](https://github.com/containous/traefik#web-ui). ```yaml apiVersion: v1 @@ -310,8 +298,7 @@ spec: kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/ui.yaml ``` -Now lets setup an entry in our /etc/hosts file to route `traefik-ui.minikube` -to our cluster. +Now lets setup an entry in our /etc/hosts file to route `traefik-ui.minikube` to our cluster. > In production you would want to set up real dns entries. @@ -325,8 +312,7 @@ We should now be able to visit [traefik-ui.minikube](http://traefik-ui.minikube) ## Name based routing -In this example we are going to setup websites for 3 of the United Kingdoms -best loved cheeses, Cheddar, Stilton and Wensleydale. +In this example we are going to setup websites for 3 of the United Kingdoms best loved cheeses, Cheddar, Stilton and Wensleydale. First lets start by launching the 3 pods for the cheese websites. @@ -534,12 +520,9 @@ spec: kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-ingress.yaml ``` -Now visit the [Træfik dashboard](http://traefik-ui.minikube/) and you should -see a frontend for each host. Along with a backend listing for each service -with a Server set up for each pod. +Now visit the [Træfik dashboard](http://traefik-ui.minikube/) and you should see a frontend for each host. Along with a backend listing for each service with a Server set up for each pod. -If you edit your `/etc/hosts` again you should be able to access the cheese -websites in your browser. +If you edit your `/etc/hosts` again you should be able to access the cheese websites in your browser. ```shell echo "$(minikube ip) stilton.minikube cheddar.minikube wensleydale.minikube" | sudo tee -a /etc/hosts @@ -551,9 +534,7 @@ echo "$(minikube ip) stilton.minikube cheddar.minikube wensleydale.minikube" | s ## Path based routing -Now lets suppose that our fictional client has decided that while they are -super happy about our cheesy web design, when they asked for 3 websites -they had not really bargained on having to buy 3 domain names. +Now lets suppose that our fictional client has decided that while they are super happy about our cheesy web design, when they asked for 3 websites they had not really bargained on having to buy 3 domain names. No problem, we say, why don't we reconfigure the sites to host all 3 under one domain. @@ -646,7 +627,8 @@ spec: ## Forwarding to ExternalNames When specifying an [ExternalName](https://kubernetes.io/docs/concepts/services-networking/service/#services-without-selectors), -Træfik will forward requests to the given host accordingly and use HTTPS when the Service port matches 443. This still requires setting up a proper port mapping on the Service from the Ingress port to the (external) Service port. +Træfik will forward requests to the given host accordingly and use HTTPS when the Service port matches 443. +This still requires setting up a proper port mapping on the Service from the Ingress port to the (external) Service port. ## Disable passing the Host header @@ -663,8 +645,7 @@ disablePassHostHeaders = true ### Disable per ingress -To disable passing the Host header per ingress resource set the `traefik.frontend.passHostHeader` -annotation on your ingress to `false`. +To disable passing the Host header per ingress resource set the `traefik.frontend.passHostHeader` annotation on your ingress to `false`. Here is an example ingress definition: ```yaml @@ -700,9 +681,7 @@ spec: externalName: static.otherdomain.com ``` -If you were to visit example.com/static the request would then be passed onto -static.otherdomain.com/static and static.otherdomain.com would receive the -request with the Host header being static.otherdomain.com. +If you were to visit `example.com/static` the request would then be passed onto `static.otherdomain.com/static` and s`tatic.otherdomain.com` would receive the request with the Host header being `static.otherdomain.com`. Note: The per ingress annotation overides whatever the global value is set to. So you could set `disablePassHostHeaders` to `true` in your toml file and then enable passing diff --git a/docs/user-guide/kv-config.md b/docs/user-guide/kv-config.md index b62578523..1ba3cc949 100644 --- a/docs/user-guide/kv-config.md +++ b/docs/user-guide/kv-config.md @@ -1,4 +1,3 @@ - # Key-value store configuration 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 sorted in a Key-value store. @@ -12,7 +11,7 @@ Træfik supports several Key-value stores: - [ZooKeeper](https://zookeeper.apache.org/) - [boltdb](https://github.com/boltdb/bolt) -# Static configuration in Key-value store +## Static configuration in Key-value store We will see the steps to set it up with an easy example. Note that we could do the same with any other Key-value Store. diff --git a/docs/user-guide/marathon.md b/docs/user-guide/marathon.md index 2a10922c5..834b0d2aa 100644 --- a/docs/user-guide/marathon.md +++ b/docs/user-guide/marathon.md @@ -1,4 +1,3 @@ - # Marathon This guide explains how to integrate Marathon and operate the cluster in a reliable way from Traefik's standpoint. diff --git a/docs/user-guide/swarm-mode.md b/docs/user-guide/swarm-mode.md index 6c0b9c412..c8e0d80be 100644 --- a/docs/user-guide/swarm-mode.md +++ b/docs/user-guide/swarm-mode.md @@ -73,11 +73,9 @@ docker-machine ssh manager "docker network create --driver=overlay traefik-net" ## Deploy Træfik -Let's deploy Træfik as a docker service in our cluster. The only -requirement for Træfik to work with swarm mode is that it needs to run -on a manager node — we are going to use a -[constraint](https://docs.docker.com/engine/reference/commandline/service_create/#/specify-service-constraints-constraint) for -that. +Let's deploy Træfik as a docker service in our cluster. +The only requirement for Træfik to work with swarm mode is that it needs to run on a manager node — we are going to use a +[constraint](https://docs.docker.com/engine/reference/commandline/service_create/#/specify-service-constraints-constraint) for that. ```shell docker-machine ssh manager "docker service create \ @@ -96,24 +94,17 @@ docker-machine ssh manager "docker service create \ Let's explain this command: -- `--publish 80:80 --publish 8080:8080`: we publish port `80` and - `8080` on the cluster. -- `--constraint=node.role==manager`: we ask docker to schedule Træfik - on a manager node. +- `--publish 80:80 --publish 8080:8080`: we publish port `80` and `8080` on the cluster. +- `--constraint=node.role==manager`: we ask docker to schedule Træfik on a manager node. - `--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock`: - we bind mount the docker socket where Træfik is scheduled to be able - to speak to the daemon. -- `--network traefik-net`: we attach the Træfik service (and thus - the underlying container) to the `traefik-net` network. -- `--docker`: enable docker backend, and `--docker.swarmmode` to - enable the swarm mode on Træfik. + we bind mount the docker socket where Træfik is scheduled to be able to speak to the daemon. +- `--network traefik-net`: we attach the Træfik service (and thus the underlying container) to the `traefik-net` network. +- `--docker`: enable docker backend, and `--docker.swarmmode` to enable the swarm mode on Træfik. - `--web`: activate the webUI on port 8080 ## Deploy your apps -We can now deploy our app on the cluster, -here [whoami](https://github.com/emilevauge/whoami), a simple web -server in Go. We start 2 services, on the `traefik-net` network. +We can now deploy our app on the cluster, here [whoami](https://github.com/emilevauge/whoami), a simple web server in Go. We start 2 services, on the `traefik-net` network. ```shell docker-machine ssh manager "docker service create \ @@ -184,8 +175,7 @@ X-Forwarded-Proto: http X-Forwarded-Server: 8fbc39271b4c ``` -Note that as Træfik is published, you can access it from any machine -and not only the manager. +Note that as Træfik is published, you can access it from any machine and not only the manager. ```shell curl -H Host:whoami0.traefik http://$(docker-machine ip worker1) @@ -245,7 +235,8 @@ dtpl249tfghc traefik 1/1 traefik --docker --docker.swarmmode ``` ## Access to your whoami0 through Træfik multiple times. -Repeat the following command multiple times and note that the Hostname changes each time as Traefik load balances each request against the 5 tasks. +Repeat the following command multiple times and note that the Hostname changes each time as Traefik load balances each request against the 5 tasks: + ```shell curl -H Host:whoami0.traefik http://$(docker-machine ip manager) Hostname: 8147a7746e7a @@ -266,7 +257,8 @@ X-Forwarded-Proto: http X-Forwarded-Server: 8fbc39271b4c ``` -Do the same against whoami1. +Do the same against whoami1: + ```shell curl -H Host:whoami1.traefik http://$(docker-machine ip manager) Hostname: ba2c21488299 @@ -289,6 +281,7 @@ X-Forwarded-Server: 8fbc39271b4c Wait, I thought we added the sticky flag to whoami1? Traefik relies on a cookie to maintain stickyness so you'll need to test this with a browser. First you need to add whoami1.traefik to your hosts file: + ```ssh if [ -n "$(grep whoami1.traefik /etc/hosts)" ]; then diff --git a/mkdocs.yml b/mkdocs.yml index 766ec38a0..484556291 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -45,30 +45,29 @@ extra_css: pages: - Getting Started: index.md - Basics: basics.md - - Configration: - - 'traefik.toml': 'configuration/toml.md' + - Configuration: + - 'Commons': 'configuration/commons.md' - 'Let''s Encrypt': 'configuration/acme.md' - - Backends: - - 'API backend': 'backends/api.md' - - 'BoltDB backend': 'backends/boltdb.md' - - 'Consul backend': 'backends/consul.md' - - 'Docker backend': 'backends/docker.md' - - 'DynamoDB backend': 'backends/dynamodb.md' - - 'ECS backend': 'backends/ecs.md' - - 'Etcd backend': 'backends/etcd.md' - - 'Eureka backend': 'backends/eureka.md' - - 'File backend': 'backends/file.md' - - 'Kubernetes Ingress backend': 'backends/kubernetes.md' - - 'Marathon backend': 'backends/marathon.md' - - 'Rancher backend': 'backends/rancher.md' - - 'Zookeeper backend': 'backends/zookeeper.md' + - 'Web Backend': 'configuration/backends/web.md' + - 'BoltDB Backend': 'configuration/backends/boltdb.md' + - 'Consul Backend': 'configuration/backends/consul.md' + - 'Docker Backend': 'configuration/backends/docker.md' + - 'DynamoDB Backend': 'configuration/backends/dynamodb.md' + - 'ECS Backend': 'configuration/backends/ecs.md' + - 'Etcd Backend': 'configuration/backends/etcd.md' + - 'Eureka Backend': 'configuration/backends/eureka.md' + - 'File Backend': 'configuration/backends/file.md' + - 'Kubernetes Ingress Backend': 'configuration/backends/kubernetes.md' + - 'Marathon Backend': 'configuration/backends/marathon.md' + - 'Rancher Backend': 'configuration/backends/rancher.md' + - 'Zookeeper Backend': 'configuration/backends/zookeeper.md' - User Guide: - - 'Configuration examples': 'user-guide/examples.md' - - 'Swarm cluster': 'user-guide/swarm.md' - - 'Swarm mode cluster': 'user-guide/swarm-mode.md' - - 'Kubernetes': 'user-guide/kubernetes.md' - - 'Marathon': 'user-guide/marathon.md' - - 'Key-value store configuration': 'user-guide/kv-config.md' - - 'Clustering/HA': 'user-guide/cluster.md' - - 'Getting started with Docker & Lets Encrypt': 'user-guide/getting-started-with-docker-and-lets-encrypt.md' + - 'Configuration Examples': 'user-guide/examples.md' + - 'Swarm Cluster': 'user-guide/swarm.md' + - 'Swarm Mode Cluster': 'user-guide/swarm-mode.md' + - 'Kubernetes': 'user-guide/kubernetes.md' + - 'Marathon': 'user-guide/marathon.md' + - 'Key-value Store Configuration': 'user-guide/kv-config.md' + - 'Clustering/HA': 'user-guide/cluster.md' + - 'Getting Started with Docker & Lets Encrypt': 'user-guide/getting-started-with-docker-and-lets-encrypt.md' - Benchmarks: benchmarks.md diff --git a/provider/consul/consul_catalog.go b/provider/consul/consul_catalog.go index e221c8e1a..b058ee7e5 100644 --- a/provider/consul/consul_catalog.go +++ b/provider/consul/consul_catalog.go @@ -359,7 +359,7 @@ func (p *CatalogProvider) getConstraintTags(tags []string) []string { var list []string for _, tag := range tags { - // If 'AllTagsConstraintFiltering' is disabled, we look for a Consul tag named 'traefik.tags' (unless different 'prefix' is configured) + // We look for a Consul tag named 'traefik.tags' (unless different 'prefix' is configured) if strings.Index(strings.ToLower(tag), p.getPrefixedName("tags=")) == 0 { // If 'traefik.tags=' tag is found, take the tag value and split by ',' adding the result to the list to be returned splitedTags := strings.Split(tag[len(p.getPrefixedName("tags=")):], ",") diff --git a/provider/kubernetes/client.go b/provider/kubernetes/client.go index 45be10f20..d2f55fe14 100644 --- a/provider/kubernetes/client.go +++ b/provider/kubernetes/client.go @@ -22,7 +22,7 @@ import ( const resyncPeriod = time.Minute * 5 // Client is a client for the Provider master. -// WatchAll starts the watch of the Provider ressources and updates the stores. +// WatchAll starts the watch of the Provider resources and updates the stores. // The stores can then be accessed via the Get* functions. type Client interface { GetIngresses(namespaces Namespaces) []*v1beta1.Ingress diff --git a/traefik.sample.toml b/traefik.sample.toml index a30417562..5910be48d 100644 --- a/traefik.sample.toml +++ b/traefik.sample.toml @@ -36,7 +36,7 @@ # Access logs file # # Optional -# Deprecated - see [accessLog] lower down +# DEPRECATED - see [accessLog] lower down # # accessLogsFile = "log/access.log" @@ -433,6 +433,7 @@ # # responseHeaderTimeout = "0s" + ################################################################ # Web configuration backend ################################################################ @@ -455,21 +456,31 @@ # # CertFile = "traefik.crt" # KeyFile = "traefik.key" -# + # Set REST API to read-only mode # # Optional # ReadOnly = false -# + # Enable more detailed statistics # [web.statistics] # RecentErrors = 10 -# + # To enable Traefik to export internal metrics to Prometheus # [web.metrics.prometheus] # Buckets=[0.1,0.3,1.2,5.0] # +# DataDog metrics exporter type +# [web.metrics.datadog] +# Address = "localhost:8125" +# Pushinterval = "10s" + +# StatsD metrics exporter type +# [web.metrics.statsd] +# Address = "localhost:8125" +# Pushinterval = "10s" + # To enable basic auth on the webui # with 2 user/pass: test:test and test2:test2 # Passwords can be encoded in MD5, SHA1 and BCrypt: you can use htpasswd to generate those ones @@ -511,7 +522,6 @@ # # directory = "/path/to/config/" - # Enable watch file changes # # Optional @@ -572,7 +582,6 @@ # insecureskipverify = true - ################################################################ # Docker Swarmmode configuration backend ################################################################ @@ -693,16 +702,12 @@ # # groupsAsSubDomains = true -# Override DialerTimeout -# Amount of time to allow the Marathon provider to wait to open a TCP connection -# to a Marathon master. -# Can be provided in a format supported by Go's time.ParseDuration function or -# as raw values (digits). If no units are provided, the value is parsed assuming -# seconds. +# Enable compatibility with marathon-lb labels # # Optional -# Default: "60s" -# dialerTimeout = "60s" +# Default: false +# +# marathonLBCompatibility = true # Enable Marathon basic authentication # @@ -712,16 +717,36 @@ # httpBasicAuthUser = "foo" # httpBasicPassword = "bar" +# TLS client configuration. https://golang.org/pkg/crypto/tls/#Config +# +# Optional +# +# [marathon.TLS] +# CA = "/etc/ssl/ca.crt" +# Cert = "/etc/ssl/marathon.cert" +# Key = "/etc/ssl/marathon.key" +# InsecureSkipVerify = true + # DCOSToken for DCOS environment, This will override the Authorization header # # Optional # # dcosToken = "xxxxxx" +# Override DialerTimeout +# Amount of time to allow the Marathon provider to wait to open a TCP connection +# to a Marathon master. +# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw +# values (digits). If no units are provided, the value is parsed assuming +# seconds. +# +# Optional +# Default: "60s" +# dialerTimeout = "60s" # Set the TCP Keep Alive interval for the Marathon HTTP Client. -# Can be provided in a format supported by Go's time.ParseDuration function or -# as raw values (digits). If no units are provided, the value is parsed assuming +# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw +# values (digits). If no units are provided, the value is parsed assuming # seconds. # # Optional @@ -751,6 +776,7 @@ # # respectReadinessChecks = false + ################################################################ # Mesos configuration backend ################################################################ @@ -830,6 +856,7 @@ # # StateTimeoutSecond = "30" + ################################################################ # Kubernetes Ingress configuration backend ################################################################ @@ -881,9 +908,15 @@ # # namespaces = ["default"] -# See: http://kubernetes.io/docs/user-guide/labels/#list-and-watch-filtering +# Ingress label selector to identify Ingress objects that should be processed. +# See https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors for details. +# +# Optional +# Default: empty (process all Ingresses) +# # labelselector = "A and not B" + ################################################################ # Consul KV configuration backend ################################################################ @@ -928,6 +961,7 @@ # key = "/etc/ssl/consul.key" # insecureskipverify = true + ################################################################ # Consul Catalog configuration backend ################################################################ @@ -963,20 +997,16 @@ # prefix = "traefik" # Default frontEnd Rule for Consul services -# - The format is a Go Template with ".ServiceName", ".Domain" and ".Attributes" available -# -- "getTag(name, tags, defaultValue)", "hasTag(name, tags)" and "getAttribute(name, tags, defaultValue)" functions are available -# --- "getAttribute(...)" function uses prefixed tag names based on "prefix" value +# +# The format is a Go Template with: +# - ".ServiceName", ".Domain" and ".Attributes" available +# - "getTag(name, tags, defaultValue)", "hasTag(name, tags)" and "getAttribute(name, tags, defaultValue)" functions are available +# - "getAttribute(...)" function uses prefixed tag names based on "prefix" value # # Optional # #frontEndRule = "Host:{{.ServiceName}}.{{Domain}}" -# Should use all Consul catalog tags for constraint filtering -# -# Optional -# -#allTagsConstraintFiltering = false - # Constraints # # Optional @@ -984,6 +1014,7 @@ # constraints = ["tag==api", "tag==he*ld"] # Matching with containers having this tag: "traefik.tags=api,helloworld" + ################################################################ # Etcd configuration backend ################################################################ @@ -1035,6 +1066,37 @@ # key = "/etc/ssl/etcd.key" # insecureskipverify = true + +################################################################ +# Eureka configuration backend +################################################################ + +# Enable Eureka configuration backend +# +# Optional +# +# [eureka] + +# Eureka server endpoint. +# endpoint := "http://my.eureka.server/eureka" +# +# Required +# +# endpoint = "http://my.eureka.server/eureka" + +# Override default configuration time between refresh +# +# Optional +# default 30s +# delay = "1m" + +# Override default configuration template. For advanced users :) +# +# Optional +# +# filename = "eureka.tmpl" + + ################################################################ # Zookeeper configuration backend ################################################################ @@ -1117,7 +1179,7 @@ # ECS Cluster Name # -# Deprecated - Please use Clusters +# DEPRECATED - Please use Clusters # # Cluster = "default" @@ -1135,6 +1197,13 @@ # # Watch = true +# Enable auto discover ECS clusters +# +# Optional +# Default: false +# +# AutoDiscoverClusters = false + # Polling interval (in seconds) # # Optional @@ -1173,6 +1242,7 @@ # # filename = "ecs.tmpl" + ################################################################ # Rancher configuration backend ################################################################ @@ -1263,6 +1333,7 @@ # Required # SecretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ################################################################ # DynamoDB configuration backend ################################################################ diff --git a/types/types.go b/types/types.go index 73854d280..c22b8044b 100644 --- a/types/types.go +++ b/types/types.go @@ -354,7 +354,7 @@ type Prometheus struct { // Datadog contains address and metrics pushing interval configuration type Datadog struct { - Address string `description:"DataDog's Dogstatsd address"` + Address string `description:"DataDog's address"` PushInterval string `description:"DataDog push interval"` }