mirror of
https://github.com/containous/traefik.git
synced 2025-09-09 17:44:30 +03:00
Compare commits
107 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
40cd6ada4f | ||
|
c843c182e4 | ||
|
c35a8bdb15 | ||
|
dd0701dd16 | ||
|
32500773b8 | ||
|
e7d3f4316f | ||
|
4b38d7368f | ||
|
dce6a86900 | ||
|
dc9c558c06 | ||
|
b8a466c571 | ||
|
bae28c5f57 | ||
|
911c439858 | ||
|
f81f85cea2 | ||
|
1325cc5cd0 | ||
|
951d61bfcd | ||
|
0937cba870 | ||
|
5597d7633d | ||
|
502c88ee3f | ||
|
5ef6297daa | ||
|
9e33e23b8b | ||
|
16d00ccffb | ||
|
f482e5e84a | ||
|
447c3567b4 | ||
|
3c5e6fe7f8 | ||
|
bf4a578bbb | ||
|
4cabea069d | ||
|
c53033a778 | ||
|
ea8642e2a1 | ||
|
73cea2d303 | ||
|
96a3468791 | ||
|
2065f4c003 | ||
|
9a931e4dc9 | ||
|
49ec62c757 | ||
|
a371f971fb | ||
|
5f9a84fc8b | ||
|
1305bf49a5 | ||
|
da0a16e122 | ||
|
fb10687168 | ||
|
f0d78471af | ||
|
a90b2a672e | ||
|
c74918321d | ||
|
8c5dc3b5cb | ||
|
afa05329d9 | ||
|
dbbff393e1 | ||
|
0dae829080 | ||
|
e62a00a3f5 | ||
|
ab4c93dd2f | ||
|
fb21e3bb5c | ||
|
3595292f7f | ||
|
47fb6e036a | ||
|
92886c46ea | ||
|
83fa3f4cc8 | ||
|
c24f75ce0b | ||
|
63929b0341 | ||
|
60d87f3c64 | ||
|
5d800ba5fe | ||
|
d4f0a9ff62 | ||
|
c4fa96c41e | ||
|
f54136b602 | ||
|
5dd1728bf8 | ||
|
da1c9f48b7 | ||
|
0ec0e37532 | ||
|
544dc2eaa5 | ||
|
f8ae972e70 | ||
|
3140a4e0cd | ||
|
31038e0e12 | ||
|
ec0075e0d0 | ||
|
7900d266b1 | ||
|
c21597c593 | ||
|
ea418aa7d8 | ||
|
eebbe64b36 | ||
|
64a65cadf3 | ||
|
a488430f23 | ||
|
b5db753e11 | ||
|
b0aa27db31 | ||
|
2112de6f15 | ||
|
84b125bdde | ||
|
520fcf82ae | ||
|
74d1d55051 | ||
|
3a8cb3f010 | ||
|
d38d11f02e | ||
|
af04e92cf2 | ||
|
05333b9579 | ||
|
49cdb67ddc | ||
|
b5198e63c4 | ||
|
699cf71652 | ||
|
015f24a901 | ||
|
4fccde84bd | ||
|
edb15a9346 | ||
|
714a4d4f2d | ||
|
3567ae88ad | ||
|
afcec56be4 | ||
|
326be29568 | ||
|
f2e53a3569 | ||
|
5e63ab619e | ||
|
050968cbac | ||
|
cd947ae822 | ||
|
86c099d629 | ||
|
498e8545b6 | ||
|
76f42a3013 | ||
|
6075f7e8fd | ||
|
29bd6faa18 | ||
|
3db47f0adc | ||
|
483e2c43cf | ||
|
449afea4fc | ||
|
de458b7357 | ||
|
7c039ca223 |
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -3,11 +3,11 @@ PLEASE READ THIS MESSAGE.
|
||||
|
||||
Documentation fixes or enhancements:
|
||||
- for Traefik v1: use branch v1.7
|
||||
- for Traefik v2: use branch v2.3
|
||||
- for Traefik v2: use branch v2.4
|
||||
|
||||
Bug fixes:
|
||||
- for Traefik v1: use branch v1.7
|
||||
- for Traefik v2: use branch v2.3
|
||||
- for Traefik v2: use branch v2.4
|
||||
|
||||
Enhancements:
|
||||
- for Traefik v1: we only accept bug fixes
|
||||
|
52
.github/workflows/documentation.yml
vendored
Normal file
52
.github/workflows/documentation.yml
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
name: Build and Publish Documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- v*
|
||||
|
||||
jobs:
|
||||
|
||||
docs:
|
||||
name: Doc Process
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'traefik/traefik'
|
||||
env:
|
||||
STRUCTOR_VERSION: v1.11.2
|
||||
MIXTUS_VERSION: v0.4.1
|
||||
|
||||
steps:
|
||||
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Install Structor ${{ env.STRUCTOR_VERSION }}
|
||||
run: curl -sSfL https://raw.githubusercontent.com/traefik/structor/master/godownloader.sh | sh -s -- -b $HOME/bin ${STRUCTOR_VERSION}
|
||||
|
||||
- name: Install Seo-doc
|
||||
run: curl -sSfL https://raw.githubusercontent.com/traefik/seo-doc/master/godownloader.sh | sh -s -- -b "${HOME}/bin"
|
||||
|
||||
- name: Install Mixtus ${{ env.MIXTUS_VERSION }}
|
||||
run: curl -sSfL https://raw.githubusercontent.com/traefik/mixtus/master/godownloader.sh | sh -s -- -b $HOME/bin ${MIXTUS_VERSION}
|
||||
|
||||
- name: Build documentation
|
||||
run: $HOME/bin/structor -o traefik -r traefik --dockerfile-url="https://raw.githubusercontent.com/traefik/traefik/v1.7/docs.Dockerfile" --menu.js-url="https://raw.githubusercontent.com/traefik/structor/master/traefik-menu.js.gotmpl" --rqts-url="https://raw.githubusercontent.com/traefik/structor/master/requirements-override.txt" --force-edit-url --exp-branch=master --debug
|
||||
env:
|
||||
STRUCTOR_LATEST_TAG: ${{ secrets.STRUCTOR_LATEST_TAG }}
|
||||
|
||||
- name: Apply seo
|
||||
run: $HOME/bin/seo -path=./site
|
||||
|
||||
- name: Publish documentation
|
||||
run: $HOME/bin/mixtus --dst-doc-path="./traefik" --dst-owner=traefik --dst-repo-name=doc --git-user-email="30906710+traefiker@users.noreply.github.com" --git-user-name=traefiker --src-doc-path="./site" --src-owner=containous --src-repo-name=traefik
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN_REPO }}
|
@@ -57,7 +57,11 @@
|
||||
"nlreturn", # Not relevant
|
||||
"wrapcheck", # Too strict
|
||||
"tparallel", # Not relevant
|
||||
"paralleltest", # Not relevant
|
||||
"exhaustivestruct", # Not relevant
|
||||
"makezero", # not relevant
|
||||
"forbidigo", # not relevant
|
||||
"ifshort", # not relevant
|
||||
]
|
||||
|
||||
[issues]
|
||||
@@ -116,4 +120,4 @@
|
||||
text = "printf-like formatting function 'SetErrorWithEvent' should be named 'SetErrorWithEventf'"
|
||||
[[issues.exclude-rules]]
|
||||
path = "pkg/log/deprecated.go"
|
||||
linters = ["godot"]
|
||||
linters = ["godot"]
|
||||
|
@@ -38,6 +38,8 @@ builds:
|
||||
goarch: arm64
|
||||
- goos: freebsd
|
||||
goarch: arm64
|
||||
- goos: darwin
|
||||
goarch: arm64
|
||||
|
||||
changelog:
|
||||
skip: true
|
||||
|
@@ -10,7 +10,7 @@ else
|
||||
export VERSION=''
|
||||
fi
|
||||
|
||||
export CODENAME=picodon
|
||||
export CODENAME=livarot
|
||||
|
||||
export N_MAKE_JOBS=2
|
||||
|
||||
|
13
.travis.yml
13
.travis.yml
@@ -11,7 +11,7 @@ env:
|
||||
global:
|
||||
- REPO=$TRAVIS_REPO_SLUG
|
||||
- VERSION=$TRAVIS_TAG
|
||||
- CODENAME=picodon
|
||||
- CODENAME=livarot
|
||||
- GO111MODULE=on
|
||||
|
||||
script:
|
||||
@@ -25,13 +25,11 @@ before_deploy:
|
||||
sudo -E apt-get -yq update;
|
||||
sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install docker-ce=${DOCKER_VERSION}*;
|
||||
docker version;
|
||||
echo "${DOCKERHUB_PASSWORD}" | docker login -u "${DOCKERHUB_USERNAME}" --password-stdin;
|
||||
make build-image;
|
||||
if [ "$TRAVIS_TAG" ]; then
|
||||
make release-packages;
|
||||
fi;
|
||||
curl -sfL https://raw.githubusercontent.com/traefik/structor/master/godownloader.sh | bash -s -- -b "${GOPATH}/bin" ${STRUCTOR_VERSION}
|
||||
curl -sSfL https://raw.githubusercontent.com/traefik/mixtus/master/godownloader.sh | sh -s -- -b "${GOPATH}/bin" ${MIXTUS_VERSION}
|
||||
structor -o traefik -r traefik --dockerfile-url="https://raw.githubusercontent.com/traefik/traefik/v1.7/docs.Dockerfile" --menu.js-url="https://raw.githubusercontent.com/traefik/structor/master/traefik-menu.js.gotmpl" --rqts-url="https://raw.githubusercontent.com/traefik/structor/master/requirements-override.txt" --force-edit-url --exp-branch=master --debug;
|
||||
fi
|
||||
|
||||
deploy:
|
||||
@@ -49,9 +47,4 @@ deploy:
|
||||
on:
|
||||
repo: traefik/traefik
|
||||
tags: true
|
||||
- provider: script
|
||||
script: mixtus --dst-doc-path="./traefik" --dst-owner=traefik --dst-repo-name=doc --git-user-email="30906710+traefiker@users.noreply.github.com" --git-user-name=traefiker --src-doc-path="./site" --src-owner=containous --src-repo-name=traefik
|
||||
skip_cleanup: true
|
||||
on:
|
||||
repo: traefik/traefik
|
||||
all_branches: true
|
||||
|
||||
|
210
CHANGELOG.md
210
CHANGELOG.md
@@ -1,3 +1,161 @@
|
||||
## [v2.4.6](https://github.com/traefik/traefik/tree/v2.4.6) (2021-03-01)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.4.5...v2.4.6)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[plugins]** Update Yaegi to v0.9.13 ([#7928](https://github.com/traefik/traefik/pull/7928) by [ldez](https://github.com/ldez))
|
||||
- **[provider]** Fix: wait for file and internal before applying configurations ([#7925](https://github.com/traefik/traefik/pull/7925) by [juliens](https://github.com/juliens))
|
||||
|
||||
**Documentation:**
|
||||
- **[file]** Fix reflink typo in file provider documentation ([#7913](https://github.com/traefik/traefik/pull/7913) by [vgerak](https://github.com/vgerak))
|
||||
- **[k8s/serviceapi]** Fix Kubernetes Gateway API documentation links ([#7914](https://github.com/traefik/traefik/pull/7914) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[service]** Fix typo in routing/services/index.md ([#7922](https://github.com/traefik/traefik/pull/7922) by [snikch](https://github.com/snikch))
|
||||
- Fixing doc for default value of checknewversion ([#7933](https://github.com/traefik/traefik/pull/7933) by [tomMoulard](https://github.com/tomMoulard))
|
||||
|
||||
## [v2.4.5](https://github.com/traefik/traefik/tree/v2.4.5) (2021-02-18)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.4.3...v2.4.5)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[webui]** Only allow iframes to be loaded from our domain ([#7904](https://github.com/traefik/traefik/pull/7904) by [SantoDE](https://github.com/SantoDE))
|
||||
|
||||
## [v2.4.4](https://github.com/traefik/traefik/tree/v2.4.4) (2021-02-18)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.4.3...v2.4.4)
|
||||
|
||||
Release canceled.
|
||||
|
||||
## [v2.4.3](https://github.com/traefik/traefik/tree/v2.4.3) (2021-02-15)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.4.2...v2.4.3)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[acme]** Fix TLS challenge timeout and validation error ([#7879](https://github.com/traefik/traefik/pull/7879) by [ldez](https://github.com/ldez))
|
||||
- **[consulcatalog]** Fixed typo in consul catalog tests ([#7865](https://github.com/traefik/traefik/pull/7865) by [apollo13](https://github.com/apollo13))
|
||||
- **[middleware]** Apply content type exclusion on response ([#7888](https://github.com/traefik/traefik/pull/7888) by [jbdoumenjou](https://github.com/jbdoumenjou))
|
||||
|
||||
**Documentation:**
|
||||
- **[middleware]** Add HEAD as available option for Method ([#7858](https://github.com/traefik/traefik/pull/7858) by [mlandauer](https://github.com/mlandauer))
|
||||
- **[middleware]** Middleware documentation fixes ([#7808](https://github.com/traefik/traefik/pull/7808) by [Ullaakut](https://github.com/Ullaakut))
|
||||
- **[provider]** Add missing doc about servers transport ([#7894](https://github.com/traefik/traefik/pull/7894) by [ldez](https://github.com/ldez))
|
||||
- **[provider]** Provider documentation fixes ([#7823](https://github.com/traefik/traefik/pull/7823) by [Ullaakut](https://github.com/Ullaakut))
|
||||
- Fix the static reference documentation for the internal redirection router ([#7860](https://github.com/traefik/traefik/pull/7860) by [jbdoumenjou](https://github.com/jbdoumenjou))
|
||||
|
||||
## [v2.4.2](https://github.com/traefik/traefik/tree/v2.4.2) (2021-02-02)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.4.1...v2.4.2)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[acme]** Fix the redirect entrypoint default priority ([#7851](https://github.com/traefik/traefik/pull/7851) by [jbdoumenjou](https://github.com/jbdoumenjou))
|
||||
- **[middleware]** Fix the infinite loop in forwarded header middleware. ([#7847](https://github.com/traefik/traefik/pull/7847) by [ldez](https://github.com/ldez))
|
||||
|
||||
**Documentation:**
|
||||
- Fix the static configuration generation for environment variables ([#7849](https://github.com/traefik/traefik/pull/7849) by [jbdoumenjou](https://github.com/jbdoumenjou))
|
||||
|
||||
## [v2.4.1](https://github.com/traefik/traefik/tree/v2.4.1) (2021-02-01)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.4.0...v2.4.1)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[acme,provider]** Fix HTTP challenge router unexpected delayed creation ([#7805](https://github.com/traefik/traefik/pull/7805) by [jspdown](https://github.com/jspdown))
|
||||
- **[acme]** Update go-acme/lego to v4.2.0 ([#7793](https://github.com/traefik/traefik/pull/7793) by [ldez](https://github.com/ldez))
|
||||
- **[api,plugins]** Fix plugin type on middleware endpoint response ([#7782](https://github.com/traefik/traefik/pull/7782) by [jspdown](https://github.com/jspdown))
|
||||
- **[authentication,middleware]** Forward Proxy-Authorization header to authentication server ([#7433](https://github.com/traefik/traefik/pull/7433) by [Scapal](https://github.com/Scapal))
|
||||
- **[k8s,k8s/ingress]** Add support for multiple ingress classes ([#7799](https://github.com/traefik/traefik/pull/7799) by [LandryBe](https://github.com/LandryBe))
|
||||
- **[middleware]** Improve forwarded header and recovery middlewares performances ([#7783](https://github.com/traefik/traefik/pull/7783) by [juliens](https://github.com/juliens))
|
||||
- **[pilot]** Reduce pressure of pilot services when errors occurs ([#7824](https://github.com/traefik/traefik/pull/7824) by [darkweaver87](https://github.com/darkweaver87))
|
||||
- **[provider]** Fix aggregator test comment ([#7840](https://github.com/traefik/traefik/pull/7840) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[provider]** Fix servers transport not found ([#7839](https://github.com/traefik/traefik/pull/7839) by [jspdown](https://github.com/jspdown))
|
||||
|
||||
**Documentation:**
|
||||
- **[consulcatalog]** Fix refresh interval option description in consulcatalog provider ([#7810](https://github.com/traefik/traefik/pull/7810) by [GabeL7r](https://github.com/GabeL7r))
|
||||
- **[docker]** Fix missing serverstransport documentation ([#7822](https://github.com/traefik/traefik/pull/7822) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[k8s]** Fix YAML syntax in providers docs ([#7787](https://github.com/traefik/traefik/pull/7787) by [4ops](https://github.com/4ops))
|
||||
- **[service]** Fix typo in server transports documentation ([#7797](https://github.com/traefik/traefik/pull/7797) by [obezuk](https://github.com/obezuk))
|
||||
|
||||
## [v2.4.0](https://github.com/traefik/traefik/tree/v2.4.0) (2021-01-19)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.3.0-rc1...v2.4.0)
|
||||
|
||||
**Enhancements:**
|
||||
- **[acme]** New HTTP and TLS challenges implementations ([#7458](https://github.com/traefik/traefik/pull/7458) by [ldez](https://github.com/ldez))
|
||||
- **[acme]** Add external account binding support ([#7599](https://github.com/traefik/traefik/pull/7599) by [ldez](https://github.com/ldez))
|
||||
- **[authentication,middleware]** Middlewares: add forwardAuth.authResponseHeadersRegex ([#7449](https://github.com/traefik/traefik/pull/7449) by [iamolegga](https://github.com/iamolegga))
|
||||
- **[authentication,middleware]** Filter ForwardAuth request headers ([#7226](https://github.com/traefik/traefik/pull/7226) by [nkonev](https://github.com/nkonev))
|
||||
- **[k8s,k8s/ingress]** Update more than one LoadBalancer IP ([#6951](https://github.com/traefik/traefik/pull/6951) by [iameli](https://github.com/iameli))
|
||||
- **[k8s,k8s/ingress]** Set kubernetes client User-Agent to something meaningful ([#7392](https://github.com/traefik/traefik/pull/7392) by [sylr](https://github.com/sylr))
|
||||
- **[k8s]** Add Kubernetes Gateway Provider ([#7416](https://github.com/traefik/traefik/pull/7416) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[k8s]** Bump k8s client to v0.19.2 ([#7402](https://github.com/traefik/traefik/pull/7402) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[kv]** Allows multi-level KV prefixes ([#6664](https://github.com/traefik/traefik/pull/6664) by [niki-timofe](https://github.com/niki-timofe))
|
||||
- **[logs,middleware,docker]** Support configuring a HTTP client timeout in the Docker provider ([#7094](https://github.com/traefik/traefik/pull/7094) by [sirlatrom](https://github.com/sirlatrom))
|
||||
- **[marathon]** Extend marathon port discovery to allow port names as identifier ([#7359](https://github.com/traefik/traefik/pull/7359) by [basert](https://github.com/basert))
|
||||
- **[metrics]** Re-add server up metrics ([#6461](https://github.com/traefik/traefik/pull/6461) by [coder-hugo](https://github.com/coder-hugo))
|
||||
- **[middleware]** Feature: Exponential Backoff in Retry Middleware ([#7460](https://github.com/traefik/traefik/pull/7460) by [danieladams456](https://github.com/danieladams456))
|
||||
- **[middleware]** Allow to use regular expressions for `AccessControlAllowOriginList` ([#6881](https://github.com/traefik/traefik/pull/6881) by [jodosha](https://github.com/jodosha))
|
||||
- **[pilot]** Enable stats collection when pilot is enabled ([#7483](https://github.com/traefik/traefik/pull/7483) by [mmatur](https://github.com/mmatur))
|
||||
- **[pilot]** Send anonymized dynamic configuration to Pilot ([#7615](https://github.com/traefik/traefik/pull/7615) by [jspdown](https://github.com/jspdown))
|
||||
- **[server]** Added support for tcp proxyProtocol v1&v2 to backend ([#7320](https://github.com/traefik/traefik/pull/7320) by [mschneider82](https://github.com/mschneider82))
|
||||
- **[service,tls]** Add ServersTransport on services ([#7203](https://github.com/traefik/traefik/pull/7203) by [juliens](https://github.com/juliens))
|
||||
- **[webui]** Display Proxy Protocol version for backend services in web dashboard ([#7602](https://github.com/traefik/traefik/pull/7602) by [95ulisse](https://github.com/95ulisse))
|
||||
- Improve setup readability ([#7604](https://github.com/traefik/traefik/pull/7604) by [juliens](https://github.com/juliens))
|
||||
|
||||
**Bug fixes:**
|
||||
- **[docker]** Fix default value of docker client timeout ([#7345](https://github.com/traefik/traefik/pull/7345) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[middleware,k8s/crd]** Add AccessControlAllowOriginListRegex field to deepcopy ([#7512](https://github.com/traefik/traefik/pull/7512) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
**Documentation:**
|
||||
- **[middleware]** Rephrase forwardauth.authRequestHeaders documentation ([#7701](https://github.com/traefik/traefik/pull/7701) by [Beanow](https://github.com/Beanow))
|
||||
- Update copyright year for 2021 ([#7754](https://github.com/traefik/traefik/pull/7754) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Prepare release v2.4.0-rc2 ([#7747](https://github.com/traefik/traefik/pull/7747) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[kv]** KV doc reference ([#7415](https://github.com/traefik/traefik/pull/7415) by [rtribotte](https://github.com/rtribotte))
|
||||
- Add jspdown to maintainers ([#7671](https://github.com/traefik/traefik/pull/7671) by [emilevauge](https://github.com/emilevauge))
|
||||
- Add kevinpollet to maintainers ([#7464](https://github.com/traefik/traefik/pull/7464) by [SantoDE](https://github.com/SantoDE))
|
||||
- Add security policies ([#7110](https://github.com/traefik/traefik/pull/7110) by [ldez](https://github.com/ldez))
|
||||
|
||||
**Misc:**
|
||||
- Merge current v2.3 branch into v2.4 ([#7765](https://github.com/traefik/traefik/pull/7765) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.3 branch into v2.4 ([#7760](https://github.com/traefik/traefik/pull/7760) by [rtribotte](https://github.com/rtribotte))
|
||||
- Merge current v2.3 branch into v2.4 ([#7744](https://github.com/traefik/traefik/pull/7744) by [rtribotte](https://github.com/rtribotte))
|
||||
- Merge current v2.3 branch into v2.4 ([#7742](https://github.com/traefik/traefik/pull/7742) by [rtribotte](https://github.com/rtribotte))
|
||||
- Merge current v2.3 branch into v2.4 ([#7727](https://github.com/traefik/traefik/pull/7727) by [mmatur](https://github.com/mmatur))
|
||||
- Merge current v2.3 branch into v2.4 ([#7703](https://github.com/traefik/traefik/pull/7703) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Merge current v2.3 branch into v2.4 ([#7689](https://github.com/traefik/traefik/pull/7689) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Merge current v2.3 branch into master ([#7677](https://github.com/traefik/traefik/pull/7677) by [rtribotte](https://github.com/rtribotte))
|
||||
- Merge current v2.3 branch into master ([#7670](https://github.com/traefik/traefik/pull/7670) by [rtribotte](https://github.com/rtribotte))
|
||||
- Merge current v2.3 branch into master ([#7653](https://github.com/traefik/traefik/pull/7653) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Merge current v2.3 branch into master ([#7574](https://github.com/traefik/traefik/pull/7574) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Merge current v2.3 branch into master ([#7529](https://github.com/traefik/traefik/pull/7529) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.3 branch into master ([#7472](https://github.com/traefik/traefik/pull/7472) by [jbdoumenjou](https://github.com/jbdoumenjou))
|
||||
- Merge current v2.3 branch into master ([#7453](https://github.com/traefik/traefik/pull/7453) by [jbdoumenjou](https://github.com/jbdoumenjou))
|
||||
- Merge current v2.3 branch into master ([#7405](https://github.com/traefik/traefik/pull/7405) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.3 branch into master ([#7401](https://github.com/traefik/traefik/pull/7401) by [rtribotte](https://github.com/rtribotte))
|
||||
- Merge current v2.3 branch into master ([#7346](https://github.com/traefik/traefik/pull/7346) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.3 branch into master ([#7335](https://github.com/traefik/traefik/pull/7335) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.3 branch into master ([#7299](https://github.com/traefik/traefik/pull/7299) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.3 branch into master ([#7263](https://github.com/traefik/traefik/pull/7263) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.3 branch into master ([#7215](https://github.com/traefik/traefik/pull/7215) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.3 branch into master ([#7122](https://github.com/traefik/traefik/pull/7122) by [ldez](https://github.com/ldez))
|
||||
|
||||
## [v2.4.0-rc2](https://github.com/traefik/traefik/tree/v2.4.0-rc2) (2021-01-12)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.4.0-rc1...v2.4.0-rc2)
|
||||
|
||||
**Documentation:**
|
||||
- **[middleware]** Rephrase forwardauth.authRequestHeaders documentation ([#7701](https://github.com/traefik/traefik/pull/7701) by [Beanow](https://github.com/Beanow))
|
||||
|
||||
**Misc:**
|
||||
- Merge current v2.3 branch into v2.4 ([#7744](https://github.com/traefik/traefik/pull/7744) by [rtribotte](https://github.com/rtribotte))
|
||||
- Merge current v2.3 branch into v2.4 ([#7742](https://github.com/traefik/traefik/pull/7742) by [rtribotte](https://github.com/rtribotte))
|
||||
- Merge current v2.3 branch into v2.4 ([#7727](https://github.com/traefik/traefik/pull/7727) by [mmatur](https://github.com/mmatur))
|
||||
- Merge current v2.3 branch into v2.4 ([#7703](https://github.com/traefik/traefik/pull/7703) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Merge current v2.3 branch into v2.4 ([#7689](https://github.com/traefik/traefik/pull/7689) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
## [v2.3.7](https://github.com/traefik/traefik/tree/v2.3.7) (2021-01-11)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.3.6...v2.3.7)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[k8s,k8s/ingress]** Fix wildcard hostname issue ([#7711](https://github.com/traefik/traefik/pull/7711) by [avdhoot](https://github.com/avdhoot))
|
||||
- **[k8s,k8s/ingress]** Compile kubernetes ingress annotation regex only once ([#7647](https://github.com/traefik/traefik/pull/7647) by [hensur](https://github.com/hensur))
|
||||
- **[middleware,webui]** webui: fix missing custom request and response header names ([#7706](https://github.com/traefik/traefik/pull/7706) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[middleware]** Fix log level on error pages middleware ([#7737](https://github.com/traefik/traefik/pull/7737) by [Nowheresly](https://github.com/Nowheresly))
|
||||
|
||||
**Documentation:**
|
||||
- **[docker]** docs: fix broken links to docker-compose documentation ([#7702](https://github.com/traefik/traefik/pull/7702) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[ecs]** Add ECS to supported providers list ([#7714](https://github.com/traefik/traefik/pull/7714) by [anilmaurya](https://github.com/anilmaurya))
|
||||
- Update copyright year for 2021 ([#7734](https://github.com/traefik/traefik/pull/7734) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
## [v2.3.6](https://github.com/traefik/traefik/tree/v2.3.6) (2020-12-17)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.3.5...v2.3.6)
|
||||
|
||||
@@ -10,6 +168,58 @@
|
||||
- **[logs]** Add configuration example for access log filePath ([#7655](https://github.com/traefik/traefik/pull/7655) by [wernerfred](https://github.com/wernerfred))
|
||||
- **[middleware]** Add missing quotes in errorpages k8s example yaml ([#7675](https://github.com/traefik/traefik/pull/7675) by [icelynjennings](https://github.com/icelynjennings))
|
||||
|
||||
## [v2.4.0-rc1](https://github.com/traefik/traefik/tree/v2.4.0-rc1) (2020-12-16)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.3.0-rc1...v2.4.0-rc1)
|
||||
|
||||
**Enhancements:**
|
||||
- **[acme]** New HTTP and TLS challenges implementations ([#7458](https://github.com/traefik/traefik/pull/7458) by [ldez](https://github.com/ldez))
|
||||
- **[acme]** Add external account binding support ([#7599](https://github.com/traefik/traefik/pull/7599) by [ldez](https://github.com/ldez))
|
||||
- **[authentication,middleware]** Middlewares: add forwardAuth.authResponseHeadersRegex ([#7449](https://github.com/traefik/traefik/pull/7449) by [iamolegga](https://github.com/iamolegga))
|
||||
- **[authentication,middleware]** Filter ForwardAuth request headers ([#7226](https://github.com/traefik/traefik/pull/7226) by [nkonev](https://github.com/nkonev))
|
||||
- **[k8s,k8s/ingress]** Update more than one LoadBalancer IP ([#6951](https://github.com/traefik/traefik/pull/6951) by [iameli](https://github.com/iameli))
|
||||
- **[k8s,k8s/ingress]** Set kubernetes client User-Agent to something meaningful ([#7392](https://github.com/traefik/traefik/pull/7392) by [sylr](https://github.com/sylr))
|
||||
- **[k8s]** Add Kubernetes Gateway Provider ([#7416](https://github.com/traefik/traefik/pull/7416) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[k8s]** Bump k8s client to v0.19.2 ([#7402](https://github.com/traefik/traefik/pull/7402) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[kv]** Allows multi-level KV prefixes ([#6664](https://github.com/traefik/traefik/pull/6664) by [niki-timofe](https://github.com/niki-timofe))
|
||||
- **[logs,middleware,docker]** Support configuring a HTTP client timeout in the Docker provider ([#7094](https://github.com/traefik/traefik/pull/7094) by [sirlatrom](https://github.com/sirlatrom))
|
||||
- **[marathon]** Extend marathon port discovery to allow port names as identifier ([#7359](https://github.com/traefik/traefik/pull/7359) by [basert](https://github.com/basert))
|
||||
- **[metrics]** Re-add server up metrics ([#6461](https://github.com/traefik/traefik/pull/6461) by [coder-hugo](https://github.com/coder-hugo))
|
||||
- **[middleware]** Feature: Exponential Backoff in Retry Middleware ([#7460](https://github.com/traefik/traefik/pull/7460) by [danieladams456](https://github.com/danieladams456))
|
||||
- **[middleware]** Allow to use regular expressions for `AccessControlAllowOriginList` ([#6881](https://github.com/traefik/traefik/pull/6881) by [jodosha](https://github.com/jodosha))
|
||||
- **[pilot]** Enable stats collection when pilot is enabled ([#7483](https://github.com/traefik/traefik/pull/7483) by [mmatur](https://github.com/mmatur))
|
||||
- **[pilot]** Send anonymized dynamic configuration to Pilot ([#7615](https://github.com/traefik/traefik/pull/7615) by [jspdown](https://github.com/jspdown))
|
||||
- **[server]** Added support for tcp proxyProtocol v1&v2 to backend ([#7320](https://github.com/traefik/traefik/pull/7320) by [mschneider82](https://github.com/mschneider82))
|
||||
- **[service,tls]** Add ServersTransport on services ([#7203](https://github.com/traefik/traefik/pull/7203) by [juliens](https://github.com/juliens))
|
||||
- **[webui]** Display Proxy Protocol version for backend services in web dashboard ([#7602](https://github.com/traefik/traefik/pull/7602) by [95ulisse](https://github.com/95ulisse))
|
||||
- Improve setup readability ([#7604](https://github.com/traefik/traefik/pull/7604) by [juliens](https://github.com/juliens))
|
||||
|
||||
**Bug fixes:**
|
||||
- **[docker]** Fix default value of docker client timeout ([#7345](https://github.com/traefik/traefik/pull/7345) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[middleware,k8s/crd]** Add AccessControlAllowOriginListRegex field to deepcopy ([#7512](https://github.com/traefik/traefik/pull/7512) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
**Documentation:**
|
||||
- **[kv]** KV doc reference ([#7415](https://github.com/traefik/traefik/pull/7415) by [rtribotte](https://github.com/rtribotte))
|
||||
- Add jspdown to maintainers ([#7671](https://github.com/traefik/traefik/pull/7671) by [emilevauge](https://github.com/emilevauge))
|
||||
- Add kevinpollet to maintainers ([#7464](https://github.com/traefik/traefik/pull/7464) by [SantoDE](https://github.com/SantoDE))
|
||||
- Add security policies ([#7110](https://github.com/traefik/traefik/pull/7110) by [ldez](https://github.com/ldez))
|
||||
|
||||
**Misc:**
|
||||
- Merge current v2.3 branch into master ([#7677](https://github.com/traefik/traefik/pull/7677) by [rtribotte](https://github.com/rtribotte))
|
||||
- Merge current v2.3 branch into master ([#7670](https://github.com/traefik/traefik/pull/7670) by [rtribotte](https://github.com/rtribotte))
|
||||
- Merge current v2.3 branch into master ([#7653](https://github.com/traefik/traefik/pull/7653) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Merge current v2.3 branch into master ([#7574](https://github.com/traefik/traefik/pull/7574) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Merge current v2.3 branch into master ([#7529](https://github.com/traefik/traefik/pull/7529) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.3 branch into master ([#7472](https://github.com/traefik/traefik/pull/7472) by [jbdoumenjou](https://github.com/jbdoumenjou))
|
||||
- Merge current v2.3 branch into master ([#7453](https://github.com/traefik/traefik/pull/7453) by [jbdoumenjou](https://github.com/jbdoumenjou))
|
||||
- Merge current v2.3 branch into master ([#7405](https://github.com/traefik/traefik/pull/7405) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.3 branch into master ([#7401](https://github.com/traefik/traefik/pull/7401) by [rtribotte](https://github.com/rtribotte))
|
||||
- Merge current v2.3 branch into master ([#7346](https://github.com/traefik/traefik/pull/7346) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.3 branch into master ([#7335](https://github.com/traefik/traefik/pull/7335) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.3 branch into master ([#7299](https://github.com/traefik/traefik/pull/7299) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.3 branch into master ([#7263](https://github.com/traefik/traefik/pull/7263) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.3 branch into master ([#7215](https://github.com/traefik/traefik/pull/7215) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.3 branch into master ([#7122](https://github.com/traefik/traefik/pull/7122) by [ldez](https://github.com/ldez))
|
||||
|
||||
## [v2.3.5](https://github.com/traefik/traefik/tree/v2.3.5) (2020-12-10)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.3.4...v2.3.5)
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016-2020 Containous SAS; 2020 Traefik Labs
|
||||
Copyright (c) 2016-2020 Containous SAS; 2020-2021 Traefik Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@@ -137,7 +137,7 @@ By participating in this project, you agree to abide by its terms.
|
||||
|
||||
## Release Cycle
|
||||
|
||||
- We release a new version (e.g. 1.1.0, 1.2.0, 1.3.0) every other month.
|
||||
- We usually release 3/4 new versions (e.g. 1.1.0, 1.2.0, 1.3.0) per year.
|
||||
- Release Candidates are available before the release (e.g. 1.1.0-rc1, 1.1.0-rc2, 1.1.0-rc3, 1.1.0-rc4, before 1.1.0).
|
||||
- Bug-fixes (e.g. 1.1.1, 1.1.2, 1.2.1, 1.2.3) are released as needed (no additional features are delivered in those versions, bug-fixes only).
|
||||
|
||||
|
29
SECURITY.md
Normal file
29
SECURITY.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Security Policy
|
||||
|
||||
We strongly advise you to register your Traefik instances to [Pilot](http://pilot.traefik.io) to be notified of security advisories that apply to your Traefik version.
|
||||
You can also join our security mailing list to be aware of the latest announcements from our security team.
|
||||
You can subscribe sending a mail to security+subscribe@traefik.io or on [the online viewer](https://groups.google.com/a/traefik.io/forum/#!forum/security).
|
||||
|
||||
Reported vulnerabilities can be found on [cve.mitre.org](https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=traefik).
|
||||
|
||||
## Supported Versions
|
||||
|
||||
- We usually release 3/4 new versions (e.g. 1.1.0, 1.2.0, 1.3.0) per year.
|
||||
- Release Candidates are available before the release (e.g. 1.1.0-rc1, 1.1.0-rc2, 1.1.0-rc3, 1.1.0-rc4, before 1.1.0).
|
||||
- Bug-fixes (e.g. 1.1.1, 1.1.2, 1.2.1, 1.2.3) are released as needed (no additional features are delivered in those versions, bug-fixes only).
|
||||
|
||||
Each version is supported until the next one is released (e.g. 1.1.x will be supported until 1.2.0 is out).
|
||||
|
||||
We use [Semantic Versioning](https://semver.org/).
|
||||
|
||||
| Version | Supported |
|
||||
| --------- | ------------------ |
|
||||
| `2.2.x` | :white_check_mark: |
|
||||
| `< 2.2.x` | :x: |
|
||||
| `1.7.x` | :white_check_mark: |
|
||||
| `< 1.7.x` | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
We want to keep Traefik safe for everyone.
|
||||
If you've discovered a security vulnerability in Traefik, we appreciate your help in disclosing it to us in a responsible manner, using [this form](https://security.traefik.io).
|
@@ -19,7 +19,7 @@ RUN mkdir -p /usr/local/bin \
|
||||
&& chmod +x /usr/local/bin/go-bindata
|
||||
|
||||
# Download golangci-lint binary to bin folder in $GOPATH
|
||||
RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.32.2
|
||||
RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.36.0
|
||||
|
||||
# Download misspell binary to bin folder in $GOPATH
|
||||
RUN curl -sfL https://raw.githubusercontent.com/client9/misspell/master/install-misspell.sh | bash -s -- -b $GOPATH/bin v0.3.4
|
||||
|
@@ -7,6 +7,15 @@ import (
|
||||
|
||||
const outputDir = "./plugins-storage/"
|
||||
|
||||
func createPluginBuilder(staticConfiguration *static.Configuration) (*plugins.Builder, error) {
|
||||
client, plgs, devPlugin, err := initPlugins(staticConfiguration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return plugins.NewBuilder(client, plgs, devPlugin)
|
||||
}
|
||||
|
||||
func initPlugins(staticCfg *static.Configuration) (*plugins.Client, map[string]plugins.Descriptor, *plugins.DevPlugin, error) {
|
||||
if !isPilotEnabled(staticCfg) || !hasPlugins(staticCfg) {
|
||||
return nil, map[string]plugins.Descriptor{}, nil, nil
|
||||
|
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
"github.com/coreos/go-systemd/daemon"
|
||||
assetfs "github.com/elazarl/go-bindata-assetfs"
|
||||
"github.com/go-acme/lego/v4/challenge"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/traefik/paerser/cli"
|
||||
"github.com/traefik/traefik/v2/autogen/genstatic"
|
||||
@@ -28,7 +29,6 @@ import (
|
||||
"github.com/traefik/traefik/v2/pkg/metrics"
|
||||
"github.com/traefik/traefik/v2/pkg/middlewares/accesslog"
|
||||
"github.com/traefik/traefik/v2/pkg/pilot"
|
||||
"github.com/traefik/traefik/v2/pkg/plugins"
|
||||
"github.com/traefik/traefik/v2/pkg/provider/acme"
|
||||
"github.com/traefik/traefik/v2/pkg/provider/aggregator"
|
||||
"github.com/traefik/traefik/v2/pkg/provider/traefik"
|
||||
@@ -173,15 +173,30 @@ func runCmd(staticConfiguration *static.Configuration) error {
|
||||
func setupServer(staticConfiguration *static.Configuration) (*server.Server, error) {
|
||||
providerAggregator := aggregator.NewProviderAggregator(*staticConfiguration.Providers)
|
||||
|
||||
ctx := context.Background()
|
||||
routinesPool := safe.NewPool(ctx)
|
||||
|
||||
// adds internal provider
|
||||
err := providerAggregator.AddProvider(traefik.New(*staticConfiguration))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tlsManager := traefiktls.NewManager()
|
||||
// ACME
|
||||
|
||||
acmeProviders := initACMEProvider(staticConfiguration, &providerAggregator, tlsManager)
|
||||
tlsManager := traefiktls.NewManager()
|
||||
httpChallengeProvider := acme.NewChallengeHTTP()
|
||||
|
||||
// we need to wait at least 2 times the ProvidersThrottleDuration to be sure to handle the challenge.
|
||||
tlsChallengeProvider := acme.NewChallengeTLSALPN(time.Duration(staticConfiguration.Providers.ProvidersThrottleDuration) * 2)
|
||||
err = providerAggregator.AddProvider(tlsChallengeProvider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
acmeProviders := initACMEProvider(staticConfiguration, &providerAggregator, tlsManager, httpChallengeProvider, tlsChallengeProvider)
|
||||
|
||||
// Entrypoints
|
||||
|
||||
serverEntryPointsTCP, err := server.NewTCPEntryPoints(staticConfiguration.EntryPoints)
|
||||
if err != nil {
|
||||
@@ -193,91 +208,99 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
routinesPool := safe.NewPool(ctx)
|
||||
|
||||
metricRegistries := registerMetricClients(staticConfiguration.Metrics)
|
||||
// Pilot
|
||||
|
||||
var aviator *pilot.Pilot
|
||||
var pilotRegistry *metrics.PilotRegistry
|
||||
if isPilotEnabled(staticConfiguration) {
|
||||
pilotRegistry := metrics.RegisterPilot()
|
||||
pilotRegistry = metrics.RegisterPilot()
|
||||
|
||||
aviator = pilot.New(staticConfiguration.Pilot.Token, pilotRegistry, routinesPool)
|
||||
|
||||
routinesPool.GoCtx(func(ctx context.Context) {
|
||||
aviator.Tick(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
// Plugins
|
||||
|
||||
pluginBuilder, err := createPluginBuilder(staticConfiguration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Metrics
|
||||
|
||||
metricRegistries := registerMetricClients(staticConfiguration.Metrics)
|
||||
if pilotRegistry != nil {
|
||||
metricRegistries = append(metricRegistries, pilotRegistry)
|
||||
}
|
||||
|
||||
metricsRegistry := metrics.NewMultiRegistry(metricRegistries)
|
||||
|
||||
// Service manager factory
|
||||
|
||||
roundTripperManager := service.NewRoundTripperManager()
|
||||
acmeHTTPHandler := getHTTPChallengeHandler(acmeProviders, httpChallengeProvider)
|
||||
managerFactory := service.NewManagerFactory(*staticConfiguration, routinesPool, metricsRegistry, roundTripperManager, acmeHTTPHandler)
|
||||
|
||||
// Router factory
|
||||
|
||||
accessLog := setupAccessLog(staticConfiguration.AccessLog)
|
||||
chainBuilder := middleware.NewChainBuilder(*staticConfiguration, metricsRegistry, accessLog)
|
||||
managerFactory := service.NewManagerFactory(*staticConfiguration, routinesPool, metricsRegistry)
|
||||
|
||||
client, plgs, devPlugin, err := initPlugins(staticConfiguration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pluginBuilder, err := plugins.NewBuilder(client, plgs, devPlugin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
routerFactory := server.NewRouterFactory(*staticConfiguration, managerFactory, tlsManager, chainBuilder, pluginBuilder)
|
||||
|
||||
var defaultEntryPoints []string
|
||||
for name, cfg := range staticConfiguration.EntryPoints {
|
||||
protocol, err := cfg.GetProtocol()
|
||||
if err != nil {
|
||||
// Should never happen because Traefik should not start if protocol is invalid.
|
||||
log.WithoutContext().Errorf("Invalid protocol: %v", err)
|
||||
}
|
||||
|
||||
if protocol != "udp" && name != static.DefaultInternalEntryPointName {
|
||||
defaultEntryPoints = append(defaultEntryPoints, name)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(defaultEntryPoints)
|
||||
// Watcher
|
||||
|
||||
watcher := server.NewConfigurationWatcher(
|
||||
routinesPool,
|
||||
providerAggregator,
|
||||
time.Duration(staticConfiguration.Providers.ProvidersThrottleDuration),
|
||||
defaultEntryPoints,
|
||||
getDefaultsEntrypoints(staticConfiguration),
|
||||
"internal",
|
||||
)
|
||||
|
||||
// TLS
|
||||
watcher.AddListener(func(conf dynamic.Configuration) {
|
||||
ctx := context.Background()
|
||||
tlsManager.UpdateConfigs(ctx, conf.TLS.Stores, conf.TLS.Options, conf.TLS.Certificates)
|
||||
})
|
||||
|
||||
// Metrics
|
||||
watcher.AddListener(func(_ dynamic.Configuration) {
|
||||
metricsRegistry.ConfigReloadsCounter().Add(1)
|
||||
metricsRegistry.LastConfigReloadSuccessGauge().Set(float64(time.Now().Unix()))
|
||||
})
|
||||
|
||||
watcher.AddListener(switchRouter(routerFactory, acmeProviders, serverEntryPointsTCP, serverEntryPointsUDP, aviator))
|
||||
|
||||
// Server Transports
|
||||
watcher.AddListener(func(conf dynamic.Configuration) {
|
||||
if metricsRegistry.IsEpEnabled() || metricsRegistry.IsSvcEnabled() {
|
||||
var eps []string
|
||||
for key := range serverEntryPointsTCP {
|
||||
eps = append(eps, key)
|
||||
}
|
||||
|
||||
metrics.OnConfigurationUpdate(conf, eps)
|
||||
}
|
||||
roundTripperManager.Update(conf.HTTP.ServersTransports)
|
||||
})
|
||||
|
||||
// Switch router
|
||||
watcher.AddListener(switchRouter(routerFactory, serverEntryPointsTCP, serverEntryPointsUDP, aviator))
|
||||
|
||||
// Metrics
|
||||
if metricsRegistry.IsEpEnabled() || metricsRegistry.IsSvcEnabled() {
|
||||
var eps []string
|
||||
for key := range serverEntryPointsTCP {
|
||||
eps = append(eps, key)
|
||||
}
|
||||
watcher.AddListener(func(conf dynamic.Configuration) {
|
||||
metrics.OnConfigurationUpdate(conf, eps)
|
||||
})
|
||||
}
|
||||
|
||||
// TLS challenge
|
||||
watcher.AddListener(tlsChallengeProvider.ListenConfiguration)
|
||||
|
||||
// ACME
|
||||
resolverNames := map[string]struct{}{}
|
||||
for _, p := range acmeProviders {
|
||||
resolverNames[p.ResolverName] = struct{}{}
|
||||
watcher.AddListener(p.ListenConfiguration)
|
||||
}
|
||||
|
||||
// Certificate resolver logs
|
||||
watcher.AddListener(func(config dynamic.Configuration) {
|
||||
for rtName, rt := range config.HTTP.Routers {
|
||||
if rt.TLS == nil || rt.TLS.CertResolver == "" {
|
||||
@@ -293,23 +316,43 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err
|
||||
return server.NewServer(routinesPool, serverEntryPointsTCP, serverEntryPointsUDP, watcher, chainBuilder, accessLog), nil
|
||||
}
|
||||
|
||||
func switchRouter(routerFactory *server.RouterFactory, acmeProviders []*acme.Provider, serverEntryPointsTCP server.TCPEntryPoints, serverEntryPointsUDP server.UDPEntryPoints, aviator *pilot.Pilot) func(conf dynamic.Configuration) {
|
||||
func getHTTPChallengeHandler(acmeProviders []*acme.Provider, httpChallengeProvider http.Handler) http.Handler {
|
||||
var acmeHTTPHandler http.Handler
|
||||
for _, p := range acmeProviders {
|
||||
if p != nil && p.HTTPChallenge != nil {
|
||||
acmeHTTPHandler = httpChallengeProvider
|
||||
break
|
||||
}
|
||||
}
|
||||
return acmeHTTPHandler
|
||||
}
|
||||
|
||||
func getDefaultsEntrypoints(staticConfiguration *static.Configuration) []string {
|
||||
var defaultEntryPoints []string
|
||||
for name, cfg := range staticConfiguration.EntryPoints {
|
||||
protocol, err := cfg.GetProtocol()
|
||||
if err != nil {
|
||||
// Should never happen because Traefik should not start if protocol is invalid.
|
||||
log.WithoutContext().Errorf("Invalid protocol: %v", err)
|
||||
}
|
||||
|
||||
if protocol != "udp" && name != static.DefaultInternalEntryPointName {
|
||||
defaultEntryPoints = append(defaultEntryPoints, name)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(defaultEntryPoints)
|
||||
return defaultEntryPoints
|
||||
}
|
||||
|
||||
func switchRouter(routerFactory *server.RouterFactory, serverEntryPointsTCP server.TCPEntryPoints, serverEntryPointsUDP server.UDPEntryPoints, aviator *pilot.Pilot) func(conf dynamic.Configuration) {
|
||||
return func(conf dynamic.Configuration) {
|
||||
rtConf := runtime.NewConfig(conf)
|
||||
|
||||
routers, udpRouters := routerFactory.CreateRouters(rtConf)
|
||||
|
||||
for entryPointName, rt := range routers {
|
||||
for _, p := range acmeProviders {
|
||||
if p != nil && p.HTTPChallenge != nil && p.HTTPChallenge.EntryPoint == entryPointName {
|
||||
rt.HTTPHandler(p.CreateHandler(rt.GetHTTPHandler()))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if aviator != nil {
|
||||
aviator.SetRuntimeConfiguration(rtConf)
|
||||
aviator.SetDynamicConfiguration(conf)
|
||||
}
|
||||
|
||||
serverEntryPointsTCP.Switch(routers)
|
||||
@@ -318,8 +361,7 @@ func switchRouter(routerFactory *server.RouterFactory, acmeProviders []*acme.Pro
|
||||
}
|
||||
|
||||
// initACMEProvider creates an acme provider from the ACME part of globalConfiguration.
|
||||
func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.ProviderAggregator, tlsManager *traefiktls.Manager) []*acme.Provider {
|
||||
challengeStore := acme.NewLocalChallengeStore()
|
||||
func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.ProviderAggregator, tlsManager *traefiktls.Manager, httpChallengeProvider, tlsChallengeProvider challenge.Provider) []*acme.Provider {
|
||||
localStores := map[string]*acme.LocalStore{}
|
||||
|
||||
var resolvers []*acme.Provider
|
||||
@@ -330,10 +372,11 @@ func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.Pr
|
||||
}
|
||||
|
||||
p := &acme.Provider{
|
||||
Configuration: resolver.ACME,
|
||||
Store: localStores[resolver.ACME.Storage],
|
||||
ChallengeStore: challengeStore,
|
||||
ResolverName: name,
|
||||
Configuration: resolver.ACME,
|
||||
Store: localStores[resolver.ACME.Storage],
|
||||
ResolverName: name,
|
||||
HTTPChallengeProvider: httpChallengeProvider,
|
||||
TLSChallengeProvider: tlsChallengeProvider,
|
||||
}
|
||||
|
||||
if err := providerAggregator.AddProvider(p); err != nil {
|
||||
@@ -343,15 +386,12 @@ func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.Pr
|
||||
|
||||
p.SetTLSManager(tlsManager)
|
||||
|
||||
if p.TLSChallenge != nil {
|
||||
tlsManager.TLSAlpnGetter = p.GetTLSALPNCertificate
|
||||
}
|
||||
|
||||
p.SetConfigListenerChan(make(chan dynamic.Configuration))
|
||||
|
||||
resolvers = append(resolvers, p)
|
||||
}
|
||||
}
|
||||
|
||||
return resolvers
|
||||
}
|
||||
|
||||
|
@@ -130,7 +130,7 @@
|
||||
"tableColumn": "",
|
||||
"targets": [
|
||||
{
|
||||
"expr": "count(kube_pod_status_ready{namespace=\"$namespace\",condition=\"true\",pod=~\"traefik.*\"})",
|
||||
"expr": "count(kube_pod_status_ready{condition=\"true\",pod=~\"traefik.*\"})",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"refId": "A"
|
||||
@@ -150,10 +150,7 @@
|
||||
"valueName": "current"
|
||||
},
|
||||
{
|
||||
"aliasColors": {
|
||||
"Latency over 1 min": "rgb(9, 116, 190)",
|
||||
"Latency over 5 min": "#bf1b00"
|
||||
},
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
@@ -183,22 +180,17 @@
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [
|
||||
{
|
||||
"alias": "Latency over 5 min",
|
||||
"yaxis": 1
|
||||
}
|
||||
],
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "histogram_quantile(0.$percentiles, sum(rate(traefik_entrypoint_request_duration_seconds_bucket{namespace=\"$namespace\", code=\"200\",method=\"GET\"}[5m])) by (le))",
|
||||
"expr": "histogram_quantile(0.$percentiles, sum(rate(traefik_entrypoint_request_duration_seconds_bucket{code=~\"2..\"}[5m])) by (le))",
|
||||
"format": "time_series",
|
||||
"hide": false,
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Latency over 1 min",
|
||||
"legendFormat": "Latency over 5 min",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
@@ -281,7 +273,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "histogram_quantile(0.$percentiles, rate(traefik_entrypoint_request_duration_seconds_bucket{namespace=\"$namespace\",code=\"200\",method=\"GET\"}[5m]))",
|
||||
"expr": "histogram_quantile(0.$percentiles, sum(rate(traefik_entrypoint_request_duration_seconds_bucket{code=~\"2..\"}[5m])) by (instance, le))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "{{ instance }}",
|
||||
@@ -343,7 +335,7 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": null,
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"fill": 7,
|
||||
"gridPos": {
|
||||
"h": 7,
|
||||
@@ -379,7 +371,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(traefik_entrypoint_open_connections{namespace=\"$namespace\"}) by (method)",
|
||||
"expr": "sum(traefik_entrypoint_open_connections) by (method)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "{{ method }}",
|
||||
@@ -431,7 +423,7 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": null,
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 7,
|
||||
@@ -465,7 +457,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(traefik_entrypoint_request_duration_seconds_bucket{namespace=\"$namespace\",le=\"0.1\",code=\"200\"}[5m])) by (job) / sum(rate(traefik_entrypoint_request_duration_seconds_count{namespace=\"$namespace\",code=\"200\"}[5m])) by (job)",
|
||||
"expr": "(sum(rate(traefik_entrypoint_request_duration_seconds_bucket{le=\"0.1\",code=\"200\"}[5m])) by (job) + sum(rate(traefik_entrypoint_request_duration_seconds_bucket{le=\"0.3\",code=\"200\"}[5m])) by (job)) / 2 / sum(rate(traefik_entrypoint_request_duration_seconds_count{code=\"200\"}[5m])) by (job)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Code 200",
|
||||
@@ -511,9 +503,97 @@
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": true,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 10,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 23
|
||||
},
|
||||
"id": 3,
|
||||
"legend": {
|
||||
"alignAsTable": true,
|
||||
"avg": true,
|
||||
"current": true,
|
||||
"max": true,
|
||||
"min": false,
|
||||
"rightSide": false,
|
||||
"show": true,
|
||||
"sort": "avg",
|
||||
"sortDesc": true,
|
||||
"total": false,
|
||||
"values": true
|
||||
},
|
||||
"lines": false,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(traefik_entrypoint_requests_total[1m])) by (entrypoint)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{ entrypoint }}",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Service total requests over 1min per entrypoint",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Frontends (entrypoints)",
|
||||
"title": "Entrypoints",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
@@ -522,7 +602,7 @@
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 16
|
||||
"y": 33
|
||||
},
|
||||
"id": 24,
|
||||
"panels": [
|
||||
@@ -531,13 +611,13 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": null,
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"fill": 7,
|
||||
"gridPos": {
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 17
|
||||
"y": 34
|
||||
},
|
||||
"id": 25,
|
||||
"legend": {
|
||||
@@ -567,7 +647,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(traefik_backend_open_connections{namespace=\"$namespace\"}) by (method)",
|
||||
"expr": "sum(traefik_service_open_connections) by (method)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "{{ method }}",
|
||||
@@ -619,13 +699,13 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": null,
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 17
|
||||
"y": 34
|
||||
},
|
||||
"id": 26,
|
||||
"legend": {
|
||||
@@ -653,7 +733,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(traefik_backend_request_duration_seconds_bucket{namespace=\"$namespace\",le=\"0.1\",code=\"200\"}[5m])) by (job) / sum(rate(traefik_backend_request_duration_seconds_count{namespace=\"$namespace\",code=\"200\"}[5m])) by (job)",
|
||||
"expr": "(sum(rate(traefik_service_request_duration_seconds_bucket{le=\"0.1\",code=\"200\"}[5m])) by (job) + sum(rate(traefik_service_request_duration_seconds_bucket{le=\"0.3\",code=\"200\"}[5m])) by (job)) / 2 / sum(rate(traefik_service_request_duration_seconds_count{code=\"200\"}[5m])) by (job)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Code 200",
|
||||
@@ -699,9 +779,97 @@
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": true,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 10,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 41
|
||||
},
|
||||
"id": 4,
|
||||
"legend": {
|
||||
"alignAsTable": true,
|
||||
"avg": true,
|
||||
"current": true,
|
||||
"max": true,
|
||||
"min": false,
|
||||
"rightSide": false,
|
||||
"show": true,
|
||||
"sort": "avg",
|
||||
"sortDesc": true,
|
||||
"total": false,
|
||||
"values": true
|
||||
},
|
||||
"lines": false,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(traefik_service_requests_total[1m])) by (service)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{ service }}",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Service total requests over 1min per service",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Backends",
|
||||
"title": "Services",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
@@ -710,7 +878,7 @@
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 17
|
||||
"y": 51
|
||||
},
|
||||
"id": 15,
|
||||
"panels": [
|
||||
@@ -725,7 +893,7 @@
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 18
|
||||
"y": 52
|
||||
},
|
||||
"id": 5,
|
||||
"legend": {
|
||||
@@ -755,7 +923,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(traefik_backend_requests_total{namespace=\"$namespace\",code=~\"2..\"}[5m])) by (method, code)",
|
||||
"expr": "sum(rate(traefik_service_requests_total{code=~\"2..\"}[5m])) by (method, code)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{method}} : {{code}}",
|
||||
@@ -813,7 +981,7 @@
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 18
|
||||
"y": 52
|
||||
},
|
||||
"id": 27,
|
||||
"legend": {
|
||||
@@ -841,7 +1009,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(traefik_backend_requests_total{namespace=\"$namespace\",code=~\"5..\"}[5m])) by (method, code)",
|
||||
"expr": "sum(rate(traefik_service_requests_total{code=~\"5..\"}[5m])) by (method, code)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{method}} : {{code}}",
|
||||
@@ -899,95 +1067,7 @@
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 27
|
||||
},
|
||||
"id": 3,
|
||||
"legend": {
|
||||
"alignAsTable": true,
|
||||
"avg": true,
|
||||
"current": true,
|
||||
"max": true,
|
||||
"min": false,
|
||||
"rightSide": true,
|
||||
"show": true,
|
||||
"sort": "avg",
|
||||
"sortDesc": true,
|
||||
"total": false,
|
||||
"values": true
|
||||
},
|
||||
"lines": false,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(traefik_backend_requests_total{namespace=\"$namespace\"}[1m])) by (backend)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{ backend }}",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Backend total requests over 1min per backend",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": true,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 27
|
||||
"y": 61
|
||||
},
|
||||
"id": 6,
|
||||
"legend": {
|
||||
@@ -1016,7 +1096,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(traefik_backend_requests_total{namespace=\"$namespace\",code!~\"2..|5..\"}[5m])) by (method, code)",
|
||||
"expr": "sum(rate(traefik_service_requests_total{code!~\"2..|5..\"}[5m])) by (method, code)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{ method }} : {{code}}",
|
||||
@@ -1026,7 +1106,7 @@
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Others status code over 5min",
|
||||
"title": "Others statuses code over 5min",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
@@ -1064,7 +1144,7 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "HTTP Codes stats",
|
||||
"title": "HTTP Codes stats",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
@@ -1073,7 +1153,7 @@
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 18
|
||||
"y": 70
|
||||
},
|
||||
"id": 35,
|
||||
"panels": [
|
||||
@@ -1082,13 +1162,13 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": null,
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 19
|
||||
"y": 71
|
||||
},
|
||||
"id": 31,
|
||||
"legend": {
|
||||
@@ -1116,21 +1196,21 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "max(container_memory_usage_bytes{namespace=\"$namespace\", container_name=\"traefik\"})",
|
||||
"expr": "sum(container_memory_usage_bytes{container=\"traefik\"})",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Max memory used",
|
||||
"legendFormat": "Memory used",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "avg(kube_pod_container_resource_requests_memory_bytes{namespace=\"$namespace\", container=\"traefik\"})",
|
||||
"expr": "sum(kube_pod_container_resource_requests_memory_bytes{container=\"traefik\"})",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Requested memory usage",
|
||||
"legendFormat": "Requested memory",
|
||||
"refId": "B"
|
||||
},
|
||||
{
|
||||
"expr": "avg(kube_pod_container_resource_limits_memory_bytes{namespace=\"$namespace\", container=\"traefik\"})",
|
||||
"expr": "sum(kube_pod_container_resource_limits_memory_bytes{container=\"traefik\"})",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Limit memory usage",
|
||||
@@ -1140,7 +1220,7 @@
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Traefik max memory usage",
|
||||
"title": "Traefik memory usage",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
@@ -1182,13 +1262,13 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": null,
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 19
|
||||
"y": 71
|
||||
},
|
||||
"id": 33,
|
||||
"legend": {
|
||||
@@ -1215,21 +1295,21 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "max(rate(container_cpu_usage_seconds_total{namespace=\"$namespace\", container_name=\"traefik\"}[1m]))",
|
||||
"expr": "sum(rate(container_cpu_usage_seconds_total{container=\"traefik\"}[2m]))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Max cpu used",
|
||||
"legendFormat": "Cpu used",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "avg(kube_pod_container_resource_requests_cpu_cores{namespace=\"$namespace\", container=\"traefik\"})",
|
||||
"expr": "sum(kube_pod_container_resource_requests_cpu_cores{container=\"traefik\"})",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Requested cpu usage",
|
||||
"legendFormat": "Requested cpu",
|
||||
"refId": "B"
|
||||
},
|
||||
{
|
||||
"expr": "avg(kube_pod_container_resource_limits_cpu_cores{namespace=\"$namespace\", container=\"traefik\"})",
|
||||
"expr": "sum(kube_pod_container_resource_limits_cpu_cores{container=\"traefik\"})",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Limit cpu usage",
|
||||
@@ -1239,7 +1319,7 @@
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Traefik max CPU usage",
|
||||
"title": "Traefik CPU usage",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
@@ -1277,7 +1357,7 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Pods ressources",
|
||||
"title": "Pods resources",
|
||||
"type": "row"
|
||||
}
|
||||
],
|
||||
@@ -1288,26 +1368,6 @@
|
||||
],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"allValue": null,
|
||||
"current": {},
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"label": null,
|
||||
"multi": false,
|
||||
"name": "namespace",
|
||||
"options": [],
|
||||
"query": "label_values(traefik_config_reloads_total, namespace)",
|
||||
"refresh": 1,
|
||||
"regex": "",
|
||||
"sort": 0,
|
||||
"tagValuesQuery": "",
|
||||
"tags": [],
|
||||
"tagsQuery": "",
|
||||
"type": "query",
|
||||
"useTags": false
|
||||
},
|
||||
{
|
||||
"allValue": null,
|
||||
"current": {
|
||||
@@ -1370,5 +1430,5 @@
|
||||
"timezone": "",
|
||||
"title": "Traefik",
|
||||
"uid": "traefik-kubernetes",
|
||||
"version": 1
|
||||
"version": 2
|
||||
}
|
||||
|
@@ -64,10 +64,7 @@
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
"aliasColors": {
|
||||
"Latency over 1 min": "rgb(9, 116, 190)",
|
||||
"Latency over 5 min": "#bf1b00"
|
||||
},
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
@@ -97,22 +94,17 @@
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [
|
||||
{
|
||||
"alias": "Latency over 5 min",
|
||||
"yaxis": 1
|
||||
}
|
||||
],
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "histogram_quantile(0.$percentiles, sum(rate(traefik_entrypoint_request_duration_seconds_bucket{code=\"200\",method=\"GET\"}[5m])) by (le))",
|
||||
"expr": "histogram_quantile(0.$percentiles, sum(rate(traefik_entrypoint_request_duration_seconds_bucket{code=~\"2..\"}[5m])) by (le))",
|
||||
"format": "time_series",
|
||||
"hide": false,
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Latency over 1 min",
|
||||
"legendFormat": "Latency over 5 min",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
@@ -195,7 +187,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "histogram_quantile(0.$percentiles, rate(traefik_entrypoint_request_duration_seconds_bucket{code=\"200\",method=\"GET\"}[5m]))",
|
||||
"expr": "histogram_quantile(0.$percentiles, sum(rate(traefik_entrypoint_request_duration_seconds_bucket{code=~\"2..\"}[5m])) by (instance, le))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "{{ instance }}",
|
||||
@@ -257,13 +249,13 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": null,
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"fill": 7,
|
||||
"gridPos": {
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 2
|
||||
"y": 16
|
||||
},
|
||||
"id": 19,
|
||||
"legend": {
|
||||
@@ -345,13 +337,13 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": null,
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 2
|
||||
"y": 16
|
||||
},
|
||||
"id": 22,
|
||||
"legend": {
|
||||
@@ -379,7 +371,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(traefik_entrypoint_request_duration_seconds_bucket{le=\"0.1\",code=\"200\"}[5m])) by (job) / sum(rate(traefik_entrypoint_request_duration_seconds_count{code=\"200\"}[5m])) by (job)",
|
||||
"expr": "(sum(rate(traefik_entrypoint_request_duration_seconds_bucket{le=\"0.1\",code=\"200\"}[5m])) by (job) + sum(rate(traefik_entrypoint_request_duration_seconds_bucket{le=\"0.3\",code=\"200\"}[5m])) by (job)) / 2 / sum(rate(traefik_entrypoint_request_duration_seconds_count{code=\"200\"}[5m])) by (job)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Code 200",
|
||||
@@ -425,9 +417,97 @@
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": true,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 10,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 23
|
||||
},
|
||||
"id": 3,
|
||||
"legend": {
|
||||
"alignAsTable": true,
|
||||
"avg": true,
|
||||
"current": true,
|
||||
"max": true,
|
||||
"min": false,
|
||||
"rightSide": false,
|
||||
"show": true,
|
||||
"sort": "avg",
|
||||
"sortDesc": true,
|
||||
"total": false,
|
||||
"values": true
|
||||
},
|
||||
"lines": false,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(traefik_entrypoint_requests_total[1m])) by (entrypoint)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{ entrypoint }}",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Service total requests over 1min per entrypoint",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Frontends (entrypoints)",
|
||||
"title": "Entrypoints",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
@@ -436,7 +516,7 @@
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 16
|
||||
"y": 33
|
||||
},
|
||||
"id": 24,
|
||||
"panels": [
|
||||
@@ -445,13 +525,13 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": null,
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"fill": 7,
|
||||
"gridPos": {
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 3
|
||||
"y": 34
|
||||
},
|
||||
"id": 25,
|
||||
"legend": {
|
||||
@@ -481,7 +561,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(traefik_backend_open_connections) by (method)",
|
||||
"expr": "sum(traefik_service_open_connections) by (method)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "{{ method }}",
|
||||
@@ -533,13 +613,13 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": null,
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 3
|
||||
"y": 34
|
||||
},
|
||||
"id": 26,
|
||||
"legend": {
|
||||
@@ -567,7 +647,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(traefik_backend_request_duration_seconds_bucket{le=\"0.1\",code=\"200\"}[5m])) by (job) / sum(rate(traefik_backend_request_duration_seconds_count{code=\"200\"}[5m])) by (job)",
|
||||
"expr": "(sum(rate(traefik_service_request_duration_seconds_bucket{le=\"0.1\",code=\"200\"}[5m])) by (job) + sum(rate(traefik_service_request_duration_seconds_bucket{le=\"0.3\",code=\"200\"}[5m])) by (job)) / 2 / sum(rate(traefik_service_request_duration_seconds_count{code=\"200\"}[5m])) by (job)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Code 200",
|
||||
@@ -613,9 +693,97 @@
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": true,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 10,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 41
|
||||
},
|
||||
"id": 4,
|
||||
"legend": {
|
||||
"alignAsTable": true,
|
||||
"avg": true,
|
||||
"current": true,
|
||||
"max": true,
|
||||
"min": false,
|
||||
"rightSide": false,
|
||||
"show": true,
|
||||
"sort": "avg",
|
||||
"sortDesc": true,
|
||||
"total": false,
|
||||
"values": true
|
||||
},
|
||||
"lines": false,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(traefik_service_requests_total[1m])) by (service)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{ service }}",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Service total requests over 1min per service",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Backends",
|
||||
"title": "Services",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
@@ -624,7 +792,7 @@
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 17
|
||||
"y": 51
|
||||
},
|
||||
"id": 15,
|
||||
"panels": [
|
||||
@@ -639,7 +807,7 @@
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 4
|
||||
"y": 52
|
||||
},
|
||||
"id": 5,
|
||||
"legend": {
|
||||
@@ -669,7 +837,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(traefik_backend_requests_total{code=~\"2..\"}[5m])) by (method, code)",
|
||||
"expr": "sum(rate(traefik_service_requests_total{code=~\"2..\"}[5m])) by (method, code)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{method}} : {{code}}",
|
||||
@@ -727,7 +895,7 @@
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 4
|
||||
"y": 52
|
||||
},
|
||||
"id": 27,
|
||||
"legend": {
|
||||
@@ -755,7 +923,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(traefik_backend_requests_total{code=~\"5..\"}[5m])) by (method, code)",
|
||||
"expr": "sum(rate(traefik_service_requests_total{code=~\"5..\"}[5m])) by (method, code)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{method}} : {{code}}",
|
||||
@@ -813,95 +981,7 @@
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 13
|
||||
},
|
||||
"id": 3,
|
||||
"legend": {
|
||||
"alignAsTable": true,
|
||||
"avg": true,
|
||||
"current": true,
|
||||
"max": true,
|
||||
"min": false,
|
||||
"rightSide": true,
|
||||
"show": true,
|
||||
"sort": "avg",
|
||||
"sortDesc": true,
|
||||
"total": false,
|
||||
"values": true
|
||||
},
|
||||
"lines": false,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(traefik_backend_requests_total[1m])) by (backend)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{ backend }}",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Backend total requests over 1min per backend",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": true,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 13
|
||||
"y": 61
|
||||
},
|
||||
"id": 6,
|
||||
"legend": {
|
||||
@@ -930,7 +1010,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(traefik_backend_requests_total{code!~\"2..|5..\"}[5m])) by (method, code)",
|
||||
"expr": "sum(rate(traefik_service_requests_total{code!~\"2..|5..\"}[5m])) by (method, code)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{ method }} : {{code}}",
|
||||
@@ -940,7 +1020,7 @@
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Others status code over 5min",
|
||||
"title": "Others statuses code over 5min",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
@@ -978,7 +1058,7 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "HTTP Codes stats",
|
||||
"title": "HTTP Codes stats",
|
||||
"type": "row"
|
||||
}
|
||||
],
|
||||
@@ -1051,5 +1131,5 @@
|
||||
"timezone": "",
|
||||
"title": "Traefik",
|
||||
"uid": "traefik",
|
||||
"version": 1
|
||||
"version": 2
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
|
||||
FROM alpine:3.10 as alpine
|
||||
FROM alpine:3.13 as alpine
|
||||
|
||||
RUN apk --no-cache --no-progress add \
|
||||
libcurl \
|
||||
|
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
|
||||
Atom One Light by Daniel Gamage
|
||||
Original One Light Syntax theme from https://github.com/atom/one-light-syntax
|
||||
|
||||
base: #fafafa
|
||||
mono-1: #383a42
|
||||
mono-2: #686b77
|
||||
mono-3: #a0a1a7
|
||||
hue-1: #0184bb
|
||||
hue-2: #4078f2
|
||||
hue-3: #a626a4
|
||||
hue-4: #50a14f
|
||||
hue-5: #e45649
|
||||
hue-5-2: #c91243
|
||||
hue-6: #986801
|
||||
hue-6-2: #c18401
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #383a42;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #a0a1a7;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-doctag,
|
||||
.hljs-keyword,
|
||||
.hljs-formula {
|
||||
color: #a626a4;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name,
|
||||
.hljs-selector-tag,
|
||||
.hljs-deletion,
|
||||
.hljs-subst {
|
||||
color: #e45649;
|
||||
}
|
||||
|
||||
.hljs-literal {
|
||||
color: #0184bb;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-regexp,
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-meta-string {
|
||||
color: #50a14f;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-class .hljs-title {
|
||||
color: #c18401;
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-type,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-number {
|
||||
color: #986801;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-link,
|
||||
.hljs-meta,
|
||||
.hljs-selector-id,
|
||||
.hljs-title {
|
||||
color: #4078f2;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
@@ -1,70 +0,0 @@
|
||||
.md-container {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.md-content h1 {
|
||||
color: var(--dark) !important;
|
||||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
.md-content a {
|
||||
color: var(--blue) !important;
|
||||
}
|
||||
|
||||
.md-content a:hover {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
.md-typeset p code,
|
||||
.md-typeset .codehilite,
|
||||
.md-typeset .highlight {
|
||||
background-color: var(--light-blue) !important;
|
||||
}
|
||||
|
||||
.md-typeset table:not([class]) th {
|
||||
background: var(--dark) !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
/* Front page image size */
|
||||
img[src$='#small'] {
|
||||
width: 150px;
|
||||
}
|
||||
img[src$='#medium'] {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
/* Center table and objects */
|
||||
.center,
|
||||
img,
|
||||
.md-typeset__table {
|
||||
display: block !important;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.md-typeset table:not([class]) tr td:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
.md-typeset table:not([class]) th:not([align]),
|
||||
.md-typeset table:not([class]) td:not([align]) {
|
||||
text-align: center;
|
||||
}
|
||||
article p:not([class]),
|
||||
article ul:not([class]),
|
||||
article ol:not([class]) {
|
||||
padding-left: 0.8em !important;
|
||||
}
|
||||
|
||||
/* Fix for Chrome */
|
||||
.md-typeset__table td code {
|
||||
word-break: unset;
|
||||
}
|
||||
|
||||
.md-typeset__table tr :nth-child(1) {
|
||||
word-wrap: break-word;
|
||||
max-width: 30em;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: justify;
|
||||
}
|
@@ -1,10 +0,0 @@
|
||||
.md-footer-meta {
|
||||
background-color: var(--dark);
|
||||
}
|
||||
|
||||
.md-footer-privacy-policy {
|
||||
margin: 0 .6rem;
|
||||
padding: .4rem 0;
|
||||
color: hsla(0,0%,100%,.3);
|
||||
font-size: .64rem;
|
||||
}
|
@@ -1,484 +0,0 @@
|
||||
@import url('https://fonts.googleapis.com/css?family=Rubik:300i,400,400i,500,500i,700&display=swap');
|
||||
|
||||
.wrapper-1200 {
|
||||
width: 100%;
|
||||
max-width: 61rem;
|
||||
margin: 0 auto;
|
||||
padding: 0 .6rem;
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
.wrapper-1200 {
|
||||
padding: 0 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-type-1 {
|
||||
outline: none;
|
||||
border: none;
|
||||
background-color: #1e54d5;
|
||||
line-height: 1em;
|
||||
border-radius: 8px;
|
||||
padding: 12px 15px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
font-size: 1.25rem;
|
||||
background-image: linear-gradient(to top, rgba(0, 0, 0, 0.28) 1%, #1e54d5 99%);
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
color: white;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.button--secondary {
|
||||
outline: none;
|
||||
border: 2px solid #1e54d5 !important;
|
||||
background: transparent;
|
||||
line-height: 1em;
|
||||
border-radius: 8px;
|
||||
padding: 9px 13px;
|
||||
letter-spacing: 0;
|
||||
font-size: 1.3rem;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
color: #1e54d5;
|
||||
transition: all 0.2s;
|
||||
display: inline-block;
|
||||
}
|
||||
.button--secondary:hover {
|
||||
color: white !important;
|
||||
background: #1e54d5;
|
||||
}
|
||||
.button--secondary:focus {
|
||||
color: white !important;
|
||||
background: #1e54d5;
|
||||
}
|
||||
|
||||
.site-header-and-placeholder-wrapper {
|
||||
position: relative;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.site-header {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transition: height 0.1s;
|
||||
z-index: 100;
|
||||
background: white;
|
||||
box-shadow: 0 0 7px 0 #00000021;
|
||||
border-bottom: 1px solid #e2e2e2;
|
||||
height: 64px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 10px;
|
||||
font-family: 'Rubik', -apple-system, 'BlinkMacSystemFont', 'Segoe UI',
|
||||
'Helvetica Neue', sans-serif;
|
||||
color: #06102a;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.site-header.scrolled {
|
||||
box-shadow: 0 0 5px 0 #00000028;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
height: 52px;
|
||||
}
|
||||
.site-header.scrolled .site-header__title a {
|
||||
font-size: 2.2em;
|
||||
}
|
||||
|
||||
.header-placeholder {
|
||||
background: none;
|
||||
width: 100%;
|
||||
height: 64px;
|
||||
position: absolute;
|
||||
}
|
||||
.header-placeholder.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.site-header .wrapper-1200 {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.site-header .wrapper-1200 .left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.site-header__logo {
|
||||
max-width: 145px;
|
||||
}
|
||||
|
||||
.site-header__title a {
|
||||
color: #06102a;
|
||||
font-size: 2.2em;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
/* Navigation */
|
||||
.site-header__nav .menu-item-wrapper {
|
||||
display: inline-block;
|
||||
padding-left: 30px;
|
||||
}
|
||||
.site-header__nav .menu-item {
|
||||
color: #06102a;
|
||||
transition: all 0.05s;
|
||||
font-size: 1.45em;
|
||||
line-height: 1em;
|
||||
font-weight: 500;
|
||||
}
|
||||
.site-header__nav .menu-item:hover {
|
||||
color: #8a959e;
|
||||
}
|
||||
.site-header__nav .menu-item--with-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.site-header__nav .menu-item--with-icon .title {
|
||||
margin-right: 3px;
|
||||
}
|
||||
.site-header__nav .menu-item--with-icon .icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
transition: all 0.1s;
|
||||
}
|
||||
.site-header__nav .menu-item--with-icon .icon svg {
|
||||
stroke-width: 2.5 !important;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.site-header__nav .menu-item-wrapper--dropdown {
|
||||
position: relative;
|
||||
}
|
||||
.site-header__nav .menu-item-wrapper--dropdown:hover .nav-dropdown-menu {
|
||||
display: block;
|
||||
}
|
||||
.site-header__nav .nav-dropdown-menu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-dropdown-menu {
|
||||
position: absolute;
|
||||
z-index: 500;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.nav-dropdown-menu-wrapper {
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 12px 40px 0 rgba(1, 10, 32, 0.24);
|
||||
background: white;
|
||||
margin: 8px 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Products, Solutions dropdown menu */
|
||||
.nav-dropdown-menu--products,
|
||||
.nav-dropdown-menu--solutions {
|
||||
width: 500px;
|
||||
}
|
||||
.nav-dropdown-menu--products .nav-dropdown-menu-wrapper,
|
||||
.nav-dropdown-menu--solutions .nav-dropdown-menu-wrapper {
|
||||
padding: 20px;
|
||||
}
|
||||
.nav-dropdown-menu--products .nav-dropdown-menu-wrapper {
|
||||
height: 430px;
|
||||
}
|
||||
|
||||
.nav-dropdown-menu--products .dm-header,
|
||||
.nav-dropdown-menu--solutions .dm-header {
|
||||
font-size: 1.1em;
|
||||
font-weight: 500;
|
||||
font-stretch: normal;
|
||||
font-style: normal;
|
||||
line-height: normal;
|
||||
letter-spacing: 3.67px;
|
||||
color: #505769;
|
||||
margin-bottom: 20px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.nav-dropdown-menu--products .dm-item,
|
||||
.nav-dropdown-menu--solutions .dm-item {
|
||||
border: none;
|
||||
margin: 0 0 24px;
|
||||
color: #06102a;
|
||||
transition: all 0.1s;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
.nav-dropdown-menu--products .dm-item:last-child,
|
||||
.nav-dropdown-menu--solutions .dm-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.nav-dropdown-menu--products .dm-item .dmi-image {
|
||||
width: 104px;
|
||||
height: 72px;
|
||||
position: absolute;
|
||||
/*background: #f4f4f4;*/
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
border-radius: 4px;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.nav-dropdown-menu--solutions .dm-item .dmi-image {
|
||||
width: 65px;
|
||||
padding: 10px;
|
||||
background: white;
|
||||
height: auto;
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.nav-dropdown-menu--solutions .dm-item .dmi-image img {
|
||||
width: 100%;
|
||||
}
|
||||
.nav-dropdown-menu--products .dm-item .dmi-details,
|
||||
.nav-dropdown-menu--solutions .dm-item .dmi-details {
|
||||
padding: 6px 0 0 127px;
|
||||
width: 100%;
|
||||
background: transparent;
|
||||
display: block;
|
||||
color: #06102a;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.nav-dropdown-menu--products .dm-item .dmi-details:hover,
|
||||
.nav-dropdown-menu--solutions .dm-item .dmi-details:hover {
|
||||
color: #1e54d5;
|
||||
}
|
||||
.nav-dropdown-menu--products .dm-item .dmi-title,
|
||||
.nav-dropdown-menu--solutions .dm-item .dmi-title {
|
||||
font-size: 1.6em;
|
||||
font-weight: 500;
|
||||
margin: 0 0 2px;
|
||||
}
|
||||
.nav-dropdown-menu--products .dm-item .dmi-description,
|
||||
.nav-dropdown-menu--solutions .dm-item .dmi-description {
|
||||
font-size: 1.4em;
|
||||
opacity: 0.7;
|
||||
line-height: 1.6em;
|
||||
}
|
||||
.nav-dropdown-menu--products .dm-item--traefikee .dmi-image img,
|
||||
.nav-dropdown-menu--solutions .dm-item--traefikee .dmi-image img {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.nav-dropdown-menu--solutions .dm-item .dmi-details {
|
||||
padding: 5px 0 0 80px;
|
||||
}
|
||||
.nav-dropdown-menu--solutions .dm-item:last-child {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* Dropdown menu: Learn and Company */
|
||||
.nav-dropdown-menu--learn {
|
||||
width: 250px;
|
||||
}
|
||||
.nav-dropdown-menu--company {
|
||||
width: 500px;
|
||||
}
|
||||
.nav-dropdown-menu--company .nav-dropdown-menu-wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: 50% 50%;
|
||||
}
|
||||
.nav-dropdown-menu--learn .dm-left,
|
||||
.nav-dropdown-menu--company .dm-left {
|
||||
padding: 25px;
|
||||
}
|
||||
.nav-dropdown-menu--learn .dm-header,
|
||||
.nav-dropdown-menu--company .dm-header {
|
||||
font-size: 1.1em;
|
||||
font-weight: 500;
|
||||
font-stretch: normal;
|
||||
font-style: normal;
|
||||
line-height: normal;
|
||||
letter-spacing: 3.67px;
|
||||
color: #505769;
|
||||
margin-bottom: 20px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.nav-dropdown-menu--learn .dm-item,
|
||||
.nav-dropdown-menu--company .dm-item {
|
||||
display: block;
|
||||
font-size: 1.6em;
|
||||
font-weight: 500;
|
||||
color: #06102a;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.nav-dropdown-menu--learn .dm-item:last-child,
|
||||
.nav-dropdown-menu--company .dm-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.nav-dropdown-menu--learn .dm-item:hover,
|
||||
.nav-dropdown-menu--company .dm-item:hover {
|
||||
color: #1e54d5;
|
||||
}
|
||||
|
||||
.dm-preview {
|
||||
background: #edeff4;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.dm-preview__feature-image {
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dm-preview__feature-image img {
|
||||
width: 100%;
|
||||
height: 145px;
|
||||
background: #ffffff no-repeat 50%;
|
||||
object-fit: cover;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.dm-preview__content {
|
||||
padding: 15px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dm-preview__tag {
|
||||
display: block;
|
||||
font-size: 1.2em;
|
||||
color: #db7d11;
|
||||
letter-spacing: 2.5px;
|
||||
font-weight: 500;
|
||||
margin: 0 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.dm-preview__title {
|
||||
font-size: 1.6em;
|
||||
font-weight: 500;
|
||||
line-height: 1.6em;
|
||||
margin: 0;
|
||||
color: #06102a;
|
||||
display: block;
|
||||
flex: 1;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.dm-preview .arrow-link {
|
||||
justify-content: flex-start;
|
||||
font-size: 1.4em;
|
||||
position: absolute;
|
||||
bottom: 12px;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
/* Dropdown menu: Company */
|
||||
.nav-dropdown-menu--company {
|
||||
width: 450px;
|
||||
}
|
||||
|
||||
.nav-dropdown-menu--company .dm-right {
|
||||
background: #06102a;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
color: white;
|
||||
padding: 20px;
|
||||
}
|
||||
.nav-dropdown-menu--company .dm-right p {
|
||||
font-size: 1.6em;
|
||||
font-weight: 500;
|
||||
margin: 0 0 15px;
|
||||
text-align: center;
|
||||
}
|
||||
.nav-dropdown-menu--company .dm-right a {
|
||||
text-transform: uppercase;
|
||||
line-height: 1.5em;
|
||||
padding: 9px 12px;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
/* Demo */
|
||||
.site-header__demo-button .button--secondary {
|
||||
font-size: 1.4em;
|
||||
padding: 8px 12px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
/* Drawer */
|
||||
.site-header .drawer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (max-width: 1219px) {
|
||||
.site-header__nav .menu-item-wrapper {
|
||||
padding-left: 20px;
|
||||
}
|
||||
}
|
||||
@media (max-width: 980px) {
|
||||
.site-header__nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.site-header .drawer {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.site-header .right .site-header__demo-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
html [data-md-color-primary=indigo] .md-nav--primary .md-nav__title--site {
|
||||
background-color: #06102a;
|
||||
}
|
||||
|
||||
html .md-nav--primary .md-nav__title {
|
||||
padding: 64px .8rem .2rem;
|
||||
}
|
||||
|
||||
.md-search__inner {
|
||||
top: 64px;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.md-header .md-search {
|
||||
margin-right: 12.1rem;
|
||||
}
|
||||
|
||||
.site-header__main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dmi-image.proxy {
|
||||
background-color: #24a1c1;
|
||||
}
|
||||
|
||||
.dmi-image.mesh {
|
||||
background-color: #9d0fb0;
|
||||
}
|
||||
|
||||
.dmi-image.enterprise {
|
||||
background-color: #0060e0;
|
||||
}
|
||||
|
||||
.dmi-image.pilot {
|
||||
background-color: #db7d11;
|
||||
}
|
@@ -1,105 +0,0 @@
|
||||
.md-nav__link {
|
||||
margin-left: -0.4rem;
|
||||
padding: 0 0.4rem;
|
||||
line-height: 32px;
|
||||
color: var(--dark) !important;
|
||||
}
|
||||
|
||||
.md-nav__link::after {
|
||||
font-size: 16px;
|
||||
vertical-align: -.25em;
|
||||
}
|
||||
|
||||
.md-nav__toggle:checked + .md-nav__link,
|
||||
.md-nav__link--active,
|
||||
.md-nav__link:hover {
|
||||
border-radius: 8px;
|
||||
background-color: var(--light-blue) !important;
|
||||
color: var(--dark) !important;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
.md-nav__link--active {
|
||||
color: var(--blue) !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.md-sidebar--primary {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.md-sidebar--secondary .md-nav__title {
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 0.4rem;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.md-sidebar__scrollwrap {
|
||||
max-height: calc(100% - 50px);
|
||||
}
|
||||
|
||||
.md-sidebar--secondary .md-sidebar__scrollwrap {
|
||||
border-radius: 8px;
|
||||
background-color: var(--light-blue) !important;
|
||||
}
|
||||
|
||||
.md-sidebar--secondary .md-nav__title {
|
||||
padding: 0.8rem 0.4rem 0.8rem;
|
||||
}
|
||||
|
||||
.md-sidebar--secondary .md-nav__list {
|
||||
padding: 0 0.4rem 0.8rem 1.2rem;
|
||||
}
|
||||
|
||||
.md-sidebar--secondary .md-sidebar__scrollwrap .md-nav__link {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.md-sidebar--secondary
|
||||
.md-sidebar__scrollwrap
|
||||
.md-nav__link[data-md-state='blur'],
|
||||
.md-sidebar--secondary .md-sidebar__scrollwrap .md-nav__link:hover {
|
||||
color: var(--blue) !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.md-sidebar--secondary .md-nav__item {
|
||||
padding: 0 0 0 0.4rem;
|
||||
}
|
||||
|
||||
.md-sidebar--secondary .md-nav__link {
|
||||
margin-top: 0.225em;
|
||||
padding: 0.1rem 0.2rem;
|
||||
}
|
||||
|
||||
.md-sidebar--secondary li {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
.md-sidebar--secondary .repo_url {
|
||||
padding: 10px 0 14px 0;
|
||||
}
|
||||
|
||||
|
||||
.md-search__inner {
|
||||
width: inherit;
|
||||
float: inherit;
|
||||
}
|
||||
|
||||
.md-search__input {
|
||||
margin-bottom: 10px;
|
||||
border-radius: 4px;
|
||||
background-color: inherit;
|
||||
border: 1px solid rgba(0,0,0,.07);
|
||||
}
|
||||
|
||||
.md-search__input::placeholder {
|
||||
color: rgba(0,0,0,.07);
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 60em) {
|
||||
[data-md-toggle=search]:checked~.md-header .md-search__inner {
|
||||
margin-top: 100px;
|
||||
}
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
.product-switcher {
|
||||
font-size: 10px;
|
||||
font-family: 'Rubik', -apple-system, 'BlinkMacSystemFont', 'Segoe UI',
|
||||
'Helvetica Neue', sans-serif;
|
||||
color: #06102a;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.product-switcher .menu-item-wrapper {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.product-switcher img {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.product-switcher img.gopher {
|
||||
margin: 0 2px 0 16px;
|
||||
}
|
||||
|
||||
.product-switcher .nav-dropdown-menu--products .nav-dropdown-menu-wrapper {
|
||||
width: auto;
|
||||
height: 335px;
|
||||
}
|
@@ -1,10 +0,0 @@
|
||||
:root {
|
||||
--dark: #06102a;
|
||||
--blue: #04B5D1;
|
||||
--light-blue: #E4F7FA;
|
||||
|
||||
--input-bg-color: white;
|
||||
--input-color: black;
|
||||
--input-placeholder-color: #bbb;
|
||||
--input-border-color: #dcdcdc;
|
||||
}
|
@@ -31,6 +31,8 @@ For this very reason, the sendAnonymousUsage option is mandatory: we want you to
|
||||
|
||||
This feature comes from the public proposal [here](https://github.com/traefik/traefik/issues/2369).
|
||||
|
||||
This feature is activated when using Traefik Pilot to better understand the community's need, and also to get information about plug-ins popularity.
|
||||
|
||||
In order to help us learn more about how Traefik is being used and improve it, we collect anonymous usage statistics from running instances.
|
||||
Those data help us prioritize our developments and focus on what's important for our users (for example, which provider is popular, and which is not).
|
||||
|
||||
|
@@ -17,6 +17,8 @@
|
||||
* Jean-Baptiste Doumenjou [@jbdoumenjou](https://github.com/jbdoumenjou)
|
||||
* Mathieu Lonjaret [@mpl](https://github.com/mpl)
|
||||
* Romain Tribotté [@rtribotte](https://github.com/rtribotte)
|
||||
* Kevin Pollet [@kevinpollet](https://github.com/kevinpollet)
|
||||
* Harold Ozouf [@jspdown](https://github.com/jspdown)
|
||||
|
||||
## Issue Triage
|
||||
|
||||
|
@@ -11,12 +11,12 @@ You can install Traefik with the following flavors:
|
||||
|
||||
Choose one of the [official Docker images](https://hub.docker.com/_/traefik) and run it with one sample configuration file:
|
||||
|
||||
* [TOML](https://raw.githubusercontent.com/traefik/traefik/v2.3/traefik.sample.toml)
|
||||
* [YAML](https://raw.githubusercontent.com/traefik/traefik/v2.3/traefik.sample.yml)
|
||||
* [TOML](https://raw.githubusercontent.com/traefik/traefik/v2.4/traefik.sample.toml)
|
||||
* [YAML](https://raw.githubusercontent.com/traefik/traefik/v2.4/traefik.sample.yml)
|
||||
|
||||
```bash
|
||||
docker run -d -p 8080:8080 -p 80:80 \
|
||||
-v $PWD/traefik.toml:/etc/traefik/traefik.toml traefik:v2.3
|
||||
-v $PWD/traefik.toml:/etc/traefik/traefik.toml traefik:v2.4
|
||||
```
|
||||
|
||||
For more details, go to the [Docker provider documentation](../providers/docker.md)
|
||||
|
@@ -15,7 +15,7 @@ version: '3'
|
||||
services:
|
||||
reverse-proxy:
|
||||
# The official v2 Traefik docker image
|
||||
image: traefik:v2.3
|
||||
image: traefik:v2.4
|
||||
# Enables the web UI and tells Traefik to listen to docker
|
||||
command: --api.insecure=true --providers.docker
|
||||
ports:
|
||||
|
@@ -10,7 +10,7 @@ You can configure Traefik to use an ACME provider (like Let's Encrypt) for autom
|
||||
|
||||
Use Let's Encrypt staging server with the [`caServer`](#caserver) configuration option
|
||||
when experimenting to avoid hitting this limit too fast.
|
||||
|
||||
|
||||
## Certificate Resolvers
|
||||
|
||||
Traefik requires you to define "Certificate Resolvers" in the [static configuration](../getting-started/configuration-overview.md#the-static-configuration),
|
||||
@@ -324,10 +324,12 @@ For complete details, refer to your provider's _Additional configuration_ link.
|
||||
| [IIJ](https://www.iij.ad.jp/) | `iij` | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE` | [Additional configuration](https://go-acme.github.io/lego/dns/iij) |
|
||||
| [Infomaniak](https://www.infomaniak.com) | `infomaniak` | `INFOMANIAK_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/infomaniak) |
|
||||
| [INWX](https://www.inwx.de/en) | `inwx` | `INWX_USERNAME`, `INWX_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/inwx) |
|
||||
| [ionos](https://ionos.com/) | `ionos` | `IONOS_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ionos) |
|
||||
| [Joker.com](https://joker.com) | `joker` | `JOKER_API_MODE` with `JOKER_API_KEY` or `JOKER_USERNAME`, `JOKER_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/joker) |
|
||||
| [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/lightsail) |
|
||||
| [Linode v4](https://www.linode.com) | `linode` | `LINODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/linode) |
|
||||
| [Liquid Web](https://www.liquidweb.com/) | `liquidweb` | `LIQUID_WEB_PASSWORD`, `LIQUID_WEB_USERNAME`, `LIQUID_WEB_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/liquidweb) |
|
||||
| [Loopia](https://loopia.com/) | `loopia` | `LOOPIA_API_PASSWORD`, `LOOPIA_API_USER` | [Additional configuration](https://go-acme.github.io/lego/dns/loopia) |
|
||||
| [LuaDNS](https://luadns.com) | `luadns` | `LUADNS_API_USERNAME`, `LUADNS_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/luadns) |
|
||||
| manual | `manual` | none, but you need to run Traefik interactively [^4], turn on debug log to see instructions and press <kbd>Enter</kbd>. | |
|
||||
| [MyDNS.jp](https://www.mydns.jp/) | `mydnsjp` | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mydnsjp) |
|
||||
@@ -408,6 +410,35 @@ certificatesResolvers:
|
||||
[ACME V2](https://community.letsencrypt.org/t/acme-v2-and-wildcard-certificate-support-is-live/55579) supports wildcard certificates.
|
||||
As described in [Let's Encrypt's post](https://community.letsencrypt.org/t/staging-endpoint-for-acme-v2/49605) wildcard certificates can only be generated through a [`DNS-01` challenge](#dnschallenge).
|
||||
|
||||
## External Account Binding
|
||||
|
||||
- `kid`: Key identifier from External CA
|
||||
- `hmacEncoded`: HMAC key from External CA, should be in Base64 URL Encoding without padding format
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[certificatesResolvers.myresolver.acme]
|
||||
# ...
|
||||
[certificatesResolvers.myresolver.acme.eab]
|
||||
kid = "abc-keyID-xyz"
|
||||
hmacEncoded = "abc-hmac-xyz"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
certificatesResolvers:
|
||||
myresolver:
|
||||
acme:
|
||||
# ...
|
||||
eab:
|
||||
kid: abc-keyID-xyz
|
||||
hmacEncoded: abc-hmac-xyz
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
# ...
|
||||
--certificatesresolvers.myresolver.acme.eab.kid=abc-keyID-xyz
|
||||
--certificatesresolvers.myresolver.acme.eab.hmacencoded=abc-hmac-xyz
|
||||
```
|
||||
|
||||
## More Configuration
|
||||
|
||||
### `caServer`
|
||||
|
@@ -5,7 +5,7 @@ Prefixing the Path
|
||||
|
||||

|
||||
|
||||
The AddPrefix middleware updates the URL Path of the request before forwarding it.
|
||||
The AddPrefix middleware updates the path of a request before forwarding it.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
@@ -64,4 +64,4 @@ http:
|
||||
### `prefix`
|
||||
|
||||
`prefix` is the string to add before the current path in the requested URL.
|
||||
It should include the leading slash (`/`).
|
||||
It should include a leading slash (`/`).
|
||||
|
@@ -5,7 +5,7 @@ Adding Basic Authentication
|
||||
|
||||

|
||||
|
||||
The BasicAuth middleware is a quick way to restrict access to your services to known users.
|
||||
The BasicAuth middleware restricts access to your services to known users.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
@@ -81,7 +81,7 @@ Passwords must be hashed using MD5, SHA1, or BCrypt.
|
||||
|
||||
### `users`
|
||||
|
||||
The `users` option is an array of authorized users. Each user will be declared using the `name:hashed-password` format.
|
||||
The `users` option is an array of authorized users. Each user must be declared using the `name:hashed-password` format.
|
||||
|
||||
!!! note ""
|
||||
|
||||
|
@@ -5,22 +5,22 @@ How to Read the Request before Forwarding It
|
||||
|
||||

|
||||
|
||||
The Buffering middleware gives you control on how you want to read the requests before sending them to services.
|
||||
The Buffering middleware limits the size of requests that can be forwarded to services.
|
||||
|
||||
With Buffering, Traefik reads the entire request into memory (possibly buffering large requests into disk), and rejects requests that are over a specified limit.
|
||||
With Buffering, Traefik reads the entire request into memory (possibly buffering large requests into disk), and rejects requests that are over a specified size limit.
|
||||
|
||||
This can help services deal with large data (multipart/form-data for example), and can minimize time spent sending data to a service.
|
||||
This can help services avoid large amounts of data (`multipart/form-data` for example), and can minimize the time spent sending data to a service.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
```yaml tab="Docker"
|
||||
# Sets the maximum request body to 2Mb
|
||||
# Sets the maximum request body to 2MB
|
||||
labels:
|
||||
- "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
# Sets the maximum request body to 2Mb
|
||||
# Sets the maximum request body to 2MB
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
@@ -31,7 +31,7 @@ spec:
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Sets the maximum request body to 2Mb
|
||||
# Sets the maximum request body to 2MB
|
||||
- "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000"
|
||||
```
|
||||
|
||||
@@ -42,20 +42,20 @@ spec:
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
# Sets the maximum request body to 2Mb
|
||||
# Sets the maximum request body to 2MB
|
||||
labels:
|
||||
- "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
# Sets the maximum request body to 2Mb
|
||||
# Sets the maximum request body to 2MB
|
||||
[http.middlewares]
|
||||
[http.middlewares.limit.buffering]
|
||||
maxRequestBodyBytes = 2000000
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
# Sets the maximum request body to 2Mb
|
||||
# Sets the maximum request body to 2MB
|
||||
http:
|
||||
middlewares:
|
||||
limit:
|
||||
@@ -67,9 +67,9 @@ http:
|
||||
|
||||
### `maxRequestBodyBytes`
|
||||
|
||||
With the `maxRequestBodyBytes` option, you can configure the maximum allowed body size for the request (in Bytes).
|
||||
The `maxRequestBodyBytes` option configures the maximum allowed body size for the request (in bytes).
|
||||
|
||||
If the request exceeds the allowed size, it is not forwarded to the service and the client gets a `413 (Request Entity Too Large)` response.
|
||||
If the request exceeds the allowed size, it is not forwarded to the service, and the client gets a `413 (Request Entity Too Large)` response.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
@@ -117,7 +117,7 @@ http:
|
||||
|
||||
### `memRequestBodyBytes`
|
||||
|
||||
You can configure a threshold (in Bytes) from which the request will be buffered on disk instead of in memory with the `memRequestBodyBytes` option.
|
||||
You can configure a threshold (in bytes) from which the request will be buffered on disk instead of in memory with the `memRequestBodyBytes` option.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
@@ -165,7 +165,7 @@ http:
|
||||
|
||||
### `maxResponseBodyBytes`
|
||||
|
||||
With the `maxResponseBodyBytes` option, you can configure the maximum allowed response size from the service (in Bytes).
|
||||
The `maxResponseBodyBytes` option configures the maximum allowed response size from the service (in bytes).
|
||||
|
||||
If the response exceeds the allowed size, it is not forwarded to the client. The client gets a `413 (Request Entity Too Large) response` instead.
|
||||
|
||||
@@ -215,7 +215,7 @@ http:
|
||||
|
||||
### `memResponseBodyBytes`
|
||||
|
||||
You can configure a threshold (in Bytes) from which the response will be buffered on disk instead of in memory with the `memResponseBodyBytes` option.
|
||||
You can configure a threshold (in bytes) from which the response will be buffered on disk instead of in memory with the `memResponseBodyBytes` option.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
@@ -263,9 +263,9 @@ http:
|
||||
|
||||
### `retryExpression`
|
||||
|
||||
You can have the Buffering middleware replay the request with the help of the `retryExpression` option.
|
||||
You can have the Buffering middleware replay the request using `retryExpression`.
|
||||
|
||||
??? example "Retries once in case of a network error"
|
||||
??? example "Retries once in the case of a network error"
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
@@ -315,4 +315,4 @@ The retry expression is defined as a logical combination of the functions below
|
||||
|
||||
- `Attempts()` number of attempts (the first one counts)
|
||||
- `ResponseCode()` response code of the service
|
||||
- `IsNetworkError()` - if the response code is related to networking error
|
||||
- `IsNetworkError()` whether the response code is related to networking error
|
||||
|
@@ -5,12 +5,12 @@ When One Isn't Enough
|
||||
|
||||

|
||||
|
||||
The Chain middleware enables you to define reusable combinations of other pieces of middleware.
|
||||
The Chain middleware enables you to define reusable combinations of other pieces of middleware.
|
||||
It makes reusing the same groups easier.
|
||||
|
||||
## Configuration Example
|
||||
|
||||
Example "A Chain for WhiteList, BasicAuth, and HTTPS"
|
||||
Below is an example of a Chain containing `WhiteList`, `BasicAuth`, and `RedirectScheme`.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
@@ -30,11 +30,9 @@ kind: IngressRoute
|
||||
metadata:
|
||||
name: test
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
entryPoints:
|
||||
- web
|
||||
|
||||
routes:
|
||||
- match: Host(`mydomain`)
|
||||
kind: Rule
|
||||
@@ -148,7 +146,7 @@ labels:
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
# ...
|
||||
# ...
|
||||
http:
|
||||
routers:
|
||||
router1:
|
||||
|
@@ -3,27 +3,24 @@
|
||||
Don't Waste Time Calling Unhealthy Services
|
||||
{: .subtitle }
|
||||
|
||||

|
||||

|
||||
|
||||
The circuit breaker protects your system from stacking requests to unhealthy services (resulting in cascading failures).
|
||||
The circuit breaker protects your system from stacking requests to unhealthy services, resulting in cascading failures.
|
||||
|
||||
When your system is healthy, the circuit is closed (normal operations).
|
||||
When your system becomes unhealthy, the circuit becomes open and the requests are no longer forwarded (but handled by a fallback mechanism).
|
||||
When your system becomes unhealthy, the circuit opens, and the requests are no longer forwarded, but instead are handled by a fallback mechanism.
|
||||
|
||||
To assess if your system is healthy, the circuit breaker constantly monitors the services.
|
||||
To assess if your system is healthy, the circuit breaker constantly monitors the services.
|
||||
|
||||
!!! note ""
|
||||
|
||||
- The CircuitBreaker only analyses what happens _after_ it is positioned in the middleware chain. What happens _before_ has no impact on its state.
|
||||
- The CircuitBreaker only affects the routers that use it. Routers that don't use the CircuitBreaker won't be affected by its state.
|
||||
The CircuitBreaker only analyzes what happens _after_ its position within the middleware chain. What happens _before_ has no impact on its state.
|
||||
|
||||
!!! important
|
||||
|
||||
Each router will eventually gets its own instance of a given circuit breaker.
|
||||
|
||||
If two different routers refer to the same circuit breaker definition, they will get one instance each.
|
||||
It means that one circuit breaker can be open while the other stays closed: their state is not shared.
|
||||
|
||||
Each router gets its own instance of a given circuit breaker.
|
||||
One circuit breaker instance can be open while the other remains closed: their state is not shared.
|
||||
|
||||
This is the expected behavior, we want you to be able to define what makes a service healthy without having to declare a circuit breaker for each route.
|
||||
|
||||
## Configuration Examples
|
||||
@@ -90,70 +87,71 @@ There are three possible states for your circuit breaker:
|
||||
|
||||
While the circuit is closed, the circuit breaker only collects metrics to analyze the behavior of the requests.
|
||||
|
||||
At specified intervals (`checkPeriod`), it will evaluate `expression` to decide if its state must change.
|
||||
At specified intervals (`checkPeriod`), the circuit breaker evaluates `expression` to decide if its state must change.
|
||||
|
||||
### Open
|
||||
|
||||
While open, the fallback mechanism takes over the normal service calls for a duration of `FallbackDuration`.
|
||||
After this duration, it will enter the recovering state.
|
||||
After this duration, it enters the recovering state.
|
||||
|
||||
### Recovering
|
||||
|
||||
While recovering, the circuit breaker will progressively send requests to your service again (in a linear way, for `RecoveryDuration`).
|
||||
If your service fails during recovery, the circuit breaker becomes open again.
|
||||
If the service operates normally during the whole recovering duration, then the circuit breaker returns to close.
|
||||
While recovering, the circuit breaker sends linearly increasing amounts of requests to your service (for `RecoveryDuration`).
|
||||
If your service fails during recovery, the circuit breaker opens again.
|
||||
If the service operates normally during the entire recovery duration, then the circuit breaker closes.
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### Configuring the Trigger
|
||||
|
||||
You can specify an `expression` that, once matched, will trigger the circuit breaker (and apply the fallback mechanism instead of calling your services).
|
||||
You can specify an `expression` that, once matched, opens the circuit breaker and applies the fallback mechanism instead of calling your services.
|
||||
|
||||
The `expression` can check three different metrics:
|
||||
The `expression` option can check three different metrics:
|
||||
|
||||
- The network error ratio (`NetworkErrorRatio`)
|
||||
- The status code ratio (`ResponseCodeRatio`)
|
||||
- The latency at quantile, in milliseconds (`LatencyAtQuantileMS`)
|
||||
- The latency at a quantile in milliseconds (`LatencyAtQuantileMS`)
|
||||
|
||||
#### `NetworkErrorRatio`
|
||||
|
||||
If you want the circuit breaker to trigger at a 30% ratio of network errors, the expression will be `NetworkErrorRatio() > 0.30`
|
||||
If you want the circuit breaker to open at a 30% ratio of network errors, the `expression` is `NetworkErrorRatio() > 0.30`
|
||||
|
||||
#### `ResponseCodeRatio`
|
||||
|
||||
You can trigger the circuit breaker based on the ratio of a given range of status codes.
|
||||
You can configure the circuit breaker to open based on the ratio of a given range of status codes.
|
||||
|
||||
The `ResponseCodeRatio` accepts four parameters, `from`, `to`, `dividedByFrom`, `dividedByTo`.
|
||||
|
||||
The operation that will be computed is sum(`to` -> `from`) / sum (`dividedByFrom` -> `dividedByTo`).
|
||||
|
||||
!!! note ""
|
||||
If sum (`dividedByFrom` -> `dividedByTo`) equals 0, then `ResponseCodeRatio` returns 0.
|
||||
|
||||
`from`is inclusive, `to` is exclusive.
|
||||
|
||||
For example, the expression `ResponseCodeRatio(500, 600, 0, 600) > 0.25` will trigger the circuit breaker if 25% of the requests returned a 5XX status (amongst the request that returned a status code from 0 to 5XX).
|
||||
If sum (`dividedByFrom` -> `dividedByTo`) equals 0, then `ResponseCodeRatio` returns 0.
|
||||
|
||||
`from`is inclusive, `to` is exclusive.
|
||||
|
||||
For example, the expression `ResponseCodeRatio(500, 600, 0, 600) > 0.25` will trigger the circuit breaker if 25% of the requests returned a 5XX status (amongst the request that returned a status code from 0 to 5XX).
|
||||
|
||||
#### `LatencyAtQuantileMS`
|
||||
|
||||
You can trigger the circuit breaker when a given proportion of your requests become too slow.
|
||||
You can configure the circuit breaker to open when a given proportion of your requests become too slow.
|
||||
|
||||
For example, the expression `LatencyAtQuantileMS(50.0) > 100` will trigger the circuit breaker when the median latency (quantile 50) reaches 100MS.
|
||||
For example, the expression `LatencyAtQuantileMS(50.0) > 100` opens the circuit breaker when the median latency (quantile 50) reaches 100ms.
|
||||
|
||||
!!! note ""
|
||||
|
||||
You must provide a float number (with the trailing .0) for the quantile value
|
||||
|
||||
#### Using multiple metrics
|
||||
You must provide a floating point number (with the trailing .0) for the quantile value
|
||||
|
||||
You can combine multiple metrics using operators in your expression.
|
||||
#### Using Multiple Metrics
|
||||
|
||||
You can combine multiple metrics using operators in your `expression`.
|
||||
|
||||
Supported operators are:
|
||||
|
||||
- AND (`&&`)
|
||||
- OR (`||`)
|
||||
|
||||
For example, `ResponseCodeRatio(500, 600, 0, 600) > 0.30 || NetworkErrorRatio() > 0.10` triggers the circuit breaker when 30% of the requests return a 5XX status code, or when the ratio of network errors reaches 10%.
|
||||
For example, `ResponseCodeRatio(500, 600, 0, 600) > 0.30 || NetworkErrorRatio() > 0.10` triggers the circuit breaker when 30% of the requests return a 5XX status code, or when the ratio of network errors reaches 10%.
|
||||
|
||||
#### Operators
|
||||
|
||||
@@ -168,8 +166,8 @@ Here is the list of supported operators:
|
||||
|
||||
### Fallback mechanism
|
||||
|
||||
The fallback mechanism returns a `HTTP 503 Service Unavailable` to the client (instead of calling the target service).
|
||||
This behavior cannot be configured.
|
||||
The fallback mechanism returns a `HTTP 503 Service Unavailable` to the client instead of calling the target service.
|
||||
This behavior cannot be configured.
|
||||
|
||||
### `CheckPeriod`
|
||||
|
||||
@@ -182,6 +180,6 @@ By default, `FallbackDuration` is 10 seconds. This value cannot be configured.
|
||||
|
||||
### `RecoveringDuration`
|
||||
|
||||
The duration of the recovering mode (recovering state).
|
||||
The duration of the recovering mode (recovering state).
|
||||
|
||||
By default, `RecoveringDuration` is 10 seconds. This value cannot be configured.
|
||||
By default, `RecoveringDuration` is 10 seconds. This value cannot be configured.
|
||||
|
@@ -1,11 +1,11 @@
|
||||
# Compress
|
||||
|
||||
Compressing the Response before Sending it to the Client
|
||||
Compress Responses before Sending them to the Client
|
||||
{: .subtitle }
|
||||
|
||||

|
||||
|
||||
The Compress middleware enables the gzip compression.
|
||||
The Compress middleware uses gzip compression.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
@@ -57,23 +57,23 @@ http:
|
||||
```
|
||||
|
||||
!!! info
|
||||
|
||||
Responses are compressed when:
|
||||
|
||||
|
||||
Responses are compressed when the following criteria are all met:
|
||||
|
||||
* The response body is larger than `1400` bytes.
|
||||
* The `Accept-Encoding` request header contains `gzip`.
|
||||
* The response is not already compressed, i.e. the `Content-Encoding` response header is not already set.
|
||||
|
||||
If Content-Type header is not defined, or empty, the compress middleware will automatically [detect](https://mimesniff.spec.whatwg.org/) a content type.
|
||||
It will also set accordingly the `Content-Type` header with the detected MIME type.
|
||||
|
||||
If the `Content-Type` header is not defined, or empty, the compress middleware will automatically [detect](https://mimesniff.spec.whatwg.org/) a content type.
|
||||
It will also set the `Content-Type` header according to the detected MIME type.
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### `excludedContentTypes`
|
||||
|
||||
`excludedContentTypes` specifies a list of content types to compare the `Content-Type` header of the incoming requests to before compressing.
|
||||
`excludedContentTypes` specifies a list of content types to compare the `Content-Type` header of the incoming requests and responses before compressing.
|
||||
|
||||
The requests with content types defined in `excludedContentTypes` are not compressed.
|
||||
The responses with content types defined in `excludedContentTypes` are not compressed.
|
||||
|
||||
Content types are compared in a case-insensitive, whitespace-ignored manner.
|
||||
|
||||
|
@@ -1,18 +1,19 @@
|
||||
|
||||
# ContentType
|
||||
|
||||
Handling ContentType auto-detection
|
||||
Handling Content-Type auto-detection
|
||||
{: .subtitle }
|
||||
|
||||
The Content-Type middleware - or rather its unique `autoDetect` option -
|
||||
The Content-Type middleware - or rather its `autoDetect` option -
|
||||
specifies whether to let the `Content-Type` header,
|
||||
if it has not been set by the backend,
|
||||
if it has not been defined by the backend,
|
||||
be automatically set to a value derived from the contents of the response.
|
||||
|
||||
As a proxy, the default behavior should be to leave the header alone,
|
||||
regardless of what the backend did with it.
|
||||
However, the historic default was to always auto-detect and set the header if it was nil,
|
||||
and it is going to be kept that way in order to support users currently relying on it.
|
||||
However, the historic default was to always auto-detect and set the header if it was not already defined,
|
||||
and altering this behavior would be a breaking change which would impact many users.
|
||||
|
||||
This middleware exists to enable the correct behavior until at least the default one can be changed in a future version.
|
||||
|
||||
!!! info
|
||||
@@ -21,7 +22,7 @@ This middleware exists to enable the correct behavior until at least the default
|
||||
is still to automatically set the `Content-Type` header.
|
||||
Therefore, given the default value of the `autoDetect` option (false),
|
||||
simply enabling this middleware for a router switches the router's behavior.
|
||||
|
||||
|
||||
The scope of the Content-Type middleware is the MIME type detection done by the core of Traefik (the server part).
|
||||
Therefore, it has no effect against any other `Content-Type` header modifications (e.g.: in another middleware such as compress).
|
||||
|
||||
|
@@ -1,11 +1,11 @@
|
||||
# DigestAuth
|
||||
|
||||
Adding Digest Authentication
|
||||
{: .subtitle }
|
||||
{: .subtitle }
|
||||
|
||||

|
||||
|
||||
The DigestAuth middleware is a quick way to restrict access to your services to known users.
|
||||
The DigestAuth middleware restricts access to your services to known users.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
@@ -66,8 +66,8 @@ http:
|
||||
|
||||
## Configuration Options
|
||||
|
||||
!!! tip
|
||||
|
||||
!!! tip
|
||||
|
||||
Use `htdigest` to generate passwords.
|
||||
|
||||
### `users`
|
||||
@@ -75,9 +75,9 @@ http:
|
||||
The `users` option is an array of authorized users. Each user will be declared using the `name:realm:encoded-password` format.
|
||||
|
||||
!!! note ""
|
||||
|
||||
|
||||
- If both `users` and `usersFile` are provided, the two are merged. The contents of `usersFile` have precedence over the values in `users`.
|
||||
- For security reasons, the field `users` doesn't exist for Kubernetes IngressRoute, and one should use the `secret` field instead.
|
||||
- For security reasons, the field `users` doesn't exist for Kubernetes IngressRoute, and one should use the `secret` field instead.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
@@ -146,7 +146,7 @@ The `usersFile` option is the path to an external file that contains the authori
|
||||
The file content is a list of `name:realm:encoded-password`.
|
||||
|
||||
!!! note ""
|
||||
|
||||
|
||||
- If both `users` and `usersFile` are provided, the two are merged. The contents of `usersFile` have precedence over the values in `users`.
|
||||
- Because it does not make much sense to refer to a file path on Kubernetes, the `usersFile` field doesn't exist for Kubernetes IngressRoute, and one should use the `secret` field instead.
|
||||
|
||||
@@ -215,7 +215,7 @@ http:
|
||||
|
||||
### `realm`
|
||||
|
||||
You can customize the realm for the authentication with the `realm` option. The default value is `traefik`.
|
||||
You can customize the realm for the authentication with the `realm` option. The default value is `traefik`.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
|
@@ -85,28 +85,30 @@ http:
|
||||
# ... definition of error-handler-service and my-service
|
||||
```
|
||||
|
||||
!!! note ""
|
||||
!!! note ""
|
||||
|
||||
In this example, the error page URL is based on the status code (`query=/{status}.html`).
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### `status`
|
||||
|
||||
The `status` that will trigger the error page.
|
||||
The `status` option defines which status or range of statuses should result in an error page.
|
||||
|
||||
The status code ranges are inclusive (`500-599` will trigger with every code between `500` and `599`, `500` and `599` included).
|
||||
|
||||
!!! note ""
|
||||
|
||||
You can define either a status code like `500` or ranges with a syntax like `500-599`.
|
||||
!!! note ""
|
||||
|
||||
You can define either a status code as a number (`500`) or ranges by separating two codes with a dash (`500-599`).
|
||||
|
||||
### `service`
|
||||
|
||||
The service that will serve the new requested error page.
|
||||
|
||||
!!! note ""
|
||||
In kubernetes, you need to reference a kubernetes service instead of a traefik service.
|
||||
!!! note ""
|
||||
|
||||
In Kubernetes, you need to reference a Kubernetes Service instead of a Traefik service.
|
||||
|
||||
### `query`
|
||||
|
||||
The URL for the error page (hosted by `service`). You can use `{status}` in the query, that will be replaced by the received status code.
|
||||
The URL for the error page (hosted by `service`). You can use the `{status}` variable in the `query` option in order to insert the status code in the URL.
|
||||
|
@@ -1,12 +1,12 @@
|
||||
# ForwardAuth
|
||||
|
||||
Using an External Service to Check for Credentials
|
||||
Using an External Service to Forward Authentication
|
||||
{: .subtitle }
|
||||
|
||||

|
||||
|
||||
The ForwardAuth middleware delegate the authentication to an external service.
|
||||
If the service response code is 2XX, access is granted and the original request is performed.
|
||||
The ForwardAuth middleware delegates authentication to an external service.
|
||||
If the service answers with a 2XX code, access is granted, and the original request is performed.
|
||||
Otherwise, the response from the authentication server is returned.
|
||||
|
||||
## Configuration Examples
|
||||
@@ -125,7 +125,7 @@ http:
|
||||
|
||||
### `trustForwardHeader`
|
||||
|
||||
Set the `trustForwardHeader` option to `true` to trust all the existing `X-Forwarded-*` headers.
|
||||
Set the `trustForwardHeader` option to `true` to trust all `X-Forwarded-*` headers.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
@@ -176,7 +176,8 @@ http:
|
||||
|
||||
### `authResponseHeaders`
|
||||
|
||||
The `authResponseHeaders` option is the list of the headers to copy from the authentication server to the request.
|
||||
The `authResponseHeaders` option is the list of headers to copy from the authentication server response and set on
|
||||
forwarded request, replacing any existing conflicting headers.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
@@ -229,6 +230,117 @@ http:
|
||||
- "X-Secret"
|
||||
```
|
||||
|
||||
### `authResponseHeadersRegex`
|
||||
|
||||
The `authResponseHeadersRegex` option is the regex to match headers to copy from the authentication server response and
|
||||
set on forwarded request, after stripping all headers that match the regex.
|
||||
It allows partial matching of the regular expression against the header key.
|
||||
The start of string (`^`) and end of string (`$`) anchors should be used to ensure a full match against the header key.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.authResponseHeadersRegex=^X-"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: test-auth
|
||||
spec:
|
||||
forwardAuth:
|
||||
address: https://example.com/auth
|
||||
authResponseHeadersRegex: ^X-
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.authResponseHeadersRegex=^X-"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.forwardauth.authResponseHeadersRegex": "^X-"
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.authResponseHeadersRegex=^X-"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-auth.forwardAuth]
|
||||
address = "https://example.com/auth"
|
||||
authResponseHeadersRegex = "^X-"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
http:
|
||||
middlewares:
|
||||
test-auth:
|
||||
forwardAuth:
|
||||
address: "https://example.com/auth"
|
||||
authResponseHeadersRegex: "^X-"
|
||||
```
|
||||
|
||||
### `authRequestHeaders`
|
||||
|
||||
The `authRequestHeaders` option is the list of the headers to copy from the request to the authentication server.
|
||||
It allows filtering headers that should not be passed to the authentication server.
|
||||
If not set or empty then all request headers are passed.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.authRequestHeaders=Accept,X-CustomHeader"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: test-auth
|
||||
spec:
|
||||
forwardAuth:
|
||||
address: https://example.com/auth
|
||||
authRequestHeaders:
|
||||
- "Accept"
|
||||
- "X-CustomHeader"
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.authRequestHeaders=Accept,X-CustomHeader"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.forwardauth.authRequestHeaders": "Accept,X-CustomHeader"
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.authRequestHeaders=Accept,X-CustomHeader"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-auth.forwardAuth]
|
||||
address = "https://example.com/auth"
|
||||
authRequestHeaders = "Accept,X-CustomHeader"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
http:
|
||||
middlewares:
|
||||
test-auth:
|
||||
forwardAuth:
|
||||
address: "https://example.com/auth"
|
||||
authRequestHeaders:
|
||||
- "Accept"
|
||||
- "X-CustomHeader"
|
||||
```
|
||||
|
||||
### `tls`
|
||||
|
||||
The `tls` option is the TLS configuration from Traefik to the authentication server.
|
||||
@@ -299,12 +411,15 @@ http:
|
||||
|
||||
#### `tls.caOptional`
|
||||
|
||||
Policy used for the secured connection with TLS Client Authentication to the authentication server.
|
||||
Requires `tls.ca` to be defined.
|
||||
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to the authentication server.
|
||||
|
||||
- `true`: VerifyClientCertIfGiven
|
||||
- `false`: RequireAndVerifyClientCert
|
||||
- if `tls.ca` is undefined NoClientCert
|
||||
!!! warning ""
|
||||
|
||||
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
|
||||
|
||||
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
|
||||
|
||||
When this option is set to `false`, a client certificate is requested during the handshake, and at least one valid certificate should be sent by the client.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
@@ -358,7 +473,7 @@ http:
|
||||
|
||||
#### `tls.cert`
|
||||
|
||||
Public certificate used for the secured connection to the authentication server.
|
||||
The public certificate used for the secure connection to the authentication server.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
@@ -428,11 +543,12 @@ http:
|
||||
```
|
||||
|
||||
!!! info
|
||||
For security reasons, the field doesn't exist for Kubernetes IngressRoute, and one should use the `secret` field instead.
|
||||
|
||||
For security reasons, the field does not exist for Kubernetes IngressRoute, and one should use the `secret` field instead.
|
||||
|
||||
#### `tls.key`
|
||||
|
||||
Private certificate used for the secure connection to the authentication server.
|
||||
The private certificate used for the secure connection to the authentication server.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
@@ -502,11 +618,12 @@ http:
|
||||
```
|
||||
|
||||
!!! info
|
||||
For security reasons, the field doesn't exist for Kubernetes IngressRoute, and one should use the `secret` field instead.
|
||||
|
||||
For security reasons, the field does not exist for Kubernetes IngressRoute, and one should use the `secret` field instead.
|
||||
|
||||
#### `tls.insecureSkipVerify`
|
||||
|
||||
If `insecureSkipVerify` is `true`, TLS for the connection to authentication server accepts any certificate presented by the server and any host name in that certificate.
|
||||
If `insecureSkipVerify` is `true`, the TLS connection to the authentication server accepts any certificate presented by the server regardless of the hostnames it covers.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
|
@@ -1,17 +1,17 @@
|
||||
# Headers
|
||||
# Headers
|
||||
|
||||
Adding Headers to the Request / Response
|
||||
Managing Request/Response headers
|
||||
{: .subtitle }
|
||||
|
||||

|
||||
|
||||
The Headers middleware can manage the requests/responses headers.
|
||||
The Headers middleware manages the headers of requests and responses.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
### Adding Headers to the Request and the Response
|
||||
|
||||
Add the `X-Script-Name` header to the proxied request and the `X-Custom-Response-Header` to the response
|
||||
The following example adds the `X-Script-Name` header to the proxied request and the `X-Custom-Response-Header` header to the response
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
@@ -72,8 +72,8 @@ http:
|
||||
|
||||
### Adding and Removing Headers
|
||||
|
||||
`X-Script-Name` header added to the proxied request, the `X-Custom-Request-Header` header removed from the request,
|
||||
and the `X-Custom-Response-Header` header removed from the response.
|
||||
In the following example, requests are proxied with an extra `X-Script-Name` header while their `X-Custom-Request-Header` header gets stripped,
|
||||
and responses are stripped of their `X-Custom-Response-Header` header.
|
||||
|
||||
Please note that it is not possible to remove headers through the use of labels (Docker, Rancher, Marathon, ...) for now.
|
||||
|
||||
@@ -135,8 +135,8 @@ http:
|
||||
|
||||
### Using Security Headers
|
||||
|
||||
Security related headers (HSTS headers, SSL redirection, Browser XSS filter, etc) can be added and configured in a manner similar to the custom headers above.
|
||||
This functionality allows for some easy security features to quickly be set.
|
||||
Security-related headers (HSTS headers, SSL redirection, Browser XSS filter, etc) can be managed similarly to custom headers as shown above.
|
||||
This functionality makes it possible to easily use security features by adding headers.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
@@ -173,14 +173,14 @@ labels:
|
||||
- "traefik.http.middlewares.testheader.headers.sslredirect=true"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares]
|
||||
[http.middlewares.testHeader.headers]
|
||||
frameDeny = true
|
||||
sslRedirect = true
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
```yaml tab="File (YAML)"
|
||||
http:
|
||||
middlewares:
|
||||
testHeader:
|
||||
@@ -244,7 +244,7 @@ labels:
|
||||
- "traefik.http.middlewares.testheader.headers.addvaryheader=true"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares]
|
||||
[http.middlewares.testHeader.headers]
|
||||
accessControlAllowMethods= ["GET", "OPTIONS", "PUT"]
|
||||
@@ -274,18 +274,20 @@ http:
|
||||
### General
|
||||
|
||||
!!! warning
|
||||
If the custom header name is the same as one header name of the request or response, it will be replaced.
|
||||
|
||||
Custom headers will overwrite existing headers if they have identical names.
|
||||
|
||||
!!! note ""
|
||||
The detailed documentation for the security headers can be found in [unrolled/secure](https://github.com/unrolled/secure#available-options).
|
||||
|
||||
The detailed documentation for security headers can be found in [unrolled/secure](https://github.com/unrolled/secure#available-options).
|
||||
|
||||
### `customRequestHeaders`
|
||||
|
||||
The `customRequestHeaders` option lists the Header names and values to apply to the request.
|
||||
The `customRequestHeaders` option lists the header names and values to apply to the request.
|
||||
|
||||
### `customResponseHeaders`
|
||||
|
||||
The `customResponseHeaders` option lists the Header names and values to apply to the response.
|
||||
The `customResponseHeaders` option lists the header names and values to apply to the response.
|
||||
|
||||
### `accessControlAllowCredentials`
|
||||
|
||||
@@ -303,18 +305,27 @@ The `accessControlAllowMethods` indicates which methods can be used during requ
|
||||
|
||||
The `accessControlAllowOriginList` indicates whether a resource can be shared by returning different values.
|
||||
|
||||
A wildcard origin `*` can also be configured, and will match all requests.
|
||||
If this value is set by a backend server, it will be overwritten by Traefik
|
||||
A wildcard origin `*` can also be configured, and matches all requests.
|
||||
If this value is set by a backend service, it will be overwritten by Traefik.
|
||||
|
||||
This value can contains a list of allowed origins.
|
||||
This value can contain a list of allowed origins.
|
||||
|
||||
More information including how to use the settings can be found on:
|
||||
More information including how to use the settings can be found at:
|
||||
|
||||
- [Mozilla.org](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin)
|
||||
- [w3](https://fetch.spec.whatwg.org/#http-access-control-allow-origin)
|
||||
- [IETF](https://tools.ietf.org/html/rfc6454#section-7.1)
|
||||
|
||||
Traefik no longer supports the null value, as it is [no longer recommended as a return value](https://w3c.github.io/webappsec-cors-for-developers/#avoid-returning-access-control-allow-origin-null).
|
||||
Traefik no longer supports the `null` value, as it is [no longer recommended as a return value](https://w3c.github.io/webappsec-cors-for-developers/#avoid-returning-access-control-allow-origin-null).
|
||||
|
||||
### `accessControlAllowOriginListRegex`
|
||||
|
||||
The `accessControlAllowOriginListRegex` option is the counterpart of the `accessControlAllowOriginList` option with regular expressions instead of origin values.
|
||||
It allows all origins that contain any match of a regular expression in the `accessControlAllowOriginList`.
|
||||
|
||||
!!! tip
|
||||
|
||||
Regular expressions can be tested using online tools such as [Go Playground](https://play.golang.org/p/mWU9p-wk2ru) or the [Regex101](https://regex101.com/r/58sIgx/2).
|
||||
|
||||
### `accessControlExposeHeaders`
|
||||
|
||||
@@ -322,66 +333,66 @@ The `accessControlExposeHeaders` indicates which headers are safe to expose to t
|
||||
|
||||
### `accessControlMaxAge`
|
||||
|
||||
The `accessControlMaxAge` indicates how long (in seconds) a preflight request can be cached.
|
||||
The `accessControlMaxAge` indicates how many seconds a preflight request can be cached for.
|
||||
|
||||
### `addVaryHeader`
|
||||
|
||||
The `addVaryHeader` is used in conjunction with `accessControlAllowOriginList` to determine whether the vary header should be added or modified to demonstrate that server responses can differ based on the value of the origin header.
|
||||
The `addVaryHeader` is used in conjunction with `accessControlAllowOriginList` to determine whether the `Vary` header should be added or modified to demonstrate that server responses can differ based on the value of the origin header.
|
||||
|
||||
### `allowedHosts`
|
||||
### `allowedHosts`
|
||||
|
||||
The `allowedHosts` option lists fully qualified domain names that are allowed.
|
||||
|
||||
### `hostsProxyHeaders`
|
||||
### `hostsProxyHeaders`
|
||||
|
||||
The `hostsProxyHeaders` option is a set of header keys that may hold a proxied hostname value for the request.
|
||||
|
||||
### `sslRedirect`
|
||||
### `sslRedirect`
|
||||
|
||||
The `sslRedirect` is set to true, then only allow https requests.
|
||||
The `sslRedirect` only allow HTTPS requests when set to `true`.
|
||||
|
||||
### `sslTemporaryRedirect`
|
||||
|
||||
Set the `sslTemporaryRedirect` to `true` to force an SSL redirection using a 302 (instead of a 301).
|
||||
|
||||
### `sslHost`
|
||||
Set `sslTemporaryRedirect` to `true` to force an SSL redirection using a 302 (instead of a 301).
|
||||
|
||||
The `sslHost` option is the host name that is used to redirect http requests to https.
|
||||
### `sslHost`
|
||||
|
||||
### `sslProxyHeaders`
|
||||
The `sslHost` option is the host name that is used to redirect HTTP requests to HTTPS.
|
||||
|
||||
The `sslProxyHeaders` option is set of header keys with associated values that would indicate a valid https request.
|
||||
Useful when using other proxies with header like: `"X-Forwarded-Proto": "https"`.
|
||||
### `sslProxyHeaders`
|
||||
|
||||
### `sslForceHost`
|
||||
The `sslProxyHeaders` option is set of header keys with associated values that would indicate a valid HTTPS request.
|
||||
It can be useful when using other proxies (example: `"X-Forwarded-Proto": "https"`).
|
||||
|
||||
Set `sslForceHost` to true and set SSLHost to forced requests to use `SSLHost` even the ones that are already using SSL.
|
||||
### `sslForceHost`
|
||||
|
||||
### `stsSeconds`
|
||||
Set `sslForceHost` to `true` and set `sslHost` to force requests to use `SSLHost` regardless of whether they already use SSL.
|
||||
|
||||
The `stsSeconds` is the max-age of the Strict-Transport-Security header.
|
||||
If set to 0, would NOT include the header.
|
||||
### `stsSeconds`
|
||||
|
||||
### `stsIncludeSubdomains`
|
||||
The `stsSeconds` is the max-age of the `Strict-Transport-Security` header.
|
||||
If set to `0`, the header is not set.
|
||||
|
||||
The `stsIncludeSubdomains` is set to true, the `includeSubDomains` directive will be appended to the Strict-Transport-Security header.
|
||||
### `stsIncludeSubdomains`
|
||||
|
||||
### `stsPreload`
|
||||
If the `stsIncludeSubdomains` is set to `true`, the `includeSubDomains` directive is appended to the `Strict-Transport-Security` header.
|
||||
|
||||
Set `stsPreload` to true to have the `preload` flag appended to the Strict-Transport-Security header.
|
||||
### `stsPreload`
|
||||
|
||||
Set `stsPreload` to `true` to have the `preload` flag appended to the `Strict-Transport-Security` header.
|
||||
|
||||
### `forceSTSHeader`
|
||||
|
||||
Set `forceSTSHeader` to true, to add the STS header even when the connection is HTTP.
|
||||
Set `forceSTSHeader` to `true` to add the STS header even when the connection is HTTP.
|
||||
|
||||
### `frameDeny`
|
||||
### `frameDeny`
|
||||
|
||||
Set `frameDeny` to true to add the `X-Frame-Options` header with the value of `DENY`.
|
||||
|
||||
### `customFrameOptionsValue`
|
||||
Set `frameDeny` to `true` to add the `X-Frame-Options` header with the value of `DENY`.
|
||||
|
||||
### `customFrameOptionsValue`
|
||||
|
||||
The `customFrameOptionsValue` allows the `X-Frame-Options` header value to be set with a custom value.
|
||||
This overrides the FrameDeny option.
|
||||
This overrides the `FrameDeny` option.
|
||||
|
||||
### `contentTypeNosniff`
|
||||
|
||||
@@ -394,7 +405,7 @@ Set `browserXssFilter` to true to add the `X-XSS-Protection` header with the val
|
||||
### `customBrowserXSSValue`
|
||||
|
||||
The `customBrowserXssValue` option allows the `X-XSS-Protection` header value to be set with a custom value.
|
||||
This overrides the BrowserXssFilter option.
|
||||
This overrides the `BrowserXssFilter` option.
|
||||
|
||||
### `contentSecurityPolicy`
|
||||
|
||||
@@ -402,11 +413,11 @@ The `contentSecurityPolicy` option allows the `Content-Security-Policy` header v
|
||||
|
||||
### `publicKey`
|
||||
|
||||
The `publicKey` implements HPKP to prevent MITM attacks with forged certificates.
|
||||
The `publicKey` implements HPKP to prevent MITM attacks with forged certificates.
|
||||
|
||||
### `referrerPolicy`
|
||||
|
||||
The `referrerPolicy` allows sites to control when browsers will pass the Referer header to other sites.
|
||||
The `referrerPolicy` allows sites to control whether browsers forward the `Referer` header to other sites.
|
||||
|
||||
### `featurePolicy`
|
||||
|
||||
@@ -414,7 +425,6 @@ The `featurePolicy` allows sites to control browser features.
|
||||
|
||||
### `isDevelopment`
|
||||
|
||||
Set `isDevelopment` to true when developing.
|
||||
The AllowedHosts, SSL, and STS options can cause some unwanted effects.
|
||||
Usually testing happens on http, not https, and on localhost, not your production domain.
|
||||
If you would like your development environment to mimic production with complete Host blocking, SSL redirects, and STS headers, leave this as false.
|
||||
Set `isDevelopment` to `true` when developing to mitigate the unwanted effects of the `AllowedHosts`, SSL, and STS options.
|
||||
Usually testing takes place using HTTP, not HTTPS, and on `localhost`, not your production domain.
|
||||
If you would like your development environment to mimic production with complete Host blocking, SSL redirects, and STS headers, leave this as `false`.
|
||||
|
@@ -5,7 +5,7 @@ Limiting the Number of Simultaneous In-Flight Requests
|
||||
|
||||

|
||||
|
||||
To proactively prevent services from being overwhelmed with high load, a limit on the number of simultaneous in-flight requests can be applied.
|
||||
To proactively prevent services from being overwhelmed with high load, the number of allowed simultaneous in-flight requests can be limited.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
@@ -45,7 +45,7 @@ labels:
|
||||
# Limiting to 10 simultaneous connections
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-inflightreq.inFlightReq]
|
||||
amount = 10
|
||||
amount = 10
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
@@ -54,7 +54,7 @@ http:
|
||||
middlewares:
|
||||
test-inflightreq:
|
||||
inFlightReq:
|
||||
amount: 10
|
||||
amount: 10
|
||||
```
|
||||
|
||||
## Configuration Options
|
||||
@@ -62,7 +62,7 @@ http:
|
||||
### `amount`
|
||||
|
||||
The `amount` option defines the maximum amount of allowed simultaneous in-flight request.
|
||||
The middleware will return an `HTTP 429 Too Many Requests` if there are already `amount` requests in progress (based on the same `sourceCriterion` strategy).
|
||||
The middleware responds with `HTTP 429 Too Many Requests` if there are already `amount` requests in progress (based on the same `sourceCriterion` strategy).
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
@@ -100,7 +100,7 @@ labels:
|
||||
# Limiting to 10 simultaneous connections
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-inflightreq.inFlightReq]
|
||||
amount = 10
|
||||
amount = 10
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
@@ -109,29 +109,29 @@ http:
|
||||
middlewares:
|
||||
test-inflightreq:
|
||||
inFlightReq:
|
||||
amount: 10
|
||||
amount: 10
|
||||
```
|
||||
|
||||
### `sourceCriterion`
|
||||
|
||||
SourceCriterion defines what criterion is used to group requests as originating from a common source.
|
||||
|
||||
The `sourceCriterion` option defines what criterion is used to group requests as originating from a common source.
|
||||
The precedence order is `ipStrategy`, then `requestHeaderName`, then `requestHost`.
|
||||
If none are set, the default is to use the `requestHost`.
|
||||
|
||||
#### `sourceCriterion.ipStrategy`
|
||||
|
||||
The `ipStrategy` option defines two parameters that sets how Traefik will determine the client IP: `depth`, and `excludedIPs`.
|
||||
The `ipStrategy` option defines two parameters that configures how Traefik determines the client IP: `depth`, and `excludedIPs`.
|
||||
|
||||
##### `ipStrategy.depth`
|
||||
|
||||
The `depth` option tells Traefik to use the `X-Forwarded-For` header and take the IP located at the `depth` position (starting from the right).
|
||||
The `depth` option tells Traefik to use the `X-Forwarded-For` header and select the IP located at the `depth` position (starting from the right).
|
||||
|
||||
- If `depth` is greater than the total number of IPs in `X-Forwarded-For`, then the client IP is empty.
|
||||
- `depth` is ignored if its value is less than or equal to 0.
|
||||
|
||||
- If `depth` is greater than the total number of IPs in `X-Forwarded-For`, then the client IP will be empty.
|
||||
- `depth` is ignored if its value is lesser than or equal to 0.
|
||||
|
||||
!!! example "Example of Depth & X-Forwarded-For"
|
||||
|
||||
If `depth` was equal to 2, and the request `X-Forwarded-For` header was `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` then the "real" client IP would be `"10.0.0.1"` (at depth 4) but the IP used as the criterion would be `"12.0.0.1"` (`depth=2`).
|
||||
If `depth` is set to 2, and the request `X-Forwarded-For` header is `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` then the "real" client IP is `"10.0.0.1"` (at depth 4) but the IP used as the criterion is `"12.0.0.1"` (`depth=2`).
|
||||
|
||||
| `X-Forwarded-For` | `depth` | clientIP |
|
||||
|-----------------------------------------|---------|--------------|
|
||||
@@ -190,7 +190,7 @@ http:
|
||||
|
||||
##### `ipStrategy.excludedIPs`
|
||||
|
||||
`excludedIPs` tells Traefik to scan the `X-Forwarded-For` header and pick the first IP not in the list.
|
||||
`excludedIPs` configures Traefik to scan the `X-Forwarded-For` header and select the first IP not in the list.
|
||||
|
||||
!!! important "If `depth` is specified, `excludedIPs` is ignored."
|
||||
|
||||
@@ -259,7 +259,7 @@ http:
|
||||
|
||||
#### `sourceCriterion.requestHeaderName`
|
||||
|
||||
Requests having the same value for the given header are grouped as coming from the same source.
|
||||
Name of the header used to group incoming requests.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
|
@@ -70,95 +70,105 @@ The `sourceRange` option sets the allowed IPs (or ranges of allowed IPs by using
|
||||
|
||||
### `ipStrategy`
|
||||
|
||||
The `ipStrategy` option defines two parameters that sets how Traefik will determine the client IP: `depth`, and `excludedIPs`.
|
||||
The `ipStrategy` option defines two parameters that set how Traefik determines the client IP: `depth`, and `excludedIPs`.
|
||||
|
||||
#### `ipStrategy.depth`
|
||||
|
||||
The `depth` option tells Traefik to use the `X-Forwarded-For` header and take the IP located at the `depth` position (starting from the right).
|
||||
|
||||
- If `depth` is greater than the total number of IPs in `X-Forwarded-For`, then the client IP will be empty.
|
||||
- `depth` is ignored if its value is less than or equal to 0.
|
||||
|
||||
!!! example "Examples of Depth & X-Forwarded-For"
|
||||
|
||||
```yaml tab="Docker"
|
||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||
labels:
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth=2"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: testIPwhitelist
|
||||
spec:
|
||||
If `depth` is set to 2, and the request `X-Forwarded-For` header is `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` then the "real" client IP is `"10.0.0.1"` (at depth 4) but the IP used for the whitelisting is `"12.0.0.1"` (`depth=2`).
|
||||
|
||||
| `X-Forwarded-For` | `depth` | clientIP |
|
||||
|-----------------------------------------|---------|--------------|
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `1` | `"13.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `3` | `"11.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `5` | `""` |
|
||||
|
||||
```yaml tab="Docker"
|
||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||
labels:
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth=2"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: testIPwhitelist
|
||||
spec:
|
||||
ipWhiteList:
|
||||
sourceRange:
|
||||
- 127.0.0.1/32
|
||||
- 192.168.1.7
|
||||
ipStrategy:
|
||||
depth: 2
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth=2"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.testIPwhitelist.ipwhitelist.sourcerange": "127.0.0.1/32, 192.168.1.7",
|
||||
"traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth": "2"
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||
labels:
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth=2"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-ipwhitelist.ipWhiteList]
|
||||
sourceRange = ["127.0.0.1/32", "192.168.1.7"]
|
||||
[http.middlewares.test-ipwhitelist.ipWhiteList.ipStrategy]
|
||||
depth = 2
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||
http:
|
||||
middlewares:
|
||||
test-ipwhitelist:
|
||||
ipWhiteList:
|
||||
sourceRange:
|
||||
- 127.0.0.1/32
|
||||
- 192.168.1.7
|
||||
- "127.0.0.1/32"
|
||||
- "192.168.1.7"
|
||||
ipStrategy:
|
||||
depth: 2
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth=2"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.testIPwhitelist.ipwhitelist.sourcerange": "127.0.0.1/32, 192.168.1.7",
|
||||
"traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth": "2"
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||
labels:
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth=2"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-ipwhitelist.ipWhiteList]
|
||||
sourceRange = ["127.0.0.1/32", "192.168.1.7"]
|
||||
[http.middlewares.test-ipwhitelist.ipWhiteList.ipStrategy]
|
||||
depth = 2
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||
http:
|
||||
middlewares:
|
||||
test-ipwhitelist:
|
||||
ipWhiteList:
|
||||
sourceRange:
|
||||
- "127.0.0.1/32"
|
||||
- "192.168.1.7"
|
||||
ipStrategy:
|
||||
depth: 2
|
||||
```
|
||||
|
||||
If `depth` was equal to 2, and the request `X-Forwarded-For` header was `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` then the "real" client IP would be `"10.0.0.1"` (at depth 4) but the IP used for the whitelisting would be `"12.0.0.1"` (`depth=2`).
|
||||
|
||||
??? example "More examples"
|
||||
|
||||
| `X-Forwarded-For` | `depth` | clientIP |
|
||||
|-----------------------------------------|---------|--------------|
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `1` | `"13.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `3` | `"11.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `5` | `""` |
|
||||
|
||||
!!! info
|
||||
|
||||
- If `depth` is greater than the total number of IPs in `X-Forwarded-For`, then the client IP will be empty.
|
||||
- `depth` is ignored if its value is lesser than or equal to 0.
|
||||
```
|
||||
|
||||
#### `ipStrategy.excludedIPs`
|
||||
|
||||
`excludedIPs` configures Traefik to scan the `X-Forwarded-For` header and select the first IP not in the list.
|
||||
|
||||
!!! important "If `depth` is specified, `excludedIPs` is ignored."
|
||||
|
||||
!!! example "Example of ExcludedIPs & X-Forwarded-For"
|
||||
|
||||
| `X-Forwarded-For` | `excludedIPs` | clientIP |
|
||||
|-----------------------------------------|-----------------------|--------------|
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"12.0.0.1,13.0.0.1"` | `"11.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"10.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,16.0.0.1"` | `"13.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1"` | `"10.0.0.1,11.0.0.1"` | `""` |
|
||||
|
||||
```yaml tab="Docker"
|
||||
# Exclude from `X-Forwarded-For`
|
||||
labels:
|
||||
@@ -215,17 +225,3 @@ http:
|
||||
- "127.0.0.1/32"
|
||||
- "192.168.1.7"
|
||||
```
|
||||
|
||||
`excludedIPs` tells Traefik to scan the `X-Forwarded-For` header and pick the first IP not in the list.
|
||||
|
||||
!!! important "If `depth` is specified, `excludedIPs` is ignored."
|
||||
|
||||
!!! example "Examples of ExcludedIPs & X-Forwarded-For"
|
||||
|
||||
| `X-Forwarded-For` | `excludedIPs` | clientIP |
|
||||
|-----------------------------------------|-----------------------|--------------|
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"12.0.0.1,13.0.0.1"` | `"11.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"10.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,16.0.0.1"` | `"13.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1"` | `"10.0.0.1,11.0.0.1"` | `""` |
|
||||
|
@@ -13,7 +13,7 @@ Pieces of middleware can be combined in chains to fit every scenario.
|
||||
|
||||
!!! warning "Provider Namespace"
|
||||
|
||||
Be aware of the concept of Providers Namespace described in the [Configuration Discovery](../providers/overview.md#provider-namespace) section.
|
||||
Be aware of the concept of Providers Namespace described in the [Configuration Discovery](../providers/overview.md#provider-namespace) section.
|
||||
It also applies to Middlewares.
|
||||
|
||||
## Configuration Example
|
||||
|
@@ -7,7 +7,7 @@ Adding Client Certificates in a Header
|
||||
TODO: add schema
|
||||
-->
|
||||
|
||||
PassTLSClientCert adds in header the selected data from the passed client tls certificate.
|
||||
PassTLSClientCert adds the selected data from the passed client TLS certificate to a header.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
@@ -86,7 +86,7 @@ http:
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.province=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber=true"
|
||||
```
|
||||
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
# Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
@@ -116,7 +116,7 @@ http:
|
||||
serialNumber: true
|
||||
domainComponent: true
|
||||
```
|
||||
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notafter=true"
|
||||
@@ -137,7 +137,7 @@ http:
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.province=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber=true"
|
||||
```
|
||||
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notafter": "true",
|
||||
@@ -159,7 +159,7 @@ http:
|
||||
"traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber": "true"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
```yaml tab="Rancher"
|
||||
# Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header
|
||||
labels:
|
||||
@@ -240,7 +240,7 @@ http:
|
||||
|
||||
### General
|
||||
|
||||
PassTLSClientCert can add two headers to the request:
|
||||
PassTLSClientCert can add two headers to the request:
|
||||
|
||||
- `X-Forwarded-Tls-Client-Cert` that contains the escaped pem.
|
||||
- `X-Forwarded-Tls-Client-Cert-Info` that contains all the selected certificate information in an escaped string.
|
||||
@@ -251,9 +251,9 @@ PassTLSClientCert can add two headers to the request:
|
||||
* These options only work accordingly to the [MutualTLS configuration](../https/tls.md#client-authentication-mtls).
|
||||
That is to say, only the certificates that match the `clientAuth.clientAuthType` policy are passed.
|
||||
|
||||
In the following example, you can see a complete certificate. We will use each part of it to explain the middleware options.
|
||||
The following example shows a complete certificate and explains each of the middleware options.
|
||||
|
||||
??? example "A complete client tls certificate"
|
||||
??? example "A complete client TLS certificate"
|
||||
|
||||
```
|
||||
Certificate:
|
||||
@@ -292,16 +292,16 @@ In the following example, you can see a complete certificate. We will use each p
|
||||
X509v3 extensions:
|
||||
X509v3 Key Usage: critical
|
||||
Digital Signature, Key Encipherment
|
||||
X509v3 Basic Constraints:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
X509v3 Extended Key Usage:
|
||||
X509v3 Extended Key Usage:
|
||||
TLS Web Server Authentication, TLS Web Client Authentication
|
||||
X509v3 Subject Key Identifier:
|
||||
X509v3 Subject Key Identifier:
|
||||
94:BA:73:78:A2:87:FB:58:28:28:CF:98:3B:C2:45:70:16:6E:29:2F
|
||||
X509v3 Authority Key Identifier:
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:1E:52:A2:E8:54:D5:37:EB:D5:A8:1D:E4:C2:04:1D:37:E2:F7:70:03
|
||||
|
||||
X509v3 Subject Alternative Name:
|
||||
|
||||
X509v3 Subject Alternative Name:
|
||||
DNS:*.example.org, DNS:*.example.net, DNS:*.example.com, IP Address:10.0.1.0, IP Address:10.0.1.2, email:test@example.org, email:test@example.net
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
76:6b:05:b0:0e:34:11:b1:83:99:91:dc:ae:1b:e2:08:15:8b:
|
||||
@@ -359,9 +359,9 @@ In the following example, you can see a complete certificate. We will use each p
|
||||
|
||||
### `pem`
|
||||
|
||||
The `pem` option sets the `X-Forwarded-Tls-Client-Cert` header with the escape certificate.
|
||||
The `pem` option sets the `X-Forwarded-Tls-Client-Cert` header with the escaped certificate.
|
||||
|
||||
In the example, it is the part between `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----` delimiters :
|
||||
In the example, it is the part between `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----` delimiters:
|
||||
|
||||
??? example "The data used by the pem option"
|
||||
|
||||
@@ -403,23 +403,24 @@ In the example, it is the part between `-----BEGIN CERTIFICATE-----` and `-----E
|
||||
ML9n/4zmm1PMhzZHcEA72ZAq0tKCxpz10djg5v2qL5V+Oaz8TtTOZbPsxpiKMQ==
|
||||
-----END CERTIFICATE-----
|
||||
```
|
||||
|
||||
|
||||
!!! info "Extracted data"
|
||||
|
||||
The delimiters and `\n` will be removed.
|
||||
|
||||
The delimiters and `\n` will be removed.
|
||||
If there are more than one certificate, they are separated by a "`,`".
|
||||
|
||||
!!! warning "`X-Forwarded-Tls-Client-Cert` value could exceed the web server header size limit"
|
||||
|
||||
The header size limit of web servers is commonly between 4kb and 8kb.
|
||||
The header size limit of web servers is commonly between 4kb and 8kb.
|
||||
You could change the server configuration to allow bigger header or use the `info` option with the needed field(s).
|
||||
|
||||
### `info`
|
||||
|
||||
The `info` option select the specific client certificate details you want to add to the `X-Forwarded-Tls-Client-Cert-Info` header.
|
||||
The value of the header will be an escaped concatenation of all the selected certificate details.
|
||||
The `info` option selects the specific client certificate details you want to add to the `X-Forwarded-Tls-Client-Cert-Info` header.
|
||||
|
||||
The following example shows an unescaped result that uses all the available fields:
|
||||
The value of the header is an escaped concatenation of all the selected certificate details.
|
||||
|
||||
The following example shows an unescaped result that uses all the available fields:
|
||||
|
||||
```text
|
||||
Subject="DC=org,DC=cheese,C=FR,C=US,ST=Cheese org state,ST=Cheese com state,L=TOULOUSE,L=LYON,O=Cheese,O=Cheese 2,CN=*.example.com";Issuer="DC=org,DC=cheese,C=FR,C=US,ST=Signing State,ST=Signing State 2,L=TOULOUSE,L=LYON,O=Cheese,O=Cheese 2,CN=Simple Signing CA 2";NB="1544094616";NA="1607166616";SAN="*.example.org,*.example.net,*.example.com,test@example.org,test@example.net,10.0.1.0,10.0.1.2"
|
||||
@@ -433,14 +434,14 @@ Subject="DC=org,DC=cheese,C=FR,C=US,ST=Cheese org state,ST=Cheese com state,L=TO
|
||||
|
||||
Set the `info.notAfter` option to `true` to add the `Not After` information from the `Validity` part.
|
||||
|
||||
The data are taken from the following certificate part:
|
||||
The data is taken from the following certificate part:
|
||||
|
||||
```text
|
||||
Validity
|
||||
Not After : Dec 5 11:10:16 2020 GMT
|
||||
Not After : Dec 5 11:10:16 2020 GMT
|
||||
```
|
||||
|
||||
The escape `notAfter` info part will be like:
|
||||
The escaped `notAfter` info part is formatted as below:
|
||||
|
||||
```text
|
||||
NA="1607166616"
|
||||
@@ -450,14 +451,14 @@ NA="1607166616"
|
||||
|
||||
Set the `info.notBefore` option to `true` to add the `Not Before` information from the `Validity` part.
|
||||
|
||||
The data are taken from the following certificate part:
|
||||
The data is taken from the following certificate part:
|
||||
|
||||
```text
|
||||
Validity
|
||||
Not Before: Dec 6 11:10:16 2018 GMT
|
||||
```
|
||||
|
||||
The escape `notBefore` info part will be like:
|
||||
The escaped `notBefore` info part is formatted as below:
|
||||
|
||||
```text
|
||||
NB="1544094616"
|
||||
@@ -467,28 +468,28 @@ NB="1544094616"
|
||||
|
||||
Set the `info.sans` option to `true` to add the `Subject Alternative Name` information from the `Subject Alternative Name` part.
|
||||
|
||||
The data are taken from the following certificate part:
|
||||
The data is taken from the following certificate part:
|
||||
|
||||
```text
|
||||
X509v3 Subject Alternative Name:
|
||||
X509v3 Subject Alternative Name:
|
||||
DNS:*.example.org, DNS:*.example.net, DNS:*.example.com, IP Address:10.0.1.0, IP Address:10.0.1.2, email:test@example.org, email:test@example.net
|
||||
```
|
||||
|
||||
The escape SANs info part will be like:
|
||||
The escape SANs info part is formatted as below:
|
||||
|
||||
```text
|
||||
SAN="*.example.org,*.example.net,*.example.com,test@example.org,test@example.net,10.0.1.0,10.0.1.2"
|
||||
```
|
||||
|
||||
!!! info "multiple values"
|
||||
!!! info "Multiple values"
|
||||
|
||||
All the SANs data are separated by a `,`.
|
||||
The SANs are separated by a `,`.
|
||||
|
||||
#### `info.subject`
|
||||
|
||||
The `info.subject` select the specific client certificate subject details you want to add to the `X-Forwarded-Tls-Client-Cert-Info` header.
|
||||
The `info.subject` selects the specific client certificate subject details you want to add to the `X-Forwarded-Tls-Client-Cert-Info` header.
|
||||
|
||||
The data are taken from the following certificate part :
|
||||
The data is taken from the following certificate part:
|
||||
|
||||
```text
|
||||
Subject: DC=org, DC=cheese, O=Cheese, O=Cheese 2, OU=Simple Signing Section, OU=Simple Signing Section 2, CN=*.example.org, CN=*.example.com, C=FR, C=US, L=TOULOUSE, L=LYON, ST=Cheese org state, ST=Cheese com state/emailAddress=cert@example.org/emailAddress=cert@sexample.com
|
||||
@@ -496,9 +497,11 @@ Subject: DC=org, DC=cheese, O=Cheese, O=Cheese 2, OU=Simple Signing Section, OU=
|
||||
|
||||
##### `info.subject.country`
|
||||
|
||||
Set the `info.subject.country` option to true to add the `country` information into the subject.
|
||||
The data are taken from the subject part with the `C` key.
|
||||
The escape country info in the subject part will be like :
|
||||
Set the `info.subject.country` option to `true` to add the `country` information into the subject.
|
||||
|
||||
The data is taken from the subject part with the `C` key.
|
||||
|
||||
The escape country info in the subject part is formatted as below:
|
||||
|
||||
```text
|
||||
C=FR,C=US
|
||||
@@ -506,11 +509,11 @@ C=FR,C=US
|
||||
|
||||
##### `info.subject.province`
|
||||
|
||||
Set the `info.subject.province` option to true to add the `province` information into the subject.
|
||||
|
||||
The data are taken from the subject part with the `ST` key.
|
||||
Set the `info.subject.province` option to `true` to add the `province` information into the subject.
|
||||
|
||||
The escape province info in the subject part will be like :
|
||||
The data is taken from the subject part with the `ST` key.
|
||||
|
||||
The escape province info in the subject part is formatted as below:
|
||||
|
||||
```text
|
||||
ST=Cheese org state,ST=Cheese com state
|
||||
@@ -518,11 +521,11 @@ ST=Cheese org state,ST=Cheese com state
|
||||
|
||||
##### `info.subject.locality`
|
||||
|
||||
Set the `info.subject.locality` option to true to add the `locality` information into the subject.
|
||||
|
||||
The data are taken from the subject part with the `L` key.
|
||||
Set the `info.subject.locality` option to `true` to add the `locality` information into the subject.
|
||||
|
||||
The escape locality info in the subject part will be like :
|
||||
The data is taken from the subject part with the `L` key.
|
||||
|
||||
The escape locality info in the subject part is formatted as below:
|
||||
|
||||
```text
|
||||
L=TOULOUSE,L=LYON
|
||||
@@ -530,11 +533,11 @@ L=TOULOUSE,L=LYON
|
||||
|
||||
##### `info.subject.organization`
|
||||
|
||||
Set the `info.subject.organization` option to true to add the `organization` information into the subject.
|
||||
|
||||
The data are taken from the subject part with the `O` key.
|
||||
Set the `info.subject.organization` option to `true` to add the `organization` information into the subject.
|
||||
|
||||
The escape organization info in the subject part will be like :
|
||||
The data is taken from the subject part with the `O` key.
|
||||
|
||||
The escape organization info in the subject part is formatted as below:
|
||||
|
||||
```text
|
||||
O=Cheese,O=Cheese 2
|
||||
@@ -542,11 +545,11 @@ O=Cheese,O=Cheese 2
|
||||
|
||||
##### `info.subject.commonName`
|
||||
|
||||
Set the `info.subject.commonName` option to true to add the `commonName` information into the subject.
|
||||
|
||||
The data are taken from the subject part with the `CN` key.
|
||||
Set the `info.subject.commonName` option to `true` to add the `commonName` information into the subject.
|
||||
|
||||
The escape common name info in the subject part will be like :
|
||||
The data is taken from the subject part with the `CN` key.
|
||||
|
||||
The escape common name info in the subject part is formatted as below:
|
||||
|
||||
```text
|
||||
CN=*.example.com
|
||||
@@ -554,11 +557,11 @@ CN=*.example.com
|
||||
|
||||
##### `info.subject.serialNumber`
|
||||
|
||||
Set the `info.subject.serialNumber` option to true to add the `serialNumber` information into the subject.
|
||||
|
||||
The data are taken from the subject part with the `SN` key.
|
||||
Set the `info.subject.serialNumber` option to `true` to add the `serialNumber` information into the subject.
|
||||
|
||||
The escape serial number info in the subject part will be like :
|
||||
The data is taken from the subject part with the `SN` key.
|
||||
|
||||
The escape serial number info in the subject part is formatted as below:
|
||||
|
||||
```text
|
||||
SN=1234567890
|
||||
@@ -566,11 +569,11 @@ SN=1234567890
|
||||
|
||||
##### `info.subject.domainComponent`
|
||||
|
||||
Set the `info.subject.domainComponent` option to true to add the `domainComponent` information into the subject.
|
||||
|
||||
The data are taken from the subject part with the `DC` key.
|
||||
Set the `info.subject.domainComponent` option to `true` to add the `domainComponent` information into the subject.
|
||||
|
||||
The escape domaincomponent info in the subject part will be like :
|
||||
The data is taken from the subject part with the `DC` key.
|
||||
|
||||
The escape domain component info in the subject part is formatted as below:
|
||||
|
||||
```text
|
||||
DC=org,DC=cheese
|
||||
@@ -578,9 +581,9 @@ DC=org,DC=cheese
|
||||
|
||||
#### `info.issuer`
|
||||
|
||||
The `info.issuer` select the specific client certificate issuer details you want to add to the `X-Forwarded-Tls-Client-Cert-Info` header.
|
||||
The `info.issuer` selects the specific client certificate issuer details you want to add to the `X-Forwarded-Tls-Client-Cert-Info` header.
|
||||
|
||||
The data are taken from the following certificate part :
|
||||
The data is taken from the following certificate part:
|
||||
|
||||
```text
|
||||
Issuer: DC=org, DC=cheese, O=Cheese, O=Cheese 2, OU=Simple Signing Section, OU=Simple Signing Section 2, CN=Simple Signing CA, CN=Simple Signing CA 2, C=FR, C=US, L=TOULOUSE, L=LYON, ST=Signing State, ST=Signing State 2/emailAddress=simple@signing.com/emailAddress=simple2@signing.com
|
||||
@@ -588,9 +591,11 @@ Issuer: DC=org, DC=cheese, O=Cheese, O=Cheese 2, OU=Simple Signing Section, OU=S
|
||||
|
||||
##### `info.issuer.country`
|
||||
|
||||
Set the `info.issuer.country` option to true to add the `country` information into the issuer.
|
||||
The data are taken from the issuer part with the `C` key.
|
||||
The escape country info in the issuer part will be like :
|
||||
Set the `info.issuer.country` option to `true` to add the `country` information into the issuer.
|
||||
|
||||
The data is taken from the issuer part with the `C` key.
|
||||
|
||||
The escape country info in the issuer part is formatted as below:
|
||||
|
||||
```text
|
||||
C=FR,C=US
|
||||
@@ -598,11 +603,11 @@ C=FR,C=US
|
||||
|
||||
##### `info.issuer.province`
|
||||
|
||||
Set the `info.issuer.province` option to true to add the `province` information into the issuer.
|
||||
|
||||
The data are taken from the issuer part with the `ST` key.
|
||||
Set the `info.issuer.province` option to `true` to add the `province` information into the issuer.
|
||||
|
||||
The escape province info in the issuer part will be like :
|
||||
The data is taken from the issuer part with the `ST` key.
|
||||
|
||||
The escape province info in the issuer part is formatted as below:
|
||||
|
||||
```text
|
||||
ST=Signing State,ST=Signing State 2
|
||||
@@ -610,11 +615,11 @@ ST=Signing State,ST=Signing State 2
|
||||
|
||||
##### `info.issuer.locality`
|
||||
|
||||
Set the `info.issuer.locality` option to true to add the `locality` information into the issuer.
|
||||
|
||||
The data are taken from the issuer part with the `L` key.
|
||||
Set the `info.issuer.locality` option to `true` to add the `locality` information into the issuer.
|
||||
|
||||
The escape locality info in the issuer part will be like :
|
||||
The data is taken from the issuer part with the `L` key.
|
||||
|
||||
The escape locality info in the issuer part is formatted as below:
|
||||
|
||||
```text
|
||||
L=TOULOUSE,L=LYON
|
||||
@@ -622,11 +627,11 @@ L=TOULOUSE,L=LYON
|
||||
|
||||
##### `info.issuer.organization`
|
||||
|
||||
Set the `info.issuer.organization` option to true to add the `organization` information into the issuer.
|
||||
|
||||
The data are taken from the issuer part with the `O` key.
|
||||
Set the `info.issuer.organization` option to `true` to add the `organization` information into the issuer.
|
||||
|
||||
The escape organization info in the issuer part will be like :
|
||||
The data is taken from the issuer part with the `O` key.
|
||||
|
||||
The escape organization info in the issuer part is formatted as below:
|
||||
|
||||
```text
|
||||
O=Cheese,O=Cheese 2
|
||||
@@ -634,11 +639,11 @@ O=Cheese,O=Cheese 2
|
||||
|
||||
##### `info.issuer.commonName`
|
||||
|
||||
Set the `info.issuer.commonName` option to true to add the `commonName` information into the issuer.
|
||||
|
||||
The data are taken from the issuer part with the `CN` key.
|
||||
Set the `info.issuer.commonName` option to `true` to add the `commonName` information into the issuer.
|
||||
|
||||
The escape common name info in the issuer part will be like :
|
||||
The data is taken from the issuer part with the `CN` key.
|
||||
|
||||
The escape common name info in the issuer part is formatted as below:
|
||||
|
||||
```text
|
||||
CN=Simple Signing CA 2
|
||||
@@ -646,11 +651,11 @@ CN=Simple Signing CA 2
|
||||
|
||||
##### `info.issuer.serialNumber`
|
||||
|
||||
Set the `info.issuer.serialNumber` option to true to add the `serialNumber` information into the issuer.
|
||||
|
||||
The data are taken from the issuer part with the `SN` key.
|
||||
Set the `info.issuer.serialNumber` option to `true` to add the `serialNumber` information into the issuer.
|
||||
|
||||
The escape serial number info in the issuer part will be like :
|
||||
The data is taken from the issuer part with the `SN` key.
|
||||
|
||||
The escape serial number info in the issuer part is formatted as below:
|
||||
|
||||
```text
|
||||
SN=1234567890
|
||||
@@ -658,11 +663,11 @@ SN=1234567890
|
||||
|
||||
##### `info.issuer.domainComponent`
|
||||
|
||||
Set the `info.issuer.domainComponent` option to true to add the `domainComponent` information into the issuer.
|
||||
|
||||
The data are taken from the issuer part with the `DC` key.
|
||||
Set the `info.issuer.domainComponent` option to `true` to add the `domainComponent` information into the issuer.
|
||||
|
||||
The escape domain component info in the issuer part will be like :
|
||||
The data is taken from the issuer part with the `DC` key.
|
||||
|
||||
The escape domain component info in the issuer part is formatted as below:
|
||||
|
||||
```text
|
||||
DC=org,DC=cheese
|
||||
|
@@ -3,7 +3,7 @@
|
||||
To Control the Number of Requests Going to a Service
|
||||
{: .subtitle }
|
||||
|
||||
The RateLimit middleware ensures that services will receive a _fair_ number of requests, and allows one to define what fair is.
|
||||
The RateLimit middleware ensures that services will receive a _fair_ amount of requests, and allows one to define what fair is.
|
||||
|
||||
## Configuration Example
|
||||
|
||||
@@ -74,7 +74,7 @@ http:
|
||||
|
||||
### `average`
|
||||
|
||||
`average` is the maximum rate, by default in requests by second, allowed for the given source.
|
||||
`average` is the maximum rate, by default in requests per second, allowed from a given source.
|
||||
|
||||
It defaults to `0`, which means no rate limiting.
|
||||
|
||||
@@ -219,7 +219,7 @@ spec:
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.burst=100"
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.burst=100"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
@@ -230,7 +230,7 @@ spec:
|
||||
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.burst=100"
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.burst=100"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
@@ -248,25 +248,25 @@ http:
|
||||
```
|
||||
|
||||
### `sourceCriterion`
|
||||
|
||||
SourceCriterion defines what criterion is used to group requests as originating from a common source.
|
||||
|
||||
The `sourceCriterion` option defines what criterion is used to group requests as originating from a common source.
|
||||
The precedence order is `ipStrategy`, then `requestHeaderName`, then `requestHost`.
|
||||
If none are set, the default is to use the request's remote address field (as an `ipStrategy`).
|
||||
|
||||
#### `sourceCriterion.ipStrategy`
|
||||
|
||||
The `ipStrategy` option defines two parameters that sets how Traefik will determine the client IP: `depth`, and `excludedIPs`.
|
||||
The `ipStrategy` option defines two parameters that configures how Traefik determines the client IP: `depth`, and `excludedIPs`.
|
||||
|
||||
##### `ipStrategy.depth`
|
||||
|
||||
The `depth` option tells Traefik to use the `X-Forwarded-For` header and take the IP located at the `depth` position (starting from the right).
|
||||
The `depth` option tells Traefik to use the `X-Forwarded-For` header and select the IP located at the `depth` position (starting from the right).
|
||||
|
||||
- If `depth` is greater than the total number of IPs in `X-Forwarded-For`, then the client IP will be empty.
|
||||
- `depth` is ignored if its value is lesser than or equal to 0.
|
||||
- If `depth` is greater than the total number of IPs in `X-Forwarded-For`, then the client IP is empty.
|
||||
- `depth` is ignored if its value is less than or equal to 0.
|
||||
|
||||
!!! example "Example of Depth & X-Forwarded-For"
|
||||
|
||||
If `depth` was equal to 2, and the request `X-Forwarded-For` header was `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` then the "real" client IP would be `"10.0.0.1"` (at depth 4) but the IP used as the criterion would be `"12.0.0.1"` (`depth=2`).
|
||||
If `depth` is set to 2, and the request `X-Forwarded-For` header is `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` then the "real" client IP is `"10.0.0.1"` (at depth 4) but the IP used as the criterion is `"12.0.0.1"` (`depth=2`).
|
||||
|
||||
| `X-Forwarded-For` | `depth` | clientIP |
|
||||
|-----------------------------------------|---------|--------------|
|
||||
@@ -274,8 +274,71 @@ The `depth` option tells Traefik to use the `X-Forwarded-For` header and take th
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `3` | `"11.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `5` | `""` |
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.depth=2"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: test-ratelimit
|
||||
spec:
|
||||
rateLimit:
|
||||
sourceCriterion:
|
||||
ipStrategy:
|
||||
depth: 2
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.depth=2"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.depth": "2"
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.depth=2"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-ratelimit.rateLimit]
|
||||
[http.middlewares.test-ratelimit.rateLimit.sourceCriterion.ipStrategy]
|
||||
depth = 2
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
http:
|
||||
middlewares:
|
||||
test-ratelimit:
|
||||
rateLimit:
|
||||
sourceCriterion:
|
||||
ipStrategy:
|
||||
depth: 2
|
||||
```
|
||||
|
||||
##### `ipStrategy.excludedIPs`
|
||||
|
||||
`excludedIPs` configures Traefik to scan the `X-Forwarded-For` header and select the first IP not in the list.
|
||||
|
||||
!!! important "If `depth` is specified, `excludedIPs` is ignored."
|
||||
|
||||
!!! example "Example of ExcludedIPs & X-Forwarded-For"
|
||||
|
||||
| `X-Forwarded-For` | `excludedIPs` | clientIP |
|
||||
|-----------------------------------------|-----------------------|--------------|
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"12.0.0.1,13.0.0.1"` | `"11.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"10.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,16.0.0.1"` | `"13.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1"` | `"10.0.0.1,11.0.0.1"` | `""` |
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||
@@ -329,23 +392,9 @@ http:
|
||||
- "192.168.1.7"
|
||||
```
|
||||
|
||||
`excludedIPs` tells Traefik to scan the `X-Forwarded-For` header and pick the first IP not in the list.
|
||||
|
||||
!!! important "If `depth` is specified, `excludedIPs` is ignored."
|
||||
|
||||
!!! example "Example of ExcludedIPs & X-Forwarded-For"
|
||||
|
||||
| `X-Forwarded-For` | `excludedIPs` | clientIP |
|
||||
|-----------------------------------------|-----------------------|--------------|
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"12.0.0.1,13.0.0.1"` | `"11.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"10.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,16.0.0.1"` | `"13.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1"` | `"10.0.0.1,11.0.0.1"` | `""` |
|
||||
|
||||
#### `sourceCriterion.requestHeaderName`
|
||||
|
||||
Requests having the same value for the given header are grouped as coming from the same source.
|
||||
Name of the header used to group incoming requests.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
|
@@ -7,7 +7,7 @@ Redirecting the Client to a Different Location
|
||||
TODO: add schema
|
||||
-->
|
||||
|
||||
RegexRedirect redirect a request from an url to another with regex matching and replacement.
|
||||
The RedirectRegex redirects a request using regex matching and replacement.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
@@ -73,6 +73,10 @@ http:
|
||||
|
||||
## Configuration Options
|
||||
|
||||
!!! tip
|
||||
|
||||
Regular expressions and replacements can be tested using online tools such as [Go Playground](https://play.golang.org/p/mWU9p-wk2ru) or the [Regex101](https://regex101.com/r/58sIgx/2).
|
||||
|
||||
### `permanent`
|
||||
|
||||
Set the `permanent` option to `true` to apply a permanent redirection.
|
||||
@@ -80,15 +84,11 @@ Set the `permanent` option to `true` to apply a permanent redirection.
|
||||
### `regex`
|
||||
|
||||
The `regex` option is the regular expression to match and capture elements from the request URL.
|
||||
|
||||
!!! warning
|
||||
|
||||
Care should be taken when defining replacement expand variables: `$1x` is equivalent to `${1x}`, not `${1}x` (see [Regexp.Expand](https://golang.org/pkg/regexp/#Regexp.Expand)), so use `${1}` syntax.
|
||||
|
||||
!!! tip
|
||||
|
||||
Regular expressions and replacements can be tested using online tools such as [Go Playground](https://play.golang.org/p/mWU9p-wk2ru) or the [Regex101](https://regex101.com/r/58sIgx/2).
|
||||
|
||||
### `replacement`
|
||||
|
||||
The `replacement` option defines how to modify the URL to have the new target URL.
|
||||
|
||||
!!! warning
|
||||
|
||||
Care should be taken when defining replacement expand variables: `$1x` is equivalent to `${1x}`, not `${1}x` (see [Regexp.Expand](https://golang.org/pkg/regexp/#Regexp.Expand)), so use `${1}` syntax.
|
||||
|
@@ -7,7 +7,7 @@ Redirecting the Client to a Different Scheme/Port
|
||||
TODO: add schema
|
||||
-->
|
||||
|
||||
RedirectScheme redirect request from a scheme to another.
|
||||
RedirectScheme redirects requests from a scheme/port to another.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
@@ -135,7 +135,7 @@ http:
|
||||
|
||||
### `scheme`
|
||||
|
||||
The `scheme` option defines the scheme of the new url.
|
||||
The `scheme` option defines the scheme of the new URL.
|
||||
|
||||
```yaml tab="Docker"
|
||||
# Redirect to https
|
||||
@@ -190,7 +190,7 @@ http:
|
||||
|
||||
### `port`
|
||||
|
||||
The `port` option defines the port of the new url.
|
||||
The `port` option defines the port of the new URL.
|
||||
|
||||
```yaml tab="Docker"
|
||||
# Redirect to https
|
||||
|
@@ -7,18 +7,18 @@ Updating the Path Before Forwarding the Request
|
||||
TODO: add schema
|
||||
-->
|
||||
|
||||
Replace the path of the request url.
|
||||
Replace the path of the request URL.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
```yaml tab="Docker"
|
||||
# Replace the path by /foo
|
||||
# Replace the path with /foo
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-replacepath.replacepath.path=/foo"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
# Replace the path by /foo
|
||||
# Replace the path with /foo
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
@@ -29,7 +29,7 @@ spec:
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Replace the path by /foo
|
||||
# Replace the path with /foo
|
||||
- "traefik.http.middlewares.test-replacepath.replacepath.path=/foo"
|
||||
```
|
||||
|
||||
@@ -40,20 +40,20 @@ spec:
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
# Replace the path by /foo
|
||||
# Replace the path with /foo
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-replacepath.replacepath.path=/foo"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
# Replace the path by /foo
|
||||
# Replace the path with /foo
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-replacepath.replacePath]
|
||||
path = "/foo"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
# Replace the path by /foo
|
||||
# Replace the path with /foo
|
||||
http:
|
||||
middlewares:
|
||||
test-replacepath:
|
||||
@@ -67,9 +67,9 @@ http:
|
||||
|
||||
The ReplacePath middleware will:
|
||||
|
||||
- replace the actual path by the specified one.
|
||||
- replace the actual path with the specified one.
|
||||
- store the original path in a `X-Replaced-Path` header.
|
||||
|
||||
### `path`
|
||||
|
||||
The `path` option defines the path to use as replacement in the request url.
|
||||
The `path` option defines the path to use as replacement in the request URL.
|
||||
|
@@ -7,7 +7,7 @@ Updating the Path Before Forwarding the Request (Using a Regex)
|
||||
TODO: add schema
|
||||
-->
|
||||
|
||||
The ReplaceRegex replace a path from an url to another with regex matching and replacement.
|
||||
The ReplaceRegex replaces the path of a URL using regex matching and replacement.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
@@ -51,7 +51,7 @@ labels:
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
# Redirect with domain replacement
|
||||
# Replace path with regex
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-replacepathregex.replacePathRegex]
|
||||
regex = "^/foo/(.*)"
|
||||
@@ -59,7 +59,7 @@ labels:
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
# Redirect with domain replacement
|
||||
# Replace path with regex
|
||||
http:
|
||||
middlewares:
|
||||
test-replacepathregex:
|
||||
@@ -74,21 +74,21 @@ http:
|
||||
|
||||
The ReplacePathRegex middleware will:
|
||||
|
||||
- replace the matching path by the specified one.
|
||||
- replace the matching path with the specified one.
|
||||
- store the original path in a `X-Replaced-Path` header.
|
||||
|
||||
!!! tip
|
||||
|
||||
Regular expressions and replacements can be tested using online tools such as [Go Playground](https://play.golang.org/p/mWU9p-wk2ru) or [Regex101](https://regex101.com/r/58sIgx/2).
|
||||
|
||||
### `regex`
|
||||
|
||||
The `regex` option is the regular expression to match and capture the path from the request URL.
|
||||
|
||||
### `replacement`
|
||||
|
||||
The `replacement` option defines the replacement path format, which can include captured variables.
|
||||
|
||||
!!! warning
|
||||
|
||||
Care should be taken when defining replacement expand variables: `$1x` is equivalent to `${1x}`, not `${1}x` (see [Regexp.Expand](https://golang.org/pkg/regexp/#Regexp.Expand)), so use `${1}` syntax.
|
||||
|
||||
!!! tip
|
||||
|
||||
Regular expressions and replacements can be tested using online tools such as [Go Playground](https://play.golang.org/p/mWU9p-wk2ru) or the [Regex101](https://regex101.com/r/58sIgx/2).
|
||||
|
||||
### `replacement`
|
||||
|
||||
The `replacement` option defines how to modify the path to have the new target path.
|
||||
|
@@ -7,19 +7,21 @@ Retrying until it Succeeds
|
||||
TODO: add schema
|
||||
-->
|
||||
|
||||
The Retry middleware is in charge of reissuing a request a given number of times to a backend server if that server does not reply.
|
||||
To be clear, as soon as the server answers, the middleware stops retrying, regardless of the response status.
|
||||
The Retry middleware reissues requests a given number of times to a backend server if that server does not reply.
|
||||
As soon as the server answers, the middleware stops retrying, regardless of the response status.
|
||||
The Retry middleware has an optional configuration to enable an exponential backoff.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
```yaml tab="Docker"
|
||||
# Retry to send request 4 times
|
||||
# Retry 4 times with exponential backoff
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-retry.retry.attempts=4"
|
||||
- "traefik.http.middlewares.test-retry.retry.initialinterval=100ms"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
# Retry to send request 4 times
|
||||
# Retry 4 times with exponential backoff
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
@@ -27,45 +29,58 @@ metadata:
|
||||
spec:
|
||||
retry:
|
||||
attempts: 4
|
||||
initialInterval: 100ms
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Retry to send request 4 times
|
||||
# Retry 4 times with exponential backoff
|
||||
- "traefik.http.middlewares.test-retry.retry.attempts=4"
|
||||
- "traefik.http.middlewares.test-retry.retry.initialinterval=100ms"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-retry.retry.attempts": "4"
|
||||
"traefik.http.middlewares.test-retry.retry.attempts": "4",
|
||||
"traefik.http.middlewares.test-retry.retry.initialinterval": "100ms",
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
# Retry to send request 4 times
|
||||
# Retry 4 times with exponential backoff
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-retry.retry.attempts=4"
|
||||
- "traefik.http.middlewares.test-retry.retry.initialinterval=100ms"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
# Retry to send request 4 times
|
||||
# Retry 4 times with exponential backoff
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-retry.retry]
|
||||
attempts = 4
|
||||
attempts = 4
|
||||
initialInterval = "100ms"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
# Retry to send request 4 times
|
||||
# Retry 4 times with exponential backoff
|
||||
http:
|
||||
middlewares:
|
||||
test-retry:
|
||||
retry:
|
||||
attempts: 4
|
||||
attempts: 4
|
||||
initialInterval: 100ms
|
||||
```
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### `attempts`
|
||||
### `attempts`
|
||||
|
||||
_mandatory_
|
||||
|
||||
The `attempts` option defines how many times the request should be retried.
|
||||
|
||||
### `initialInterval`
|
||||
|
||||
The `initialInterval` option defines the first wait time in the exponential backoff series. The maximum interval is
|
||||
calculated as twice the `initialInterval`. If unspecified, requests will be retried immediately.
|
||||
|
||||
The value of initialInterval should be provided in seconds or as a valid duration format, see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration).
|
||||
|
@@ -69,32 +69,55 @@ http:
|
||||
|
||||
### General
|
||||
|
||||
The StripPrefix middleware will:
|
||||
|
||||
- strip the matching path prefix.
|
||||
- store the matching path prefix in a `X-Forwarded-Prefix` header.
|
||||
The StripPrefix middleware strips the matching path prefix and stores it in a `X-Forwarded-Prefix` header.
|
||||
|
||||
!!! tip
|
||||
|
||||
Use a `StripPrefix` middleware if your backend listens on the root path (`/`) but should be routeable on a specific prefix.
|
||||
|
||||
Use a `StripPrefix` middleware if your backend listens on the root path (`/`) but should be exposed on a specific prefix.
|
||||
|
||||
### `prefixes`
|
||||
|
||||
The `prefixes` option defines the prefixes to strip from the request URL.
|
||||
|
||||
For instance, `/products` would match `/products` but also `/products/shoes` and `/products/shirts`.
|
||||
For instance, `/products` also matches `/products/shoes` and `/products/shirts`.
|
||||
|
||||
Since the path is stripped prior to forwarding, your backend is expected to listen on `/`.
|
||||
|
||||
If your backend is serving assets (e.g., images or Javascript files), chances are it must return properly constructed relative URLs.
|
||||
Continuing on the example, the backend should return `/products/shoes/image.png` (and not `/images.png` which Traefik would likely not be able to associate with the same backend).
|
||||
|
||||
The `X-Forwarded-Prefix` header can be queried to build such URLs dynamically.
|
||||
If your backend is serving assets (e.g., images or JavaScript files), it can use the `X-Forwarded-Prefix` header to properly construct relative URLs.
|
||||
Using the previous example, the backend should return `/products/shoes/image.png` (and not `/images.png`, which Traefik would likely not be able to associate with the same backend).
|
||||
|
||||
### `forceSlash`
|
||||
|
||||
_Optional, Default=true_
|
||||
|
||||
The `forceSlash` option ensures the resulting stripped path is not the empty string, by replacing it with `/` when necessary.
|
||||
|
||||
This option was added to keep the initial (non-intuitive) behavior of this middleware, in order to avoid introducing a breaking change.
|
||||
|
||||
It is recommended to explicitly set `forceSlash` to `false`.
|
||||
|
||||
??? info "Behavior examples"
|
||||
|
||||
- `forceSlash=true`
|
||||
|
||||
| Path | Prefix to strip | Result |
|
||||
|------------|-----------------|--------|
|
||||
| `/` | `/` | `/` |
|
||||
| `/foo` | `/foo` | `/` |
|
||||
| `/foo/` | `/foo` | `/` |
|
||||
| `/foo/` | `/foo/` | `/` |
|
||||
| `/bar` | `/foo` | `/bar` |
|
||||
| `/foo/bar` | `/foo` | `/bar` |
|
||||
|
||||
- `forceSlash=false`
|
||||
|
||||
| Path | Prefix to strip | Result |
|
||||
|------------|-----------------|--------|
|
||||
| `/` | `/` | empty |
|
||||
| `/foo` | `/foo` | empty |
|
||||
| `/foo/` | `/foo` | `/` |
|
||||
| `/foo/` | `/foo/` | empty |
|
||||
| `/bar` | `/foo` | `/bar` |
|
||||
| `/foo/bar` | `/foo` | `/bar` |
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
- "traefik.http.middlewares.example.stripprefix.prefixes=/foobar"
|
||||
@@ -142,33 +165,3 @@ http:
|
||||
- "/foobar"
|
||||
forceSlash: false
|
||||
```
|
||||
|
||||
The `forceSlash` option makes sure that the resulting stripped path is not the empty string, by replacing it with `/` when necessary.
|
||||
|
||||
This option was added to keep the initial (non-intuitive) behavior of this middleware, in order to avoid introducing a breaking change.
|
||||
|
||||
It's recommended to explicitly set `forceSlash` to `false`.
|
||||
|
||||
??? info "Behavior examples"
|
||||
|
||||
- `forceSlash=true`
|
||||
|
||||
| Path | Prefix to strip | Result |
|
||||
|------------|-----------------|--------|
|
||||
| `/` | `/` | `/` |
|
||||
| `/foo` | `/foo` | `/` |
|
||||
| `/foo/` | `/foo` | `/` |
|
||||
| `/foo/` | `/foo/` | `/` |
|
||||
| `/bar` | `/foo` | `/bar` |
|
||||
| `/foo/bar` | `/foo` | `/bar` |
|
||||
|
||||
- `forceSlash=false`
|
||||
|
||||
| Path | Prefix to strip | Result |
|
||||
|------------|-----------------|--------|
|
||||
| `/` | `/` | empty |
|
||||
| `/foo` | `/foo` | empty |
|
||||
| `/foo/` | `/foo` | `/` |
|
||||
| `/foo/` | `/foo/` | empty |
|
||||
| `/bar` | `/foo` | `/bar` |
|
||||
| `/foo/bar` | `/foo` | `/bar` |
|
||||
|
@@ -57,14 +57,11 @@ http:
|
||||
|
||||
### General
|
||||
|
||||
The StripPrefixRegex middleware will:
|
||||
|
||||
- strip the matching path prefix.
|
||||
- store the matching path prefix in a `X-Forwarded-Prefix` header.
|
||||
The StripPrefixRegex middleware strips the matching path prefix and stores it in a `X-Forwarded-Prefix` header.
|
||||
|
||||
!!! tip
|
||||
|
||||
Use a `stripPrefixRegex` middleware if your backend listens on the root path (`/`) but should be routeable on a specific prefix.
|
||||
|
||||
Use a `stripPrefixRegex` middleware if your backend listens on the root path (`/`) but should be exposed on a specific prefix.
|
||||
|
||||
### `regex`
|
||||
|
||||
@@ -74,12 +71,7 @@ The `regex` option is the regular expression to match the path prefix from the r
|
||||
|
||||
Regular expressions can be tested using online tools such as [Go Playground](https://play.golang.org/p/mWU9p-wk2ru) or the [Regex101](https://regex101.com/r/58sIgx/2).
|
||||
|
||||
For instance, `/products` would match `/products` but also `/products/shoes` and `/products/shirts`.
|
||||
For instance, `/products` also matches `/products/shoes` and `/products/shirts`.
|
||||
|
||||
Since the path is stripped prior to forwarding, your backend is expected to listen on `/`.
|
||||
|
||||
If your backend is serving assets (e.g., images or Javascript files), chances are it must return properly constructed relative URLs.
|
||||
|
||||
Continuing on the example, the backend should return `/products/shoes/image.png` (and not `/images.png` which Traefik would likely not be able to associate with the same backend).
|
||||
|
||||
The `X-Forwarded-Prefix` header can be queried to build such URLs dynamically.
|
||||
If your backend is serving assets (e.g., images or JavaScript files), it can use the `X-Forwarded-Prefix` header to properly construct relative URLs.
|
||||
Using the previous example, the backend should return `/products/shoes/image.png` (and not `/images.png`, which Traefik would likely not be able to associate with the same backend).
|
||||
|
@@ -16,12 +16,12 @@ Attach tags to your services and let Traefik do the rest!
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
```
|
||||
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog: {}
|
||||
```
|
||||
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog=true
|
||||
```
|
||||
@@ -42,6 +42,8 @@ See the dedicated section in [routing](../routing/providers/consul-catalog.md).
|
||||
|
||||
_Optional, Default=15s_
|
||||
|
||||
Defines the polling interval.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
refreshInterval = "30s"
|
||||
@@ -60,12 +62,12 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Defines the polling interval.
|
||||
|
||||
### `prefix`
|
||||
|
||||
_required, Default="traefik"_
|
||||
|
||||
The prefix for Consul Catalog tags defining Traefik labels.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
prefix = "test"
|
||||
@@ -84,12 +86,18 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
The prefix for Consul Catalog tags defining traefik labels.
|
||||
|
||||
### `requireConsistent`
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
Forces the read to be fully consistent.
|
||||
|
||||
!!! note ""
|
||||
|
||||
It is more expensive due to an extra round-trip but prevents ever performing a stale read.
|
||||
|
||||
For more information, see the consul [documentation on consistency](https://www.consul.io/api-docs/features/consistency).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
requireConsistent = true
|
||||
@@ -108,12 +116,18 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Forces the read to be fully consistent.
|
||||
|
||||
### `stale`
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
Use stale consistency for catalog reads.
|
||||
|
||||
!!! note ""
|
||||
|
||||
This makes reads very fast and scalable at the cost of a higher likelihood of stale values.
|
||||
|
||||
For more information, see the consul [documentation on consistency](https://www.consul.io/api-docs/features/consistency).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
stale = true
|
||||
@@ -132,12 +146,12 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Use stale consistency for catalog reads.
|
||||
|
||||
### `cache`
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
Use local agent caching for catalog reads.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
cache = true
|
||||
@@ -156,14 +170,14 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Use local agent caching for catalog reads.
|
||||
|
||||
### `endpoint`
|
||||
|
||||
Defines the Consul server endpoint.
|
||||
|
||||
#### `address`
|
||||
|
||||
Defines the address of the Consul server.
|
||||
|
||||
_Optional, Default="127.0.0.1:8500"_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
@@ -186,12 +200,12 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Defines the address of the Consul server.
|
||||
|
||||
#### `scheme`
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
Defines the URI scheme for the Consul server.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
[providers.consulCatalog.endpoint]
|
||||
@@ -212,12 +226,13 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Defines the URI scheme for the Consul server.
|
||||
|
||||
#### `datacenter`
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
Defines the datacenter to use.
|
||||
If not provided in Traefik, Consul uses the default agent datacenter.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
[providers.consulCatalog.endpoint]
|
||||
@@ -238,13 +253,12 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Defines the Data center to use.
|
||||
If not provided, the default agent data center is used.
|
||||
|
||||
#### `token`
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
Token is used to provide a per-request ACL token which overwrites the agent's default token.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
[providers.consulCatalog.endpoint]
|
||||
@@ -265,12 +279,13 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Token is used to provide a per-request ACL token which overrides the agent's default token.
|
||||
|
||||
#### `endpointWaitTime`
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
Limits the duration for which a Watch can block.
|
||||
If not provided, the agent default values will be used.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
[providers.consulCatalog.endpoint]
|
||||
@@ -291,18 +306,17 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
WaitTime limits how long a Watch will block.
|
||||
If not provided, the agent default values will be used
|
||||
|
||||
#### `httpAuth`
|
||||
|
||||
_Optional_
|
||||
|
||||
Used to authenticate http client with HTTP Basic Authentication.
|
||||
Used to authenticate the HTTP client using HTTP Basic Authentication.
|
||||
|
||||
##### `username`
|
||||
|
||||
_Optional_
|
||||
_Optional, Default=""_
|
||||
|
||||
Username to use for HTTP Basic Authentication.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog.endpoint.httpAuth]
|
||||
@@ -321,11 +335,11 @@ providers:
|
||||
--providers.consulcatalog.endpoint.httpauth.username=test
|
||||
```
|
||||
|
||||
Username to use for HTTP Basic Authentication
|
||||
|
||||
##### `password`
|
||||
|
||||
_Optional_
|
||||
_Optional, Default=""_
|
||||
|
||||
Password to use for HTTP Basic Authentication.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog.endpoint.httpAuth]
|
||||
@@ -344,8 +358,6 @@ providers:
|
||||
--providers.consulcatalog.endpoint.httpauth.password=test
|
||||
```
|
||||
|
||||
Password to use for HTTP Basic Authentication
|
||||
|
||||
#### `tls`
|
||||
|
||||
_Optional_
|
||||
@@ -356,6 +368,8 @@ Defines TLS options for Consul server endpoint.
|
||||
|
||||
_Optional_
|
||||
|
||||
`ca` is the path to the CA certificate used for Consul communication, defaults to the system bundle if not specified.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog.endpoint.tls]
|
||||
ca = "path/to/ca.crt"
|
||||
@@ -373,12 +387,20 @@ providers:
|
||||
--providers.consulcatalog.endpoint.tls.ca=path/to/ca.crt
|
||||
```
|
||||
|
||||
`ca` is the path to the CA certificate used for Consul communication, defaults to the system bundle if not specified.
|
||||
|
||||
##### `caOptional`
|
||||
|
||||
_Optional_
|
||||
|
||||
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Consul.
|
||||
|
||||
!!! warning ""
|
||||
|
||||
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
|
||||
|
||||
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
|
||||
|
||||
When this option is set to `false`, a client certificate is requested during the handshake, and at least one valid certificate should be sent by the client.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog.endpoint.tls]
|
||||
caOptional = true
|
||||
@@ -396,17 +418,14 @@ providers:
|
||||
--providers.consulcatalog.endpoint.tls.caoptional=true
|
||||
```
|
||||
|
||||
Policy followed for the secured connection with TLS Client Authentication to Consul.
|
||||
Requires `tls.ca` to be defined.
|
||||
|
||||
- `true`: VerifyClientCertIfGiven
|
||||
- `false`: RequireAndVerifyClientCert
|
||||
- if `tls.ca` is undefined NoClientCert
|
||||
|
||||
##### `cert`
|
||||
|
||||
_Optional_
|
||||
|
||||
`cert` is the path to the public certificate to use for Consul communication.
|
||||
|
||||
When using this option, setting the `key` option is required.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog.endpoint.tls]
|
||||
cert = "path/to/foo.cert"
|
||||
@@ -427,13 +446,14 @@ providers:
|
||||
--providers.consulcatalog.endpoint.tls.key=path/to/foo.key
|
||||
```
|
||||
|
||||
`cert` is the path to the public certificate for Consul communication.
|
||||
If this is set then you need to also set `key.
|
||||
|
||||
##### `key`
|
||||
|
||||
_Optional_
|
||||
|
||||
`key` is the path to the private key for Consul communication.
|
||||
|
||||
When using this option, setting the `cert` option is required.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog.endpoint.tls]
|
||||
cert = "path/to/foo.cert"
|
||||
@@ -454,13 +474,12 @@ providers:
|
||||
--providers.consulcatalog.endpoint.tls.key=path/to/foo.key
|
||||
```
|
||||
|
||||
`key` is the path to the private key for Consul communication.
|
||||
If this is set then you need to also set `cert`.
|
||||
|
||||
##### `insecureSkipVerify`
|
||||
|
||||
_Optional_
|
||||
|
||||
If `insecureSkipVerify` is `true`, the TLS connection to Consul accepts any certificate presented by the server regardless of the hostnames it covers.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog.endpoint.tls]
|
||||
insecureSkipVerify = true
|
||||
@@ -478,12 +497,15 @@ providers:
|
||||
--providers.consulcatalog.endpoint.tls.insecureskipverify=true
|
||||
```
|
||||
|
||||
If `insecureSkipVerify` is `true`, TLS for the connection to Consul server accepts any certificate presented by the server and any host name in that certificate.
|
||||
|
||||
### `exposedByDefault`
|
||||
|
||||
_Optional, Default=true_
|
||||
|
||||
Expose Consul Catalog services by default in Traefik.
|
||||
If set to `false`, services that don't have a `traefik.enable=true` tag will be ignored from the resulting routing configuration.
|
||||
|
||||
For additional information, refer to [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
exposedByDefault = false
|
||||
@@ -502,15 +524,20 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Expose Consul Catalog services by default in Traefik.
|
||||
If set to false, services that don't have a `traefik.enable=true` tag will be ignored from the resulting routing configuration.
|
||||
|
||||
See also [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
|
||||
|
||||
### `defaultRule`
|
||||
|
||||
_Optional, Default=```Host(`{{ normalize .Name }}`)```_
|
||||
|
||||
The default host rule for all services.
|
||||
|
||||
For a given service, if no routing rule was defined by a tag, it is defined by this `defaultRule` instead.
|
||||
The `defaultRule` must be set to a valid [Go template](https://golang.org/pkg/text/template/),
|
||||
and can include [sprig template functions](http://masterminds.github.io/sprig/).
|
||||
The service name can be accessed with the `Name` identifier,
|
||||
and the template has access to all the labels (i.e. tags beginning with the `prefix`) defined on this service.
|
||||
|
||||
The option can be overridden on an instance basis with the `traefik.http.routers.{name-of-your-choice}.rule` tag.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)"
|
||||
@@ -529,20 +556,49 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
The default host rule for all services.
|
||||
|
||||
For a given service if no routing rule was defined by a tag, it is defined by this defaultRule instead.
|
||||
It must be a valid [Go template](https://golang.org/pkg/text/template/),
|
||||
augmented with the [sprig template functions](http://masterminds.github.io/sprig/).
|
||||
The service name can be accessed as the `Name` identifier,
|
||||
and the template has access to all the labels (i.e. tags beginning with the `prefix`) defined on this service.
|
||||
|
||||
The option can be overridden on an instance basis with the `traefik.http.routers.{name-of-your-choice}.rule` tag.
|
||||
|
||||
### `constraints`
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
The `constraints` option can be set to an expression that Traefik matches against the service tags to determine whether
|
||||
to create any route for that service. If none of the service tags match the expression, no route for that service is
|
||||
created. If the expression is empty, all detected services are included.
|
||||
|
||||
The expression syntax is based on the ```Tag(`tag`)```, and ```TagRegex(`tag`)``` functions,
|
||||
as well as the usual boolean logic, as shown in examples below.
|
||||
|
||||
??? example "Constraints Expression Examples"
|
||||
|
||||
```toml
|
||||
# Includes only services having the tag `a.tag.name=foo`
|
||||
constraints = "Tag(`a.tag.name=foo`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Excludes services having any tag `a.tag.name=foo`
|
||||
constraints = "!Tag(`a.tag.name=foo`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND.
|
||||
constraints = "Tag(`a.tag.name`) && Tag(`another.tag.name`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical OR.
|
||||
constraints = "Tag(`a.tag.name`) || Tag(`another.tag.name`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND and OR, with precedence set by parentheses.
|
||||
constraints = "Tag(`a.tag.name`) && (Tag(`another.tag.name`) || Tag(`yet.another.tag.name`))"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Includes only services having a tag matching the `a\.tag\.t.+` regular expression.
|
||||
constraints = "TagRegex(`a\.tag\.t.+`)"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
constraints = "Tag(`a.tag.name`)"
|
||||
@@ -561,43 +617,4 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Constraints is an expression that Traefik matches against the service's tags to determine whether to create any route for that service.
|
||||
That is to say, if none of the service's tags match the expression, no route for that service is created.
|
||||
If the expression is empty, all detected services are included.
|
||||
|
||||
The expression syntax is based on the ```Tag(`tag`)```, and ```TagRegex(`tag`)``` functions,
|
||||
as well as the usual boolean logic, as shown in examples below.
|
||||
|
||||
??? example "Constraints Expression Examples"
|
||||
|
||||
```toml
|
||||
# Includes only services having the tag `a.tag.name=foo`
|
||||
constraints = "Tag(`a.tag.name=foo`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Excludes services having any tag `a.tag.name=foo`
|
||||
constraints = "!Tag(`a.tag.name=foo`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND.
|
||||
constraints = "Tag(`a.tag.name`) && Tag(`another.tag.name`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical OR.
|
||||
constraints = "Tag(`a.tag.name`) || Tag(`another.tag.name`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND and OR, with precedence set by parentheses.
|
||||
constraints = "Tag(`a.tag.name`) && (Tag(`another.tag.name`) || Tag(`yet.another.tag.name`))"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Includes only services having a tag matching the `a\.tag\.t.+` regular expression.
|
||||
constraints = "TagRegex(`a\.tag\.t.+`)"
|
||||
```
|
||||
|
||||
See also [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
|
||||
For additional information, refer to [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
|
||||
|
@@ -35,10 +35,10 @@ providers:
|
||||
|
||||
### `rootKey`
|
||||
|
||||
Defines the root key of the configuration.
|
||||
|
||||
_Required, Default="traefik"_
|
||||
|
||||
Defines the root key of the configuration.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consul]
|
||||
rootKey = "traefik"
|
||||
@@ -56,10 +56,10 @@ providers:
|
||||
|
||||
### `username`
|
||||
|
||||
Defines a username to connect with Consul.
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
Defines a username to connect to Consul with.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consul]
|
||||
# ...
|
||||
@@ -81,7 +81,7 @@ providers:
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
Defines a password to connect with Consul.
|
||||
Defines a password with which to connect to Consul.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consul]
|
||||
@@ -106,7 +106,7 @@ _Optional_
|
||||
|
||||
#### `tls.ca`
|
||||
|
||||
Certificate Authority used for the secured connection to Consul.
|
||||
Certificate Authority used for the secure connection to Consul.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consul.tls]
|
||||
@@ -126,12 +126,15 @@ providers:
|
||||
|
||||
#### `tls.caOptional`
|
||||
|
||||
Policy followed for the secured connection with TLS Client Authentication to Consul.
|
||||
Requires `tls.ca` to be defined.
|
||||
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Consul.
|
||||
|
||||
- `true`: VerifyClientCertIfGiven
|
||||
- `false`: RequireAndVerifyClientCert
|
||||
- if `tls.ca` is undefined NoClientCert
|
||||
!!! warning ""
|
||||
|
||||
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
|
||||
|
||||
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
|
||||
|
||||
When this option is set to `false`, a client certificate is requested during the handshake, and at least one valid certificate should be sent by the client.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consul.tls]
|
||||
@@ -151,7 +154,7 @@ providers:
|
||||
|
||||
#### `tls.cert`
|
||||
|
||||
Public certificate used for the secured connection to Consul.
|
||||
Public certificate used for the secure connection to Consul.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consul.tls]
|
||||
@@ -174,7 +177,7 @@ providers:
|
||||
|
||||
#### `tls.key`
|
||||
|
||||
Private certificate used for the secured connection to Consul.
|
||||
Private certificate used for the secure connection to Consul.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consul.tls]
|
||||
@@ -197,7 +200,7 @@ providers:
|
||||
|
||||
#### `tls.insecureSkipVerify`
|
||||
|
||||
If `insecureSkipVerify` is `true`, TLS for the connection to Consul accepts any certificate presented by the server and any host name in that certificate.
|
||||
If `insecureSkipVerify` is `true`, the TLS connection to Consul accepts any certificate presented by the server regardless of the hostnames it covers.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consul.tls]
|
||||
|
@@ -11,23 +11,24 @@ Traefik works with both [Docker (standalone) Engine](https://docs.docker.com/eng
|
||||
and [Docker Swarm Mode](https://docs.docker.com/engine/swarm/).
|
||||
|
||||
!!! tip "The Quick Start Uses Docker"
|
||||
If you haven't already, maybe you'd like to go through the [quick start](../getting-started/quick-start.md) that uses the docker provider!
|
||||
|
||||
If you have not already read it, maybe you would like to go through the [quick start guide](../getting-started/quick-start.md) that uses the Docker provider.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
??? example "Configuring Docker & Deploying / Exposing Services"
|
||||
|
||||
Enabling the docker provider
|
||||
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.docker]
|
||||
```
|
||||
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
docker: {}
|
||||
```
|
||||
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.docker=true
|
||||
```
|
||||
@@ -55,7 +56,7 @@ and [Docker Swarm Mode](https://docs.docker.com/engine/swarm/).
|
||||
endpoint = "tcp://127.0.0.1:2377"
|
||||
swarmMode = true
|
||||
```
|
||||
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
docker:
|
||||
@@ -65,7 +66,7 @@ and [Docker Swarm Mode](https://docs.docker.com/engine/swarm/).
|
||||
endpoint: "tcp://127.0.0.1:2377"
|
||||
swarmMode: true
|
||||
```
|
||||
|
||||
|
||||
```bash tab="CLI"
|
||||
# swarm classic (1.12-)
|
||||
# --providers.docker.endpoint=tcp://127.0.0.1:2375
|
||||
@@ -98,21 +99,22 @@ See the list of labels in the dedicated [routing](../routing/providers/docker.md
|
||||
By default, Traefik watches for [container level labels](https://docs.docker.com/config/labels-custom-metadata/) on a standalone Docker Engine.
|
||||
|
||||
When using Docker Compose, labels are specified by the directive
|
||||
[`labels`](https://docs.docker.com/compose/compose-file/#labels) from the
|
||||
["services" objects](https://docs.docker.com/compose/compose-file/#service-configuration-reference).
|
||||
[`labels`](https://docs.docker.com/compose/compose-file/compose-file-v3/#labels) from the
|
||||
["services" objects](https://docs.docker.com/compose/compose-file/compose-file-v3/#service-configuration-reference).
|
||||
|
||||
!!! tip "Not Only Docker"
|
||||
|
||||
Please note that any tool like Nomad, Terraform, Ansible, etc.
|
||||
that is able to define a Docker container with labels can work
|
||||
with Traefik & the Docker provider.
|
||||
with Traefik and the Docker provider.
|
||||
|
||||
### Port Detection
|
||||
|
||||
Traefik retrieves the private IP and port of containers from the Docker API.
|
||||
|
||||
Ports detection works as follows:
|
||||
Port detection works as follows:
|
||||
|
||||
- If a container [exposes](https://docs.docker.com/engine/reference/builder/#expose) only one port,
|
||||
- If a container [exposes](https://docs.docker.com/engine/reference/builder/#expose) a single port,
|
||||
then Traefik uses this port for private communication.
|
||||
- If a container [exposes](https://docs.docker.com/engine/reference/builder/#expose) multiple ports,
|
||||
or does not expose any port, then you must manually specify which port Traefik should use for communication
|
||||
@@ -126,12 +128,11 @@ the IP address of the host is resolved as follows:
|
||||
|
||||
<!-- TODO: verify and document the swarm mode case with container.Node.IPAddress coming from the API -->
|
||||
- try a lookup of `host.docker.internal`
|
||||
- otherwise fall back to `127.0.0.1`
|
||||
- if the lookup was unsuccessful, fall back to `127.0.0.1`
|
||||
|
||||
On Linux, (and until [github.com/moby/moby/pull/40007](https://github.com/moby/moby/pull/40007) is included in a release),
|
||||
for `host.docker.internal` to be defined, it should be provided as an `extra_host` to the Traefik container,
|
||||
using the `--add-host` flag. For example, to set it to the IP address of the bridge interface (docker0 by default):
|
||||
`--add-host=host.docker.internal:172.17.0.1`
|
||||
On Linux, for versions of Docker older than 20.10.0, for `host.docker.internal` to be defined, it should be provided
|
||||
as an `extra_host` to the Traefik container, using the `--add-host` flag. For example, to set it to the IP address of
|
||||
the bridge interface (`docker0` by default): `--add-host=host.docker.internal:172.17.0.1`
|
||||
|
||||
### Docker API Access
|
||||
|
||||
@@ -145,9 +146,10 @@ You can specify which Docker API Endpoint to use with the directive [`endpoint`]
|
||||
If Traefik is attacked, then the attacker might get access to the underlying host.
|
||||
{: #security-note }
|
||||
|
||||
As explained in the Docker documentation: ([Docker Daemon Attack Surface page](https://docs.docker.com/engine/security/#docker-daemon-attack-surface)):
|
||||
As explained in the [Docker Daemon Attack Surface documentation](https://docs.docker.com/engine/security/#docker-daemon-attack-surface):
|
||||
|
||||
!!! quote
|
||||
|
||||
[...] only **trusted** users should be allowed to control your Docker daemon [...]
|
||||
|
||||
??? success "Solutions"
|
||||
@@ -155,7 +157,7 @@ You can specify which Docker API Endpoint to use with the directive [`endpoint`]
|
||||
Expose the Docker socket over TCP or SSH, instead of the default Unix socket file.
|
||||
It allows different implementation levels of the [AAA (Authentication, Authorization, Accounting) concepts](https://en.wikipedia.org/wiki/AAA_(computer_security)), depending on your security assessment:
|
||||
|
||||
- Authentication with Client Certificates as described in ["Protect the Docker daemon socket."](https://docs.docker.com/engine/security/https/)
|
||||
- Authentication with Client Certificates as described in ["Protect the Docker daemon socket."](https://docs.docker.com/engine/security/protect-access/)
|
||||
- Authorize and filter requests to restrict possible actions with [the TecnativaDocker Socket Proxy](https://github.com/Tecnativa/docker-socket-proxy).
|
||||
- Authorization with the [Docker Authorization Plugin Mechanism](https://web.archive.org/web/20190920092526/https://docs.docker.com/engine/extend/plugins_authorization/)
|
||||
- Accounting at networking level, by exposing the socket only inside a Docker private network, only available for Traefik.
|
||||
@@ -165,6 +167,7 @@ You can specify which Docker API Endpoint to use with the directive [`endpoint`]
|
||||
- SSH public key authentication (SSH is supported with Docker > 18.09)
|
||||
|
||||
??? info "More Resources and Examples"
|
||||
|
||||
- ["Paranoid about mounting /var/run/docker.sock?"](https://medium.com/@containeroo/traefik-2-0-paranoid-about-mounting-var-run-docker-sock-22da9cb3e78c)
|
||||
- [Traefik and Docker: A Discussion with Docker Captain, Bret Fisher](https://blog.traefik.io/traefik-and-docker-a-discussion-with-docker-captain-bret-fisher-7f0b9a54ff88)
|
||||
- [KubeCon EU 2018 Keynote, Running with Scissors, from Liz Rice](https://www.youtube.com/watch?v=ltrV-Qmh3oY)
|
||||
@@ -186,23 +189,23 @@ set the [`swarmMode`](#swarmmode) directive to `true`.
|
||||
While in Swarm Mode, Traefik uses labels found on services, not on individual containers.
|
||||
|
||||
Therefore, if you use a compose file with Swarm Mode, labels should be defined in the
|
||||
[`deploy`](https://docs.docker.com/compose/compose-file/#labels-1) part of your service.
|
||||
[`deploy`](https://docs.docker.com/compose/compose-file/compose-file-v3/#labels-1) part of your service.
|
||||
|
||||
This behavior is only enabled for docker-compose version 3+ ([Compose file reference](https://docs.docker.com/compose/compose-file)).
|
||||
This behavior is only enabled for docker-compose version 3+ ([Compose file reference](https://docs.docker.com/compose/compose-file/compose-file-v3/)).
|
||||
|
||||
### Port Detection
|
||||
|
||||
Docker Swarm does not provide any [port detection](#port-detection) information to Traefik.
|
||||
|
||||
Therefore you **must** specify the port to use for communication by using the label `traefik.http.services.<service_name>.loadbalancer.server.port`
|
||||
Therefore, you **must** specify the port to use for communication by using the label `traefik.http.services.<service_name>.loadbalancer.server.port`
|
||||
(Check the reference for this label in the [routing section for Docker](../routing/providers/docker.md#port)).
|
||||
|
||||
### Docker API Access
|
||||
|
||||
Docker Swarm Mode follows the same rules as Docker [API Access](#docker-api-access).
|
||||
|
||||
As the Swarm API is only exposed on the [manager nodes](https://docs.docker.com/engine/swarm/how-swarm-mode-works/nodes/#manager-nodes), you should schedule Traefik on the Swarm manager nodes by default,
|
||||
by deploying Traefik with a constraint on the node's "role":
|
||||
Since the Swarm API is only exposed on the [manager nodes](https://docs.docker.com/engine/swarm/how-swarm-mode-works/nodes/#manager-nodes),
|
||||
these are the nodes that Traefik should be scheduled on by deploying Traefik with a constraint on the node "role":
|
||||
|
||||
```shell tab="With Docker CLI"
|
||||
docker service create \
|
||||
@@ -223,13 +226,13 @@ services:
|
||||
```
|
||||
|
||||
!!! tip "Scheduling Traefik on Worker Nodes"
|
||||
|
||||
|
||||
Following the guidelines given in the previous section ["Docker API Access"](#docker-api-access),
|
||||
if you expose the Docker API through TCP, then Traefik can be scheduled on any node if the TCP
|
||||
socket is reachable.
|
||||
|
||||
|
||||
Please consider the security implications by reading the [Security Note](#security-note).
|
||||
|
||||
|
||||
A good example can be found on [Bret Fisher's repository](https://github.com/BretFisher/dogvscat/blob/master/stack-proxy-global.yml#L124).
|
||||
|
||||
## Provider Configuration
|
||||
@@ -238,21 +241,6 @@ services:
|
||||
|
||||
_Required, Default="unix:///var/run/docker.sock"_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.docker]
|
||||
endpoint = "unix:///var/run/docker.sock"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
docker:
|
||||
endpoint: "unix:///var/run/docker.sock"
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.docker.endpoint=unix:///var/run/docker.sock
|
||||
```
|
||||
|
||||
See the sections [Docker API Access](#docker-api-access) and [Docker Swarm API Access](#docker-api-access_1) for more information.
|
||||
|
||||
??? example "Using the docker.sock"
|
||||
@@ -264,7 +252,7 @@ See the sections [Docker API Access](#docker-api-access) and [Docker Swarm API A
|
||||
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:v2.3 # The official v2 Traefik docker image
|
||||
image: traefik:v2.4 # The official v2 Traefik docker image
|
||||
ports:
|
||||
- "80:80"
|
||||
volumes:
|
||||
@@ -278,14 +266,14 @@ See the sections [Docker API Access](#docker-api-access) and [Docker Swarm API A
|
||||
endpoint = "unix:///var/run/docker.sock"
|
||||
# ...
|
||||
```
|
||||
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
docker:
|
||||
endpoint: "unix:///var/run/docker.sock"
|
||||
# ...
|
||||
```
|
||||
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.docker.endpoint=unix:///var/run/docker.sock
|
||||
# ...
|
||||
@@ -302,23 +290,66 @@ See the sections [Docker API Access](#docker-api-access) and [Docker Swarm API A
|
||||
endpoint = "ssh://traefik@192.168.2.5:2022"
|
||||
# ...
|
||||
```
|
||||
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
docker:
|
||||
endpoint: "ssh://traefik@192.168.2.5:2022"
|
||||
# ...
|
||||
```
|
||||
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.docker.endpoint=ssh://traefik@192.168.2.5:2022
|
||||
# ...
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.docker]
|
||||
endpoint = "unix:///var/run/docker.sock"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
docker:
|
||||
endpoint: "unix:///var/run/docker.sock"
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.docker.endpoint=unix:///var/run/docker.sock
|
||||
```
|
||||
|
||||
### `useBindPortIP`
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
Traefik routes requests to the IP/port of the matching container.
|
||||
When setting `useBindPortIP=true`, you tell Traefik to use the IP/Port attached to the container's _binding_ instead of its inner network IP/Port.
|
||||
|
||||
When used in conjunction with the `traefik.http.services.<name>.loadbalancer.server.port` label (that tells Traefik to route requests to a specific port),
|
||||
Traefik tries to find a binding on port `traefik.http.services.<name>.loadbalancer.server.port`.
|
||||
If it cannot find such a binding, Traefik falls back on the internal network IP of the container,
|
||||
but still uses the `traefik.http.services.<name>.loadbalancer.server.port` that is set in the label.
|
||||
|
||||
??? example "Examples of `usebindportip` in different situations."
|
||||
|
||||
| port label | Container's binding | Routes to |
|
||||
|--------------------|----------------------------------------------------|----------------|
|
||||
| - | - | IntIP:IntPort |
|
||||
| - | ExtPort:IntPort | IntIP:IntPort |
|
||||
| - | ExtIp:ExtPort:IntPort | ExtIp:ExtPort |
|
||||
| LblPort | - | IntIp:LblPort |
|
||||
| LblPort | ExtIp:ExtPort:LblPort | ExtIp:ExtPort |
|
||||
| LblPort | ExtIp:ExtPort:OtherPort | IntIp:LblPort |
|
||||
| LblPort | ExtIp1:ExtPort1:IntPort1 & ExtIp2:LblPort:IntPort2 | ExtIp2:LblPort |
|
||||
|
||||
!!! info ""
|
||||
In the above table:
|
||||
|
||||
- `ExtIp` stands for "external IP found in the binding"
|
||||
- `IntIp` stands for "internal network container's IP",
|
||||
- `ExtPort` stands for "external Port found in the binding"
|
||||
- `IntPort` stands for "internal network container's port."
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.docker]
|
||||
useBindPortIP = true
|
||||
@@ -337,38 +368,15 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Traefik routes requests to the IP/Port of the matching container.
|
||||
When setting `useBindPortIP=true`, you tell Traefik to use the IP/Port attached to the container's _binding_ instead of its inner network IP/Port.
|
||||
|
||||
When used in conjunction with the `traefik.http.services.<name>.loadbalancer.server.port` label (that tells Traefik to route requests to a specific port),
|
||||
Traefik tries to find a binding on port `traefik.http.services.<name>.loadbalancer.server.port`.
|
||||
If it can't find such a binding, Traefik falls back on the internal network IP of the container,
|
||||
but still uses the `traefik.http.services.<name>.loadbalancer.server.port` that is set in the label.
|
||||
|
||||
??? example "Examples of `usebindportip` in different situations."
|
||||
|
||||
| port label | Container's binding | Routes to |
|
||||
|--------------------|----------------------------------------------------|----------------|
|
||||
| - | - | IntIP:IntPort |
|
||||
| - | ExtPort:IntPort | IntIP:IntPort |
|
||||
| - | ExtIp:ExtPort:IntPort | ExtIp:ExtPort |
|
||||
| LblPort | - | IntIp:LblPort |
|
||||
| LblPort | ExtIp:ExtPort:LblPort | ExtIp:ExtPort |
|
||||
| LblPort | ExtIp:ExtPort:OtherPort | IntIp:LblPort |
|
||||
| LblPort | ExtIp1:ExtPort1:IntPort1 & ExtIp2:LblPort:IntPort2 | ExtIp2:LblPort |
|
||||
|
||||
!!! info ""
|
||||
In the above table:
|
||||
|
||||
- `ExtIp` stands for "external IP found in the binding"
|
||||
- `IntIp` stands for "internal network container's IP",
|
||||
- `ExtPort` stands for "external Port found in the binding"
|
||||
- `IntPort` stands for "internal network container's port."
|
||||
|
||||
### `exposedByDefault`
|
||||
|
||||
_Optional, Default=true_
|
||||
|
||||
Expose containers by default through Traefik.
|
||||
If set to `false`, containers that do not have a `traefik.enable=true` label are ignored from the resulting routing configuration.
|
||||
|
||||
For additional information, refer to [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.docker]
|
||||
exposedByDefault = false
|
||||
@@ -387,14 +395,13 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Expose containers by default through Traefik.
|
||||
If set to false, containers that don't have a `traefik.enable=true` label will be ignored from the resulting routing configuration.
|
||||
|
||||
See also [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
|
||||
|
||||
### `network`
|
||||
|
||||
_Optional, Default=empty_
|
||||
_Optional, Default=""_
|
||||
|
||||
Defines a default docker network to use for connections to all containers.
|
||||
|
||||
This option can be overridden on a per-container basis with the `traefik.docker.network` label.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.docker]
|
||||
@@ -414,14 +421,17 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Defines a default docker network to use for connections to all containers.
|
||||
|
||||
This option can be overridden on a container basis with the `traefik.docker.network` label.
|
||||
|
||||
### `defaultRule`
|
||||
|
||||
_Optional, Default=```Host(`{{ normalize .Name }}`)```_
|
||||
|
||||
The `defaultRule` option defines what routing rule to apply to a container if no rule is defined by a label.
|
||||
|
||||
It must be a valid [Go template](https://golang.org/pkg/text/template/), and can use
|
||||
[sprig template functions](http://masterminds.github.io/sprig/).
|
||||
The container service name can be accessed with the `Name` identifier,
|
||||
and the template has access to all the labels defined on this container.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.docker]
|
||||
defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)"
|
||||
@@ -440,16 +450,12 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
For a given container if no routing rule was defined by a label, it is defined by this defaultRule instead.
|
||||
It must be a valid [Go template](https://golang.org/pkg/text/template/),
|
||||
augmented with the [sprig template functions](http://masterminds.github.io/sprig/).
|
||||
The container service name can be accessed as the `Name` identifier,
|
||||
and the template has access to all the labels defined on this container.
|
||||
|
||||
### `swarmMode`
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
Enables the Swarm Mode (instead of standalone Docker).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.docker]
|
||||
swarmMode = true
|
||||
@@ -468,12 +474,12 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Activates the Swarm Mode (instead of standalone Docker).
|
||||
|
||||
### `swarmModeRefreshSeconds`
|
||||
|
||||
_Optional, Default=15_
|
||||
|
||||
Defines the polling interval (in seconds) for Swarm Mode.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.docker]
|
||||
swarmModeRefreshSeconds = 30
|
||||
@@ -492,12 +498,36 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Defines the polling interval (in seconds) in Swarm Mode.
|
||||
### `httpClientTimeout`
|
||||
|
||||
_Optional, Default=0_
|
||||
|
||||
Defines the client timeout (in seconds) for HTTP connections. If its value is `0`, no timeout is set.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.docker]
|
||||
httpClientTimeout = 300
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
docker:
|
||||
httpClientTimeout: 300
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.docker.httpClientTimeout=300
|
||||
# ...
|
||||
```
|
||||
|
||||
### `watch`
|
||||
|
||||
_Optional, Default=true_
|
||||
|
||||
Watch Docker Swarm events.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.docker]
|
||||
watch = false
|
||||
@@ -516,12 +546,51 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Watch Docker Swarm events.
|
||||
|
||||
### `constraints`
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
The `constraints` option can be set to an expression that Traefik matches against the container tags to determine whether
|
||||
to create any route for that container. If none of the container tags match the expression, no route for that container is
|
||||
created. If the expression is empty, all detected containers are included.
|
||||
|
||||
The expression syntax is based on the ```Tag(`tag`)```, and ```TagRegex(`tag`)``` functions,
|
||||
as well as the usual boolean logic, as shown in examples below.
|
||||
|
||||
??? example "Constraints Expression Examples"
|
||||
|
||||
```toml
|
||||
# Includes only containers having a label with key `a.label.name` and value `foo`
|
||||
constraints = "Label(`a.label.name`, `foo`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Excludes containers having any label with key `a.label.name` and value `foo`
|
||||
constraints = "!Label(`a.label.name`, `value`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND.
|
||||
constraints = "Label(`a.label.name`, `valueA`) && Label(`another.label.name`, `valueB`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical OR.
|
||||
constraints = "Label(`a.label.name`, `valueA`) || Label(`another.label.name`, `valueB`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND and OR, with precedence set by parentheses.
|
||||
constraints = "Label(`a.label.name`, `valueA`) && (Label(`another.label.name`, `valueB`) || Label(`yet.another.label.name`, `valueC`))"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Includes only containers having a label with key `a.label.name` and a value matching the `a.+` regular expression.
|
||||
constraints = "LabelRegex(`a.label.name`, `a.+`)"
|
||||
```
|
||||
|
||||
For additional information, refer to [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.docker]
|
||||
constraints = "Label(`a.label.name`,`foo`)"
|
||||
@@ -540,53 +609,13 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container.
|
||||
That is to say, if none of the container's labels match the expression, no route for the container is created.
|
||||
If the expression is empty, all detected containers are included.
|
||||
|
||||
The expression syntax is based on the `Label("key", "value")`, and `LabelRegex("key", "value")` functions, as well as the usual boolean logic, as shown in examples below.
|
||||
|
||||
??? example "Constraints Expression Examples"
|
||||
|
||||
```toml
|
||||
# Includes only containers having a label with key `a.label.name` and value `foo`
|
||||
constraints = "Label(`a.label.name`, `foo`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Excludes containers having any label with key `a.label.name` and value `foo`
|
||||
constraints = "!Label(`a.label.name`, `value`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND.
|
||||
constraints = "Label(`a.label.name`, `valueA`) && Label(`another.label.name`, `valueB`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical OR.
|
||||
constraints = "Label(`a.label.name`, `valueA`) || Label(`another.label.name`, `valueB`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND and OR, with precedence set by parentheses.
|
||||
constraints = "Label(`a.label.name`, `valueA`) && (Label(`another.label.name`, `valueB`) || Label(`yet.another.label.name`, `valueC`))"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Includes only containers having a label with key `a.label.name` and a value matching the `a.+` regular expression.
|
||||
constraints = "LabelRegex(`a.label.name`, `a.+`)"
|
||||
```
|
||||
|
||||
See also [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
|
||||
|
||||
### `tls`
|
||||
|
||||
_Optional_
|
||||
|
||||
#### `tls.ca`
|
||||
|
||||
Certificate Authority used for the secured connection to Docker.
|
||||
Certificate Authority used for the secure connection to Docker.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.docker.tls]
|
||||
@@ -606,12 +635,15 @@ providers:
|
||||
|
||||
#### `tls.caOptional`
|
||||
|
||||
Policy followed for the secured connection with TLS Client Authentication to Docker.
|
||||
Requires `tls.ca` to be defined.
|
||||
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Docker.
|
||||
|
||||
- `true`: VerifyClientCertIfGiven
|
||||
- `false`: RequireAndVerifyClientCert
|
||||
- if `tls.ca` is undefined NoClientCert
|
||||
!!! warning ""
|
||||
|
||||
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
|
||||
|
||||
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
|
||||
|
||||
When this option is set to `false`, a client certificate is requested during the handshake, and at least one valid certificate should be sent by the client.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.docker.tls]
|
||||
@@ -631,7 +663,7 @@ providers:
|
||||
|
||||
#### `tls.cert`
|
||||
|
||||
Public certificate used for the secured connection to Docker.
|
||||
Public certificate used for the secure connection to Docker.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.docker.tls]
|
||||
@@ -654,7 +686,7 @@ providers:
|
||||
|
||||
#### `tls.key`
|
||||
|
||||
Private certificate used for the secured connection to Docker.
|
||||
Private certificate used for the secure connection to Docker.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.docker.tls]
|
||||
@@ -677,7 +709,7 @@ providers:
|
||||
|
||||
#### `tls.insecureSkipVerify`
|
||||
|
||||
If `insecureSkipVerify` is `true`, TLS for the connection to Docker accepts any certificate presented by the server and any host name in that certificate.
|
||||
If `insecureSkipVerify` is `true`, the TLS connection to Docker accepts any certificate presented by the server regardless of the hostnames it covers.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.docker.tls]
|
||||
|
@@ -10,16 +10,16 @@ Attach labels to your ECS containers and let Traefik do the rest!
|
||||
??? example "Configuring ECS provider"
|
||||
|
||||
Enabling the ECS provider:
|
||||
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.ecs]
|
||||
```
|
||||
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
ecs: {}
|
||||
```
|
||||
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.ecs=true
|
||||
```
|
||||
@@ -52,12 +52,17 @@ Traefik needs the following policy to read ECS information:
|
||||
}
|
||||
```
|
||||
|
||||
## Provider configuration
|
||||
## Provider Configuration
|
||||
|
||||
### `autoDiscoverClusters`
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
Search for services in cluster list.
|
||||
|
||||
- If set to `true` service discovery is disabled on configured clusters, but enabled for all other clusters.
|
||||
- If set to `false` service discovery is enabled on configured clusters only.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.ecs]
|
||||
autoDiscoverClusters = true
|
||||
@@ -76,15 +81,12 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Search for services in clusters list.
|
||||
|
||||
- If set to `true` the configured clusters will be ignored and the clusters will be discovered.
|
||||
- If set to `false` the services will be discovered only in configured clusters.
|
||||
|
||||
### `clusters`
|
||||
|
||||
_Optional, Default=["default"]_
|
||||
|
||||
Search for services in cluster list.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.ecs]
|
||||
clusters = ["default"]
|
||||
@@ -104,12 +106,14 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Search for services in clusters list.
|
||||
|
||||
### `exposedByDefault`
|
||||
|
||||
_Optional, Default=true_
|
||||
|
||||
Expose ECS services by default in Traefik.
|
||||
|
||||
If set to `false`, services that do not have a `traefik.enable=true` label are ignored from the resulting routing configuration.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.ecs]
|
||||
exposedByDefault = false
|
||||
@@ -128,13 +132,17 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Expose ECS services by default in Traefik.
|
||||
If set to false, services that don't have a `traefik.enable=true` label will be ignored from the resulting routing configuration.
|
||||
|
||||
### `defaultRule`
|
||||
|
||||
_Optional, Default=```Host(`{{ normalize .Name }}`)```_
|
||||
|
||||
The `defaultRule` option defines what routing rule to apply to a container if no rule is defined by a label.
|
||||
|
||||
It must be a valid [Go template](https://golang.org/pkg/text/template/), and can use
|
||||
[sprig template functions](http://masterminds.github.io/sprig/).
|
||||
The container service name can be accessed with the `Name` identifier,
|
||||
and the template has access to all the labels defined on this container.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.ecs]
|
||||
defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)"
|
||||
@@ -153,16 +161,12 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
For a given container if no routing rule was defined by a label, it is defined by this defaultRule instead.
|
||||
It must be a valid [Go template](https://golang.org/pkg/text/template/),
|
||||
augmented with the [sprig template functions](http://masterminds.github.io/sprig/).
|
||||
The service name can be accessed as the `Name` identifier,
|
||||
and the template has access to all the labels defined on this container.
|
||||
|
||||
### `refreshSeconds`
|
||||
|
||||
_Optional, Default=15_
|
||||
|
||||
Polling interval (in seconds).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.ecs]
|
||||
refreshSeconds = 15
|
||||
@@ -181,12 +185,19 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Polling interval (in seconds).
|
||||
|
||||
### Credentials
|
||||
|
||||
_Optional_
|
||||
|
||||
If `region` is not provided, it is resolved from the EC2 metadata endpoint for EC2 tasks.
|
||||
In a FARGATE context it is resolved from the `AWS_REGION` environment variable.
|
||||
|
||||
If `accessKeyID` and `secretAccessKey` are not provided, credentials are resolved in the following order:
|
||||
|
||||
- Using the environment variables `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN`.
|
||||
- Using shared credentials, determined by `AWS_PROFILE` and `AWS_SHARED_CREDENTIALS_FILE`, defaults to `default` and `~/.aws/credentials`.
|
||||
- Using EC2 instance role or ECS task role
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.ecs]
|
||||
region = "us-east-1"
|
||||
@@ -209,12 +220,3 @@ providers:
|
||||
--providers.ecs.secretAccessKey="123"
|
||||
# ...
|
||||
```
|
||||
|
||||
If `region` is not provided, it will be resolved from the EC2 metadata endpoint for EC2 tasks.
|
||||
In a FARGATE context it will be resolved from the `AWS_REGION` env variable.
|
||||
|
||||
If `accessKeyID` / `secretAccessKey` are not provided, credentials will be resolved in the following order:
|
||||
|
||||
- From environment variables `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN`.
|
||||
- Shared credentials, determined by `AWS_PROFILE` and `AWS_SHARED_CREDENTIALS_FILE`, defaults to default and `~/.aws/credentials`.
|
||||
- EC2 instance role or ECS task role
|
||||
|
@@ -3,7 +3,7 @@
|
||||
A Story of KV store & Containers
|
||||
{: .subtitle }
|
||||
|
||||
Store your configuration in Etcd and let Traefik do the rest!
|
||||
Store your configuration in etcd and let Traefik do the rest!
|
||||
|
||||
## Routing Configuration
|
||||
|
||||
@@ -15,7 +15,7 @@ See the dedicated section in [routing](../routing/providers/kv.md).
|
||||
|
||||
_Required, Default="127.0.0.1:2379"_
|
||||
|
||||
Defines how to access to Etcd.
|
||||
Defines how to access etcd.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.etcd]
|
||||
@@ -35,10 +35,10 @@ providers:
|
||||
|
||||
### `rootKey`
|
||||
|
||||
Defines the root key of the configuration.
|
||||
|
||||
_Required, Default="traefik"_
|
||||
|
||||
Defines the root key of the configuration.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.etcd]
|
||||
rootKey = "traefik"
|
||||
@@ -56,10 +56,10 @@ providers:
|
||||
|
||||
### `username`
|
||||
|
||||
Defines a username to connect with Etcd.
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
Defines a username with which to connect to etcd.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.etcd]
|
||||
# ...
|
||||
@@ -81,7 +81,7 @@ providers:
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
Defines a password to connect with Etcd.
|
||||
Defines a password with which to connect to etcd.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.etcd]
|
||||
@@ -106,7 +106,7 @@ _Optional_
|
||||
|
||||
#### `tls.ca`
|
||||
|
||||
Certificate Authority used for the secured connection to Etcd.
|
||||
Certificate Authority used for the secure connection to etcd.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.etcd.tls]
|
||||
@@ -126,12 +126,15 @@ providers:
|
||||
|
||||
#### `tls.caOptional`
|
||||
|
||||
Policy followed for the secured connection with TLS Client Authentication to Etcd.
|
||||
Requires `tls.ca` to be defined.
|
||||
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to etcd.
|
||||
|
||||
- `true`: VerifyClientCertIfGiven
|
||||
- `false`: RequireAndVerifyClientCert
|
||||
- if `tls.ca` is undefined NoClientCert
|
||||
!!! warning ""
|
||||
|
||||
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
|
||||
|
||||
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
|
||||
|
||||
When this option is set to `false`, a client certificate is requested during the handshake, and at least one valid certificate should be sent by the client.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.etcd.tls]
|
||||
@@ -151,7 +154,7 @@ providers:
|
||||
|
||||
#### `tls.cert`
|
||||
|
||||
Public certificate used for the secured connection to Etcd.
|
||||
Public certificate used for the secure connection to etcd.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.etcd.tls]
|
||||
@@ -174,7 +177,7 @@ providers:
|
||||
|
||||
#### `tls.key`
|
||||
|
||||
Private certificate used for the secured connection to Etcd.
|
||||
Private certificate used for the secure connection to etcd.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.etcd.tls]
|
||||
@@ -197,7 +200,7 @@ providers:
|
||||
|
||||
#### `tls.insecureSkipVerify`
|
||||
|
||||
If `insecureSkipVerify` is `true`, TLS for the connection to Etcd accepts any certificate presented by the server and any host name in that certificate.
|
||||
If `insecureSkipVerify` is `true`, the TLS connection to etcd accepts any certificate presented by the server regardless of the hostnames it covers.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.etcd.tls]
|
||||
|
@@ -1,43 +1,43 @@
|
||||
# Traefik & File
|
||||
|
||||
Good Old Configuration File
|
||||
{: .subtitle }
|
||||
{: .subtitle }
|
||||
|
||||
The file provider lets you define the [dynamic configuration](./overview.md) in a TOML or YAML file.
|
||||
You can write one of these mutually exclusive configuration elements:
|
||||
|
||||
* In [a dedicated file](#filename)
|
||||
* In [several dedicated files](#directory)
|
||||
It supports providing configuration through a [single configuration file](#filename) or [multiple separate files](#directory).
|
||||
|
||||
!!! info
|
||||
The file provider is the default format used throughout the documentation to show samples of the configuration for many features.
|
||||
|
||||
The file provider is the default format used throughout the documentation to show samples of the configuration for many features.
|
||||
|
||||
!!! tip
|
||||
The file provider can be a good location for common elements you'd like to re-use from other providers; e.g. declaring whitelist middlewares, basic authentication, ...
|
||||
|
||||
The file provider can be a good solution for reusing common elements from other providers (e.g. declaring whitelist middlewares, basic authentication, ...)
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
??? example "Declaring Routers, Middlewares & Services"
|
||||
|
||||
Enabling the file provider:
|
||||
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.file]
|
||||
directory = "/path/to/dynamic/conf"
|
||||
```
|
||||
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
file:
|
||||
directory: "/path/to/dynamic/conf"
|
||||
```
|
||||
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.file.directory=/path/to/dynamic/conf
|
||||
```
|
||||
|
||||
|
||||
Declaring Routers, Middlewares & Services:
|
||||
|
||||
|
||||
```toml tab="TOML"
|
||||
[http]
|
||||
# Add the router
|
||||
@@ -47,14 +47,14 @@ You can write one of these mutually exclusive configuration elements:
|
||||
middlewares = ["my-basic-auth"]
|
||||
service = "service-foo"
|
||||
rule = "Path(`/foo`)"
|
||||
|
||||
|
||||
# Add the middleware
|
||||
[http.middlewares]
|
||||
[http.middlewares]
|
||||
[http.middlewares.my-basic-auth.basicAuth]
|
||||
users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
|
||||
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"]
|
||||
usersFile = "etc/traefik/.htpasswd"
|
||||
|
||||
|
||||
# Add the service
|
||||
[http.services]
|
||||
[http.services.service-foo]
|
||||
@@ -64,7 +64,7 @@ You can write one of these mutually exclusive configuration elements:
|
||||
[[http.services.service-foo.loadBalancer.servers]]
|
||||
url = "http://bar/"
|
||||
```
|
||||
|
||||
|
||||
```yaml tab="YAML"
|
||||
http:
|
||||
# Add the router
|
||||
@@ -76,7 +76,7 @@ You can write one of these mutually exclusive configuration elements:
|
||||
- my-basic-auth
|
||||
service: service-foo
|
||||
rule: Path(`/foo`)
|
||||
|
||||
|
||||
# Add the middleware
|
||||
middlewares:
|
||||
my-basic-auth:
|
||||
@@ -85,7 +85,7 @@ You can write one of these mutually exclusive configuration elements:
|
||||
- test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/
|
||||
- test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0
|
||||
usersFile: etc/traefik/.htpasswd
|
||||
|
||||
|
||||
# Add the service
|
||||
services:
|
||||
service-foo:
|
||||
@@ -98,31 +98,32 @@ You can write one of these mutually exclusive configuration elements:
|
||||
|
||||
## Provider Configuration
|
||||
|
||||
If you're in a hurry, maybe you'd rather go through the [dynamic configuration](../reference/dynamic-configuration/file.md) references and the [static configuration](../reference/static-configuration/overview.md).
|
||||
For an overview of all the options that can be set with the file provider, see the [dynamic configuration](../reference/dynamic-configuration/file.md) and [static configuration](../reference/static-configuration/overview.md) references.
|
||||
|
||||
!!! warning "Limitations"
|
||||
|
||||
With the file provider, Traefik listens for file system notifications to update the dynamic configuration.
|
||||
|
||||
|
||||
If you use a mounted/bound file system in your orchestrator (like docker or kubernetes), the way the files are linked may be a source of errors.
|
||||
If the link between the file systems is broken, when a source file/directory is changed/renamed, nothing will be reported to the linked file/directory, so the file system notifications will be neither triggered nor caught.
|
||||
|
||||
For example, in docker, if the host file is renamed, the link to the mounted file will be broken and the container's file will not be updated.
|
||||
To avoid this kind of issue, a good practice is to:
|
||||
|
||||
|
||||
For example, in Docker, if the host file is renamed, the link to the mounted file is broken and the container's file is no longer updated.
|
||||
To avoid this kind of issue, it is recommended to:
|
||||
|
||||
* set the Traefik [**directory**](#directory) configuration with the parent directory
|
||||
* mount/bind the parent directory
|
||||
|
||||
As it is very difficult to listen to all file system notifications, Traefik use [fsnotify](https://github.com/fsnotify/fsnotify).
|
||||
As it is very difficult to listen to all file system notifications, Traefik uses [fsnotify](https://github.com/fsnotify/fsnotify).
|
||||
If using a directory with a mounted directory does not fix your issue, please check your file system compatibility with fsnotify.
|
||||
|
||||
|
||||
### `filename`
|
||||
|
||||
Defines the path to the configuration file.
|
||||
|
||||
!!! warning ""
|
||||
`filename` and `directory` are mutually exclusive.
|
||||
The recommendation is to use `directory`.
|
||||
|
||||
The `filename` and `directory` options are mutually exclusive.
|
||||
It is recommended to use `directory`.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers]
|
||||
@@ -145,8 +146,9 @@ providers:
|
||||
Defines the path to the directory that contains the configuration files.
|
||||
|
||||
!!! warning ""
|
||||
`filename` and `directory` are mutually exclusive.
|
||||
The recommendation is to use `directory`.
|
||||
|
||||
The `filename` and `directory` options are mutually exclusive.
|
||||
It is recommended to use `directory`.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers]
|
||||
@@ -166,7 +168,7 @@ providers:
|
||||
|
||||
### `watch`
|
||||
|
||||
Set the `watch` option to `true` to allow Traefik to automatically watch for file changes.
|
||||
Set the `watch` option to `true` to allow Traefik to automatically watch for file changes.
|
||||
It works with both the `filename` and the `directory` options.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
@@ -191,63 +193,62 @@ providers:
|
||||
### Go Templating
|
||||
|
||||
!!! warning
|
||||
|
||||
Go Templating only works with dedicated dynamic configuration files.
|
||||
Templating does not work in the Traefik main static configuration file.
|
||||
|
||||
Traefik supports using Go templating to automatically generate repetitive portions of configuration files.
|
||||
These sections must be valid [Go templates](https://golang.org/pkg/text/template/),
|
||||
augmented with the [Sprig template functions](http://masterminds.github.io/sprig/).
|
||||
Traefik supports using Go templating to automatically generate repetitive sections of configuration files.
|
||||
These sections must be a valid [Go template](https://golang.org/pkg/text/template/), and can use
|
||||
[sprig template functions](http://masterminds.github.io/sprig/).
|
||||
|
||||
To illustrate, it's possible to easily define multiple routers, services, and TLS certificates as described in the following examples:
|
||||
To illustrate, it is possible to easily define multiple routers, services, and TLS certificates as described in the following examples:
|
||||
|
||||
??? example "Configuring Using Templating"
|
||||
|
||||
|
||||
```toml tab="TOML"
|
||||
# template-rules.toml
|
||||
[http]
|
||||
|
||||
|
||||
[http.routers]
|
||||
{{ range $i, $e := until 100 }}
|
||||
[http.routers.router{{ $e }}-{{ env "MY_ENV_VAR" }}]
|
||||
# ...
|
||||
{{ end }}
|
||||
|
||||
|
||||
{{ end }}
|
||||
|
||||
[http.services]
|
||||
{{ range $i, $e := until 100 }}
|
||||
[http.services.service{{ $e }}]
|
||||
# ...
|
||||
{{ end }}
|
||||
|
||||
{{ end }}
|
||||
|
||||
[tcp]
|
||||
|
||||
|
||||
[tcp.routers]
|
||||
{{ range $i, $e := until 100 }}
|
||||
[tcp.routers.router{{ $e }}]
|
||||
# ...
|
||||
{{ end }}
|
||||
|
||||
|
||||
{{ end }}
|
||||
|
||||
[tcp.services]
|
||||
{{ range $i, $e := until 100 }}
|
||||
[http.services.service{{ $e }}]
|
||||
# ...
|
||||
{{ end }}
|
||||
|
||||
{{ end }}
|
||||
|
||||
{{ range $i, $e := until 10 }}
|
||||
[[tls.certificates]]
|
||||
certFile = "/etc/traefik/cert-{{ $e }}.pem"
|
||||
keyFile = "/etc/traefik/cert-{{ $e }}.key"
|
||||
stores = ["my-store-foo-{{ $e }}", "my-store-bar-{{ $e }}"]
|
||||
{{ end }}
|
||||
|
||||
|
||||
[tls.config]
|
||||
{{ range $i, $e := until 10 }}
|
||||
[tls.config.TLS{{ $e }}]
|
||||
# ...
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
|
||||
```yaml tab="YAML"
|
||||
http:
|
||||
routers:
|
||||
@@ -255,26 +256,26 @@ To illustrate, it's possible to easily define multiple routers, services, and TL
|
||||
router{{ $e }}-{{ env "MY_ENV_VAR" }}:
|
||||
# ...
|
||||
{{end}}
|
||||
|
||||
|
||||
services:
|
||||
{{range $i, $e := until 100 }}
|
||||
application{{ $e }}:
|
||||
# ...
|
||||
{{end}}
|
||||
|
||||
|
||||
tcp:
|
||||
routers:
|
||||
{{range $i, $e := until 100 }}
|
||||
router{{ $e }}:
|
||||
# ...
|
||||
{{end}}
|
||||
|
||||
|
||||
services:
|
||||
{{range $i, $e := until 100 }}
|
||||
service{{ $e }}:
|
||||
# ...
|
||||
{{end}}
|
||||
|
||||
|
||||
tls:
|
||||
certificates:
|
||||
{{ range $i, $e := until 10 }}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# Traefik & HTTP
|
||||
|
||||
Provide your [dynamic configuration](./overview.md) via an HTTP(s) endpoint and let Traefik do the rest!
|
||||
Provide your [dynamic configuration](./overview.md) via an HTTP(S) endpoint and let Traefik do the rest!
|
||||
|
||||
## Routing Configuration
|
||||
|
||||
@@ -12,7 +12,7 @@ The HTTP provider uses the same configuration as the [File Provider](./file.md)
|
||||
|
||||
_Required_
|
||||
|
||||
Defines the HTTP(s) endpoint to poll.
|
||||
Defines the HTTP(S) endpoint to poll.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.http]
|
||||
@@ -78,7 +78,7 @@ _Optional_
|
||||
|
||||
#### `tls.ca`
|
||||
|
||||
Certificate Authority used for the secured connection to the configured Endpoint.
|
||||
Certificate Authority used for the secure connection to the configured endpoint.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.http.tls]
|
||||
@@ -98,12 +98,15 @@ providers:
|
||||
|
||||
#### `tls.caOptional`
|
||||
|
||||
Policy followed for the secured connection with TLS Client Authentication to the configured Endpoint.
|
||||
Requires `tls.ca` to be defined.
|
||||
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to the configured endpoint.
|
||||
|
||||
- `true`: VerifyClientCertIfGiven
|
||||
- `false`: RequireAndVerifyClientCert
|
||||
- if `tls.ca` is undefined NoClientCert
|
||||
!!! warning ""
|
||||
|
||||
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
|
||||
|
||||
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
|
||||
|
||||
When this option is set to `false`, a client certificate is requested during the handshake, and at least one valid certificate should be sent by the client.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.http.tls]
|
||||
@@ -123,7 +126,7 @@ providers:
|
||||
|
||||
#### `tls.cert`
|
||||
|
||||
Public certificate used for the secured connection to the configured Endpoint.
|
||||
Public certificate used for the secure connection to the configured endpoint.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.http.tls]
|
||||
@@ -146,7 +149,7 @@ providers:
|
||||
|
||||
#### `tls.key`
|
||||
|
||||
Private certificate used for the secured connection to the configured Endpoint.
|
||||
Private certificate used for the secure connection to the configured endpoint.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.http.tls]
|
||||
@@ -169,8 +172,7 @@ providers:
|
||||
|
||||
#### `tls.insecureSkipVerify`
|
||||
|
||||
If `insecureSkipVerify` is `true`, TLS connection to the configured Endpoint accepts any certificate presented by the
|
||||
server and any host name in that certificate.
|
||||
If `insecureSkipVerify` is `true`, the TLS connection to the endpoint accepts any certificate presented by the server regardless of the hostnames it covers.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.http.tls]
|
||||
|
@@ -3,10 +3,11 @@
|
||||
The Kubernetes Ingress Controller, The Custom Resource Way.
|
||||
{: .subtitle }
|
||||
|
||||
Traefik used to support Kubernetes only through the [Kubernetes Ingress provider](./kubernetes-ingress.md), which is a Kubernetes Ingress controller in the strict sense of the term.
|
||||
In early versions, Traefik supported Kubernetes only through the [Kubernetes Ingress provider](./kubernetes-ingress.md), which is a Kubernetes Ingress controller in the strict sense of the term.
|
||||
|
||||
However, as the community expressed the need to benefit from Traefik features without resorting to (lots of) annotations,
|
||||
we ended up writing a [Custom Resource Definition](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) (alias CRD in the following) for an IngressRoute type, defined below, in order to provide a better way to configure access to a Kubernetes cluster.
|
||||
the Traefik engineering team developed a [Custom Resource Definition](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/)
|
||||
(CRD) for an IngressRoute type, defined below, in order to provide a better way to configure access to a Kubernetes cluster.
|
||||
|
||||
## Configuration Requirements
|
||||
|
||||
@@ -17,8 +18,8 @@ we ended up writing a [Custom Resource Definition](https://kubernetes.io/docs/co
|
||||
* Use [Helm Chart](../getting-started/install-traefik.md#use-the-helm-chart) or use a custom Traefik Deployment
|
||||
* Enable the kubernetesCRD provider
|
||||
* Apply the needed kubernetesCRD provider [configuration](#provider-configuration)
|
||||
* Add all needed traefik custom [resources](../reference/dynamic-configuration/kubernetes-crd.md#resources)
|
||||
|
||||
* Add all necessary Traefik custom [resources](../reference/dynamic-configuration/kubernetes-crd.md#resources)
|
||||
|
||||
??? example "Initializing Resource Definition and RBAC"
|
||||
|
||||
```yaml tab="Traefik Resource Definition"
|
||||
@@ -37,13 +38,11 @@ Traefik uses [Custom Resource Definition](https://kubernetes.io/docs/concepts/ex
|
||||
Traefik Custom Resource Definitions are a Kubernetes implementation of the Traefik concepts. The main particularities are:
|
||||
|
||||
* The usage of `name` **and** `namespace` to refer to another Kubernetes resource.
|
||||
* The usage of [secret](https://kubernetes.io/docs/concepts/configuration/secret/) for sensible data like:
|
||||
* TLS certificate.
|
||||
* Authentication data.
|
||||
* The usage of [secret](https://kubernetes.io/docs/concepts/configuration/secret/) for sensitive data (TLS certificates and credentials).
|
||||
* The structure of the configuration.
|
||||
* The obligation to declare all the [definitions](../reference/dynamic-configuration/kubernetes-crd.md#definitions).
|
||||
* The requirement to declare all the [definitions](../reference/dynamic-configuration/kubernetes-crd.md#definitions).
|
||||
|
||||
The Traefik CRD are building blocks which you can assemble according to your needs.
|
||||
The Traefik CRDs are building blocks that you can assemble according to your needs.
|
||||
See the list of CRDs in the dedicated [routing section](../routing/providers/kubernetes-crd.md).
|
||||
|
||||
## LetsEncrypt Support with the Custom Resource Definition Provider
|
||||
@@ -51,23 +50,36 @@ See the list of CRDs in the dedicated [routing section](../routing/providers/kub
|
||||
By design, Traefik is a stateless application, meaning that it only derives its configuration from the environment it runs in, without additional configuration.
|
||||
For this reason, users can run multiple instances of Traefik at the same time to achieve HA, as is a common pattern in the kubernetes ecosystem.
|
||||
|
||||
When using a single instance of Traefik with LetsEncrypt, no issues should be encountered, however this could be a single point of failure.
|
||||
Unfortunately, it is not possible to run multiple instances of Traefik 2.0 with LetsEncrypt enabled, because there is no way to ensure that the correct instance of Traefik will receive the challenge request, and subsequent responses.
|
||||
Previous versions of Traefik used a [KV store](https://doc.traefik.io/traefik/v1.7/configuration/acme/#storage) to attempt to achieve this, but due to sub-optimal performance was dropped as a feature in 2.0.
|
||||
When using a single instance of Traefik with Let's Encrypt, you should encounter no issues. However, this could be a single point of failure.
|
||||
Unfortunately, it is not possible to run multiple instances of Traefik Proxy 2.0 with Let's Encrypt enabled, because there is no way to ensure that the correct instance of Traefik will receive the challenge request and subsequent responses.
|
||||
Previous versions of Traefik used a [KV store](https://doc.traefik.io/traefik/v1.7/configuration/acme/#storage) to attempt to achieve this, but due to sub-optimal performance that feature was dropped in 2.0.
|
||||
|
||||
If you require LetsEncrypt with HA in a kubernetes environment, we recommend using [Traefik Enterprise](https://traefik.io/traefik-enterprise/) where distributed LetsEncrypt is a supported feature.
|
||||
If you need Let's Encrypt with HA in a Kubernetes environment, we recommend using [Traefik Enterprise](https://traefik.io/traefik-enterprise/), which includes distributed Let's Encrypt as a supported feature.
|
||||
|
||||
If you are wanting to continue to run Traefik Community Edition, LetsEncrypt HA can be achieved by using a Certificate Controller such as [Cert-Manager](https://docs.cert-manager.io/en/latest/index.html).
|
||||
When using Cert-Manager to manage certificates, it will create secrets in your namespaces that can be referenced as TLS secrets in your [ingress objects](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls).
|
||||
When using the Traefik Kubernetes CRD Provider, unfortunately Cert-Manager cannot interface directly with the CRDs _yet_, but this is being worked on by our team.
|
||||
If you want to keep using Traefik Proxy, high availability for Let's Encrypt can be achieved by using a Certificate Controller such as [Cert-Manager](https://docs.cert-manager.io/en/latest/index.html).
|
||||
When using Cert-Manager to manage certificates, it creates secrets in your namespaces that can be referenced as TLS secrets in your [ingress objects](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls).
|
||||
When using the Traefik Kubernetes CRD Provider, unfortunately Cert-Manager cannot yet interface directly with the CRDs.
|
||||
A workaround is to enable the [Kubernetes Ingress provider](./kubernetes-ingress.md) to allow Cert-Manager to create ingress objects to complete the challenges.
|
||||
Please note that this still requires manual intervention to create the certificates through Cert-Manager, but once created, Cert-Manager will keep the certificate renewed.
|
||||
Please note that this still requires manual intervention to create the certificates through Cert-Manager, but once the certificates are created, Cert-Manager keeps them renewed.
|
||||
|
||||
## Provider Configuration
|
||||
|
||||
### `endpoint`
|
||||
|
||||
_Optional, Default=empty_
|
||||
_Optional, Default=""_
|
||||
|
||||
The Kubernetes server endpoint URL.
|
||||
|
||||
When deployed into Kubernetes, Traefik reads the environment variables `KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` or `KUBECONFIG` to construct the endpoint.
|
||||
|
||||
The access token is looked up in `/var/run/secrets/kubernetes.io/serviceaccount/token` and the SSL CA certificate in `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`.
|
||||
Both are mounted automatically when deployed inside Kubernetes.
|
||||
|
||||
The endpoint may be specified to override the environment variable values inside a cluster.
|
||||
|
||||
When the environment variables are not found, Traefik tries to connect to the Kubernetes API server with an external-cluster client.
|
||||
In this case, the endpoint is required.
|
||||
Specifically, it may be set to the URL used by `kubectl proxy` to connect to a Kubernetes cluster using the granted authentication and authorization of the associated kubeconfig.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesCRD]
|
||||
@@ -86,22 +98,11 @@ providers:
|
||||
--providers.kubernetescrd.endpoint=http://localhost:8080
|
||||
```
|
||||
|
||||
The Kubernetes server endpoint as URL.
|
||||
|
||||
When deployed into Kubernetes, Traefik will read the environment variables `KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` or `KUBECONFIG` to construct the endpoint.
|
||||
|
||||
The access token will be looked up in `/var/run/secrets/kubernetes.io/serviceaccount/token` and the SSL CA certificate in `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`.
|
||||
Both are provided mounted automatically when deployed inside Kubernetes.
|
||||
|
||||
The endpoint may be specified to override the environment variable values inside a cluster.
|
||||
|
||||
When the environment variables are not found, Traefik will try to connect to the Kubernetes API server with an external-cluster client.
|
||||
In this case, the endpoint is required.
|
||||
Specifically, it may be set to the URL used by `kubectl proxy` to connect to a Kubernetes cluster using the granted authentication and authorization of the associated kubeconfig.
|
||||
|
||||
### `token`
|
||||
|
||||
_Optional, Default=empty_
|
||||
_Optional, Default=""_
|
||||
|
||||
Bearer token used for the Kubernetes client configuration.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesCRD]
|
||||
@@ -120,11 +121,12 @@ providers:
|
||||
--providers.kubernetescrd.token=mytoken
|
||||
```
|
||||
|
||||
Bearer token used for the Kubernetes client configuration.
|
||||
|
||||
### `certAuthFilePath`
|
||||
|
||||
_Optional, Default=empty_
|
||||
_Optional, Default=""_
|
||||
|
||||
Path to the certificate authority file.
|
||||
Used for the Kubernetes client configuration.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesCRD]
|
||||
@@ -143,12 +145,12 @@ providers:
|
||||
--providers.kubernetescrd.certauthfilepath=/my/ca.crt
|
||||
```
|
||||
|
||||
Path to the certificate authority file.
|
||||
Used for the Kubernetes client configuration.
|
||||
|
||||
### `namespaces`
|
||||
|
||||
_Optional, Default: all namespaces (empty array)_
|
||||
_Optional, Default: []_
|
||||
|
||||
Array of namespaces to watch.
|
||||
If left empty, watches all namespaces if the value of `namespaces`.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesCRD]
|
||||
@@ -169,11 +171,20 @@ providers:
|
||||
--providers.kubernetescrd.namespaces=default,production
|
||||
```
|
||||
|
||||
Array of namespaces to watch.
|
||||
|
||||
### `labelselector`
|
||||
|
||||
_Optional,Default: empty (process all resources)_
|
||||
_Optional, Default: ""_
|
||||
|
||||
A label selector can be defined to filter on specific resource objects only,
|
||||
this applies only to Traefik [Custom Resources](../routing/providers/kubernetes-crd.md#custom-resource-definition-crd)
|
||||
and has no effect on Kubernetes `Secrets`, `Endpoints` and `Services`.
|
||||
If left empty, Traefik processes all resource objects in the configured namespaces.
|
||||
|
||||
See [label-selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors) for details.
|
||||
|
||||
!!! warning
|
||||
|
||||
Because the label selector is applied to all Traefik Custom Resources, they all must match the filter.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesCRD]
|
||||
@@ -192,20 +203,14 @@ providers:
|
||||
--providers.kubernetescrd.labelselector="app=traefik"
|
||||
```
|
||||
|
||||
By default, Traefik processes all resource objects in the configured namespaces.
|
||||
A label selector can be defined to filter on specific resource objects only,
|
||||
this will apply only on Traefik [Custom Resources](../routing/providers/kubernetes-crd.md#custom-resource-definition-crd)
|
||||
and has no effect on Kubernetes `Secrets`, `Endpoints` and `Services`.
|
||||
|
||||
See [label-selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors) for details.
|
||||
|
||||
!!! warning
|
||||
|
||||
As the LabelSelector is applied to all Traefik Custom Resources, they all must match the filter.
|
||||
|
||||
### `ingressClass`
|
||||
|
||||
_Optional, Default: empty_
|
||||
_Optional, Default: ""_
|
||||
|
||||
Value of `kubernetes.io/ingress.class` annotation that identifies resource objects to be processed.
|
||||
|
||||
If the parameter is set, only resources containing an annotation with the same value are processed.
|
||||
Otherwise, resources missing the annotation, having an empty value, or the value `traefik` are processed.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesCRD]
|
||||
@@ -224,14 +229,17 @@ providers:
|
||||
--providers.kubernetescrd.ingressclass=traefik-internal
|
||||
```
|
||||
|
||||
Value of `kubernetes.io/ingress.class` annotation that identifies resource objects to be processed.
|
||||
|
||||
If the parameter is non-empty, only resources containing an annotation with the same value are processed.
|
||||
Otherwise, resources missing the annotation, having an empty value, or the value `traefik` are processed.
|
||||
|
||||
### `throttleDuration`
|
||||
|
||||
_Optional, Default: 0 (no throttling)_
|
||||
_Optional, Default: 0_
|
||||
|
||||
The `throttleDuration` option defines how often the provider is allowed to handle events from Kubernetes. This prevents
|
||||
a Kubernetes cluster that updates many times per second from continuously changing your Traefik configuration.
|
||||
|
||||
If left empty, the provider does not apply any throttling and does not drop any Kubernetes events.
|
||||
|
||||
The value of `throttleDuration` should be provided in seconds or as a valid duration format,
|
||||
see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesCRD]
|
||||
@@ -254,6 +262,12 @@ providers:
|
||||
|
||||
_Optional, Default: true_
|
||||
|
||||
If the parameter is set to `false`, IngressRoutes are not able to reference any resources in other namespaces than theirs.
|
||||
|
||||
!!! warning "Deprecation"
|
||||
|
||||
Please note that the default value for this option will be set to `false` in a future version.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesCRD]
|
||||
allowCrossNamespace = false
|
||||
@@ -271,13 +285,6 @@ providers:
|
||||
--providers.kubernetescrd.allowCrossNamespace=false
|
||||
```
|
||||
|
||||
If the parameter is set to `false`, an IngressRoute will not be able to reference any resources
|
||||
in another namespace than the IngressRoute namespace.
|
||||
## Full Example
|
||||
|
||||
!!! warning "Deprecation"
|
||||
|
||||
Please notice that the default value for this option will be set to `false` in a future version.
|
||||
|
||||
## Further
|
||||
|
||||
Also see the [full example](../user-guides/crd-acme/index.md) with Let's Encrypt.
|
||||
For additional information, refer to the [full example](../user-guides/crd-acme/index.md) with Let's Encrypt.
|
||||
|
263
docs/content/providers/kubernetes-gateway.md
Normal file
263
docs/content/providers/kubernetes-gateway.md
Normal file
@@ -0,0 +1,263 @@
|
||||
# Traefik & Kubernetes with Gateway API
|
||||
|
||||
The Kubernetes Gateway API, The Experimental Way.
|
||||
{: .subtitle }
|
||||
|
||||
Gateway API is the evolution of Kubernetes APIs that relate to `Services`, such as `Ingress`.
|
||||
The Gateway API project is part of Kubernetes, working under SIG-NETWORK.
|
||||
|
||||
The Kubernetes Gateway provider is a Traefik implementation of the [Gateway API](https://gateway-api.sigs.k8s.io/)
|
||||
specifications from the Kubernetes Special Interest Groups (SIGs).
|
||||
|
||||
This provider is proposed as an experimental feature and partially supports the Service APIs [v0.1.0](https://github.com/kubernetes-sigs/service-apis/releases/tag/v0.1.0) specification.
|
||||
|
||||
!!! warning "Enabling The Experimental Kubernetes Gateway Provider"
|
||||
|
||||
Since this provider is still experimental, it needs to be activated in the experimental section of the static configuration.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[experimental]
|
||||
kubernetesGateway = true
|
||||
|
||||
[providers.kubernetesGateway]
|
||||
#...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
experimental:
|
||||
kubernetesGateway: true
|
||||
|
||||
providers:
|
||||
kubernetesGateway: {}
|
||||
#...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--experimental.kubernetesgateway=true --providers.kubernetesgateway=true #...
|
||||
```
|
||||
|
||||
## Configuration Requirements
|
||||
|
||||
!!! tip "All Steps for a Successful Deployment"
|
||||
|
||||
* Add/update the Kubernetes Gateway API [definitions](../reference/dynamic-configuration/kubernetes-gateway.md#definitions).
|
||||
* Add/update the [RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) for the Traefik custom resources.
|
||||
* Add all needed Kubernetes Gateway API [resources](../reference/dynamic-configuration/kubernetes-gateway.md#resources).
|
||||
|
||||
## Examples
|
||||
|
||||
??? example "Kubernetes Gateway Provider Basic Example"
|
||||
|
||||
```yaml tab="Gateway API"
|
||||
--8<-- "content/reference/dynamic-configuration/kubernetes-gateway-simple-https.yml"
|
||||
```
|
||||
|
||||
```yaml tab="Whoami Service"
|
||||
--8<-- "content/reference/dynamic-configuration/kubernetes-whoami-svc.yml"
|
||||
```
|
||||
|
||||
```yaml tab="Traefik Service"
|
||||
--8<-- "content/reference/dynamic-configuration/kubernetes-gateway-traefik-lb-svc.yml"
|
||||
```
|
||||
|
||||
```yaml tab="Gateway API CRDs"
|
||||
# All resources definition must be declared
|
||||
--8<-- "content/reference/dynamic-configuration/networking.x-k8s.io_gatewayclasses.yaml"
|
||||
--8<-- "content/reference/dynamic-configuration/networking.x-k8s.io_gateways.yaml"
|
||||
--8<-- "content/reference/dynamic-configuration/networking.x-k8s.io_httproutes.yaml"
|
||||
```
|
||||
|
||||
```yaml tab="RBAC"
|
||||
--8<-- "content/reference/dynamic-configuration/kubernetes-gateway-rbac.yml"
|
||||
```
|
||||
|
||||
The Kubernetes Gateway API project provides several [guides](https://gateway-api.sigs.k8s.io/guides/) on how to use the APIs.
|
||||
These guides can help you to go further than the example above.
|
||||
The [getting started guide](https://gateway-api.sigs.k8s.io/getting-started/) details how to install the CRDs from their repository.
|
||||
|
||||
!!! note ""
|
||||
|
||||
Keep in mind that the Traefik Gateway provider only supports the `v0.1.0`.
|
||||
|
||||
For now, the Traefik Gateway Provider can be used while following the below guides:
|
||||
|
||||
* [Simple Gateway](https://gateway-api.sigs.k8s.io/simple-gateway/)
|
||||
* [HTTP routing](https://gateway-api.sigs.k8s.io/http-routing/)
|
||||
* [TLS](https://gateway-api.sigs.k8s.io/tls/) (Partial support: only on listeners with terminate mode)
|
||||
|
||||
## Resource Configuration
|
||||
|
||||
When using Kubernetes Gateway API as a provider, Traefik uses Kubernetes
|
||||
[Custom Resource Definitions](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/)
|
||||
to retrieve its routing configuration.
|
||||
|
||||
All concepts can be found in the official API concepts [documentation](https://gateway-api.sigs.k8s.io/api-overview/).
|
||||
Traefik implements the following resources:
|
||||
|
||||
* `GatewayClass` defines a set of Gateways that share a common configuration and behaviour.
|
||||
* `Gateway` describes how traffic can be translated to Services within the cluster.
|
||||
* `HTTPRoute` define HTTP rules for mapping requests from a Gateway to Kubernetes Services.
|
||||
|
||||
## Provider Configuration
|
||||
|
||||
### `endpoint`
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
The Kubernetes server endpoint URL.
|
||||
|
||||
When deployed into Kubernetes, Traefik reads the environment variables `KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` or `KUBECONFIG` to construct the endpoint.
|
||||
|
||||
The access token is looked up in `/var/run/secrets/kubernetes.io/serviceaccount/token` and the SSL CA certificate in `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`.
|
||||
Both are mounted automatically when deployed inside Kubernetes.
|
||||
|
||||
The endpoint may be specified to override the environment variable values inside a cluster.
|
||||
|
||||
When the environment variables are not found, Traefik tries to connect to the Kubernetes API server with an external-cluster client.
|
||||
In this case, the endpoint is required.
|
||||
Specifically, it may be set to the URL used by `kubectl proxy` to connect to a Kubernetes cluster using the granted authentication and authorization of the associated kubeconfig.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesGateway]
|
||||
endpoint = "http://localhost:8080"
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
kubernetesGateway:
|
||||
endpoint: "http://localhost:8080"
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.kubernetesgateway.endpoint=http://localhost:8080
|
||||
```
|
||||
|
||||
### `token`
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
Bearer token used for the Kubernetes client configuration.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesGateway]
|
||||
token = "mytoken"
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
kubernetesGateway:
|
||||
token: "mytoken"
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.kubernetesgateway.token=mytoken
|
||||
```
|
||||
|
||||
### `certAuthFilePath`
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
Path to the certificate authority file.
|
||||
Used for the Kubernetes client configuration.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesGateway]
|
||||
certAuthFilePath = "/my/ca.crt"
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
kubernetesGateway:
|
||||
certAuthFilePath: "/my/ca.crt"
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.kubernetesgateway.certauthfilepath=/my/ca.crt
|
||||
```
|
||||
|
||||
### `namespaces`
|
||||
|
||||
_Optional, Default: []_
|
||||
|
||||
Array of namespaces to watch.
|
||||
If left empty, watches all namespaces if the value of `namespaces`.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesGateway]
|
||||
namespaces = ["default", "production"]
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
kubernetesGateway:
|
||||
namespaces:
|
||||
- "default"
|
||||
- "production"
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.kubernetesgateway.namespaces=default,production
|
||||
```
|
||||
|
||||
### `labelselector`
|
||||
|
||||
_Optional, Default: ""_
|
||||
|
||||
A label selector can be defined to filter on specific GatewayClass objects only.
|
||||
If left empty, Traefik processes all GatewayClass objects in the configured namespaces.
|
||||
|
||||
See [label-selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors) for details.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesGateway]
|
||||
labelselector = "app=traefik"
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
kubernetesGateway:
|
||||
labelselector: "app=traefik"
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.kubernetesgateway.labelselector="app=traefik"
|
||||
```
|
||||
|
||||
### `throttleDuration`
|
||||
|
||||
_Optional, Default: 0_
|
||||
|
||||
The `throttleDuration` option defines how often the provider is allowed to handle events from Kubernetes. This prevents
|
||||
a Kubernetes cluster that updates many times per second from continuously changing your Traefik configuration.
|
||||
|
||||
If left empty, the provider does not apply any throttling and does not drop any Kubernetes events.
|
||||
|
||||
The value of `throttleDuration` should be provided in seconds or as a valid duration format,
|
||||
see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesGateway]
|
||||
throttleDuration = "10s"
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
kubernetesGateway:
|
||||
throttleDuration: "10s"
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.kubernetesgateway.throttleDuration=10s
|
||||
```
|
@@ -12,7 +12,7 @@ See the dedicated section in [routing](../routing/providers/kubernetes-ingress.m
|
||||
|
||||
## Enabling and Using the Provider
|
||||
|
||||
As usual, the provider is enabled through the static configuration:
|
||||
You can enable the provider in the static configuration:
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesIngress]
|
||||
@@ -29,7 +29,7 @@ providers:
|
||||
|
||||
The provider then watches for incoming ingresses events, such as the example below,
|
||||
and derives the corresponding dynamic configuration from it,
|
||||
which in turn will create the resulting routers, services, handlers, etc.
|
||||
which in turn creates the resulting routers, services, handlers, etc.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
kind: Ingress
|
||||
@@ -61,26 +61,39 @@ without additional configuration.
|
||||
For this reason, users can run multiple instances of Traefik at the same time to achieve HA,
|
||||
as is a common pattern in the kubernetes ecosystem.
|
||||
|
||||
When using a single instance of Traefik with LetsEncrypt, no issues should be encountered,
|
||||
however this could be a single point of failure.
|
||||
Unfortunately, it is not possible to run multiple instances of Traefik 2.0 with LetsEncrypt enabled,
|
||||
because there is no way to ensure that the correct instance of Traefik will receive the challenge request, and subsequent responses.
|
||||
When using a single instance of Traefik Proxy with Let's Encrypt, you should encounter no issues.
|
||||
However, this could be a single point of failure.
|
||||
Unfortunately, it is not possible to run multiple instances of Traefik 2.0 with Let's Encrypt enabled,
|
||||
because there is no way to ensure that the correct instance of Traefik receives the challenge request, and subsequent responses.
|
||||
Previous versions of Traefik used a [KV store](https://doc.traefik.io/traefik/v1.7/configuration/acme/#storage) to attempt to achieve this,
|
||||
but due to sub-optimal performance was dropped as a feature in 2.0.
|
||||
but due to sub-optimal performance that feature was dropped in 2.0.
|
||||
|
||||
If you require LetsEncrypt with HA in a kubernetes environment,
|
||||
we recommend using [Traefik Enterprise](https://traefik.io/traefik-enterprise/) where distributed LetsEncrypt is a supported feature.
|
||||
If you need Let's Encrypt with high availability in a Kubernetes environment,
|
||||
we recommend using [Traefik Enterprise](https://traefik.io/traefik-enterprise/) which includes distributed Let's Encrypt as a supported feature.
|
||||
|
||||
If you are wanting to continue to run Traefik Community Edition,
|
||||
If you want to keep using Traefik Proxy,
|
||||
LetsEncrypt HA can be achieved by using a Certificate Controller such as [Cert-Manager](https://docs.cert-manager.io/en/latest/index.html).
|
||||
When using Cert-Manager to manage certificates,
|
||||
it will create secrets in your namespaces that can be referenced as TLS secrets in your [ingress objects](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls).
|
||||
it creates secrets in your namespaces that can be referenced as TLS secrets in your [ingress objects](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls).
|
||||
|
||||
## Provider Configuration
|
||||
|
||||
### `endpoint`
|
||||
|
||||
_Optional, Default=empty_
|
||||
_Optional, Default=""_
|
||||
|
||||
The Kubernetes server endpoint URL.
|
||||
|
||||
When deployed into Kubernetes, Traefik reads the environment variables `KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` or `KUBECONFIG` to construct the endpoint.
|
||||
|
||||
The access token is looked up in `/var/run/secrets/kubernetes.io/serviceaccount/token` and the SSL CA certificate in `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`.
|
||||
Both are mounted automatically when deployed inside Kubernetes.
|
||||
|
||||
The endpoint may be specified to override the environment variable values inside a cluster.
|
||||
|
||||
When the environment variables are not found, Traefik tries to connect to the Kubernetes API server with an external-cluster client.
|
||||
In this case, the endpoint is required.
|
||||
Specifically, it may be set to the URL used by `kubectl proxy` to connect to a Kubernetes cluster using the granted authentication and authorization of the associated kubeconfig.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesIngress]
|
||||
@@ -99,21 +112,11 @@ providers:
|
||||
--providers.kubernetesingress.endpoint=http://localhost:8080
|
||||
```
|
||||
|
||||
The Kubernetes server endpoint as URL, which is only used when the behavior based on environment variables described below does not apply.
|
||||
|
||||
When deployed into Kubernetes, Traefik reads the environment variables `KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` or `KUBECONFIG` to construct the endpoint.
|
||||
|
||||
The access token is looked up in `/var/run/secrets/kubernetes.io/serviceaccount/token` and the SSL CA certificate in `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`.
|
||||
They are both provided automatically as mounts in the pod where Traefik is deployed.
|
||||
|
||||
When the environment variables are not found, Traefik tries to connect to the Kubernetes API server with an external-cluster client.
|
||||
In which case, the endpoint is required.
|
||||
Specifically, it may be set to the URL used by `kubectl proxy` to connect to a Kubernetes cluster using the granted authentication
|
||||
and authorization of the associated kubeconfig.
|
||||
|
||||
### `token`
|
||||
|
||||
_Optional, Default=empty_
|
||||
_Optional, Default=""_
|
||||
|
||||
Bearer token used for the Kubernetes client configuration.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesIngress]
|
||||
@@ -132,11 +135,12 @@ providers:
|
||||
--providers.kubernetesingress.token=mytoken
|
||||
```
|
||||
|
||||
Bearer token used for the Kubernetes client configuration.
|
||||
|
||||
### `certAuthFilePath`
|
||||
|
||||
_Optional, Default=empty_
|
||||
_Optional, Default=""_
|
||||
|
||||
Path to the certificate authority file.
|
||||
Used for the Kubernetes client configuration.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesIngress]
|
||||
@@ -155,35 +159,12 @@ providers:
|
||||
--providers.kubernetesingress.certauthfilepath=/my/ca.crt
|
||||
```
|
||||
|
||||
Path to the certificate authority file.
|
||||
Used for the Kubernetes client configuration.
|
||||
|
||||
### `disablePassHostHeaders`
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesIngress]
|
||||
disablePassHostHeaders = true
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
kubernetesIngress:
|
||||
disablePassHostHeaders: true
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.kubernetesingress.disablepasshostheaders=true
|
||||
```
|
||||
|
||||
Whether to disable PassHost Headers.
|
||||
|
||||
### `namespaces`
|
||||
|
||||
_Optional, Default: all namespaces (empty array)_
|
||||
_Optional, Default: []_
|
||||
|
||||
Array of namespaces to watch.
|
||||
If left empty, watches all namespaces if the value of `namespaces`.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesIngress]
|
||||
@@ -204,11 +185,14 @@ providers:
|
||||
--providers.kubernetesingress.namespaces=default,production
|
||||
```
|
||||
|
||||
Array of namespaces to watch.
|
||||
|
||||
### `labelSelector`
|
||||
|
||||
_Optional,Default: empty (process all Ingresses)_
|
||||
_Optional, Default: ""_
|
||||
|
||||
A label selector can be defined to filter on specific Ingress objects only.
|
||||
If left empty, Traefik processes all Ingress objects in the configured namespaces.
|
||||
|
||||
See [label-selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors) for details.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesIngress]
|
||||
@@ -227,14 +211,48 @@ providers:
|
||||
--providers.kubernetesingress.labelselector="app=traefik"
|
||||
```
|
||||
|
||||
By default, Traefik processes all `Ingress` objects in the configured namespaces.
|
||||
A label selector can be defined to filter on specific `Ingress` objects only.
|
||||
|
||||
See [label-selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors) for details.
|
||||
|
||||
### `ingressClass`
|
||||
|
||||
_Optional, Default: empty_
|
||||
_Optional, Default: ""_
|
||||
|
||||
Value of `kubernetes.io/ingress.class` annotation that identifies Ingress objects to be processed.
|
||||
|
||||
If the parameter is set, only Ingresses containing an annotation with the same value are processed.
|
||||
Otherwise, Ingresses missing the annotation, having an empty value, or the value `traefik` are processed.
|
||||
|
||||
!!! info "Kubernetes 1.18+"
|
||||
|
||||
If the Kubernetes cluster version is 1.18+,
|
||||
the new `IngressClass` resource can be leveraged to identify Ingress objects that should be processed.
|
||||
In that case, Traefik will look for an `IngressClass` in the cluster with the controller value equal to *traefik.io/ingress-controller*.
|
||||
|
||||
Please see [this article](https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/) for more information or the example below.
|
||||
|
||||
```yaml tab="IngressClass"
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
kind: IngressClass
|
||||
metadata:
|
||||
name: traefik-lb
|
||||
spec:
|
||||
controller: traefik.io/ingress-controller
|
||||
```
|
||||
|
||||
```yaml tab="Ingress"
|
||||
apiVersion: "networking.k8s.io/v1beta1"
|
||||
kind: "Ingress"
|
||||
metadata:
|
||||
name: "example-ingress"
|
||||
spec:
|
||||
ingressClassName: "traefik-lb"
|
||||
rules:
|
||||
- host: "*.example.com"
|
||||
http:
|
||||
paths:
|
||||
- path: "/example"
|
||||
backend:
|
||||
serviceName: "example-service"
|
||||
servicePort: 80
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesIngress]
|
||||
@@ -253,50 +271,13 @@ providers:
|
||||
--providers.kubernetesingress.ingressclass=traefik-internal
|
||||
```
|
||||
|
||||
Value of `kubernetes.io/ingress.class` annotation that identifies Ingress objects to be processed.
|
||||
|
||||
If the parameter is non-empty, only Ingresses containing an annotation with the same value are processed.
|
||||
Otherwise, Ingresses missing the annotation, having an empty value, or with the value `traefik` are processed.
|
||||
|
||||
!!! info "Kubernetes 1.18+"
|
||||
|
||||
If the Kubernetes cluster version is 1.18+,
|
||||
the new `IngressClass` resource can be leveraged to identify Ingress objects that should be processed.
|
||||
In that case, Traefik will look for an `IngressClass` in the cluster with the controller value equal to *traefik.io/ingress-controller*.
|
||||
|
||||
Please see [this article](https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/) for more information or the example below.
|
||||
|
||||
```yaml tab="IngressClass"
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
kind: IngressClass
|
||||
metadata:
|
||||
name: traefik-lb
|
||||
spec:
|
||||
controller: traefik.io/ingress-controller
|
||||
```
|
||||
|
||||
```yaml tab="Ingress"
|
||||
apiVersion: "networking.k8s.io/v1beta1"
|
||||
kind: "Ingress"
|
||||
metadata:
|
||||
name: "example-ingress"
|
||||
spec:
|
||||
ingressClassName: "traefik-lb"
|
||||
rules:
|
||||
- host: "*.example.com"
|
||||
http:
|
||||
paths:
|
||||
- path: "/example"
|
||||
backend:
|
||||
serviceName: "example-service"
|
||||
servicePort: 80
|
||||
```
|
||||
|
||||
### `ingressEndpoint`
|
||||
|
||||
#### `hostname`
|
||||
|
||||
_Optional, Default: empty_
|
||||
_Optional, Default: ""_
|
||||
|
||||
Hostname used for Kubernetes Ingress endpoints.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesIngress.ingressEndpoint]
|
||||
@@ -316,11 +297,11 @@ providers:
|
||||
--providers.kubernetesingress.ingressendpoint.hostname=example.net
|
||||
```
|
||||
|
||||
Hostname used for Kubernetes Ingress endpoints.
|
||||
|
||||
#### `ip`
|
||||
|
||||
_Optional, Default: empty_
|
||||
_Optional, Default: ""_
|
||||
|
||||
IP used for Kubernetes Ingress endpoints.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesIngress.ingressEndpoint]
|
||||
@@ -340,11 +321,12 @@ providers:
|
||||
--providers.kubernetesingress.ingressendpoint.ip=1.2.3.4
|
||||
```
|
||||
|
||||
IP used for Kubernetes Ingress endpoints.
|
||||
|
||||
#### `publishedService`
|
||||
|
||||
_Optional, Default: empty_
|
||||
_Optional, Default: ""_
|
||||
|
||||
Published Kubernetes Service to copy status from.
|
||||
Format: `namespace/servicename`.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesIngress.ingressEndpoint]
|
||||
@@ -364,12 +346,17 @@ providers:
|
||||
--providers.kubernetesingress.ingressendpoint.publishedservice=namespace/foo-service
|
||||
```
|
||||
|
||||
Published Kubernetes Service to copy status from.
|
||||
Format: `namespace/servicename`.
|
||||
|
||||
### `throttleDuration`
|
||||
|
||||
_Optional, Default: 0 (no throttling)_
|
||||
_Optional, Default: 0_
|
||||
|
||||
The `throttleDuration` option defines how often the provider is allowed to handle events from Kubernetes. This prevents
|
||||
a Kubernetes cluster that updates many times per second from continuously changing your Traefik configuration.
|
||||
|
||||
If left empty, the provider does not apply any throttling and does not drop any Kubernetes events.
|
||||
|
||||
The value of `throttleDuration` should be provided in seconds or as a valid duration format,
|
||||
see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesIngress]
|
||||
@@ -390,5 +377,5 @@ providers:
|
||||
|
||||
### Further
|
||||
|
||||
If one wants to know more about the various aspects of the Ingress spec that Traefik supports,
|
||||
many examples of Ingresses definitions are located in the tests [data](https://github.com/traefik/traefik/tree/v2.3/pkg/provider/kubernetes/ingress/fixtures) of the Traefik repository.
|
||||
To learn more about the various aspects of the Ingress specification that Traefik supports,
|
||||
many examples of Ingresses definitions are located in the test [examples](https://github.com/traefik/traefik/tree/v2.4/pkg/provider/kubernetes/ingress/fixtures) of the Traefik repository.
|
||||
|
@@ -3,28 +3,28 @@
|
||||
Traefik can be configured to use Marathon as a provider.
|
||||
{: .subtitle }
|
||||
|
||||
See also [Marathon user guide](../user-guides/marathon.md).
|
||||
For additional information, refer to [Marathon user guide](../user-guides/marathon.md).
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
??? example "Configuring Marathon & Deploying / Exposing Applications"
|
||||
|
||||
Enabling the marathon provider
|
||||
Enabling the Marathon provider
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon]
|
||||
```
|
||||
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
marathon: {}
|
||||
```
|
||||
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.marathon=true
|
||||
```
|
||||
|
||||
Attaching labels to marathon applications
|
||||
Attaching labels to Marathon applications
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -59,6 +59,8 @@ See the dedicated section in [routing](../routing/providers/marathon.md).
|
||||
|
||||
_Optional_
|
||||
|
||||
Enables Marathon basic authentication.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon.basic]
|
||||
httpBasicAuthUser = "foo"
|
||||
@@ -78,12 +80,14 @@ providers:
|
||||
--providers.marathon.basic.httpbasicpassword=bar
|
||||
```
|
||||
|
||||
Enables Marathon basic authentication.
|
||||
|
||||
### `dcosToken`
|
||||
|
||||
_Optional_
|
||||
|
||||
Datacenter Operating System (DCOS) Token for DCOS environment.
|
||||
|
||||
If set, it overrides the Authorization header.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon]
|
||||
dcosToken = "xxxxxx"
|
||||
@@ -101,14 +105,20 @@ providers:
|
||||
--providers.marathon.dcosToken=xxxxxx
|
||||
```
|
||||
|
||||
DCOSToken for DCOS environment.
|
||||
|
||||
If set, it overrides the Authorization header.
|
||||
|
||||
### `defaultRule`
|
||||
|
||||
_Optional, Default=```Host(`{{ normalize .Name }}`)```_
|
||||
|
||||
The default host rule for all services.
|
||||
|
||||
For a given application, if no routing rule was defined by a label, it is defined by this `defaultRule` instead.
|
||||
|
||||
It must be a valid [Go template](https://golang.org/pkg/text/template/),
|
||||
and can include [sprig template functions](http://masterminds.github.io/sprig/).
|
||||
|
||||
The app ID can be accessed with the `Name` identifier,
|
||||
and the template has access to all the labels defined on this Marathon application.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon]
|
||||
defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)"
|
||||
@@ -127,18 +137,16 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
For a given application if no routing rule was defined by a label, it is defined by this defaultRule instead.
|
||||
|
||||
It must be a valid [Go template](https://golang.org/pkg/text/template/),
|
||||
augmented with the [sprig template functions](http://masterminds.github.io/sprig/).
|
||||
|
||||
The app ID can be accessed as the Name identifier,
|
||||
and the template has access to all the labels defined on this Marathon application.
|
||||
|
||||
### `dialerTimeout`
|
||||
|
||||
_Optional, Default=5s_
|
||||
|
||||
Amount of time the Marathon provider should wait before timing out,
|
||||
when trying to open a TCP connection to a Marathon master.
|
||||
|
||||
The value of `dialerTimeout` should be provided in seconds or as a valid duration format,
|
||||
see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon]
|
||||
dialerTimeout = "10s"
|
||||
@@ -156,18 +164,14 @@ providers:
|
||||
--providers.marathon.dialerTimeout=10s
|
||||
```
|
||||
|
||||
Overrides DialerTimeout.
|
||||
|
||||
Amount of time the Marathon provider should wait before timing out,
|
||||
when trying 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 directly as a number of seconds.
|
||||
|
||||
### `endpoint`
|
||||
|
||||
_Optional, Default=http://127.0.0.1:8080_
|
||||
|
||||
Marathon server endpoint.
|
||||
|
||||
You can optionally specify multiple endpoints.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon]
|
||||
endpoint = "http://10.241.1.71:8080,10.241.1.72:8080,10.241.1.73:8080"
|
||||
@@ -185,14 +189,16 @@ providers:
|
||||
--providers.marathon.endpoint=http://10.241.1.71:8080,10.241.1.72:8080,10.241.1.73:8080
|
||||
```
|
||||
|
||||
Marathon server endpoint.
|
||||
|
||||
You can optionally specify multiple endpoints:
|
||||
|
||||
### `exposedByDefault`
|
||||
|
||||
_Optional, Default=true_
|
||||
|
||||
Exposes Marathon applications by default through Traefik.
|
||||
|
||||
If set to `false`, applications that do not have a `traefik.enable=true` label are ignored from the resulting routing configuration.
|
||||
|
||||
For additional information, refer to [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon]
|
||||
exposedByDefault = false
|
||||
@@ -211,16 +217,63 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Exposes Marathon applications by default through Traefik.
|
||||
|
||||
If set to false, applications that don't have a `traefik.enable=true` label will be ignored from the resulting routing configuration.
|
||||
|
||||
See also [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
|
||||
|
||||
### `constraints`
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
The `constraints` option can be set to an expression that Traefik matches against the application labels to determine whether
|
||||
to create any route for that application. If none of the application labels match the expression, no route for that application is
|
||||
created. In addition, the expression is also matched against the application constraints, such as described
|
||||
in [Marathon constraints](https://mesosphere.github.io/marathon/docs/constraints.html).
|
||||
If the expression is empty, all detected applications are included.
|
||||
|
||||
The expression syntax is based on the `Label("key", "value")`, and `LabelRegex("key", "value")` functions, as well as the usual boolean logic.
|
||||
In addition, to match against Marathon constraints, the function `MarathonConstraint("field:operator:value")` can be used, where the field, operator, and value parts are concatenated in a single string using the `:` separator.
|
||||
|
||||
??? example "Constraints Expression Examples"
|
||||
|
||||
```toml
|
||||
# Includes only applications having a label with key `a.label.name` and value `foo`
|
||||
constraints = "Label(`a.label.name`, `foo`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Excludes applications having any label with key `a.label.name` and value `foo`
|
||||
constraints = "!Label(`a.label.name`, `value`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND.
|
||||
constraints = "Label(`a.label.name`, `valueA`) && Label(`another.label.name`, `valueB`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical OR.
|
||||
constraints = "Label(`a.label.name`, `valueA`) || Label(`another.label.name`, `valueB`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND and OR, with precedence set by parentheses.
|
||||
constraints = "Label(`a.label.name`, `valueA`) && (Label(`another.label.name`, `valueB`) || Label(`yet.another.label.name`, `valueC`))"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Includes only applications having a label with key `a.label.name` and a value matching the `a.+` regular expression.
|
||||
constraints = "LabelRegex(`a.label.name`, `a.+`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Includes only applications having a Marathon constraint with field `A`, operator `B`, and value `C`.
|
||||
constraints = "MarathonConstraint(`A:B:C`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Uses both Marathon constraint and application label with logical operator.
|
||||
constraints = "MarathonConstraint(`A:B:C`) && Label(`a.label.name`, `value`)"
|
||||
```
|
||||
|
||||
For additional information, refer to [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon]
|
||||
constraints = "Label(`a.label.name`,`foo`)"
|
||||
@@ -239,62 +292,14 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Constraints is an expression that Traefik matches against the application's labels to determine whether to create any route for that application.
|
||||
That is to say, if none of the application's labels match the expression, no route for the application is created.
|
||||
In addition, the expression also matched against the application's constraints, such as described in [Marathon constraints](https://mesosphere.github.io/marathon/docs/constraints.html).
|
||||
If the expression is empty, all detected applications are included.
|
||||
|
||||
The expression syntax is based on the `Label("key", "value")`, and `LabelRegex("key", "value")`, as well as the usual boolean logic.
|
||||
In addition, to match against marathon constraints, the function `MarathonConstraint("field:operator:value")` can be used, where the field, operator, and value parts are joined together in a single string with the `:` separator.
|
||||
|
||||
??? example "Constraints Expression Examples"
|
||||
|
||||
```toml
|
||||
# Includes only applications having a label with key `a.label.name` and value `foo`
|
||||
constraints = "Label(`a.label.name`, `foo`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Excludes applications having any label with key `a.label.name` and value `foo`
|
||||
constraints = "!Label(`a.label.name`, `value`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND.
|
||||
constraints = "Label(`a.label.name`, `valueA`) && Label(`another.label.name`, `valueB`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical OR.
|
||||
constraints = "Label(`a.label.name`, `valueA`) || Label(`another.label.name`, `valueB`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND and OR, with precedence set by parentheses.
|
||||
constraints = "Label(`a.label.name`, `valueA`) && (Label(`another.label.name`, `valueB`) || Label(`yet.another.label.name`, `valueC`))"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Includes only applications having a label with key `a.label.name` and a value matching the `a.+` regular expression.
|
||||
constraints = "LabelRegex(`a.label.name`, `a.+`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Includes only applications having a Marathon constraint with field `A`, operator `B`, and value `C`.
|
||||
constraints = "MarathonConstraint(`A:B:C`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Uses both Marathon constraint and application label with logical operator.
|
||||
constraints = "MarathonConstraint(`A:B:C`) && Label(`a.label.name`, `value`)"
|
||||
```
|
||||
|
||||
See also [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
|
||||
|
||||
### `forceTaskHostname`
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
By default, the task 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 setting this option to `true`.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon]
|
||||
forceTaskHostname = true
|
||||
@@ -313,14 +318,14 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
### `keepAlive`
|
||||
|
||||
_Optional, Default=10s_
|
||||
|
||||
Set the TCP Keep Alive duration for the Marathon HTTP Client.
|
||||
The value of `keepAlive` should be provided in seconds or as a valid duration format,
|
||||
see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon]
|
||||
keepAlive = "30s"
|
||||
@@ -339,14 +344,16 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
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 directly as a number of seconds.
|
||||
|
||||
### `respectReadinessChecks`
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
Applications may define readiness checks which are probed by Marathon during deployments periodically, and these check results are exposed via the API.
|
||||
Enabling `respectReadinessChecks` causes Traefik to filter out tasks whose readiness checks have not succeeded.
|
||||
Note that the checks are only valid during deployments.
|
||||
|
||||
See the Marathon guide for details.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon]
|
||||
respectReadinessChecks = true
|
||||
@@ -365,16 +372,16 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Applications may define readiness checks which are probed by Marathon during deployments periodically, and these check results are exposed via the API.
|
||||
Enabling respectReadinessChecks 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.
|
||||
|
||||
### `responseHeaderTimeout`
|
||||
|
||||
_Optional, Default=60s_
|
||||
|
||||
Amount of time the Marathon provider should wait before timing out when waiting for the first response header
|
||||
from a Marathon master.
|
||||
|
||||
The value of `responseHeaderTimeout` should be provided in seconds or as a valid duration format,
|
||||
see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon]
|
||||
responseHeaderTimeout = "66s"
|
||||
@@ -393,19 +400,13 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Overrides ResponseHeaderTimeout.
|
||||
Amount of time the Marathon provider should wait before timing out,
|
||||
when waiting for the first response header from a Marathon master.
|
||||
|
||||
Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration), or directly as a number of seconds.
|
||||
|
||||
### `tls`
|
||||
|
||||
_Optional_
|
||||
|
||||
#### `tls.ca`
|
||||
|
||||
Certificate Authority used for the secured connection to Marathon.
|
||||
Certificate Authority used for the secure connection to Marathon.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon.tls]
|
||||
@@ -425,12 +426,15 @@ providers:
|
||||
|
||||
#### `tls.caOptional`
|
||||
|
||||
Policy followed for the secured connection to Marathon with TLS Client Authentication.
|
||||
Requires `tls.ca` to be defined.
|
||||
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Marathon.
|
||||
|
||||
- `true`: VerifyClientCertIfGiven
|
||||
- `false`: RequireAndVerifyClientCert
|
||||
- if `tls.ca` is undefined NoClientCert
|
||||
!!! warning ""
|
||||
|
||||
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
|
||||
|
||||
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
|
||||
|
||||
When this option is set to `false`, a client certificate is requested during the handshake, and at least one valid certificate should be sent by the client.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon.tls]
|
||||
@@ -450,7 +454,7 @@ providers:
|
||||
|
||||
#### `tls.cert`
|
||||
|
||||
Public certificate used for the secured connection to Marathon.
|
||||
Public certificate used for the secure connection to Marathon.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon.tls]
|
||||
@@ -473,7 +477,7 @@ providers:
|
||||
|
||||
#### `tls.key`
|
||||
|
||||
Private certificate used for the secured connection to Marathon.
|
||||
Private certificate used for the secure connection to Marathon.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon.tls]
|
||||
@@ -496,7 +500,7 @@ providers:
|
||||
|
||||
#### `tls.insecureSkipVerify`
|
||||
|
||||
If `insecureSkipVerify` is `true`, TLS for the connection to Marathon accepts any certificate presented by the server and any host name in that certificate.
|
||||
If `insecureSkipVerify` is `true`, the TLS connection to Marathon accepts any certificate presented by the server regardless of the hostnames it covers.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon.tls]
|
||||
@@ -518,6 +522,12 @@ providers:
|
||||
|
||||
_Optional, Default=5s_
|
||||
|
||||
Amount of time the Marathon provider should wait before timing out,
|
||||
when waiting for the TLS handshake to complete.
|
||||
|
||||
The value of `tlsHandshakeTimeout` should be provided in seconds or as a valid duration format,
|
||||
see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon]
|
||||
responseHeaderTimeout = "10s"
|
||||
@@ -536,17 +546,12 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Overrides TLSHandshakeTimeout.
|
||||
|
||||
Amount of time the Marathon provider should wait before timing out,
|
||||
when waiting for the TLS handshake to complete.
|
||||
Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration),
|
||||
or directly as a number of seconds.
|
||||
|
||||
### `trace`
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
Displays additional provider logs when available.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon]
|
||||
trace = true
|
||||
@@ -565,12 +570,12 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Displays additional provider logs (if available).
|
||||
|
||||
### `watch`
|
||||
|
||||
_Optional, Default=true_
|
||||
|
||||
When set to `true`, watches for Marathon changes.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.marathon]
|
||||
watch = false
|
||||
@@ -588,5 +593,3 @@ providers:
|
||||
--providers.marathon.watch=false
|
||||
# ...
|
||||
```
|
||||
|
||||
Enables watching for Marathon changes.
|
||||
|
@@ -7,30 +7,28 @@ Traefik's Many Friends
|
||||
|
||||
Configuration discovery in Traefik is achieved through _Providers_.
|
||||
|
||||
The _providers_ are existing infrastructure components, whether orchestrators, container engines, cloud providers, or key-value stores.
|
||||
The idea is that Traefik will query the providers' API in order to find relevant information about routing,
|
||||
and each time Traefik detects a change, it dynamically updates the routes.
|
||||
|
||||
Deploy and forget is Traefik's credo.
|
||||
The _providers_ are infrastructure components, whether orchestrators, container engines, cloud providers, or key-value stores.
|
||||
The idea is that Traefik queries the provider APIs in order to find relevant information about routing,
|
||||
and when Traefik detects a change, it dynamically updates the routes.
|
||||
|
||||
## Orchestrators
|
||||
|
||||
Even if each provider is different, we can categorize them in four groups:
|
||||
While each provider is different, you can think of each as belonging to one of four categories:
|
||||
|
||||
- Label based (each deployed container has a set of labels attached to it)
|
||||
- Key-Value based (each deployed container updates a key-value store with relevant information)
|
||||
- Annotation based (a separate object, with annotations, defines the characteristics of the container)
|
||||
- File based (the good old configuration file)
|
||||
- Label-based: each deployed container has a set of labels attached to it
|
||||
- Key-Value-based: each deployed container updates a key-value store with relevant information
|
||||
- Annotation-based: a separate object, with annotations, defines the characteristics of the container
|
||||
- File-based: uses files to define configuration
|
||||
|
||||
## Provider Namespace
|
||||
|
||||
When you declare certain objects, in Traefik dynamic configuration,
|
||||
such as middleware, service, TLS options or servers transport, they live in its provider's namespace.
|
||||
For example, if you declare a middleware using a Docker label, under the hoods, it will reside in the docker provider namespace.
|
||||
When you declare certain objects in the Traefik dynamic configuration,
|
||||
such as middleware, services, TLS options or server transports, they reside in their provider's namespace.
|
||||
For example, if you declare a middleware using a Docker label, it resides in the Docker provider namespace.
|
||||
|
||||
If you use multiple providers and wish to reference such an object declared in another provider
|
||||
(aka referencing a cross-provider object, e.g. middleware), then you'll have to append the `@` separator,
|
||||
followed by the provider name to the object name.
|
||||
If you use multiple providers and wish to reference such an object declared in another provider
|
||||
(e.g. referencing a cross-provider object like middleware), then the object name should be suffixed by the `@`
|
||||
separator, and the provider name.
|
||||
|
||||
```text
|
||||
<resource-name>@<provider-name>
|
||||
@@ -39,14 +37,15 @@ followed by the provider name to the object name.
|
||||
!!! important "Kubernetes Namespace"
|
||||
|
||||
As Kubernetes also has its own notion of namespace,
|
||||
one should not confuse the "provider namespace" with the "kubernetes namespace" of a resource when in the context of a cross-provider usage.
|
||||
In this case, since the definition of a traefik dynamic configuration object is not in kubernetes,
|
||||
specifying a "kubernetes namespace" when referring to the resource does not make any sense,
|
||||
and therefore this specification would be ignored even if present.
|
||||
On the other hand, if you, say, declare a middleware as a Custom Resource in Kubernetes and use the non-crd Ingress objects,
|
||||
you'll have to add the Kubernetes namespace of the middleware to the annotation like this `<middleware-namespace>-<middleware-name>@kubernetescrd`.
|
||||
one should not confuse the _provider namespace_ with the _Kubernetes Namespace_ of a resource when in the context of cross-provider usage.
|
||||
|
||||
!!! abstract "Referencing a Traefik dynamic configuration object from Another Provider"
|
||||
In this case, since the definition of a Traefik dynamic configuration object is not in Kubernetes,
|
||||
specifying a Kubernetes Namespace when referring to the resource does not make any sense.
|
||||
|
||||
On the other hand, if you were to declare a middleware as a Custom Resource in Kubernetes and use the non-CRD Ingress objects,
|
||||
you would have to add the Kubernetes Namespace of the middleware to the annotation like this `<middleware-namespace>-<middleware-name>@kubernetescrd`.
|
||||
|
||||
!!! abstract "Referencing a Traefik Dynamic Configuration Object from Another Provider"
|
||||
|
||||
Declaring the add-foo-prefix in the file provider.
|
||||
|
||||
@@ -55,7 +54,7 @@ followed by the provider name to the object name.
|
||||
[http.middlewares.add-foo-prefix.addPrefix]
|
||||
prefix = "/foo"
|
||||
```
|
||||
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
http:
|
||||
middlewares:
|
||||
@@ -96,7 +95,7 @@ followed by the provider name to the object name.
|
||||
# A namespace specification such as above is ignored
|
||||
# when the cross-provider syntax is used.
|
||||
```
|
||||
|
||||
|
||||
```yaml tab="Kubernetes Ingress"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: Middleware
|
||||
@@ -107,7 +106,7 @@ followed by the provider name to the object name.
|
||||
stripPrefix:
|
||||
prefixes:
|
||||
- /stripit
|
||||
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
@@ -122,46 +121,53 @@ followed by the provider name to the object name.
|
||||
# ... regular ingress definition
|
||||
```
|
||||
|
||||
## Supported Providers
|
||||
## Supported Providers
|
||||
|
||||
Below is the list of the currently supported providers in Traefik.
|
||||
Below is the list of the currently supported providers in Traefik.
|
||||
|
||||
| Provider | Type | Configuration Type |
|
||||
|---------------------------------------|--------------|----------------------------|
|
||||
| [Docker](./docker.md) | Orchestrator | Label |
|
||||
| [Kubernetes](./kubernetes-crd.md) | Orchestrator | Custom Resource or Ingress |
|
||||
| [Consul Catalog](./consul-catalog.md) | Orchestrator | Label |
|
||||
| [ECS](./ecs.md) | Orchestrator | Label |
|
||||
| [Marathon](./marathon.md) | Orchestrator | Label |
|
||||
| [Rancher](./rancher.md) | Orchestrator | Label |
|
||||
| [File](./file.md) | Manual | TOML/YAML format |
|
||||
| [Consul](./consul.md) | KV | KV |
|
||||
| [Etcd](./etcd.md) | KV | KV |
|
||||
| [Redis](./redis.md) | KV | KV |
|
||||
| [ZooKeeper](./zookeeper.md) | KV | KV |
|
||||
| [Redis](./redis.md) | KV | KV |
|
||||
| [HTTP](./http.md) | Manual | JSON format |
|
||||
|
||||
!!! info "More Providers"
|
||||
|
||||
The current version of Traefik doesn't support (yet) every provider.
|
||||
The current version of Traefik does not yet support every provider that Traefik v1.7 did.
|
||||
See the [previous version (v1.7)](https://doc.traefik.io/traefik/v1.7/) for more providers.
|
||||
|
||||
### Configuration reload frequency
|
||||
### Configuration Reload Frequency
|
||||
|
||||
#### `providers.providersThrottleDuration`
|
||||
|
||||
_Optional, Default: 2s_
|
||||
|
||||
In some cases, some providers might undergo a sudden burst of changes,
|
||||
which would generate a lot of configuration change events.
|
||||
If Traefik took them all into account,
|
||||
that would trigger a lot more configuration reloads than what is necessary,
|
||||
that would trigger a lot more configuration reloads than is necessary,
|
||||
or even useful.
|
||||
|
||||
In order to mitigate that, the `providers.providersThrottleDuration` option can be set.
|
||||
It is the duration that Traefik waits for, after a configuration reload,
|
||||
before taking into account any new configuration refresh event.
|
||||
If any event arrives during that duration, only the most recent one is taken into account,
|
||||
and all the previous others are dropped.
|
||||
If multiple events occur within this time, only the most recent one is taken into account,
|
||||
and all others are discarded.
|
||||
|
||||
This option cannot be set per provider,
|
||||
but the throttling algorithm applies independently to each of them.
|
||||
It defaults to 2 seconds.
|
||||
but the throttling algorithm applies to each of them independently.
|
||||
|
||||
The value of `providers.providersThrottleDuration` should be provided in seconds or as a valid duration format,
|
||||
see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers]
|
||||
@@ -183,17 +189,18 @@ TODO (document TCP VS HTTP dynamic configuration)
|
||||
|
||||
## Restrict the Scope of Service Discovery
|
||||
|
||||
By default Traefik will create routes for all detected containers.
|
||||
By default, Traefik creates routes for all detected containers.
|
||||
|
||||
If you want to limit the scope of Traefik's service discovery,
|
||||
If you want to limit the scope of the Traefik service discovery,
|
||||
i.e. disallow route creation for some containers,
|
||||
you can do so in two different ways:
|
||||
either with the generic configuration option `exposedByDefault`,
|
||||
or with a finer granularity mechanism based on constraints.
|
||||
|
||||
- the generic configuration option `exposedByDefault`,
|
||||
- a finer granularity mechanism based on constraints.
|
||||
|
||||
### `exposedByDefault` and `traefik.enable`
|
||||
|
||||
List of providers that support that feature:
|
||||
List of providers that support these features:
|
||||
|
||||
- [Docker](./docker.md#exposedbydefault)
|
||||
- [Consul Catalog](./consul-catalog.md#exposedbydefault)
|
||||
@@ -210,3 +217,4 @@ List of providers that support constraints:
|
||||
- [Marathon](./marathon.md#constraints)
|
||||
- [Kubernetes CRD](./kubernetes-crd.md#labelselector)
|
||||
- [Kubernetes Ingress](./kubernetes-ingress.md#labelselector)
|
||||
- [Kubernetes Gateway](./kubernetes-gateway.md#labelselector)
|
||||
|
@@ -8,25 +8,25 @@ A Story of Labels, Services & Containers
|
||||
Attach labels to your services and let Traefik do the rest!
|
||||
|
||||
!!! important "This provider is specific to Rancher 1.x."
|
||||
|
||||
|
||||
Rancher 2.x requires Kubernetes and does not have a metadata endpoint of its own for Traefik to query.
|
||||
As such, Rancher 2.x users should utilize the [Kubernetes provider](./kubernetes-crd.md) directly.
|
||||
As such, Rancher 2.x users should utilize the [Kubernetes CRD provider](./kubernetes-crd.md) directly.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
??? example "Configuring Rancher & Deploying / Exposing Services"
|
||||
|
||||
Enabling the rancher provider
|
||||
Enabling the Rancher provider
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.rancher]
|
||||
```
|
||||
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
rancher: {}
|
||||
```
|
||||
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.rancher=true
|
||||
```
|
||||
@@ -45,16 +45,17 @@ See the dedicated section in [routing](../routing/providers/rancher.md).
|
||||
## Provider Configuration
|
||||
|
||||
??? tip "Browse the Reference"
|
||||
If you're in a hurry, maybe you'd rather go through the configuration reference:
|
||||
|
||||
|
||||
For an overview of all the options that can be set with the Rancher provider, see the following snippets:
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
--8<-- "content/providers/rancher.toml"
|
||||
```
|
||||
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
--8<-- "content/providers/rancher.yml"
|
||||
```
|
||||
|
||||
|
||||
```bash tab="CLI"
|
||||
--8<-- "content/providers/rancher.txt"
|
||||
```
|
||||
@@ -63,6 +64,11 @@ See the dedicated section in [routing](../routing/providers/rancher.md).
|
||||
|
||||
_Optional, Default=true_
|
||||
|
||||
Expose Rancher services by default in Traefik.
|
||||
If set to `false`, services that do not have a `traefik.enable=true` label are ignored from the resulting routing configuration.
|
||||
|
||||
For additional information, refer to [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.rancher]
|
||||
exposedByDefault = false
|
||||
@@ -81,15 +87,21 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Expose Rancher services by default in Traefik.
|
||||
If set to false, services that don't have a `traefik.enable=true` label will be ignored from the resulting routing configuration.
|
||||
|
||||
See also [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
|
||||
|
||||
### `defaultRule`
|
||||
|
||||
_Optional, Default=```Host(`{{ normalize .Name }}`)```_
|
||||
|
||||
The default host rule for all services.
|
||||
|
||||
The `defaultRule` option defines what routing rule to apply to a container if no rule is defined by a label.
|
||||
|
||||
It must be a valid [Go template](https://golang.org/pkg/text/template/), and can use
|
||||
[sprig template functions](http://masterminds.github.io/sprig/).
|
||||
The service name can be accessed with the `Name` identifier,
|
||||
and the template has access to all the labels defined on this container.
|
||||
|
||||
This option can be overridden on a container basis with the `traefik.http.routers.Router1.rule` label.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.rancher]
|
||||
defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)"
|
||||
@@ -108,20 +120,12 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
The default host rule for all services.
|
||||
|
||||
For a given container if no routing rule was defined by a label, it is defined by this defaultRule instead.
|
||||
It must be a valid [Go template](https://golang.org/pkg/text/template/),
|
||||
augmented with the [sprig template functions](http://masterminds.github.io/sprig/).
|
||||
The service name can be accessed as the `Name` identifier,
|
||||
and the template has access to all the labels defined on this container.
|
||||
|
||||
This option can be overridden on a container basis with the `traefik.http.routers.Router1.rule` label.
|
||||
|
||||
### `enableServiceHealthFilter`
|
||||
|
||||
_Optional, Default=true_
|
||||
|
||||
Filter out services with unhealthy states and inactive states.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.rancher]
|
||||
enableServiceHealthFilter = false
|
||||
@@ -140,12 +144,12 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Filter services with unhealthy states and inactive states.
|
||||
|
||||
### `refreshSeconds`
|
||||
|
||||
_Optional, Default=15_
|
||||
|
||||
Defines the polling interval (in seconds).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.rancher]
|
||||
refreshSeconds = 30
|
||||
@@ -164,12 +168,13 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Defines the polling interval (in seconds).
|
||||
|
||||
### `intervalPoll`
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
Poll the Rancher metadata service for changes every `rancher.refreshSeconds`,
|
||||
which is less accurate than the default long polling technique which provides near instantaneous updates to Traefik.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.rancher]
|
||||
intervalPoll = true
|
||||
@@ -188,12 +193,11 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Poll the Rancher metadata service for changes every `rancher.refreshSeconds`,
|
||||
which is less accurate than the default long polling technique which will provide near instantaneous updates to Traefik.
|
||||
|
||||
### `prefix`
|
||||
|
||||
_Optional, Default=/latest_
|
||||
_Optional, Default="/latest"_
|
||||
|
||||
Prefix used for accessing the Rancher metadata service.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.rancher]
|
||||
@@ -213,12 +217,51 @@ providers:
|
||||
# ...
|
||||
```
|
||||
|
||||
Prefix used for accessing the Rancher metadata service
|
||||
|
||||
### `constraints`
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
The `constraints` option can be set to an expression that Traefik matches against the container labels to determine whether
|
||||
to create any route for that container. If none of the container tags match the expression, no route for that container is
|
||||
created. If the expression is empty, all detected containers are included.
|
||||
|
||||
The expression syntax is based on the `Label("key", "value")`, and `LabelRegex("key", "value")` functions, as well as
|
||||
the usual boolean logic, as shown in examples below.
|
||||
|
||||
??? example "Constraints Expression Examples"
|
||||
|
||||
```toml
|
||||
# Includes only containers having a label with key `a.label.name` and value `foo`
|
||||
constraints = "Label(`a.label.name`, `foo`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Excludes containers having any label with key `a.label.name` and value `foo`
|
||||
constraints = "!Label(`a.label.name`, `value`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND.
|
||||
constraints = "Label(`a.label.name`, `valueA`) && Label(`another.label.name`, `valueB`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical OR.
|
||||
constraints = "Label(`a.label.name`, `valueA`) || Label(`another.label.name`, `valueB`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND and OR, with precedence set by parentheses.
|
||||
constraints = "Label(`a.label.name`, `valueA`) && (Label(`another.label.name`, `valueB`) || Label(`yet.another.label.name`, `valueC`))"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Includes only containers having a label with key `a.label.name` and a value matching the `a.+` regular expression.
|
||||
constraints = "LabelRegex(`a.label.name`, `a.+`)"
|
||||
```
|
||||
|
||||
For additional information, refer to [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.rancher]
|
||||
constraints = "Label(`a.label.name`,`foo`)"
|
||||
@@ -236,43 +279,3 @@ providers:
|
||||
--providers.rancher.constraints=Label(`a.label.name`,`foo`)
|
||||
# ...
|
||||
```
|
||||
|
||||
Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container.
|
||||
That is to say, if none of the container's labels match the expression, no route for the container is created.
|
||||
If the expression is empty, all detected containers are included.
|
||||
|
||||
The expression syntax is based on the `Label("key", "value")`, and `LabelRegex("key", "value")` functions, as well as the usual boolean logic, as shown in examples below.
|
||||
|
||||
??? example "Constraints Expression Examples"
|
||||
|
||||
```toml
|
||||
# Includes only containers having a label with key `a.label.name` and value `foo`
|
||||
constraints = "Label(`a.label.name`, `foo`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Excludes containers having any label with key `a.label.name` and value `foo`
|
||||
constraints = "!Label(`a.label.name`, `value`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND.
|
||||
constraints = "Label(`a.label.name`, `valueA`) && Label(`another.label.name`, `valueB`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical OR.
|
||||
constraints = "Label(`a.label.name`, `valueA`) || Label(`another.label.name`, `valueB`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND and OR, with precedence set by parentheses.
|
||||
constraints = "Label(`a.label.name`, `valueA`) && (Label(`another.label.name`, `valueB`) || Label(`yet.another.label.name`, `valueC`))"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Includes only containers having a label with key `a.label.name` and a value matching the `a.+` regular expression.
|
||||
constraints = "LabelRegex(`a.label.name`, `a.+`)"
|
||||
```
|
||||
|
||||
See also [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
|
||||
|
@@ -35,10 +35,10 @@ providers:
|
||||
|
||||
### `rootKey`
|
||||
|
||||
Defines the root key of the configuration.
|
||||
|
||||
_Required, Default="traefik"_
|
||||
|
||||
Defines the root key of the configuration.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.redis]
|
||||
rootKey = "traefik"
|
||||
@@ -56,10 +56,10 @@ providers:
|
||||
|
||||
### `username`
|
||||
|
||||
Defines a username to connect with Redis.
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
Defines a username to connect with Redis.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.redis]
|
||||
# ...
|
||||
@@ -106,7 +106,7 @@ _Optional_
|
||||
|
||||
#### `tls.ca`
|
||||
|
||||
Certificate Authority used for the secured connection to Redis.
|
||||
Certificate Authority used for the secure connection to Redis.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.redis.tls]
|
||||
@@ -126,12 +126,15 @@ providers:
|
||||
|
||||
#### `tls.caOptional`
|
||||
|
||||
Policy followed for the secured connection with TLS Client Authentication to Redis.
|
||||
Requires `tls.ca` to be defined.
|
||||
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Redis.
|
||||
|
||||
- `true`: VerifyClientCertIfGiven
|
||||
- `false`: RequireAndVerifyClientCert
|
||||
- if `tls.ca` is undefined NoClientCert
|
||||
!!! warning ""
|
||||
|
||||
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
|
||||
|
||||
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
|
||||
|
||||
When this option is set to `false`, a client certificate is requested during the handshake, and at least one valid certificate should be sent by the client.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.redis.tls]
|
||||
@@ -151,7 +154,7 @@ providers:
|
||||
|
||||
#### `tls.cert`
|
||||
|
||||
Public certificate used for the secured connection to Redis.
|
||||
Public certificate used for the secure connection to Redis.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.redis.tls]
|
||||
@@ -174,7 +177,7 @@ providers:
|
||||
|
||||
#### `tls.key`
|
||||
|
||||
Private certificate used for the secured connection to Redis.
|
||||
Private certificate used for the secure connection to Redis.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.redis.tls]
|
||||
@@ -197,7 +200,7 @@ providers:
|
||||
|
||||
#### `tls.insecureSkipVerify`
|
||||
|
||||
If `insecureSkipVerify` is `true`, TLS for the connection to Redis accepts any certificate presented by the server and any host name in that certificate.
|
||||
If `insecureSkipVerify` is `true`, the TLS connection to Redis accepts any certificate presented by the server regardless of the hostnames it covers.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.redis.tls]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# Traefik & ZooKeeper
|
||||
|
||||
A Story of KV store & Containers
|
||||
A Story of KV Store & Containers
|
||||
{: .subtitle }
|
||||
|
||||
Store your configuration in ZooKeeper and let Traefik do the rest!
|
||||
@@ -35,10 +35,10 @@ providers:
|
||||
|
||||
### `rootKey`
|
||||
|
||||
Defines the root key of the configuration.
|
||||
|
||||
_Required, Default="traefik"_
|
||||
|
||||
Defines the root key of the configuration.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.zooKeeper]
|
||||
rootKey = "traefik"
|
||||
@@ -56,10 +56,10 @@ providers:
|
||||
|
||||
### `username`
|
||||
|
||||
Defines a username to connect with ZooKeeper.
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
Defines a username to connect with ZooKeeper.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.zooKeeper]
|
||||
# ...
|
||||
@@ -106,7 +106,7 @@ _Optional_
|
||||
|
||||
#### `tls.ca`
|
||||
|
||||
Certificate Authority used for the secured connection to ZooKeeper.
|
||||
Certificate Authority used for the secure connection to ZooKeeper.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.zooKeeper.tls]
|
||||
@@ -126,12 +126,15 @@ providers:
|
||||
|
||||
#### `tls.caOptional`
|
||||
|
||||
Policy followed for the secured connection with TLS Client Authentication to ZooKeeper.
|
||||
Requires `tls.ca` to be defined.
|
||||
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Zookeeper.
|
||||
|
||||
- `true`: VerifyClientCertIfGiven
|
||||
- `false`: RequireAndVerifyClientCert
|
||||
- if `tls.ca` is undefined NoClientCert
|
||||
!!! warning ""
|
||||
|
||||
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
|
||||
|
||||
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
|
||||
|
||||
When this option is set to `false`, a client certificate is requested during the handshake, and at least one valid certificate should be sent by the client.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.zooKeeper.tls]
|
||||
@@ -151,7 +154,7 @@ providers:
|
||||
|
||||
#### `tls.cert`
|
||||
|
||||
Public certificate used for the secured connection to ZooKeeper.
|
||||
Public certificate used for the secure connection to ZooKeeper.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.zooKeeper.tls]
|
||||
@@ -174,7 +177,7 @@ providers:
|
||||
|
||||
#### `tls.key`
|
||||
|
||||
Private certificate used for the secured connection to ZooKeeper.
|
||||
Private certificate used for the secure connection to ZooKeeper.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.zooKeeper.tls]
|
||||
@@ -197,7 +200,7 @@ providers:
|
||||
|
||||
#### `tls.insecureSkipVerify`
|
||||
|
||||
If `insecureSkipVerify` is `true`, TLS for the connection to ZooKeeper accepts any certificate presented by the server and any host name in that certificate.
|
||||
If `insecureSkipVerify` is `true`, the TLS connection to Zookeeper accepts any certificate presented by the server regardless of the hostnames it covers.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.zooKeeper.tls]
|
||||
|
@@ -24,6 +24,8 @@
|
||||
- "traefik.http.middlewares.middleware08.errors.status=foobar, foobar"
|
||||
- "traefik.http.middlewares.middleware09.forwardauth.address=foobar"
|
||||
- "traefik.http.middlewares.middleware09.forwardauth.authresponseheaders=foobar, foobar"
|
||||
- "traefik.http.middlewares.middleware09.forwardauth.authresponseheadersregex=foobar"
|
||||
- "traefik.http.middlewares.middleware09.forwardauth.authrequestheaders=foobar, foobar"
|
||||
- "traefik.http.middlewares.middleware09.forwardauth.tls.ca=foobar"
|
||||
- "traefik.http.middlewares.middleware09.forwardauth.tls.caoptional=true"
|
||||
- "traefik.http.middlewares.middleware09.forwardauth.tls.cert=foobar"
|
||||
@@ -35,6 +37,7 @@
|
||||
- "traefik.http.middlewares.middleware10.headers.accesscontrolallowmethods=foobar, foobar"
|
||||
- "traefik.http.middlewares.middleware10.headers.accesscontrolalloworigin=foobar"
|
||||
- "traefik.http.middlewares.middleware10.headers.accesscontrolalloworiginlist=foobar, foobar"
|
||||
- "traefik.http.middlewares.middleware10.headers.accesscontrolalloworiginlistregex=foobar, foobar"
|
||||
- "traefik.http.middlewares.middleware10.headers.accesscontrolexposeheaders=foobar, foobar"
|
||||
- "traefik.http.middlewares.middleware10.headers.accesscontrolmaxage=42"
|
||||
- "traefik.http.middlewares.middleware10.headers.addvaryheader=true"
|
||||
@@ -109,6 +112,7 @@
|
||||
- "traefik.http.middlewares.middleware19.replacepathregex.regex=foobar"
|
||||
- "traefik.http.middlewares.middleware19.replacepathregex.replacement=foobar"
|
||||
- "traefik.http.middlewares.middleware20.retry.attempts=42"
|
||||
- "traefik.http.middlewares.middleware20.retry.initialinterval=42"
|
||||
- "traefik.http.middlewares.middleware21.stripprefix.forceslash=true"
|
||||
- "traefik.http.middlewares.middleware21.stripprefix.prefixes=foobar, foobar"
|
||||
- "traefik.http.middlewares.middleware22.stripprefixregex.regex=foobar, foobar"
|
||||
@@ -155,6 +159,7 @@
|
||||
- "traefik.http.services.service01.loadbalancer.sticky.cookie.secure=true"
|
||||
- "traefik.http.services.service01.loadbalancer.server.port=foobar"
|
||||
- "traefik.http.services.service01.loadbalancer.server.scheme=foobar"
|
||||
- "traefik.http.services.service01.loadbalancer.serverstransport=foobar"
|
||||
- "traefik.tcp.routers.tcprouter0.entrypoints=foobar, foobar"
|
||||
- "traefik.tcp.routers.tcprouter0.rule=foobar"
|
||||
- "traefik.tcp.routers.tcprouter0.service=foobar"
|
||||
@@ -179,6 +184,7 @@
|
||||
- "traefik.tcp.routers.tcprouter1.tls.passthrough=true"
|
||||
- "traefik.tcp.services.tcpservice01.loadbalancer.terminationdelay=42"
|
||||
- "traefik.tcp.services.tcpservice01.loadbalancer.server.port=foobar"
|
||||
- "traefik.tcp.services.tcpservice01.loadbalancer.proxyprotocol.version=42"
|
||||
- "traefik.udp.routers.udprouter0.entrypoints=foobar, foobar"
|
||||
- "traefik.udp.routers.udprouter0.service=foobar"
|
||||
- "traefik.udp.routers.udprouter1.entrypoints=foobar, foobar"
|
||||
|
@@ -38,6 +38,7 @@
|
||||
[http.services.Service01]
|
||||
[http.services.Service01.loadBalancer]
|
||||
passHostHeader = true
|
||||
serversTransport = "foobar"
|
||||
[http.services.Service01.loadBalancer.sticky]
|
||||
[http.services.Service01.loadBalancer.sticky.cookie]
|
||||
name = "foobar"
|
||||
@@ -138,6 +139,8 @@
|
||||
address = "foobar"
|
||||
trustForwardHeader = true
|
||||
authResponseHeaders = ["foobar", "foobar"]
|
||||
authResponseHeadersRegex = "foobar"
|
||||
authRequestHeaders = ["foobar", "foobar"]
|
||||
[http.middlewares.Middleware09.forwardAuth.tls]
|
||||
ca = "foobar"
|
||||
caOptional = true
|
||||
@@ -151,6 +154,7 @@
|
||||
accessControlAllowMethods = ["foobar", "foobar"]
|
||||
accessControlAllowOrigin = "foobar"
|
||||
accessControlAllowOriginList = ["foobar", "foobar"]
|
||||
accessControlAllowOriginListRegex = ["foobar", "foobar"]
|
||||
accessControlExposeHeaders = ["foobar", "foobar"]
|
||||
accessControlMaxAge = 42
|
||||
addVaryHeader = true
|
||||
@@ -257,6 +261,7 @@
|
||||
[http.middlewares.Middleware20]
|
||||
[http.middlewares.Middleware20.retry]
|
||||
attempts = 42
|
||||
initialInterval = 42
|
||||
[http.middlewares.Middleware21]
|
||||
[http.middlewares.Middleware21.stripPrefix]
|
||||
prefixes = ["foobar", "foobar"]
|
||||
@@ -264,6 +269,41 @@
|
||||
[http.middlewares.Middleware22]
|
||||
[http.middlewares.Middleware22.stripPrefixRegex]
|
||||
regex = ["foobar", "foobar"]
|
||||
[http.serversTransports]
|
||||
[http.serversTransports.ServersTransport0]
|
||||
serverName = "foobar"
|
||||
insecureSkipVerify = true
|
||||
rootCAs = ["foobar", "foobar"]
|
||||
maxIdleConnsPerHost = 42
|
||||
|
||||
[[http.serversTransports.ServersTransport0.certificates]]
|
||||
certFile = "foobar"
|
||||
keyFile = "foobar"
|
||||
|
||||
[[http.serversTransports.ServersTransport0.certificates]]
|
||||
certFile = "foobar"
|
||||
keyFile = "foobar"
|
||||
[http.serversTransports.ServersTransport0.forwardingTimeouts]
|
||||
dialTimeout = "42s"
|
||||
responseHeaderTimeout = "42s"
|
||||
idleConnTimeout = "42s"
|
||||
[http.serversTransports.ServersTransport1]
|
||||
serverName = "foobar"
|
||||
insecureSkipVerify = true
|
||||
rootCAs = ["foobar", "foobar"]
|
||||
maxIdleConnsPerHost = 42
|
||||
|
||||
[[http.serversTransports.ServersTransport1.certificates]]
|
||||
certFile = "foobar"
|
||||
keyFile = "foobar"
|
||||
|
||||
[[http.serversTransports.ServersTransport1.certificates]]
|
||||
certFile = "foobar"
|
||||
keyFile = "foobar"
|
||||
[http.serversTransports.ServersTransport1.forwardingTimeouts]
|
||||
dialTimeout = "42s"
|
||||
responseHeaderTimeout = "42s"
|
||||
idleConnTimeout = "42s"
|
||||
|
||||
[tcp]
|
||||
[tcp.routers]
|
||||
@@ -303,6 +343,8 @@
|
||||
[tcp.services.TCPService01]
|
||||
[tcp.services.TCPService01.loadBalancer]
|
||||
terminationDelay = 42
|
||||
[tcp.services.TCPService01.loadBalancer.proxyProtocol]
|
||||
version = 42
|
||||
|
||||
[[tcp.services.TCPService01.loadBalancer.servers]]
|
||||
address = "foobar"
|
||||
|
@@ -70,6 +70,7 @@ http:
|
||||
passHostHeader: true
|
||||
responseForwarding:
|
||||
flushInterval: foobar
|
||||
serversTransport: foobar
|
||||
Service02:
|
||||
mirroring:
|
||||
service: foobar
|
||||
@@ -157,6 +158,10 @@ http:
|
||||
authResponseHeaders:
|
||||
- foobar
|
||||
- foobar
|
||||
authResponseHeadersRegex: foobar
|
||||
authRequestHeaders:
|
||||
- foobar
|
||||
- foobar
|
||||
Middleware10:
|
||||
headers:
|
||||
customRequestHeaders:
|
||||
@@ -176,6 +181,9 @@ http:
|
||||
accessControlAllowOriginList:
|
||||
- foobar
|
||||
- foobar
|
||||
accessControlAllowOriginListRegex:
|
||||
- foobar
|
||||
- foobar
|
||||
accessControlExposeHeaders:
|
||||
- foobar
|
||||
- foobar
|
||||
@@ -290,6 +298,7 @@ http:
|
||||
Middleware20:
|
||||
retry:
|
||||
attempts: 42
|
||||
initialInterval: 42
|
||||
Middleware21:
|
||||
stripPrefix:
|
||||
prefixes:
|
||||
@@ -301,6 +310,39 @@ http:
|
||||
regex:
|
||||
- foobar
|
||||
- foobar
|
||||
serversTransports:
|
||||
ServersTransport0:
|
||||
serverName: foobar
|
||||
insecureSkipVerify: true
|
||||
rootCAs:
|
||||
- foobar
|
||||
- foobar
|
||||
certificates:
|
||||
- certFile: foobar
|
||||
keyFile: foobar
|
||||
- certFile: foobar
|
||||
keyFile: foobar
|
||||
maxIdleConnsPerHost: 42
|
||||
forwardingTimeouts:
|
||||
dialTimeout: 42s
|
||||
responseHeaderTimeout: 42s
|
||||
idleConnTimeout: 42s
|
||||
ServersTransport1:
|
||||
serverName: foobar
|
||||
insecureSkipVerify: true
|
||||
rootCAs:
|
||||
- foobar
|
||||
- foobar
|
||||
certificates:
|
||||
- certFile: foobar
|
||||
keyFile: foobar
|
||||
- certFile: foobar
|
||||
keyFile: foobar
|
||||
maxIdleConnsPerHost: 42
|
||||
forwardingTimeouts:
|
||||
dialTimeout: 42s
|
||||
responseHeaderTimeout: 42s
|
||||
idleConnTimeout: 42s
|
||||
tcp:
|
||||
routers:
|
||||
TCPRouter0:
|
||||
@@ -345,6 +387,8 @@ tcp:
|
||||
TCPService01:
|
||||
loadBalancer:
|
||||
terminationDelay: 42
|
||||
proxyProtocol:
|
||||
version: 42
|
||||
servers:
|
||||
- address: foobar
|
||||
- address: foobar
|
||||
|
@@ -101,3 +101,18 @@ spec:
|
||||
plural: traefikservices
|
||||
singular: traefikservice
|
||||
scope: Namespaced
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: serverstransports.traefik.containo.us
|
||||
|
||||
spec:
|
||||
group: traefik.containo.us
|
||||
version: v1alpha1
|
||||
names:
|
||||
kind: ServersTransport
|
||||
plural: serverstransports
|
||||
singular: serverstransport
|
||||
scope: Namespaced
|
||||
|
@@ -40,6 +40,7 @@ rules:
|
||||
- ingressrouteudps
|
||||
- tlsoptions
|
||||
- tlsstores
|
||||
- serverstransports
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
|
@@ -96,6 +96,7 @@ spec:
|
||||
strategy: RoundRobin
|
||||
- name: s2
|
||||
port: 433
|
||||
serversTransport: mytransport
|
||||
- match: PathPrefix(`/misc`)
|
||||
services:
|
||||
- name: s3
|
||||
@@ -186,3 +187,25 @@ spec:
|
||||
clientAuthType: foobar
|
||||
sniStrict: true
|
||||
preferServerCipherSuites: true
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: ServersTransport
|
||||
metadata:
|
||||
name: mytransport
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
serverName: foobar
|
||||
insecureSkipVerify: true
|
||||
rootCAsSecrets:
|
||||
- foobar
|
||||
- foobar
|
||||
certificatesSecrets:
|
||||
- foobar
|
||||
- foobar
|
||||
maxIdleConnsPerHost: 1
|
||||
forwardingTimeouts:
|
||||
dialTimeout: 42s
|
||||
responseHeaderTimeout: 42s
|
||||
idleConnTimeout: 42s
|
||||
|
@@ -0,0 +1,49 @@
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: gateway-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- services
|
||||
- endpoints
|
||||
- secrets
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- networking.x-k8s.io
|
||||
resources:
|
||||
- gatewayclasses
|
||||
- gateways
|
||||
- httproutes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- networking.x-k8s.io
|
||||
resources:
|
||||
- gatewayclasses/status
|
||||
- gateways/status
|
||||
- httproutes/status
|
||||
verbs:
|
||||
- update
|
||||
|
||||
---
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: gateway-controller
|
||||
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: gateway-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: traefik-controller
|
||||
namespace: default
|
@@ -0,0 +1,46 @@
|
||||
---
|
||||
kind: GatewayClass
|
||||
apiVersion: networking.x-k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: my-gateway-class
|
||||
spec:
|
||||
controller: traefik.io/gateway-controller
|
||||
|
||||
---
|
||||
kind: Gateway
|
||||
apiVersion: networking.x-k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: my-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gatewayClassName: my-gateway-class
|
||||
listeners: # Use GatewayClass defaults for listener definition.
|
||||
- protocol: HTTP
|
||||
port: 80
|
||||
routes:
|
||||
kind: HTTPRoute
|
||||
namespaces:
|
||||
from: Same
|
||||
selector:
|
||||
app: foo
|
||||
|
||||
---
|
||||
kind: HTTPRoute
|
||||
apiVersion: networking.x-k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: http-app-1
|
||||
namespace: default
|
||||
labels:
|
||||
app: foo
|
||||
spec:
|
||||
hostnames:
|
||||
- "foo.com"
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: Exact
|
||||
value: /bar
|
||||
forwardTo:
|
||||
- serviceName: whoami
|
||||
port: 80
|
||||
weight: 1
|
@@ -0,0 +1,47 @@
|
||||
---
|
||||
kind: GatewayClass
|
||||
apiVersion: networking.x-k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: my-gateway-class
|
||||
spec:
|
||||
controller: traefik.io/gateway-controller
|
||||
|
||||
---
|
||||
kind: Gateway
|
||||
apiVersion: networking.x-k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: my-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gatewayClassName: my-gateway-class
|
||||
listeners:
|
||||
- protocol: HTTP
|
||||
port: 80
|
||||
routes:
|
||||
kind: HTTPRoute
|
||||
namespaces:
|
||||
from: Same
|
||||
selector:
|
||||
matchLabels:
|
||||
app: foo
|
||||
|
||||
---
|
||||
kind: HTTPRoute
|
||||
apiVersion: networking.x-k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: http-app-1
|
||||
namespace: default
|
||||
labels:
|
||||
app: foo
|
||||
spec:
|
||||
hostnames:
|
||||
- "whoami"
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: Exact
|
||||
value: /bar
|
||||
forwardTo:
|
||||
- serviceName: whoami
|
||||
port: 80
|
||||
weight: 1
|
@@ -0,0 +1,48 @@
|
||||
---
|
||||
kind: GatewayClass
|
||||
apiVersion: networking.x-k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: my-gateway-class
|
||||
spec:
|
||||
controller: traefik.io/gateway-controller
|
||||
|
||||
---
|
||||
kind: Gateway
|
||||
apiVersion: networking.x-k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: my-gateway
|
||||
spec:
|
||||
gatewayClassName: my-gateway-class
|
||||
listeners:
|
||||
- protocol: HTTPS
|
||||
port: 443
|
||||
tls:
|
||||
certificateRef:
|
||||
group: "core"
|
||||
kind: "Secret"
|
||||
name: "mysecret"
|
||||
routes:
|
||||
kind: HTTPRoute
|
||||
selector:
|
||||
matchLabels:
|
||||
app: foo
|
||||
---
|
||||
kind: HTTPRoute
|
||||
apiVersion: networking.x-k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: http-app-1
|
||||
namespace: default
|
||||
labels:
|
||||
app: foo
|
||||
spec:
|
||||
hostnames:
|
||||
- "whoami"
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: Exact
|
||||
value: /foo
|
||||
forwardTo:
|
||||
- serviceName: whoami
|
||||
port: 80
|
||||
weight: 1
|
@@ -0,0 +1,56 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: traefik-controller
|
||||
|
||||
---
|
||||
kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: traefik
|
||||
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: traefik-lb
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: traefik-lb
|
||||
spec:
|
||||
serviceAccountName: traefik-controller
|
||||
containers:
|
||||
- name: traefik
|
||||
image: traefik/traefik:latest
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
- --entrypoints.web.address=:80
|
||||
- --entrypoints.websecure.address=:443
|
||||
- --experimental.kubernetesgateway
|
||||
- --providers.kubernetesgateway
|
||||
ports:
|
||||
- name: web
|
||||
containerPort: 80
|
||||
- name: websecure
|
||||
containerPort: 443
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: traefik
|
||||
spec:
|
||||
selector:
|
||||
app: traefik-lb
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: web
|
||||
name: web
|
||||
- protocol: TCP
|
||||
port: 443
|
||||
targetPort: websecure
|
||||
name: websecure
|
||||
type: LoadBalancer
|
@@ -0,0 +1,24 @@
|
||||
# Kubernetes Configuration Reference
|
||||
|
||||
Dynamic configuration with Kubernetes Gateway provider.
|
||||
{: .subtitle }
|
||||
|
||||
## Definitions
|
||||
|
||||
```yaml
|
||||
--8<-- "content/reference/dynamic-configuration/networking.x-k8s.io_gatewayclasses.yaml"
|
||||
--8<-- "content/reference/dynamic-configuration/networking.x-k8s.io_gateways.yaml"
|
||||
--8<-- "content/reference/dynamic-configuration/networking.x-k8s.io_httproutes.yaml"
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
```yaml
|
||||
--8<-- "content/reference/dynamic-configuration/kubernetes-gateway-resource.yml"
|
||||
```
|
||||
|
||||
## RBAC
|
||||
|
||||
```yaml
|
||||
--8<-- "content/reference/dynamic-configuration/kubernetes-gateway-rbac.yml"
|
||||
```
|
@@ -0,0 +1,32 @@
|
||||
---
|
||||
kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: whoami
|
||||
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: whoami
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: whoami
|
||||
spec:
|
||||
containers:
|
||||
- name: whoami
|
||||
image: traefik/whoami
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: whoami
|
||||
|
||||
spec:
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
selector:
|
||||
app: whoami
|
@@ -27,8 +27,11 @@
|
||||
| `traefik/http/middlewares/Middleware08/errors/status/0` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware08/errors/status/1` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware09/forwardAuth/address` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware09/forwardAuth/authRequestHeaders/0` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware09/forwardAuth/authRequestHeaders/1` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware09/forwardAuth/authResponseHeaders/0` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware09/forwardAuth/authResponseHeaders/1` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware09/forwardAuth/authResponseHeadersRegex` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware09/forwardAuth/tls/ca` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware09/forwardAuth/tls/caOptional` | `true` |
|
||||
| `traefik/http/middlewares/Middleware09/forwardAuth/tls/cert` | `foobar` |
|
||||
@@ -43,6 +46,8 @@
|
||||
| `traefik/http/middlewares/Middleware10/headers/accessControlAllowOrigin` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware10/headers/accessControlAllowOriginList/0` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware10/headers/accessControlAllowOriginList/1` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware10/headers/accessControlAllowOriginListRegex/0` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware10/headers/accessControlAllowOriginListRegex/1` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware10/headers/accessControlExposeHeaders/0` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware10/headers/accessControlExposeHeaders/1` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware10/headers/accessControlMaxAge` | `42` |
|
||||
@@ -124,6 +129,7 @@
|
||||
| `traefik/http/middlewares/Middleware19/replacePathRegex/regex` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware19/replacePathRegex/replacement` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware20/retry/attempts` | `42` |
|
||||
| `traefik/http/middlewares/Middleware20/retry/initialInterval` | `42` |
|
||||
| `traefik/http/middlewares/Middleware21/stripPrefix/forceSlash` | `true` |
|
||||
| `traefik/http/middlewares/Middleware21/stripPrefix/prefixes/0` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware21/stripPrefix/prefixes/1` | `foobar` |
|
||||
@@ -159,6 +165,30 @@
|
||||
| `traefik/http/routers/Router1/tls/domains/1/sans/0` | `foobar` |
|
||||
| `traefik/http/routers/Router1/tls/domains/1/sans/1` | `foobar` |
|
||||
| `traefik/http/routers/Router1/tls/options` | `foobar` |
|
||||
| `traefik/http/serversTransports/ServersTransport0/certificates/0/certFile` | `foobar` |
|
||||
| `traefik/http/serversTransports/ServersTransport0/certificates/0/keyFile` | `foobar` |
|
||||
| `traefik/http/serversTransports/ServersTransport0/certificates/1/certFile` | `foobar` |
|
||||
| `traefik/http/serversTransports/ServersTransport0/certificates/1/keyFile` | `foobar` |
|
||||
| `traefik/http/serversTransports/ServersTransport0/forwardingTimeouts/dialTimeout` | `42s` |
|
||||
| `traefik/http/serversTransports/ServersTransport0/forwardingTimeouts/idleConnTimeout` | `42s` |
|
||||
| `traefik/http/serversTransports/ServersTransport0/forwardingTimeouts/responseHeaderTimeout` | `42s` |
|
||||
| `traefik/http/serversTransports/ServersTransport0/insecureSkipVerify` | `true` |
|
||||
| `traefik/http/serversTransports/ServersTransport0/maxIdleConnsPerHost` | `42` |
|
||||
| `traefik/http/serversTransports/ServersTransport0/rootCAs/0` | `foobar` |
|
||||
| `traefik/http/serversTransports/ServersTransport0/rootCAs/1` | `foobar` |
|
||||
| `traefik/http/serversTransports/ServersTransport0/serverName` | `foobar` |
|
||||
| `traefik/http/serversTransports/ServersTransport1/certificates/0/certFile` | `foobar` |
|
||||
| `traefik/http/serversTransports/ServersTransport1/certificates/0/keyFile` | `foobar` |
|
||||
| `traefik/http/serversTransports/ServersTransport1/certificates/1/certFile` | `foobar` |
|
||||
| `traefik/http/serversTransports/ServersTransport1/certificates/1/keyFile` | `foobar` |
|
||||
| `traefik/http/serversTransports/ServersTransport1/forwardingTimeouts/dialTimeout` | `42s` |
|
||||
| `traefik/http/serversTransports/ServersTransport1/forwardingTimeouts/idleConnTimeout` | `42s` |
|
||||
| `traefik/http/serversTransports/ServersTransport1/forwardingTimeouts/responseHeaderTimeout` | `42s` |
|
||||
| `traefik/http/serversTransports/ServersTransport1/insecureSkipVerify` | `true` |
|
||||
| `traefik/http/serversTransports/ServersTransport1/maxIdleConnsPerHost` | `42` |
|
||||
| `traefik/http/serversTransports/ServersTransport1/rootCAs/0` | `foobar` |
|
||||
| `traefik/http/serversTransports/ServersTransport1/rootCAs/1` | `foobar` |
|
||||
| `traefik/http/serversTransports/ServersTransport1/serverName` | `foobar` |
|
||||
| `traefik/http/services/Service01/loadBalancer/healthCheck/followRedirects` | `true` |
|
||||
| `traefik/http/services/Service01/loadBalancer/healthCheck/headers/name0` | `foobar` |
|
||||
| `traefik/http/services/Service01/loadBalancer/healthCheck/headers/name1` | `foobar` |
|
||||
@@ -172,6 +202,7 @@
|
||||
| `traefik/http/services/Service01/loadBalancer/responseForwarding/flushInterval` | `foobar` |
|
||||
| `traefik/http/services/Service01/loadBalancer/servers/0/url` | `foobar` |
|
||||
| `traefik/http/services/Service01/loadBalancer/servers/1/url` | `foobar` |
|
||||
| `traefik/http/services/Service01/loadBalancer/serversTransport` | `foobar` |
|
||||
| `traefik/http/services/Service01/loadBalancer/sticky/cookie/httpOnly` | `true` |
|
||||
| `traefik/http/services/Service01/loadBalancer/sticky/cookie/name` | `foobar` |
|
||||
| `traefik/http/services/Service01/loadBalancer/sticky/cookie/sameSite` | `foobar` |
|
||||
@@ -216,6 +247,7 @@
|
||||
| `traefik/tcp/routers/TCPRouter1/tls/domains/1/sans/1` | `foobar` |
|
||||
| `traefik/tcp/routers/TCPRouter1/tls/options` | `foobar` |
|
||||
| `traefik/tcp/routers/TCPRouter1/tls/passthrough` | `true` |
|
||||
| `traefik/tcp/services/TCPService01/loadBalancer/proxyProtocol/version` | `42` |
|
||||
| `traefik/tcp/services/TCPService01/loadBalancer/servers/0/address` | `foobar` |
|
||||
| `traefik/tcp/services/TCPService01/loadBalancer/servers/1/address` | `foobar` |
|
||||
| `traefik/tcp/services/TCPService01/loadBalancer/terminationDelay` | `42` |
|
||||
|
@@ -24,6 +24,8 @@
|
||||
"traefik.http.middlewares.middleware08.errors.status": "foobar, foobar",
|
||||
"traefik.http.middlewares.middleware09.forwardauth.address": "foobar",
|
||||
"traefik.http.middlewares.middleware09.forwardauth.authresponseheaders": "foobar, foobar",
|
||||
"traefik.http.middlewares.middleware09.forwardauth.authresponseheadersregex": "foobar",
|
||||
"traefik.http.middlewares.middleware09.forwardauth.authrequestheaders": "foobar, foobar",
|
||||
"traefik.http.middlewares.middleware09.forwardauth.tls.ca": "foobar",
|
||||
"traefik.http.middlewares.middleware09.forwardauth.tls.caoptional": "true",
|
||||
"traefik.http.middlewares.middleware09.forwardauth.tls.cert": "foobar",
|
||||
@@ -35,6 +37,7 @@
|
||||
"traefik.http.middlewares.middleware10.headers.accesscontrolallowmethods": "foobar, foobar",
|
||||
"traefik.http.middlewares.middleware10.headers.accesscontrolalloworigin": "foobar",
|
||||
"traefik.http.middlewares.middleware10.headers.accesscontrolalloworiginlist": "foobar, foobar",
|
||||
"traefik.http.middlewares.middleware10.headers.accesscontrolalloworiginlistregex": "foobar, foobar",
|
||||
"traefik.http.middlewares.middleware10.headers.accesscontrolexposeheaders": "foobar, foobar",
|
||||
"traefik.http.middlewares.middleware10.headers.accesscontrolmaxage": "42",
|
||||
"traefik.http.middlewares.middleware10.headers.addvaryheader": "true",
|
||||
@@ -109,6 +112,7 @@
|
||||
"traefik.http.middlewares.middleware19.replacepathregex.regex": "foobar",
|
||||
"traefik.http.middlewares.middleware19.replacepathregex.replacement": "foobar",
|
||||
"traefik.http.middlewares.middleware20.retry.attempts": "42",
|
||||
"traefik.http.middlewares.middleware20.retry.initialinterval": "42",
|
||||
"traefik.http.middlewares.middleware21.stripprefix.forceslash": "true",
|
||||
"traefik.http.middlewares.middleware21.stripprefix.prefixes": "foobar, foobar",
|
||||
"traefik.http.middlewares.middleware22.stripprefixregex.regex": "foobar, foobar",
|
||||
@@ -117,6 +121,7 @@
|
||||
"traefik.http.routers.router0.priority": "42",
|
||||
"traefik.http.routers.router0.rule": "foobar",
|
||||
"traefik.http.routers.router0.service": "foobar",
|
||||
"traefik.http.routers.router0.tls": "true",
|
||||
"traefik.http.routers.router0.tls.certresolver": "foobar",
|
||||
"traefik.http.routers.router0.tls.domains[0].main": "foobar",
|
||||
"traefik.http.routers.router0.tls.domains[0].sans": "foobar, foobar",
|
||||
@@ -128,6 +133,7 @@
|
||||
"traefik.http.routers.router1.priority": "42",
|
||||
"traefik.http.routers.router1.rule": "foobar",
|
||||
"traefik.http.routers.router1.service": "foobar",
|
||||
"traefik.http.routers.router1.tls": "true",
|
||||
"traefik.http.routers.router1.tls.certresolver": "foobar",
|
||||
"traefik.http.routers.router1.tls.domains[0].main": "foobar",
|
||||
"traefik.http.routers.router1.tls.domains[0].sans": "foobar, foobar",
|
||||
@@ -153,9 +159,11 @@
|
||||
"traefik.http.services.service01.loadbalancer.sticky.cookie.secure": "true",
|
||||
"traefik.http.services.service01.loadbalancer.server.port": "foobar",
|
||||
"traefik.http.services.service01.loadbalancer.server.scheme": "foobar",
|
||||
"traefik.http.services.service01.loadbalancer.serverstransport": "foobar",
|
||||
"traefik.tcp.routers.tcprouter0.entrypoints": "foobar, foobar",
|
||||
"traefik.tcp.routers.tcprouter0.rule": "foobar",
|
||||
"traefik.tcp.routers.tcprouter0.service": "foobar",
|
||||
"traefik.tcp.routers.tcprouter0.tls": "true",
|
||||
"traefik.tcp.routers.tcprouter0.tls.certresolver": "foobar",
|
||||
"traefik.tcp.routers.tcprouter0.tls.domains[0].main": "foobar",
|
||||
"traefik.tcp.routers.tcprouter0.tls.domains[0].sans": "foobar, foobar",
|
||||
@@ -166,6 +174,7 @@
|
||||
"traefik.tcp.routers.tcprouter1.entrypoints": "foobar, foobar",
|
||||
"traefik.tcp.routers.tcprouter1.rule": "foobar",
|
||||
"traefik.tcp.routers.tcprouter1.service": "foobar",
|
||||
"traefik.tcp.routers.tcprouter1.tls": "true",
|
||||
"traefik.tcp.routers.tcprouter1.tls.certresolver": "foobar",
|
||||
"traefik.tcp.routers.tcprouter1.tls.domains[0].main": "foobar",
|
||||
"traefik.tcp.routers.tcprouter1.tls.domains[0].sans": "foobar, foobar",
|
||||
@@ -174,6 +183,7 @@
|
||||
"traefik.tcp.routers.tcprouter1.tls.options": "foobar",
|
||||
"traefik.tcp.routers.tcprouter1.tls.passthrough": "true",
|
||||
"traefik.tcp.services.tcpservice01.loadbalancer.terminationdelay": "42",
|
||||
"traefik.tcp.services.tcpservice01.loadbalancer.proxyprotocol.version": "42",
|
||||
"traefik.tcp.services.tcpservice01.loadbalancer.server.port": "foobar",
|
||||
"traefik.udp.routers.udprouter0.entrypoints": "foobar, foobar",
|
||||
"traefik.udp.routers.udprouter0.service": "foobar",
|
||||
|
@@ -0,0 +1,146 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.4.0
|
||||
creationTimestamp: null
|
||||
name: gatewayclasses.networking.x-k8s.io
|
||||
spec:
|
||||
group: networking.x-k8s.io
|
||||
names:
|
||||
kind: GatewayClass
|
||||
listKind: GatewayClassList
|
||||
plural: gatewayclasses
|
||||
shortNames:
|
||||
- gc
|
||||
singular: gatewayclass
|
||||
scope: Cluster
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.controller
|
||||
name: Controller
|
||||
type: string
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: "GatewayClass describes a class of Gateways available to the user for creating Gateway resources. \n GatewayClass is a Cluster level resource. \n Support: Core."
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: Spec for this GatewayClass.
|
||||
properties:
|
||||
controller:
|
||||
description: "Controller is a domain/path string that indicates the controller that is managing Gateways of this class. \n Example: \"acme.io/gateway-controller\". \n This field is not mutable and cannot be empty. \n The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). \n Support: Core"
|
||||
maxLength: 253
|
||||
type: string
|
||||
parametersRef:
|
||||
description: "ParametersRef is a controller-specific resource containing the configuration parameters corresponding to this class. This is optional if the controller does not require any additional configuration. \n Parameters resources are implementation specific custom resources. These resources must be cluster-scoped. \n If the referent cannot be found, the GatewayClass's \"InvalidParameters\" status condition will be true. \n Support: Custom"
|
||||
properties:
|
||||
group:
|
||||
description: Group is the group of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
kind:
|
||||
description: Kind is kind of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
name:
|
||||
description: Name is the name of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- group
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- controller
|
||||
type: object
|
||||
status:
|
||||
default:
|
||||
conditions:
|
||||
- lastTransitionTime: "1970-01-01T00:00:00Z"
|
||||
message: Waiting for controller
|
||||
reason: Waiting
|
||||
status: Unknown
|
||||
type: InvalidParameters
|
||||
description: Status of the GatewayClass.
|
||||
properties:
|
||||
conditions:
|
||||
default:
|
||||
- lastTransitionTime: "1970-01-01T00:00:00Z"
|
||||
message: Waiting for controller
|
||||
reason: Waiting
|
||||
status: "False"
|
||||
type: Admitted
|
||||
description: Conditions is the current status from the controller for this GatewayClass.
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating details about the transition. This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
maxItems: 8
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
@@ -0,0 +1,414 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.4.0
|
||||
creationTimestamp: null
|
||||
name: gateways.networking.x-k8s.io
|
||||
spec:
|
||||
group: networking.x-k8s.io
|
||||
names:
|
||||
kind: Gateway
|
||||
listKind: GatewayList
|
||||
plural: gateways
|
||||
shortNames:
|
||||
- gtw
|
||||
singular: gateway
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.gatewayClassName
|
||||
name: Class
|
||||
type: string
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: "Gateway represents an instantiation of a service-traffic handling infrastructure by binding Listeners to a set of IP addresses. \n Implementations should add the `gateway-exists-finalizer.networking.x-k8s.io` finalizer on the associated GatewayClass whenever Gateway(s) is running. This ensures that a GatewayClass associated with a Gateway(s) is not deleted while in use."
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: "GatewaySpec defines the desired state of Gateway. \n Not all possible combinations of options specified in the Spec are valid. Some invalid configurations can be caught synchronously via a webhook, but there are many cases that will require asynchronous signaling via the GatewayStatus block."
|
||||
properties:
|
||||
addresses:
|
||||
description: "Addresses requested for this gateway. This is optional and behavior can depend on the GatewayClass. If a value is set in the spec and the requested address is invalid, the GatewayClass MUST indicate this in the associated entry in GatewayStatus.Addresses. \n If no Addresses are specified, the GatewayClass may schedule the Gateway in an implementation-defined manner, assigning an appropriate set of Addresses. \n The GatewayClass MUST bind all Listeners to every GatewayAddress that it assigns to the Gateway. \n Support: Core"
|
||||
items:
|
||||
description: GatewayAddress describes an address that can be bound to a Gateway.
|
||||
properties:
|
||||
type:
|
||||
default: IPAddress
|
||||
description: "Type of the Address. This is either \"IPAddress\" or \"NamedAddress\". \n Support: Extended"
|
||||
enum:
|
||||
- IPAddress
|
||||
- NamedAddress
|
||||
type: string
|
||||
value:
|
||||
description: 'Value. Examples: "1.2.3.4", "128::1", "my-ip-address". Validity of the values will depend on `Type` and support by the controller.'
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- value
|
||||
type: object
|
||||
maxItems: 16
|
||||
type: array
|
||||
gatewayClassName:
|
||||
description: GatewayClassName used for this Gateway. This is the name of a GatewayClass resource.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
listeners:
|
||||
description: "Listeners associated with this Gateway. Listeners define logical endpoints that are bound on this Gateway's addresses. At least one Listener MUST be specified. \n An implementation MAY group Listeners by Port and then collapse each group of Listeners into a single Listener if the implementation determines that the Listeners in the group are \"compatible\". An implementation MAY also group together and collapse compatible Listeners belonging to different Gateways. \n For example, an implementation might consider Listeners to be compatible with each other if all of the following conditions are met: \n 1. Either each Listener within the group specifies the \"HTTP\" Protocol or each Listener within the group specifies either the \"HTTPS\" or \"TLS\" Protocol. \n 2. Each Listener within the group specifies a Hostname that is unique within the group. \n 3. As a special case, one Listener within a group may omit Hostname, in which case this Listener matches when no other Listener matches. \n If the implementation does collapse compatible Listeners, the hostname provided in the incoming client request MUST be matched to a Listener to find the correct set of Routes. The incoming hostname MUST be matched using the Hostname field for each Listener in order of most to least specific. That is, exact matches must be processed before wildcard matches. \n If this field specifies multiple Listeners that have the same Port value but are not compatible, the implementation must raise a \"Conflicted\" condition in the Listener status. \n Support: Core"
|
||||
items:
|
||||
description: Listener embodies the concept of a logical endpoint where a Gateway can accept network connections. Each listener in a Gateway must have a unique combination of Hostname, Port, and Protocol. This will be enforced by a validating webhook.
|
||||
properties:
|
||||
hostname:
|
||||
description: "Hostname specifies the virtual hostname to match for protocol types that define this concept. When unspecified or \"*\", all hostnames are matched. This field can be omitted for protocols that don't require hostname based matching. \n Hostname is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in the RFC: \n 1. IP literals are not allowed. 2. The `:` delimiter is not respected because ports are not allowed. \n Hostname can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain name prefixed with a single wildcard label (e.g. \"*.example.com\"). The wildcard character '*' must appear by itself as the first DNS label and matches only a single label. \n Support: Core"
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
port:
|
||||
description: "Port is the network port. Multiple listeners may use the same port, subject to the Listener compatibility rules. \n Support: Core"
|
||||
format: int32
|
||||
maximum: 65535
|
||||
minimum: 1
|
||||
type: integer
|
||||
protocol:
|
||||
description: "Protocol specifies the network protocol this listener expects to receive. The GatewayClass MUST apply the Hostname match appropriately for each protocol: \n * For the \"TLS\" protocol, the Hostname match MUST be applied to the [SNI](https://tools.ietf.org/html/rfc6066#section-3) server name offered by the client. * For the \"HTTP\" protocol, the Hostname match MUST be applied to the host portion of the [effective request URI](https://tools.ietf.org/html/rfc7230#section-5.5) or the [:authority pseudo-header](https://tools.ietf.org/html/rfc7540#section-8.1.2.3) * For the \"HTTPS\" protocol, the Hostname match MUST be applied at both the TLS and HTTP protocol layers. \n Support: Core"
|
||||
type: string
|
||||
routes:
|
||||
description: "Routes specifies a schema for associating routes with the Listener using selectors. A Route is a resource capable of servicing a request and allows a cluster operator to expose a cluster resource (i.e. Service) by externally-reachable URL, load-balance traffic and terminate SSL/TLS. Typically, a route is a \"HTTPRoute\" or \"TCPRoute\" in group \"networking.x-k8s.io\", however, an implementation may support other types of resources. \n The Routes selector MUST select a set of objects that are compatible with the application protocol specified in the Protocol field. \n Although a client request may technically match multiple route rules, only one rule may ultimately receive the request. Matching precedence MUST be determined in order of the following criteria: \n * The most specific match. For example, the most specific HTTPRoute match is determined by the longest matching combination of hostname and path. * The oldest Route based on creation timestamp. For example, a Route with a creation timestamp of \"2020-09-08 01:02:03\" is given precedence over a Route with a creation timestamp of \"2020-09-08 01:02:04\". * If everything else is equivalent, the Route appearing first in alphabetical order (namespace/name) should be given precedence. For example, foo/bar is given precedence over foo/baz. \n All valid portions of a Route selected by this field should be supported. Invalid portions of a Route can be ignored (sometimes that will mean the full Route). If a portion of a Route transitions from valid to invalid, support for that portion of the Route should be dropped to ensure consistency. For example, even if a filter specified by a Route is invalid, the rest of the Route should still be supported. \n Support: Core"
|
||||
properties:
|
||||
group:
|
||||
default: networking.x-k8s.io
|
||||
description: "Group is the group of the route resource to select. Omitting the value or specifying the empty string indicates the networking.x-k8s.io API group. For example, use the following to select an HTTPRoute: \n routes: kind: HTTPRoute \n Otherwise, if an alternative API group is desired, specify the desired group: \n routes: group: acme.io kind: FooRoute \n Support: Core"
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
kind:
|
||||
description: "Kind is the kind of the route resource to select. \n Kind MUST correspond to kinds of routes that are compatible with the application protocol specified in the Listener's Protocol field. \n If an implementation does not support or recognize this resource type, it SHOULD raise a \"ConditionInvalidRoutes\" condition for the affected Listener. \n Support: Core"
|
||||
type: string
|
||||
namespaces:
|
||||
default:
|
||||
from: Same
|
||||
description: "Namespaces indicates in which namespaces Routes should be selected for this Gateway. This is restricted to the namespace of this Gateway by default. \n Support: Core"
|
||||
properties:
|
||||
from:
|
||||
description: "From indicates where Routes will be selected for this Gateway. Possible values are: * All: Routes in all namespaces may be used by this Gateway. * Selector: Routes in namespaces selected by the selector may be used by this Gateway. * Same: Only Routes in the same namespace may be used by this Gateway. \n Support: Core"
|
||||
enum:
|
||||
- All
|
||||
- Selector
|
||||
- Same
|
||||
type: string
|
||||
selector:
|
||||
description: "Selector must be specified when From is set to \"Selector\". In that case, only Routes in Namespaces matching this Selector will be selected by this Gateway. This field is ignored for other values of \"From\". \n Support: Core"
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
selector:
|
||||
description: "Selector specifies a set of route labels used for selecting routes to associate with the Gateway. If RouteSelector is defined, only routes matching the RouteSelector are associated with the Gateway. An empty RouteSelector matches all routes. \n Support: Core"
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
required:
|
||||
- kind
|
||||
type: object
|
||||
tls:
|
||||
description: "TLS is the TLS configuration for the Listener. This field is required if the Protocol field is \"HTTPS\" or \"TLS\" and ignored otherwise. \n The association of SNIs to Certificate defined in GatewayTLSConfig is defined based on the Hostname field for this listener. \n The GatewayClass MUST use the longest matching SNI out of all available certificates for any TLS handshake. \n Support: Core"
|
||||
properties:
|
||||
certificateRef:
|
||||
description: 'CertificateRef is the reference to Kubernetes object that contain a TLS certificate and private key. This certificate MUST be used for TLS handshakes for the domain this GatewayTLSConfig is associated with. If an entry in this list omits or specifies the empty string for both the group and the resource, the resource defaults to "secrets". An implementation may support other resources (for example, resource "mycertificates" in group "networking.acme.io"). Support: Core (Kubernetes Secrets) Support: Implementation-specific (Other resource types)'
|
||||
properties:
|
||||
group:
|
||||
description: Group is the group of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
kind:
|
||||
description: Kind is kind of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
name:
|
||||
description: Name is the name of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- group
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
mode:
|
||||
description: 'Mode defines the TLS behavior for the TLS session initiated by the client. There are two possible modes: - Terminate: The TLS session between the downstream client and the Gateway is terminated at the Gateway. - Passthrough: The TLS session is NOT terminated by the Gateway. This implies that the Gateway can''t decipher the TLS stream except for the ClientHello message of the TLS protocol. CertificateRef field is ignored in this mode.'
|
||||
enum:
|
||||
- Terminate
|
||||
- Passthrough
|
||||
type: string
|
||||
options:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: "Options are a list of key/value pairs to give extended options to the provider. \n There variation among providers as to how ciphersuites are expressed. If there is a common subset for expressing ciphers then it will make sense to loft that as a core API construct. \n Support: Implementation-specific."
|
||||
type: object
|
||||
routeOverride:
|
||||
default:
|
||||
certificate: Deny
|
||||
description: "RouteOverride dictates if TLS settings can be configured via Routes or not. \n CertificateRef must be defined even if `routeOverride.certificate` is set to 'Allow' as it will be used as the default certificate for the listener."
|
||||
properties:
|
||||
certificate:
|
||||
default: Deny
|
||||
description: "Certificate dictates if TLS certificates can be configured via Routes. If set to 'Allow', a TLS certificate for a hostname defined in a Route takes precedence over the certificate defined in Gateway. \n Support: Core"
|
||||
enum:
|
||||
- Allow
|
||||
- Deny
|
||||
type: string
|
||||
required:
|
||||
- certificate
|
||||
type: object
|
||||
type: object
|
||||
required:
|
||||
- port
|
||||
- protocol
|
||||
- routes
|
||||
type: object
|
||||
maxItems: 64
|
||||
minItems: 1
|
||||
type: array
|
||||
required:
|
||||
- gatewayClassName
|
||||
- listeners
|
||||
type: object
|
||||
status:
|
||||
default:
|
||||
conditions:
|
||||
- lastTransitionTime: "1970-01-01T00:00:00Z"
|
||||
message: Waiting for controller
|
||||
reason: NotReconciled
|
||||
status: "False"
|
||||
type: Scheduled
|
||||
description: GatewayStatus defines the observed state of Gateway.
|
||||
properties:
|
||||
addresses:
|
||||
description: "Addresses lists the IP addresses that have actually been bound to the Gateway. These addresses may differ from the addresses in the Spec, e.g. if the Gateway automatically assigns an address from a reserved pool. \n These addresses should all be of type \"IPAddress\"."
|
||||
items:
|
||||
description: GatewayAddress describes an address that can be bound to a Gateway.
|
||||
properties:
|
||||
type:
|
||||
default: IPAddress
|
||||
description: "Type of the Address. This is either \"IPAddress\" or \"NamedAddress\". \n Support: Extended"
|
||||
enum:
|
||||
- IPAddress
|
||||
- NamedAddress
|
||||
type: string
|
||||
value:
|
||||
description: 'Value. Examples: "1.2.3.4", "128::1", "my-ip-address". Validity of the values will depend on `Type` and support by the controller.'
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- value
|
||||
type: object
|
||||
maxItems: 16
|
||||
type: array
|
||||
conditions:
|
||||
default:
|
||||
- lastTransitionTime: "1970-01-01T00:00:00Z"
|
||||
message: Waiting for controller
|
||||
reason: NotReconciled
|
||||
status: "False"
|
||||
type: Scheduled
|
||||
description: "Conditions describe the current conditions of the Gateway. \n Implementations should prefer to express Gateway conditions using the `GatewayConditionType` and `GatewayConditionReason` constants so that operators and tools can converge on a common vocabulary to describe Gateway state. \n Known condition types are: \n * \"Scheduled\" * \"Ready\""
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating details about the transition. This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
maxItems: 8
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
listeners:
|
||||
description: Listeners provide status for each unique listener port defined in the Spec.
|
||||
items:
|
||||
description: ListenerStatus is the status associated with a Listener.
|
||||
properties:
|
||||
conditions:
|
||||
description: Conditions describe the current condition of this listener.
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating details about the transition. This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
maxItems: 8
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
hostname:
|
||||
description: Hostname is the Listener hostname value for which this message is reporting the status.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
port:
|
||||
description: Port is the unique Listener port value for which this message is reporting the status.
|
||||
format: int32
|
||||
maximum: 65535
|
||||
minimum: 1
|
||||
type: integer
|
||||
protocol:
|
||||
description: Protocol is the Listener protocol value for which this message is reporting the status.
|
||||
type: string
|
||||
required:
|
||||
- conditions
|
||||
- port
|
||||
- protocol
|
||||
type: object
|
||||
maxItems: 64
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- port
|
||||
x-kubernetes-list-type: map
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
@@ -0,0 +1,528 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.4.0
|
||||
creationTimestamp: null
|
||||
name: httproutes.networking.x-k8s.io
|
||||
spec:
|
||||
group: networking.x-k8s.io
|
||||
names:
|
||||
kind: HTTPRoute
|
||||
listKind: HTTPRouteList
|
||||
plural: httproutes
|
||||
singular: httproute
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.hostnames
|
||||
name: Hostnames
|
||||
type: string
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: HTTPRoute is the Schema for the HTTPRoute resource.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: HTTPRouteSpec defines the desired state of HTTPRoute
|
||||
properties:
|
||||
gateways:
|
||||
default:
|
||||
allow: SameNamespace
|
||||
description: Gateways defines which Gateways can use this Route.
|
||||
properties:
|
||||
allow:
|
||||
default: SameNamespace
|
||||
description: 'Allow indicates which Gateways will be allowed to use this route. Possible values are: * All: Gateways in any namespace can use this route. * FromList: Only Gateways specified in GatewayRefs may use this route. * SameNamespace: Only Gateways in the same namespace may use this route.'
|
||||
enum:
|
||||
- All
|
||||
- FromList
|
||||
- SameNamespace
|
||||
type: string
|
||||
gatewayRefs:
|
||||
description: GatewayRefs must be specified when Allow is set to "FromList". In that case, only Gateways referenced in this list will be allowed to use this route. This field is ignored for other values of "Allow".
|
||||
items:
|
||||
description: GatewayReference identifies a Gateway in a specified namespace.
|
||||
properties:
|
||||
name:
|
||||
description: Name is the name of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace is the namespace of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- namespace
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
hostnames:
|
||||
description: "Hostnames defines a set of hostname that should match against the HTTP Host header to select a HTTPRoute to process the request. Hostname is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in the RFC: \n 1. IPs are not allowed. 2. The `:` delimiter is not respected because ports are not allowed. \n Incoming requests are matched against the hostnames before the HTTPRoute rules. If no hostname is specified, traffic is routed based on the HTTPRouteRules. \n Hostname can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain name prefixed with a single wildcard label (e.g. \"*.example.com\"). The wildcard character '*' must appear by itself as the first DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the Host field in the following order: 1. If Host is precise, the request matches this rule if the http host header is equal to Host. 2. If Host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule. \n Support: Core"
|
||||
items:
|
||||
description: Hostname is used to specify a hostname that should be matched.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
maxItems: 16
|
||||
type: array
|
||||
rules:
|
||||
description: Rules are a list of HTTP matchers, filters and actions.
|
||||
items:
|
||||
description: HTTPRouteRule defines semantics for matching an HTTP request based on conditions, optionally executing additional processing steps, and forwarding the request to an API object.
|
||||
properties:
|
||||
filters:
|
||||
description: "Filters define the filters that are applied to requests that match this rule. \n The effects of ordering of multiple behaviors are currently unspecified. This can change in the future based on feedback during the alpha stage. \n Conformance-levels at this level are defined based on the type of filter: - ALL core filters MUST be supported by all implementations. - Implementers are encouraged to support extended filters. - Implementation-specific custom filters have no API guarantees across implementations. \n Specifying a core filter multiple times has unspecified or custom conformance. \n Support: core"
|
||||
items:
|
||||
description: 'HTTPRouteFilter defines additional processing steps that must be completed during the request or response lifecycle. HTTPRouteFilters are meant as an extension point to express additional processing that may be done in Gateway implementations. Some examples include request or response modification, implementing authentication strategies, rate-limiting, and traffic shaping. API guarantee/conformance is defined based on the type of the filter. TODO(hbagdi): re-render CRDs once controller-tools supports union tags: - https://github.com/kubernetes-sigs/controller-tools/pull/298 - https://github.com/kubernetes-sigs/controller-tools/issues/461'
|
||||
properties:
|
||||
extensionRef:
|
||||
description: "ExtensionRef is an optional, implementation-specific extension to the \"filter\" behavior. For example, resource \"myroutefilter\" in group \"networking.acme.io\"). ExtensionRef MUST NOT be used for core and extended filters. \n Support: Implementation-specific"
|
||||
properties:
|
||||
group:
|
||||
description: Group is the group of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
kind:
|
||||
description: Kind is kind of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
name:
|
||||
description: Name is the name of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- group
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
requestHeaderModifier:
|
||||
description: "RequestHeaderModifier defines a schema for a filter that modifies request headers. \n Support: Core"
|
||||
properties:
|
||||
add:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: "Add adds the given header (name, value) to the request before the action. \n Input: GET /foo HTTP/1.1 \n Config: add: {\"my-header\": \"foo\"} \n Output: GET /foo HTTP/1.1 my-header: foo \n Support: Extended"
|
||||
type: object
|
||||
remove:
|
||||
description: "Remove the given header(s) from the HTTP request before the action. The value of RemoveHeader is a list of HTTP header names. Note that the header names are case-insensitive [RFC-2616 4.2]. \n Input: GET /foo HTTP/1.1 My-Header1: ABC My-Header2: DEF My-Header2: GHI \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 My-Header2: DEF \n Support: Extended"
|
||||
items:
|
||||
type: string
|
||||
maxItems: 16
|
||||
type: array
|
||||
type: object
|
||||
requestMirror:
|
||||
description: "RequestMirror defines a schema for a filter that mirrors requests. \n Support: Extended"
|
||||
properties:
|
||||
backendRef:
|
||||
description: "BackendRef is a local object reference to mirror matched requests to. If both BackendRef and ServiceName are specified, ServiceName will be given precedence. \n If the referent cannot be found, the rule is not included in the route. The controller should raise the \"ResolvedRefs\" condition on the Gateway with the \"DegradedRoutes\" reason. The gateway status for this route should be updated with a condition that describes the error more specifically. \n Support: Custom"
|
||||
properties:
|
||||
group:
|
||||
description: Group is the group of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
kind:
|
||||
description: Kind is kind of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
name:
|
||||
description: Name is the name of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- group
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
port:
|
||||
description: Port specifies the destination port number to use for the backend referenced by the ServiceName or BackendRef field.
|
||||
format: int32
|
||||
maximum: 65535
|
||||
minimum: 1
|
||||
type: integer
|
||||
serviceName:
|
||||
description: "ServiceName refers to the name of the Service to mirror matched requests to. When specified, this takes the place of BackendRef. If both BackendRef and ServiceName are specified, ServiceName will be given precedence. \n If the referent cannot be found, the rule is not included in the route. The controller should raise the \"ResolvedRefs\" condition on the Gateway with the \"DegradedRoutes\" reason. The gateway status for this route should be updated with a condition that describes the error more specifically. \n Support: Core"
|
||||
maxLength: 253
|
||||
type: string
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
type:
|
||||
description: "Type identifies the type of filter to apply. As with other API fields, types are classified into three conformance levels: \n - Core: Filter types and their corresponding configuration defined by \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All implementations must support core filters. \n - Extended: Filter types and their corresponding configuration defined by \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers are encouraged to support extended filters. \n - Custom: Filters that are defined and supported by specific vendors. In the future, filters showing convergence in behavior across multiple implementations will be considered for inclusion in extended or core conformance levels. Filter-specific configuration for such filters is specified using the ExtensionRef field. `Type` should be set to \"ExtensionRef\" for custom filters. \n Implementers are encouraged to define custom implementation types to extend the core API with implementation-specific behavior."
|
||||
enum:
|
||||
- RequestHeaderModifier
|
||||
- RequestMirror
|
||||
- ExtensionRef
|
||||
type: string
|
||||
required:
|
||||
- type
|
||||
type: object
|
||||
maxItems: 16
|
||||
type: array
|
||||
forwardTo:
|
||||
description: ForwardTo defines the backend(s) where matching requests should be sent. If unspecified, the rule performs no forwarding. If unspecified and no filters are specified that would result in a response being sent, a 503 error code is returned.
|
||||
items:
|
||||
description: HTTPRouteForwardTo defines how a HTTPRoute should forward a request.
|
||||
properties:
|
||||
backendRef:
|
||||
description: "BackendRef is a reference to a backend to forward matched requests to. If both BackendRef and ServiceName are specified, ServiceName will be given precedence. \n If the referent cannot be found, the route must be dropped from the Gateway. The controller should raise the \"ResolvedRefs\" condition on the Gateway with the \"DroppedRoutes\" reason. The gateway status for this route should be updated with a condition that describes the error more specifically. \n Support: Custom"
|
||||
properties:
|
||||
group:
|
||||
description: Group is the group of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
kind:
|
||||
description: Kind is kind of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
name:
|
||||
description: Name is the name of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- group
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
filters:
|
||||
description: "Filters defined at this-level should be executed if and only if the request is being forwarded to the backend defined here. \n Support: Custom (For broader support of filters, use the Filters field in HTTPRouteRule.)"
|
||||
items:
|
||||
description: 'HTTPRouteFilter defines additional processing steps that must be completed during the request or response lifecycle. HTTPRouteFilters are meant as an extension point to express additional processing that may be done in Gateway implementations. Some examples include request or response modification, implementing authentication strategies, rate-limiting, and traffic shaping. API guarantee/conformance is defined based on the type of the filter. TODO(hbagdi): re-render CRDs once controller-tools supports union tags: - https://github.com/kubernetes-sigs/controller-tools/pull/298 - https://github.com/kubernetes-sigs/controller-tools/issues/461'
|
||||
properties:
|
||||
extensionRef:
|
||||
description: "ExtensionRef is an optional, implementation-specific extension to the \"filter\" behavior. For example, resource \"myroutefilter\" in group \"networking.acme.io\"). ExtensionRef MUST NOT be used for core and extended filters. \n Support: Implementation-specific"
|
||||
properties:
|
||||
group:
|
||||
description: Group is the group of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
kind:
|
||||
description: Kind is kind of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
name:
|
||||
description: Name is the name of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- group
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
requestHeaderModifier:
|
||||
description: "RequestHeaderModifier defines a schema for a filter that modifies request headers. \n Support: Core"
|
||||
properties:
|
||||
add:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: "Add adds the given header (name, value) to the request before the action. \n Input: GET /foo HTTP/1.1 \n Config: add: {\"my-header\": \"foo\"} \n Output: GET /foo HTTP/1.1 my-header: foo \n Support: Extended"
|
||||
type: object
|
||||
remove:
|
||||
description: "Remove the given header(s) from the HTTP request before the action. The value of RemoveHeader is a list of HTTP header names. Note that the header names are case-insensitive [RFC-2616 4.2]. \n Input: GET /foo HTTP/1.1 My-Header1: ABC My-Header2: DEF My-Header2: GHI \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 My-Header2: DEF \n Support: Extended"
|
||||
items:
|
||||
type: string
|
||||
maxItems: 16
|
||||
type: array
|
||||
type: object
|
||||
requestMirror:
|
||||
description: "RequestMirror defines a schema for a filter that mirrors requests. \n Support: Extended"
|
||||
properties:
|
||||
backendRef:
|
||||
description: "BackendRef is a local object reference to mirror matched requests to. If both BackendRef and ServiceName are specified, ServiceName will be given precedence. \n If the referent cannot be found, the rule is not included in the route. The controller should raise the \"ResolvedRefs\" condition on the Gateway with the \"DegradedRoutes\" reason. The gateway status for this route should be updated with a condition that describes the error more specifically. \n Support: Custom"
|
||||
properties:
|
||||
group:
|
||||
description: Group is the group of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
kind:
|
||||
description: Kind is kind of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
name:
|
||||
description: Name is the name of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- group
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
port:
|
||||
description: Port specifies the destination port number to use for the backend referenced by the ServiceName or BackendRef field.
|
||||
format: int32
|
||||
maximum: 65535
|
||||
minimum: 1
|
||||
type: integer
|
||||
serviceName:
|
||||
description: "ServiceName refers to the name of the Service to mirror matched requests to. When specified, this takes the place of BackendRef. If both BackendRef and ServiceName are specified, ServiceName will be given precedence. \n If the referent cannot be found, the rule is not included in the route. The controller should raise the \"ResolvedRefs\" condition on the Gateway with the \"DegradedRoutes\" reason. The gateway status for this route should be updated with a condition that describes the error more specifically. \n Support: Core"
|
||||
maxLength: 253
|
||||
type: string
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
type:
|
||||
description: "Type identifies the type of filter to apply. As with other API fields, types are classified into three conformance levels: \n - Core: Filter types and their corresponding configuration defined by \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All implementations must support core filters. \n - Extended: Filter types and their corresponding configuration defined by \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers are encouraged to support extended filters. \n - Custom: Filters that are defined and supported by specific vendors. In the future, filters showing convergence in behavior across multiple implementations will be considered for inclusion in extended or core conformance levels. Filter-specific configuration for such filters is specified using the ExtensionRef field. `Type` should be set to \"ExtensionRef\" for custom filters. \n Implementers are encouraged to define custom implementation types to extend the core API with implementation-specific behavior."
|
||||
enum:
|
||||
- RequestHeaderModifier
|
||||
- RequestMirror
|
||||
- ExtensionRef
|
||||
type: string
|
||||
required:
|
||||
- type
|
||||
type: object
|
||||
maxItems: 16
|
||||
type: array
|
||||
port:
|
||||
description: "Port specifies the destination port number to use for the backend referenced by the ServiceName or BackendRef field. \n Support: Core"
|
||||
format: int32
|
||||
maximum: 65535
|
||||
minimum: 1
|
||||
type: integer
|
||||
serviceName:
|
||||
description: "ServiceName refers to the name of the Service to forward matched requests to. When specified, this takes the place of BackendRef. If both BackendRef and ServiceName are specified, ServiceName will be given precedence. \n If the referent cannot be found, the route must be dropped from the Gateway. The controller should raise the \"ResolvedRefs\" condition on the Gateway with the \"DroppedRoutes\" reason. The gateway status for this route should be updated with a condition that describes the error more specifically. \n The protocol to use should be specified with the AppProtocol field on Service resources. This field was introduced in Kubernetes 1.18. If using an earlier version of Kubernetes, a `networking.x-k8s.io/app-protocol` annotation on the BackendPolicy resource may be used to define the protocol. If the AppProtocol field is available, this annotation should not be used. The AppProtocol field, when populated, takes precedence over the annotation in the BackendPolicy resource. For custom backends, it is encouraged to add a semantically-equivalent field in the Custom Resource Definition. \n Support: Core"
|
||||
maxLength: 253
|
||||
type: string
|
||||
weight:
|
||||
default: 1
|
||||
description: "Weight specifies the proportion of HTTP requests forwarded to the backend referenced by the ServiceName or BackendRef field. This is computed as weight/(sum of all weights in this ForwardTo list). For non-zero values, there may be some epsilon from the exact proportion defined here depending on the precision an implementation supports. Weight is not a percentage and the sum of weights does not need to equal 100. \n If only one backend is specified and it has a weight greater than 0, 100% of the traffic is forwarded to that backend. If weight is set to 0, no traffic should be forwarded for this entry. If unspecified, weight defaults to 1. \n Support: Core"
|
||||
format: int32
|
||||
maximum: 1000000
|
||||
minimum: 0
|
||||
type: integer
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
maxItems: 4
|
||||
type: array
|
||||
matches:
|
||||
default:
|
||||
- path:
|
||||
type: Prefix
|
||||
value: /
|
||||
description: "Matches define conditions used for matching the rule against incoming HTTP requests. Each match is independent, i.e. this rule will be matched if **any** one of the matches is satisfied. \n For example, take the following matches configuration: \n ``` matches: - path: value: \"/foo\" headers: values: version: \"2\" - path: value: \"/v2/foo\" ``` \n For a request to match against this rule, a request should satisfy EITHER of the two conditions: \n - path prefixed with `/foo` AND contains the header `version: \"2\"` - path prefix of `/v2/foo` \n See the documentation for HTTPRouteMatch on how to specify multiple match conditions that should be ANDed together. \n If no matches are specified, the default is a prefix path match on \"/\", which has the effect of matching every HTTP request. \n A client request may match multiple HTTP route rules. Matching precedence MUST be determined in order of the following criteria, continuing on ties: * The longest matching hostname. * The longest matching path. * The largest number of header matches * The oldest Route based on creation timestamp. For example, a Route with a creation timestamp of \"2020-09-08 01:02:03\" is given precedence over a Route with a creation timestamp of \"2020-09-08 01:02:04\". * The Route appearing first in alphabetical order (namespace/name) for example, foo/bar is given precedence over foo/baz."
|
||||
items:
|
||||
description: "HTTPRouteMatch defines the predicate used to match requests to a given action. Multiple match types are ANDed together, i.e. the match will evaluate to true only if all conditions are satisfied. \n For example, the match below will match a HTTP request only if its path starts with `/foo` AND it contains the `version: \"1\"` header: \n ``` match: path: value: \"/foo\" headers: values: version: \"1\" ```"
|
||||
properties:
|
||||
extensionRef:
|
||||
description: "ExtensionRef is an optional, implementation-specific extension to the \"match\" behavior. For example, resource \"myroutematcher\" in group \"networking.acme.io\". If the referent cannot be found, the rule is not included in the route. The controller should raise the \"ResolvedRefs\" condition on the Gateway with the \"DegradedRoutes\" reason. The gateway status for this route should be updated with a condition that describes the error more specifically. \n Support: custom"
|
||||
properties:
|
||||
group:
|
||||
description: Group is the group of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
kind:
|
||||
description: Kind is kind of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
name:
|
||||
description: Name is the name of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- group
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
headers:
|
||||
description: Headers specifies a HTTP request header matcher.
|
||||
properties:
|
||||
type:
|
||||
default: Exact
|
||||
description: "Type specifies how to match against the value of the header. \n Support: core (Exact) Support: custom (RegularExpression, ImplementationSpecific) \n Since RegularExpression PathType has custom conformance, implementations can support POSIX, PCRE or any other dialects of regular expressions. Please read the implementation's documentation to determine the supported dialect. \n HTTP Header name matching MUST be case-insensitive (RFC 2616 - section 4.2)."
|
||||
enum:
|
||||
- Exact
|
||||
- RegularExpression
|
||||
- ImplementationSpecific
|
||||
type: string
|
||||
values:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: "Values is a map of HTTP Headers to be matched. It MUST contain at least one entry. \n The HTTP header field name to match is the map key, and the value of the HTTP header is the map value. HTTP header field name matching MUST be case-insensitive. \n Multiple match values are ANDed together, meaning, a request must match all the specified headers to select the route."
|
||||
type: object
|
||||
required:
|
||||
- values
|
||||
type: object
|
||||
path:
|
||||
default:
|
||||
type: Prefix
|
||||
value: /
|
||||
description: Path specifies a HTTP request path matcher. If this field is not specified, a default prefix match on the "/" path is provided.
|
||||
properties:
|
||||
type:
|
||||
default: Prefix
|
||||
description: "Type specifies how to match against the path Value. \n Support: core (Exact, Prefix) Support: custom (RegularExpression, ImplementationSpecific) \n Since RegularExpression PathType has custom conformance, implementations can support POSIX, PCRE or any other dialects of regular expressions. Please read the implementation's documentation to determine the supported dialect."
|
||||
enum:
|
||||
- Exact
|
||||
- Prefix
|
||||
- RegularExpression
|
||||
- ImplementationSpecific
|
||||
type: string
|
||||
value:
|
||||
description: Value of the HTTP path to match against.
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- value
|
||||
type: object
|
||||
type: object
|
||||
maxItems: 8
|
||||
type: array
|
||||
type: object
|
||||
maxItems: 16
|
||||
minItems: 1
|
||||
type: array
|
||||
tls:
|
||||
description: "TLS defines the TLS certificate to use for Hostnames defined in this Route. This configuration only takes effect if the AllowRouteOverride field is set to true in the associated Gateway resource. \n Collisions can happen if multiple HTTPRoutes define a TLS certificate for the same hostname. In such a case, conflict resolution guiding principles apply, specificallly, if hostnames are same and two different certificates are specified then the certificate in the oldest resource wins. \n Please note that HTTP Route-selection takes place after the TLS Handshake (ClientHello). Due to this, TLS certificate defined here will take precedence even if the request has the potential to match multiple routes (in case multiple HTTPRoutes share the same hostname). \n Support: Core"
|
||||
properties:
|
||||
certificateRef:
|
||||
description: 'CertificateRef refers to a Kubernetes object that contains a TLS certificate and private key. This certificate MUST be used for TLS handshakes for the domain this RouteTLSConfig is associated with. If an entry in this list omits or specifies the empty string for both the group and kind, the resource defaults to "secrets". An implementation may support other resources (for example, resource "mycertificates" in group "networking.acme.io"). Support: Core (Kubernetes Secrets) Support: Implementation-specific (Other resource types)'
|
||||
properties:
|
||||
group:
|
||||
description: Group is the group of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
kind:
|
||||
description: Kind is kind of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
name:
|
||||
description: Name is the name of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- group
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- certificateRef
|
||||
type: object
|
||||
required:
|
||||
- rules
|
||||
type: object
|
||||
status:
|
||||
description: HTTPRouteStatus defines the observed state of HTTPRoute.
|
||||
properties:
|
||||
gateways:
|
||||
description: "Gateways is a list of the Gateways that are associated with the route, and the status of the route with respect to each of these Gateways. When a Gateway selects this route, the controller that manages the Gateway should add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route is modified. \n A maximum of 100 Gateways will be represented in this list. If this list is full, there may be additional Gateways using this Route that are not included in the list."
|
||||
items:
|
||||
description: RouteGatewayStatus describes the status of a route with respect to an associated Gateway.
|
||||
properties:
|
||||
conditions:
|
||||
description: Conditions describes the status of the route with respect to the Gateway. For example, the "Admitted" condition indicates whether the route has been admitted or rejected by the Gateway, and why. Note that the route's availability is also subject to the Gateway's own status conditions and listener status.
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating details about the transition. This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
maxItems: 8
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
gatewayRef:
|
||||
description: GatewayRef is a reference to a Gateway object that is associated with the route.
|
||||
properties:
|
||||
name:
|
||||
description: Name is the name of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace is the namespace of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- namespace
|
||||
type: object
|
||||
required:
|
||||
- gatewayRef
|
||||
type: object
|
||||
maxItems: 100
|
||||
type: array
|
||||
required:
|
||||
- gateways
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
@@ -69,6 +69,12 @@ Use a DNS-01 based challenge provider rather than HTTPS.
|
||||
`--certificatesresolvers.<name>.acme.dnschallenge.resolvers`:
|
||||
Use following DNS servers to resolve the FQDN authority.
|
||||
|
||||
`--certificatesresolvers.<name>.acme.eab.hmacencoded`:
|
||||
Base64 encoded HMAC key from External CA.
|
||||
|
||||
`--certificatesresolvers.<name>.acme.eab.kid`:
|
||||
Key identifier from External CA.
|
||||
|
||||
`--certificatesresolvers.<name>.acme.email`:
|
||||
Email address used for registration.
|
||||
|
||||
@@ -112,7 +118,7 @@ Default middlewares for the routers linked to the entry point.
|
||||
Applies a permanent redirection. (Default: ```true```)
|
||||
|
||||
`--entrypoints.<name>.http.redirections.entrypoint.priority`:
|
||||
Priority of the generated router. (Default: ```2147483647```)
|
||||
Priority of the generated router. (Default: ```2147483646```)
|
||||
|
||||
`--entrypoints.<name>.http.redirections.entrypoint.scheme`:
|
||||
Scheme used for the redirection. (Default: ```https```)
|
||||
@@ -168,6 +174,9 @@ plugin's GOPATH.
|
||||
`--experimental.devplugin.modulename`:
|
||||
plugin's module name.
|
||||
|
||||
`--experimental.kubernetesgateway`:
|
||||
Allow the Kubernetes gateway api provider usage. (Default: ```false```)
|
||||
|
||||
`--experimental.plugins.<name>.modulename`:
|
||||
plugin's module name.
|
||||
|
||||
@@ -175,7 +184,7 @@ plugin's module name.
|
||||
plugin's version.
|
||||
|
||||
`--global.checknewversion`:
|
||||
Periodically check if a new version has been released. (Default: ```false```)
|
||||
Periodically check if a new version has been released. (Default: ```true```)
|
||||
|
||||
`--global.sendanonymoususage`:
|
||||
Periodically send anonymous usage statistics. If the option is not specified, it will be enabled by default. (Default: ```false```)
|
||||
@@ -385,7 +394,7 @@ Expose containers by default. (Default: ```true```)
|
||||
Prefix for consul service tags. Default 'traefik' (Default: ```traefik```)
|
||||
|
||||
`--providers.consulcatalog.refreshinterval`:
|
||||
Interval for check Consul API. Default 100ms (Default: ```15```)
|
||||
Interval for check Consul API. Default 15s (Default: ```15```)
|
||||
|
||||
`--providers.consulcatalog.requireconsistent`:
|
||||
Forces the read to be fully consistent. (Default: ```false```)
|
||||
@@ -408,6 +417,9 @@ Docker server endpoint. Can be a tcp or a unix socket endpoint. (Default: ```uni
|
||||
`--providers.docker.exposedbydefault`:
|
||||
Expose containers by default. (Default: ```true```)
|
||||
|
||||
`--providers.docker.httpclienttimeout`:
|
||||
Client timeout for HTTP connections. (Default: ```0```)
|
||||
|
||||
`--providers.docker.network`:
|
||||
Default Docker network used.
|
||||
|
||||
@@ -546,9 +558,6 @@ Allow cross namespace resource reference. (Default: ```true```)
|
||||
`--providers.kubernetescrd.certauthfilepath`:
|
||||
Kubernetes certificate authority file path (not needed for in-cluster client).
|
||||
|
||||
`--providers.kubernetescrd.disablepasshostheaders`:
|
||||
Kubernetes disable PassHost Headers. (Default: ```false```)
|
||||
|
||||
`--providers.kubernetescrd.endpoint`:
|
||||
Kubernetes server endpoint (required for external cluster client).
|
||||
|
||||
@@ -567,15 +576,33 @@ Ingress refresh throttle duration (Default: ```0```)
|
||||
`--providers.kubernetescrd.token`:
|
||||
Kubernetes bearer token (not needed for in-cluster client).
|
||||
|
||||
`--providers.kubernetesgateway`:
|
||||
Enable Kubernetes gateway api provider with default settings. (Default: ```false```)
|
||||
|
||||
`--providers.kubernetesgateway.certauthfilepath`:
|
||||
Kubernetes certificate authority file path (not needed for in-cluster client).
|
||||
|
||||
`--providers.kubernetesgateway.endpoint`:
|
||||
Kubernetes server endpoint (required for external cluster client).
|
||||
|
||||
`--providers.kubernetesgateway.labelselector`:
|
||||
Kubernetes label selector to select specific GatewayClasses.
|
||||
|
||||
`--providers.kubernetesgateway.namespaces`:
|
||||
Kubernetes namespaces.
|
||||
|
||||
`--providers.kubernetesgateway.throttleduration`:
|
||||
Kubernetes refresh throttle duration (Default: ```0```)
|
||||
|
||||
`--providers.kubernetesgateway.token`:
|
||||
Kubernetes bearer token (not needed for in-cluster client).
|
||||
|
||||
`--providers.kubernetesingress`:
|
||||
Enable Kubernetes backend with default settings. (Default: ```false```)
|
||||
|
||||
`--providers.kubernetesingress.certauthfilepath`:
|
||||
Kubernetes certificate authority file path (not needed for in-cluster client).
|
||||
|
||||
`--providers.kubernetesingress.disablepasshostheaders`:
|
||||
Kubernetes disable PassHost Headers. (Default: ```false```)
|
||||
|
||||
`--providers.kubernetesingress.endpoint`:
|
||||
Kubernetes server endpoint (required for external cluster client).
|
||||
|
||||
@@ -667,7 +694,7 @@ Display additional provider logs. (Default: ```false```)
|
||||
Watch provider. (Default: ```true```)
|
||||
|
||||
`--providers.providersthrottleduration`:
|
||||
Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time. (Default: ```0```)
|
||||
Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time. (Default: ```2```)
|
||||
|
||||
`--providers.rancher`:
|
||||
Enable Rancher backend with default settings. (Default: ```false```)
|
||||
@@ -775,7 +802,7 @@ The amount of time to wait for a server's response headers after fully writing t
|
||||
Disable SSL certificate verification. (Default: ```false```)
|
||||
|
||||
`--serverstransport.maxidleconnsperhost`:
|
||||
If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used (Default: ```0```)
|
||||
If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used (Default: ```200```)
|
||||
|
||||
`--serverstransport.rootcas`:
|
||||
Add cert file for self-signed certificate.
|
||||
|
@@ -69,6 +69,12 @@ Use a DNS-01 based challenge provider rather than HTTPS.
|
||||
`TRAEFIK_CERTIFICATESRESOLVERS_<NAME>_ACME_DNSCHALLENGE_RESOLVERS`:
|
||||
Use following DNS servers to resolve the FQDN authority.
|
||||
|
||||
`TRAEFIK_CERTIFICATESRESOLVERS_<NAME>_ACME_EAB_HMACENCODED`:
|
||||
Base64 encoded HMAC key from External CA.
|
||||
|
||||
`TRAEFIK_CERTIFICATESRESOLVERS_<NAME>_ACME_EAB_KID`:
|
||||
Key identifier from External CA.
|
||||
|
||||
`TRAEFIK_CERTIFICATESRESOLVERS_<NAME>_ACME_EMAIL`:
|
||||
Email address used for registration.
|
||||
|
||||
@@ -112,7 +118,7 @@ Default middlewares for the routers linked to the entry point.
|
||||
Applies a permanent redirection. (Default: ```true```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_REDIRECTIONS_ENTRYPOINT_PRIORITY`:
|
||||
Priority of the generated router. (Default: ```2147483647```)
|
||||
Priority of the generated router. (Default: ```2147483646```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_REDIRECTIONS_ENTRYPOINT_SCHEME`:
|
||||
Scheme used for the redirection. (Default: ```https```)
|
||||
@@ -129,10 +135,10 @@ Default certificate resolver for the routers linked to the entry point.
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_TLS_DOMAINS`:
|
||||
Default TLS domains for the routers linked to the entry point.
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_TLS_DOMAINS[n]_MAIN`:
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_TLS_DOMAINS_n_MAIN`:
|
||||
Default subject name.
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_TLS_DOMAINS[n]_SANS`:
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_TLS_DOMAINS_n_SANS`:
|
||||
Subject alternative names.
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_TLS_OPTIONS`:
|
||||
@@ -168,6 +174,9 @@ plugin's GOPATH.
|
||||
`TRAEFIK_EXPERIMENTAL_DEVPLUGIN_MODULENAME`:
|
||||
plugin's module name.
|
||||
|
||||
`TRAEFIK_EXPERIMENTAL_KUBERNETESGATEWAY`:
|
||||
Allow the Kubernetes gateway api provider usage. (Default: ```false```)
|
||||
|
||||
`TRAEFIK_EXPERIMENTAL_PLUGINS_<NAME>_MODULENAME`:
|
||||
plugin's module name.
|
||||
|
||||
@@ -175,7 +184,7 @@ plugin's module name.
|
||||
plugin's version.
|
||||
|
||||
`TRAEFIK_GLOBAL_CHECKNEWVERSION`:
|
||||
Periodically check if a new version has been released. (Default: ```false```)
|
||||
Periodically check if a new version has been released. (Default: ```true```)
|
||||
|
||||
`TRAEFIK_GLOBAL_SENDANONYMOUSUSAGE`:
|
||||
Periodically send anonymous usage statistics. If the option is not specified, it will be enabled by default. (Default: ```false```)
|
||||
@@ -358,7 +367,7 @@ Expose containers by default. (Default: ```true```)
|
||||
Prefix for consul service tags. Default 'traefik' (Default: ```traefik```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_CONSULCATALOG_REFRESHINTERVAL`:
|
||||
Interval for check Consul API. Default 100ms (Default: ```15```)
|
||||
Interval for check Consul API. Default 15s (Default: ```15```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_CONSULCATALOG_REQUIRECONSISTENT`:
|
||||
Forces the read to be fully consistent. (Default: ```false```)
|
||||
@@ -408,6 +417,9 @@ Docker server endpoint. Can be a tcp or a unix socket endpoint. (Default: ```uni
|
||||
`TRAEFIK_PROVIDERS_DOCKER_EXPOSEDBYDEFAULT`:
|
||||
Expose containers by default. (Default: ```true```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_DOCKER_HTTPCLIENTTIMEOUT`:
|
||||
Client timeout for HTTP connections. (Default: ```0```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_DOCKER_NETWORK`:
|
||||
Default Docker network used.
|
||||
|
||||
@@ -546,9 +558,6 @@ Allow cross namespace resource reference. (Default: ```true```)
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESCRD_CERTAUTHFILEPATH`:
|
||||
Kubernetes certificate authority file path (not needed for in-cluster client).
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESCRD_DISABLEPASSHOSTHEADERS`:
|
||||
Kubernetes disable PassHost Headers. (Default: ```false```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESCRD_ENDPOINT`:
|
||||
Kubernetes server endpoint (required for external cluster client).
|
||||
|
||||
@@ -567,15 +576,33 @@ Ingress refresh throttle duration (Default: ```0```)
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESCRD_TOKEN`:
|
||||
Kubernetes bearer token (not needed for in-cluster client).
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY`:
|
||||
Enable Kubernetes gateway api provider with default settings. (Default: ```false```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_CERTAUTHFILEPATH`:
|
||||
Kubernetes certificate authority file path (not needed for in-cluster client).
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_ENDPOINT`:
|
||||
Kubernetes server endpoint (required for external cluster client).
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_LABELSELECTOR`:
|
||||
Kubernetes label selector to select specific GatewayClasses.
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_NAMESPACES`:
|
||||
Kubernetes namespaces.
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_THROTTLEDURATION`:
|
||||
Kubernetes refresh throttle duration (Default: ```0```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_TOKEN`:
|
||||
Kubernetes bearer token (not needed for in-cluster client).
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESINGRESS`:
|
||||
Enable Kubernetes backend with default settings. (Default: ```false```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESINGRESS_CERTAUTHFILEPATH`:
|
||||
Kubernetes certificate authority file path (not needed for in-cluster client).
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESINGRESS_DISABLEPASSHOSTHEADERS`:
|
||||
Kubernetes disable PassHost Headers. (Default: ```false```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESINGRESS_ENDPOINT`:
|
||||
Kubernetes server endpoint (required for external cluster client).
|
||||
|
||||
@@ -667,7 +694,7 @@ Display additional provider logs. (Default: ```false```)
|
||||
Watch provider. (Default: ```true```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_PROVIDERSTHROTTLEDURATION`:
|
||||
Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time. (Default: ```0```)
|
||||
Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time. (Default: ```2```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_RANCHER`:
|
||||
Enable Rancher backend with default settings. (Default: ```false```)
|
||||
@@ -775,7 +802,7 @@ The amount of time to wait for a server's response headers after fully writing t
|
||||
Disable SSL certificate verification. (Default: ```false```)
|
||||
|
||||
`TRAEFIK_SERVERSTRANSPORT_MAXIDLECONNSPERHOST`:
|
||||
If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used (Default: ```0```)
|
||||
If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used (Default: ```200```)
|
||||
|
||||
`TRAEFIK_SERVERSTRANSPORT_ROOTCAS`:
|
||||
Add cert file for self-signed certificate.
|
||||
|
@@ -60,6 +60,7 @@
|
||||
swarmMode = true
|
||||
network = "foobar"
|
||||
swarmModeRefreshSeconds = 42
|
||||
httpClientTimeout = 42
|
||||
[providers.docker.tls]
|
||||
ca = "foobar"
|
||||
caOptional = true
|
||||
@@ -98,11 +99,10 @@
|
||||
endpoint = "foobar"
|
||||
token = "foobar"
|
||||
certAuthFilePath = "foobar"
|
||||
disablePassHostHeaders = true
|
||||
namespaces = ["foobar", "foobar"]
|
||||
labelSelector = "foobar"
|
||||
ingressClass = "foobar"
|
||||
throttleDuration = "10s"
|
||||
throttleDuration = "42s"
|
||||
[providers.kubernetesIngress.ingressEndpoint]
|
||||
ip = "foobar"
|
||||
hostname = "foobar"
|
||||
@@ -111,12 +111,18 @@
|
||||
endpoint = "foobar"
|
||||
token = "foobar"
|
||||
certAuthFilePath = "foobar"
|
||||
disablePassHostHeaders = true
|
||||
namespaces = ["foobar", "foobar"]
|
||||
allowCrossNamespace = true
|
||||
labelSelector = "foobar"
|
||||
ingressClass = "foobar"
|
||||
throttleDuration = 42
|
||||
[providers.kubernetesGateway]
|
||||
endpoint = "foobar"
|
||||
token = "foobar"
|
||||
certAuthFilePath = "foobar"
|
||||
namespaces = ["foobar", "foobar"]
|
||||
labelSelector = "foobar"
|
||||
throttleDuration = 42
|
||||
[providers.rest]
|
||||
insecure = true
|
||||
[providers.rancher]
|
||||
@@ -251,9 +257,6 @@
|
||||
addEntryPointsLabels = true
|
||||
addServicesLabels = true
|
||||
|
||||
[pilot]
|
||||
token = "foobar"
|
||||
|
||||
[ping]
|
||||
entryPoint = "foobar"
|
||||
manualRouting = true
|
||||
@@ -343,6 +346,9 @@
|
||||
preferredChain = "foobar"
|
||||
storage = "foobar"
|
||||
keyType = "foobar"
|
||||
[certificatesResolvers.CertificateResolver0.acme.eab]
|
||||
kid = "foobar"
|
||||
hmacEncoded = "foobar"
|
||||
[certificatesResolvers.CertificateResolver0.acme.dnsChallenge]
|
||||
provider = "foobar"
|
||||
delayBeforeCheck = 42
|
||||
@@ -358,6 +364,9 @@
|
||||
preferredChain = "foobar"
|
||||
storage = "foobar"
|
||||
keyType = "foobar"
|
||||
[certificatesResolvers.CertificateResolver1.acme.eab]
|
||||
kid = "foobar"
|
||||
hmacEncoded = "foobar"
|
||||
[certificatesResolvers.CertificateResolver1.acme.dnsChallenge]
|
||||
provider = "foobar"
|
||||
delayBeforeCheck = 42
|
||||
@@ -367,7 +376,11 @@
|
||||
entryPoint = "foobar"
|
||||
[certificatesResolvers.CertificateResolver1.acme.tlsChallenge]
|
||||
|
||||
[pilot]
|
||||
token = "foobar"
|
||||
|
||||
[experimental]
|
||||
kubernetesGateway = true
|
||||
[experimental.plugins]
|
||||
[experimental.plugins.Descriptor0]
|
||||
moduleName = "foobar"
|
||||
|
@@ -72,6 +72,7 @@ providers:
|
||||
swarmMode: true
|
||||
network: foobar
|
||||
swarmModeRefreshSeconds: 42
|
||||
httpClientTimeout: 42
|
||||
file:
|
||||
directory: foobar
|
||||
watch: true
|
||||
@@ -104,7 +105,6 @@ providers:
|
||||
endpoint: foobar
|
||||
token: foobar
|
||||
certAuthFilePath: foobar
|
||||
disablePassHostHeaders: true
|
||||
namespaces:
|
||||
- foobar
|
||||
- foobar
|
||||
@@ -119,7 +119,6 @@ providers:
|
||||
endpoint: foobar
|
||||
token: foobar
|
||||
certAuthFilePath: foobar
|
||||
disablePassHostHeaders: true
|
||||
namespaces:
|
||||
- foobar
|
||||
- foobar
|
||||
@@ -127,6 +126,15 @@ providers:
|
||||
labelSelector: foobar
|
||||
ingressClass: foobar
|
||||
throttleDuration: 42s
|
||||
kubernetesGateway:
|
||||
endpoint: foobar
|
||||
token: foobar
|
||||
certAuthFilePath: foobar
|
||||
namespaces:
|
||||
- foobar
|
||||
- foobar
|
||||
labelSelector: foobar
|
||||
throttleDuration: 42s
|
||||
rest:
|
||||
insecure: true
|
||||
rancher:
|
||||
@@ -270,8 +278,6 @@ metrics:
|
||||
password: foobar
|
||||
addEntryPointsLabels: true
|
||||
addServicesLabels: true
|
||||
pilot:
|
||||
token: foobar
|
||||
ping:
|
||||
entryPoint: foobar
|
||||
manualRouting: true
|
||||
@@ -358,6 +364,9 @@ certificatesResolvers:
|
||||
preferredChain: foobar
|
||||
storage: foobar
|
||||
keyType: foobar
|
||||
eab:
|
||||
kid: foobar
|
||||
hmacEncoded: foobar
|
||||
dnsChallenge:
|
||||
provider: foobar
|
||||
delayBeforeCheck: 42
|
||||
@@ -375,6 +384,9 @@ certificatesResolvers:
|
||||
preferredChain: foobar
|
||||
storage: foobar
|
||||
keyType: foobar
|
||||
eab:
|
||||
kid: foobar
|
||||
hmacEncoded: foobar
|
||||
dnsChallenge:
|
||||
provider: foobar
|
||||
delayBeforeCheck: 42
|
||||
@@ -385,7 +397,10 @@ certificatesResolvers:
|
||||
httpChallenge:
|
||||
entryPoint: foobar
|
||||
tlsChallenge: {}
|
||||
pilot:
|
||||
token: foobar
|
||||
experimental:
|
||||
kubernetesGateway: true
|
||||
plugins:
|
||||
Descriptor0:
|
||||
moduleName: foobar
|
||||
@@ -396,3 +411,4 @@ experimental:
|
||||
devPlugin:
|
||||
goPath: foobar
|
||||
moduleName: foobar
|
||||
|
||||
|
@@ -130,8 +130,17 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass
|
||||
traefik.http.services.myservice.loadbalancer.server.scheme=http
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.serverstransport`"
|
||||
|
||||
See [serverstransport](../services/index.md#serverstransport) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.<service_name>.loadbalancer.serverstransport=foobar
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
|
||||
<!-- TODO doc passHostHeader in services page -->
|
||||
|
||||
See [pass Host header](../services/index.md#pass-host-header) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.passhostheader=true
|
||||
@@ -201,12 +210,12 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass
|
||||
traefik.http.services.myservice.loadbalancer.healthcheck.followredirects=true
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky`"
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.sticky=true
|
||||
traefik.http.services.myservice.loadbalancer.sticky.cookie=true
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.httponly`"
|
||||
@@ -242,10 +251,9 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.responseforwarding.flushinterval`"
|
||||
<!-- TODO doc responseforwarding in services page -->
|
||||
|
||||
FlushInterval specifies the flush interval to flush to the client while copying the response body.
|
||||
|
||||
|
||||
See [response forwarding](../services/index.md#response-forwarding) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10
|
||||
```
|
||||
@@ -381,6 +389,14 @@ You can declare TCP Routers and/or Services using tags.
|
||||
traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay=100
|
||||
```
|
||||
|
||||
??? info "`traefik.tcp.services.<service_name>.loadbalancer.proxyprotocol.version`"
|
||||
|
||||
See [PROXY protocol](../services/index.md#proxy-protocol) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.tcp.services.mytcpservice.loadbalancer.proxyprotocol.version=1
|
||||
```
|
||||
|
||||
### UDP
|
||||
|
||||
You can declare UDP Routers and/or Services using tags.
|
||||
|
@@ -124,7 +124,7 @@ Attach labels to your containers and let Traefik do the rest!
|
||||
!!! important "Labels in Docker Swarm Mode"
|
||||
While in Swarm Mode, Traefik uses labels found on services, not on individual containers.
|
||||
Therefore, if you use a compose file with Swarm Mode, labels should be defined in the `deploy` part of your service.
|
||||
This behavior is only enabled for docker-compose version 3+ ([Compose file reference](https://docs.docker.com/compose/compose-file/#labels-1)).
|
||||
This behavior is only enabled for docker-compose version 3+ ([Compose file reference](https://docs.docker.com/compose/compose-file/compose-file-v3/#labels-1)).
|
||||
|
||||
## Routing Configuration
|
||||
|
||||
@@ -285,6 +285,14 @@ you'd add the label `traefik.http.services.<name-of-your-choice>.loadbalancer.pa
|
||||
- "traefik.http.services.myservice.loadbalancer.server.scheme=http"
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.serverstransport`"
|
||||
|
||||
See [serverstransport](../services/index.md#serverstransport) for more information.
|
||||
|
||||
```yaml
|
||||
- "traefik.http.services.<service_name>.loadbalancer.serverstransport=foobar"
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
|
||||
|
||||
See [pass Host header](../services/index.md#pass-host-header) for more information.
|
||||
@@ -547,6 +555,14 @@ You can declare TCP Routers and/or Services using labels.
|
||||
- "traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay=100"
|
||||
```
|
||||
|
||||
??? info "`traefik.tcp.services.<service_name>.loadbalancer.proxyprotocol.version`"
|
||||
|
||||
See [PROXY protocol](../services/index.md#proxy-protocol) for more information.
|
||||
|
||||
```yaml
|
||||
- "traefik.tcp.services.mytcpservice.loadbalancer.proxyprotocol.version=1"
|
||||
```
|
||||
|
||||
### UDP
|
||||
|
||||
You can declare UDP Routers and/or Services using labels.
|
||||
|
@@ -133,6 +133,14 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa
|
||||
traefik.http.services.myservice.loadbalancer.server.scheme=http
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.serverstransport`"
|
||||
|
||||
See [serverstransport](../services/index.md#serverstransport) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.<service_name>.loadbalancer.serverstransport=foobar
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
|
||||
|
||||
See [pass Host header](../services/index.md#pass-host-header) for more information.
|
||||
@@ -205,12 +213,12 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa
|
||||
traefik.http.services.myservice.loadbalancer.healthcheck.followredirects=true
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky`"
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.sticky=true
|
||||
traefik.http.services.myservice.loadbalancer.sticky.cookie=true
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.httponly`"
|
||||
@@ -388,6 +396,14 @@ You can declare TCP Routers and/or Services using labels.
|
||||
traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay=100
|
||||
```
|
||||
|
||||
??? info "`traefik.tcp.services.<service_name>.loadbalancer.proxyprotocol.version`"
|
||||
|
||||
See [PROXY protocol](../services/index.md#proxy-protocol) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.tcp.services.mytcpservice.loadbalancer.proxyprotocol.version=1
|
||||
```
|
||||
|
||||
### UDP
|
||||
|
||||
You can declare UDP Routers and/or Services using tags.
|
||||
|
@@ -43,7 +43,7 @@ The Kubernetes Ingress Controller, The Custom Resource Way.
|
||||
serviceAccountName: traefik-ingress-controller
|
||||
containers:
|
||||
- name: traefik
|
||||
image: traefik:v2.3
|
||||
image: traefik:v2.4
|
||||
args:
|
||||
- --log.level=DEBUG
|
||||
- --api
|
||||
@@ -335,6 +335,7 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne
|
||||
responseForwarding:
|
||||
flushInterval: 1ms
|
||||
scheme: https
|
||||
serversTransport: transport
|
||||
sticky:
|
||||
cookie:
|
||||
httpOnly: true
|
||||
@@ -1090,40 +1091,44 @@ Register the `IngressRouteTCP` [kind](../../reference/dynamic-configuration/kube
|
||||
port: 8080 # [6]
|
||||
weight: 10 # [7]
|
||||
terminationDelay: 400 # [8]
|
||||
tls: # [9]
|
||||
secretName: supersecret # [10]
|
||||
options: # [11]
|
||||
name: opt # [12]
|
||||
namespace: default # [13]
|
||||
certResolver: foo # [14]
|
||||
domains: # [15]
|
||||
- main: example.net # [16]
|
||||
sans: # [17]
|
||||
proxyProtocol: # [9]
|
||||
version: 1 # [10]
|
||||
tls: # [11]
|
||||
secretName: supersecret # [12]
|
||||
options: # [13]
|
||||
name: opt # [14]
|
||||
namespace: default # [15]
|
||||
certResolver: foo # [16]
|
||||
domains: # [17]
|
||||
- main: example.net # [18]
|
||||
sans: # [19]
|
||||
- a.example.net
|
||||
- b.example.net
|
||||
passthrough: false # [18]
|
||||
passthrough: false # [20]
|
||||
```
|
||||
|
||||
| Ref | Attribute | Purpose |
|
||||
|------|--------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [1] | `entryPoints` | List of [entrypoints](../routers/index.md#entrypoints_1) names |
|
||||
| [2] | `routes` | List of routes |
|
||||
| [3] | `routes[n].match` | Defines the [rule](../routers/index.md#rule_1) corresponding to an underlying router |
|
||||
| [4] | `routes[n].services` | List of [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) definitions (See below for `ExternalName Service` setup) |
|
||||
| [5] | `services[n].name` | Defines the name of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) |
|
||||
| [6] | `services[n].port` | Defines the port of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) |
|
||||
| [7] | `services[n].weight` | Defines the weight to apply to the server load balancing |
|
||||
| [8] | `services[n].terminationDelay` | corresponds to the deadline that the proxy sets, after one of its connected peers indicates it has closed the writing capability of its connection, to close the reading capability as well, hence fully terminating the connection.<br/>It is a duration in milliseconds, defaulting to 100. A negative value means an infinite deadline (i.e. the reading capability is never closed). |
|
||||
| [9] | `tls` | Defines [TLS](../routers/index.md#tls_1) certificate configuration |
|
||||
| [10] | `tls.secretName` | Defines the [secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the `IngressRoute` namespace) |
|
||||
| [11] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) |
|
||||
| [12] | `options.name` | Defines the [TLSOption](#kind-tlsoption) name |
|
||||
| [13] | `options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace |
|
||||
| [14] | `tls.certResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver_1) |
|
||||
| [15] | `tls.domains` | List of [domains](../routers/index.md#domains_1) |
|
||||
| [16] | `domains[n].main` | Defines the main domain name |
|
||||
| [17] | `domains[n].sans` | List of SANs (alternative domains) |
|
||||
| [18] | `tls.passthrough` | If `true`, delegates the TLS termination to the backend |
|
||||
| Ref | Attribute | Purpose |
|
||||
|------|--------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [1] | `entryPoints` | List of [entrypoints](../routers/index.md#entrypoints_1) names |
|
||||
| [2] | `routes` | List of routes |
|
||||
| [3] | `routes[n].match` | Defines the [rule](../routers/index.md#rule_1) corresponding to an underlying router |
|
||||
| [4] | `routes[n].services` | List of [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) definitions (See below for `ExternalName Service` setup) |
|
||||
| [5] | `services[n].name` | Defines the name of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) |
|
||||
| [6] | `services[n].port` | Defines the port of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) |
|
||||
| [7] | `services[n].weight` | Defines the weight to apply to the server load balancing |
|
||||
| [8] | `services[n].terminationDelay` | corresponds to the deadline that the proxy sets, after one of its connected peers indicates it has closed the writing capability of its connection, to close the reading capability as well, hence fully terminating the connection. It is a duration in milliseconds, defaulting to 100. A negative value means an infinite deadline (i.e. the reading capability is never closed). |
|
||||
| [9] | `proxyProtocol` | Defines the [PROXY protocol](../services/index.md#proxy-protocol) configuration |
|
||||
| [10] | `version` | Defines the [PROXY protocol](../services/index.md#proxy-protocol) version |
|
||||
| [11] | `tls` | Defines [TLS](../routers/index.md#tls_1) certificate configuration |
|
||||
| [12] | `tls.secretName` | Defines the [secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the `IngressRoute` namespace) |
|
||||
| [13] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) |
|
||||
| [14] | `options.name` | Defines the [TLSOption](#kind-tlsoption) name |
|
||||
| [15] | `options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace |
|
||||
| [16] | `tls.certResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver_1) |
|
||||
| [17] | `tls.domains` | List of [domains](../routers/index.md#domains_1) |
|
||||
| [18] | `domains[n].main` | Defines the main domain name |
|
||||
| [19] | `domains[n].sans` | List of SANs (alternative domains) |
|
||||
| [20] | `tls.passthrough` | If `true`, delegates the TLS termination to the backend |
|
||||
|
||||
??? example "Declaring an IngressRouteTCP"
|
||||
|
||||
@@ -1487,9 +1492,9 @@ or referencing TLS stores in the [`IngressRoute`](#kind-ingressroute) / [`Ingres
|
||||
secretName: mySecret # [1]
|
||||
```
|
||||
|
||||
| Ref | Attribute | Purpose |
|
||||
|-----|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [1] | `secretName` | The name of the referenced Kubernetes [Secret](https://kubernetes.io/docs/concepts/configuration/secret/) that holds the default certificate for the store. |
|
||||
| Ref | Attribute | Purpose |
|
||||
|-----|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [1] | `secretName` | The name of the referenced Kubernetes [Secret](https://kubernetes.io/docs/concepts/configuration/secret/) that holds the default certificate for the store. |
|
||||
|
||||
??? example "Declaring and referencing a TLSStore"
|
||||
|
||||
@@ -1536,6 +1541,84 @@ or referencing TLS stores in the [`IngressRoute`](#kind-ingressroute) / [`Ingres
|
||||
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
|
||||
```
|
||||
|
||||
### Kind: `ServersTransport`
|
||||
|
||||
`ServersTransport` is the CRD implementation of a [ServersTransport](../services/index.md#serverstransport).
|
||||
|
||||
!!! important "Default serversTransport"
|
||||
If no `serversTransport` is specified, the `default@internal` will be used.
|
||||
The `default@internal` serversTransport is created from the [static configuration](../overview.md#transport-configuration).
|
||||
|
||||
!!! info "ServersTransport Attributes"
|
||||
|
||||
```yaml tab="TLSStore"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: ServersTransport
|
||||
metadata:
|
||||
name: mytransport
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
serverName: foobar # [1]
|
||||
insecureSkipVerify: true # [2]
|
||||
rootCAsSecrets: # [3]
|
||||
- foobar
|
||||
- foobar
|
||||
certificatesSecrets: # [4]
|
||||
- foobar
|
||||
- foobar
|
||||
maxIdleConnsPerHost: 1 # [5]
|
||||
forwardingTimeouts: # [6]
|
||||
dialTimeout: 42s # [7]
|
||||
responseHeaderTimeout: 42s # [8]
|
||||
idleConnTimeout: 42s # [9]
|
||||
```
|
||||
|
||||
| Ref | Attribute | Purpose |
|
||||
|-----|-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [1] | `serverName` | ServerName used to contact the server. |
|
||||
| [2] | `insecureSkipVerify` | Disable SSL certificate verification. |
|
||||
| [3] | `rootCAsSecrets` | Add cert file for self-signed certificate. |
|
||||
| [4] | `certificatesSecrets` | Certificates for mTLS. |
|
||||
| [5] | `maxIdleConnsPerHost` | If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, `defaultMaxIdleConnsPerHost` is used. |
|
||||
| [6] | `forwardingTimeouts` | Timeouts for requests forwarded to the backend servers. |
|
||||
| [7] | `dialTimeout` | The amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists. |
|
||||
| [8] | `responseHeaderTimeout` | The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists. |
|
||||
| [9] | `idleConnTimeout` | The maximum period for which an idle HTTP keep-alive connection will remain open before closing itself. |
|
||||
|
||||
??? example "Declaring and referencing a ServersTransport"
|
||||
|
||||
```yaml tab="ServersTransport"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: ServersTransport
|
||||
metadata:
|
||||
name: mytransport
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
serverName: example.org
|
||||
insecureSkipVerify: true
|
||||
```
|
||||
|
||||
```yaml tab="IngressRoute"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: testroute
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
entryPoints:
|
||||
- web
|
||||
routes:
|
||||
- match: Host(`example.com`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: whoami
|
||||
port: 80
|
||||
serversTransport: mytransport
|
||||
```
|
||||
|
||||
## Further
|
||||
|
||||
Also see the [full example](../../user-guides/crd-acme/index.md) with Let's Encrypt.
|
||||
|
161
docs/content/routing/providers/kubernetes-gateway.md
Normal file
161
docs/content/routing/providers/kubernetes-gateway.md
Normal file
@@ -0,0 +1,161 @@
|
||||
# Traefik & Kubernetes
|
||||
|
||||
The Kubernetes Gateway API, The Experimental Way.
|
||||
{: .subtitle }
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
??? example "Configuring Kubernetes Gateway provider and Deploying/Exposing Services"
|
||||
|
||||
```yaml tab="Gateway API"
|
||||
--8<-- "content/reference/dynamic-configuration/kubernetes-gateway-simple-https.yml"
|
||||
```
|
||||
|
||||
```yaml tab="Whoami Service"
|
||||
--8<-- "content/reference/dynamic-configuration/kubernetes-whoami-svc.yml"
|
||||
```
|
||||
|
||||
```yaml tab="Traefik Service"
|
||||
--8<-- "content/reference/dynamic-configuration/kubernetes-gateway-traefik-lb-svc.yml"
|
||||
```
|
||||
|
||||
```yaml tab="RBAC"
|
||||
--8<-- "content/reference/dynamic-configuration/kubernetes-gateway-rbac.yml"
|
||||
```
|
||||
|
||||
## Routing Configuration
|
||||
|
||||
### Custom Resource Definition (CRD)
|
||||
|
||||
* You can find an exhaustive list, of the custom resources and their attributes in
|
||||
[the reference page](../../reference/dynamic-configuration/kubernetes-gateway.md) or in the Kubernetes Sigs `Service APIs` [repository](https://github.com/kubernetes-sigs/service-apis/).
|
||||
* Validate that [the prerequisites](../../providers/kubernetes-gateway.md#configuration-requirements) are fulfilled before using the Traefik Kubernetes Gateway Provider.
|
||||
|
||||
You can find an excerpt of the supported Kubernetes Gateway API resources in the table below:
|
||||
|
||||
| Kind | Purpose | Concept Behind |
|
||||
|------------------------------------|---------------------------------------------------------------------------|-----------------------------------------------------------------------------|
|
||||
| [GatewayClass](#kind-gatewayclass) | Defines a set of Gateways that share a common configuration and behaviour | [GatewayClass](https://gateway-api.sigs.k8s.io/api-overview/#gatewayclass) |
|
||||
| [Gateway](#kind-gateway) | Describes how traffic can be translated to Services within the cluster | [Gateway](https://gateway-api.sigs.k8s.io/api-overview/#gateway) |
|
||||
| [HTTPRoute](#kind-httproute) | HTTP rules for mapping requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/api-overview/#httptcpfooroute) |
|
||||
|
||||
### Kind: `GatewayClass`
|
||||
|
||||
`GatewayClass` is cluster-scoped resource defined by the infrastructure provider. This resource represents a class of Gateways that can be instantiated.
|
||||
More details on the GatewayClass [official documentation](https://gateway-api.sigs.k8s.io/gatewayclass/).
|
||||
|
||||
The `GatewayClass` should be declared by the infrastructure provider, otherwise please register the `GatewayClass`
|
||||
[definition](../../reference/dynamic-configuration/kubernetes-gateway.md#definitions) in the Kubernetes cluster before
|
||||
creating `GatewayClass` objects.
|
||||
|
||||
!!! info "Declaring GatewayClass"
|
||||
|
||||
```yaml
|
||||
kind: GatewayClass
|
||||
apiVersion: networking.x-k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: my-gateway-class
|
||||
spec:
|
||||
# Controller is a domain/path string that indicates
|
||||
# the controller that is managing Gateways of this class.
|
||||
controller: traefik.io/gateway-controller
|
||||
```
|
||||
|
||||
### Kind: `Gateway`
|
||||
|
||||
A `Gateway` is 1:1 with the life cycle of the configuration of infrastructure. When a user creates a Gateway,
|
||||
some load balancing infrastructure is provisioned or configured by the GatewayClass controller.
|
||||
More details on the Gateway [official documentation](https://gateway-api.sigs.k8s.io/gateway/).
|
||||
|
||||
Register the `Gateway` [definition](../../reference/dynamic-configuration/kubernetes-gateway.md#definitions) in the
|
||||
Kubernetes cluster before creating `Gateway` objects.
|
||||
|
||||
!!! info "Declaring Gateway"
|
||||
|
||||
```
|
||||
kind: Gateway
|
||||
apiVersion: networking.x-k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: my-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gatewayClassName: my-gateway-class # [1]
|
||||
listeners: # [2]
|
||||
- protocol: HTTPS # [3]
|
||||
port: 443 # [4]
|
||||
tls: # [5]
|
||||
certificateRef: # [6]
|
||||
group: "core"
|
||||
kind: "Secret"
|
||||
name: "mysecret"
|
||||
routes: # [7]
|
||||
kind: HTTPRoute # [8]
|
||||
selector: # [9]
|
||||
matchLabels: # [10]
|
||||
app: foo
|
||||
```
|
||||
|
||||
| Ref | Attribute | Description |
|
||||
|------|--------------------|-----------------------------------------------------------------------------------------------------------------------------|
|
||||
| [1] | `gatewayClassName` | GatewayClassName used for this Gateway. This is the name of a GatewayClass resource. |
|
||||
| [2] | `listeners` | Logical endpoints that are bound on this Gateway's addresses. At least one Listener MUST be specified. |
|
||||
| [3] | `protocol` | The network protocol this listener expects to receive (only HTTP and HTTPS are implemented). |
|
||||
| [4] | `port` | The network port. |
|
||||
| [5] | `tls` | TLS configuration for the Listener. This field is required if the Protocol field is "HTTPS" or "TLS" and ignored otherwise. |
|
||||
| [6] | `certificateRef` | The reference to Kubernetes object that contains a TLS certificate and private key. |
|
||||
| [7] | `routes` | A schema for associating routes with the Listener using selectors. |
|
||||
| [8] | `kind` | The kind of the referent. |
|
||||
| [9] | `selector` | Routes in namespaces selected by the selector may be used by this Gateway routes to associate with the Gateway. |
|
||||
| [10] | `matchLabels` | A set of route labels used for selecting routes to associate with the Gateway. |
|
||||
|
||||
### Kind: `HTTPRoute`
|
||||
|
||||
`HTTPRoute` defines HTTP rules for mapping requests from a `Gateway` to Kubernetes Services.
|
||||
|
||||
Register the `HTTPRoute` [definition](../../reference/dynamic-configuration/kubernetes-gateway.md#definitions) in the
|
||||
Kubernetes cluster before creating `HTTPRoute` objects.
|
||||
|
||||
!!! info "Declaring HTTPRoute"
|
||||
|
||||
```yaml
|
||||
kind: HTTPRoute
|
||||
apiVersion: networking.x-k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: http-app-1
|
||||
namespace: default
|
||||
labels: # [1]
|
||||
app: foo
|
||||
spec:
|
||||
hostnames: # [2]
|
||||
- "whoami"
|
||||
rules: # [3]
|
||||
- matches: # [4]
|
||||
- path: # [5]
|
||||
type: Exact # [6]
|
||||
value: /bar # [7]
|
||||
- headers: # [8]
|
||||
type: Exact # [9]
|
||||
values: # [10]
|
||||
- foo: bar
|
||||
forwardTo: # [11]
|
||||
- serviceName: whoami # [12]
|
||||
weight: 1 # [13]
|
||||
port: 80 # [14]
|
||||
```
|
||||
|
||||
| Ref | Attribute | Description |
|
||||
|------|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [1] | `labels` | Labels to match with the `Gateway` labelselector. |
|
||||
| [2] | `hostnames` | A set of hostname that should match against the HTTP Host header to select a HTTPRoute to process the request. |
|
||||
| [3] | `rules` | A list of HTTP matchers, filters and actions. |
|
||||
| [4] | `matches` | Conditions used for matching the rule against incoming HTTP requests. Each match is independent, i.e. this rule will be matched if **any** one of the matches is satisfied. |
|
||||
| [5] | `path` | An HTTP request path matcher. If this field is not specified, a default prefix match on the "/" path is provided. |
|
||||
| [6] | `type` | Type of match against the path Value (supported types: `Exact`, `Prefix`). |
|
||||
| [7] | `value` | The value of the HTTP path to match against. |
|
||||
| [8] | `headers` | Conditions to select a HTTP route by matching HTTP request headers. |
|
||||
| [9] | `type` | Type of match for the HTTP request header match against the `values` (supported types: `Exact`). |
|
||||
| [10] | `values` | A map of HTTP Headers to be matched. It MUST contain at least one entry. |
|
||||
| [11] | `forwardTo` | The upstream target(s) where the request should be sent. |
|
||||
| [12] | `serviceName` | The name of the referent service. |
|
||||
| [13] | `weight` | The proportion of traffic forwarded to a targetRef, computed as weight/(sum of all weights in targetRefs). |
|
||||
| [14] | `port` | The port of the referent service. |
|
@@ -112,7 +112,7 @@ which in turn will create the resulting routers, services, handlers, etc.
|
||||
serviceAccountName: traefik-ingress-controller
|
||||
containers:
|
||||
- name: traefik
|
||||
image: traefik:v2.3
|
||||
image: traefik:v2.4
|
||||
args:
|
||||
- --entrypoints.web.address=:80
|
||||
- --providers.kubernetesingress
|
||||
@@ -461,7 +461,7 @@ This way, any Ingress attached to this Entrypoint will have TLS termination by d
|
||||
serviceAccountName: traefik-ingress-controller
|
||||
containers:
|
||||
- name: traefik
|
||||
image: traefik:v2.3
|
||||
image: traefik:v2.4
|
||||
args:
|
||||
- --entrypoints.websecure.address=:443
|
||||
- --entrypoints.websecure.http.tls
|
||||
@@ -640,7 +640,7 @@ For more options, please refer to the available [annotations](#on-ingress).
|
||||
serviceAccountName: traefik-ingress-controller
|
||||
containers:
|
||||
- name: traefik
|
||||
image: traefik:v2.3
|
||||
image: traefik:v2.4
|
||||
args:
|
||||
- --entrypoints.websecure.address=:443
|
||||
- --providers.kubernetesingress
|
||||
|
@@ -110,6 +110,14 @@ A Story of key & values
|
||||
|-----------------------------------------------------------------|-----------------------------------------|
|
||||
| `traefik/http/services/myservice/loadbalancer/servers/0/url` | `http://<ip-server-1>:<port-server-1>/` |
|
||||
|
||||
??? info "`traefik/http/services/<service_name>/loadbalancer/serverstransport`"
|
||||
|
||||
See [serverstransport](../services/index.md#serverstransport) for more information.
|
||||
|
||||
| Key (Path) | Value |
|
||||
|-----------------------------------------------------------------|----------|
|
||||
| `traefik/http/services/myservice/loadbalancer/serverstransport` | `foobar` |
|
||||
|
||||
??? info "`traefik/http/services/<service_name>/loadbalancer/passhostheader`"
|
||||
|
||||
See [pass Host header](../services/index.md#pass-host-header) for more information.
|
||||
@@ -384,6 +392,14 @@ You can declare TCP Routers and/or Services using KV.
|
||||
| Key (Path) | Value |
|
||||
|-------------------------------------------------------------------|-------|
|
||||
| `traefik/tcp/services/mytcpservice/loadbalancer/terminationdelay` | `100` |
|
||||
|
||||
??? info "`traefik/tcp/services/<service_name>/loadbalancer/proxyprotocol/version`"
|
||||
|
||||
See [PROXY protocol](../services/index.md#proxy-protocol) for more information.
|
||||
|
||||
| Key (Path) | Value |
|
||||
|------------------------------------------------------------------------|-------|
|
||||
| `traefik/tcp/services/mytcpservice/loadbalancer/proxyprotocol/version` | `1` |
|
||||
|
||||
??? info "`traefik/tcp/services/<service_name>/weighted/services/<n>/name`"
|
||||
|
||||
|
@@ -160,6 +160,14 @@ For example, to change the passHostHeader behavior, you'd add the label `"traefi
|
||||
"traefik.http.services.myservice.loadbalancer.server.scheme": "http"
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.serverstransport`"
|
||||
|
||||
See [serverstransport](../services/index.md#serverstransport) for more information.
|
||||
|
||||
```json
|
||||
"traefik.http.services.<service_name>.loadbalancer.serverstransport": "foobar"
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
|
||||
|
||||
See [pass Host header](../services/index.md#pass-host-header) for more information.
|
||||
@@ -421,6 +429,14 @@ You can declare TCP Routers and/or Services using labels.
|
||||
"traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay": "100"
|
||||
```
|
||||
|
||||
??? info "`traefik.tcp.services.<service_name>.loadbalancer.proxyprotocol.version`"
|
||||
|
||||
See [PROXY protocol](../services/index.md#proxy-protocol) for more information.
|
||||
|
||||
```json
|
||||
"traefik.tcp.services.mytcpservice.loadbalancer.proxyprotocol.version": "1"
|
||||
```
|
||||
|
||||
### UDP
|
||||
|
||||
You can declare UDP Routers and/or Services using labels.
|
||||
|
@@ -166,6 +166,14 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa
|
||||
- "traefik.http.services.myservice.loadbalancer.server.scheme=http"
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.serverstransport`"
|
||||
|
||||
See [serverstransport](../services/index.md#serverstransport) for more information.
|
||||
|
||||
```yaml
|
||||
- "traefik.http.services.<service_name>.loadbalancer.serverstransport=foobar"
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
|
||||
|
||||
See [pass Host header](../services/index.md#pass-host-header) for more information.
|
||||
@@ -195,7 +203,7 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa
|
||||
See [health check](../services/index.md#health-check) for more information.
|
||||
|
||||
```yaml
|
||||
- "traefik.http.services.myservice.loadbalancer.healthcheck.interval=10"
|
||||
- "traefik.http.services.myservice.loadbalancer.healthcheck.interval=10s"
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.path`"
|
||||
@@ -424,6 +432,14 @@ You can declare TCP Routers and/or Services using labels.
|
||||
- "traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay=100"
|
||||
```
|
||||
|
||||
??? info "`traefik.tcp.services.<service_name>.loadbalancer.proxyprotocol.version`"
|
||||
|
||||
See [PROXY protocol](../services/index.md#proxy-protocol) for more information.
|
||||
|
||||
```yaml
|
||||
- "traefik.tcp.services.mytcpservice.loadbalancer.proxyprotocol.version=1"
|
||||
```
|
||||
|
||||
### UDP
|
||||
|
||||
You can declare UDP Routers and/or Services using labels.
|
||||
|
@@ -235,7 +235,7 @@ The table below lists all the available matchers:
|
||||
| ```Host(`example.com`, ...)``` | Check if the request domain (host header value) targets one of the given `domains`. |
|
||||
| ```HostHeader(`example.com`, ...)``` | Check if the request domain (host header value) targets one of the given `domains`. |
|
||||
| ```HostRegexp(`example.com`, `{subdomain:[a-z]+}.example.com`, ...)``` | Check if the request domain matches the given `regexp`. |
|
||||
| ```Method(`GET`, ...)``` | Check if the request method is one of the given `methods` (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`) |
|
||||
| ```Method(`GET`, ...)``` | Check if the request method is one of the given `methods` (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`, `HEAD`) |
|
||||
| ```Path(`/path`, `/articles/{cat:[a-z]+}/{id:[0-9]+}`, ...)``` | Match exact request path. It accepts a sequence of literal and regular expression paths. |
|
||||
| ```PathPrefix(`/products/`, `/articles/{cat:[a-z]+}/{id:[0-9]+}`)``` | Match request prefix path. It accepts a sequence of literal and regular expression prefix paths. |
|
||||
| ```Query(`foo=bar`, `bar=baz`)``` | Match Query String parameters. It accepts a sequence of key=value pairs. |
|
||||
|
@@ -332,7 +332,7 @@ Below are the available options for the health check mechanism:
|
||||
!!! info "Recovering Servers"
|
||||
|
||||
Traefik keeps monitoring the health of unhealthy servers.
|
||||
If a server has recovered (returning `2xx` -> `3xx` responses again), it will be added back to the load balacer rotation pool.
|
||||
If a server has recovered (returning `2xx` -> `3xx` responses again), it will be added back to the load balancer rotation pool.
|
||||
|
||||
!!! warning "Health check in Kubernetes"
|
||||
|
||||
@@ -460,6 +460,33 @@ By default, `passHostHeader` is true.
|
||||
passHostHeader: false
|
||||
```
|
||||
|
||||
#### ServersTransport
|
||||
|
||||
`serversTransport` allows to reference a [ServersTransport](./index.md#serverstransport_1) configuration for the communication between Traefik and your servers.
|
||||
|
||||
??? example "Specify a transport -- Using the [File Provider](../../providers/file.md)"
|
||||
|
||||
```toml tab="TOML"
|
||||
## Dynamic configuration
|
||||
[http.services]
|
||||
[http.services.Service01]
|
||||
[http.services.Service01.loadBalancer]
|
||||
serversTransport = "mytransport"
|
||||
```
|
||||
|
||||
```yaml tab="YAML"
|
||||
## Dynamic configuration
|
||||
http:
|
||||
services:
|
||||
Service01:
|
||||
loadBalancer:
|
||||
serversTransport: mytransport
|
||||
```
|
||||
|
||||
!!! info default serversTransport
|
||||
If no serversTransport is specified, the `default@internal` will be used.
|
||||
The `default@internal` serversTransport is created from the [static configuration](../overview.md#transport-configuration).
|
||||
|
||||
#### Response Forwarding
|
||||
|
||||
This section is about configuring how Traefik forwards the response from the backend server to the client.
|
||||
@@ -492,6 +519,301 @@ Below are the available options for the Response Forwarding mechanism:
|
||||
flushInterval: 1s
|
||||
```
|
||||
|
||||
### ServersTransport
|
||||
|
||||
ServersTransport allows to configure the transport between Traefik and your servers.
|
||||
|
||||
#### `ServerName`
|
||||
|
||||
_Optional_
|
||||
|
||||
`serverName` configure the server name that will be used for SNI.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
## Dynamic configuration
|
||||
[http.serversTransports.mytransport]
|
||||
serverName = "myhost"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
## Dynamic configuration
|
||||
http:
|
||||
serversTransports:
|
||||
mytransport:
|
||||
serverName: "myhost"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: ServersTransport
|
||||
metadata:
|
||||
name: mytransport
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
serverName: "test"
|
||||
```
|
||||
|
||||
#### `Certificates`
|
||||
|
||||
_Optional_
|
||||
|
||||
`certificates` is the list of certificates (as file paths, or data bytes)
|
||||
that will be set as client certificates for mTLS.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
## Dynamic configuration
|
||||
[[http.serversTransports.mytransport.certificates]]
|
||||
certFile = "foo.crt"
|
||||
keyFile = "bar.crt"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
## Dynamic configuration
|
||||
http:
|
||||
serversTransports:
|
||||
mytransport:
|
||||
certificates:
|
||||
- certFile: foo.crt
|
||||
keyFile: bar.crt
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: ServersTransport
|
||||
metadata:
|
||||
name: mytransport
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
certificatesSecrets:
|
||||
- mycert
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: mycert
|
||||
|
||||
data:
|
||||
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
|
||||
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
|
||||
```
|
||||
|
||||
#### `insecureSkipVerify`
|
||||
|
||||
_Optional_
|
||||
|
||||
`insecureSkipVerify` disables SSL certificate verification.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
## Dynamic configuration
|
||||
[http.serversTransports.mytransport]
|
||||
insecureSkipVerify = true
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
## Dynamic configuration
|
||||
http:
|
||||
serversTransports:
|
||||
mytransport:
|
||||
insecureSkipVerify: true
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: ServersTransport
|
||||
metadata:
|
||||
name: mytransport
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
insecureSkipVerify: true
|
||||
```
|
||||
|
||||
#### `rootCAs`
|
||||
|
||||
_Optional_
|
||||
|
||||
`rootCAs` is the list of certificates (as file paths, or data bytes)
|
||||
that will be set as Root Certificate Authorities when using a self-signed TLS certificate.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
## Dynamic configuration
|
||||
[http.serversTransports.mytransport]
|
||||
rootCAs = ["foo.crt", "bar.crt"]
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
## Dynamic configuration
|
||||
http:
|
||||
serversTransports:
|
||||
mytransport:
|
||||
rootCAs:
|
||||
- foo.crt
|
||||
- bar.crt
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: ServersTransport
|
||||
metadata:
|
||||
name: mytransport
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
rootCAsSecrets:
|
||||
- myca
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: myca
|
||||
|
||||
data:
|
||||
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
|
||||
```
|
||||
|
||||
#### `maxIdleConnsPerHost`
|
||||
|
||||
_Optional, Default=2_
|
||||
|
||||
If non-zero, `maxIdleConnsPerHost` controls the maximum idle (keep-alive) connections to keep per-host.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
## Dynamic configuration
|
||||
[http.serversTransports.mytransport]
|
||||
maxIdleConnsPerHost = 7
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
## Dynamic configuration
|
||||
http:
|
||||
serversTransports:
|
||||
mytransport:
|
||||
maxIdleConnsPerHost: 7
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: ServersTransport
|
||||
metadata:
|
||||
name: mytransport
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
maxIdleConnsPerHost: 7
|
||||
```
|
||||
|
||||
#### `forwardingTimeouts`
|
||||
|
||||
`forwardingTimeouts` is about a number of timeouts relevant to when forwarding requests to the backend servers.
|
||||
|
||||
##### `forwardingTimeouts.dialTimeout`
|
||||
|
||||
_Optional, Default=30s_
|
||||
|
||||
`dialTimeout` is the maximum duration allowed for a connection to a backend server to be established.
|
||||
Zero means no timeout.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
## Dynamic configuration
|
||||
[http.serversTransports.mytransport.forwardingTimeouts]
|
||||
dialTimeout = "1s"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
## Dynamic configuration
|
||||
http:
|
||||
serversTransports:
|
||||
mytransport:
|
||||
forwardingTimeouts:
|
||||
dialTimeout: "1s"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: ServersTransport
|
||||
metadata:
|
||||
name: mytransport
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
forwardingTimeouts:
|
||||
dialTimeout: "1s"
|
||||
```
|
||||
|
||||
##### `forwardingTimeouts.responseHeaderTimeout`
|
||||
|
||||
_Optional, Default=0s_
|
||||
|
||||
`responseHeaderTimeout`, if non-zero, specifies the amount of time to wait for a server's response headers
|
||||
after fully writing the request (including its body, if any).
|
||||
This time does not include the time to read the response body.
|
||||
Zero means no timeout.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
## Dynamic configuration
|
||||
[http.serversTransports.mytransport.forwardingTimeouts]
|
||||
responseHeaderTimeout = "1s"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
## Dynamic configuration
|
||||
http:
|
||||
serversTransports:
|
||||
mytransport:
|
||||
forwardingTimeouts:
|
||||
responseHeaderTimeout: "1s"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: ServersTransport
|
||||
metadata:
|
||||
name: mytransport
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
forwardingTimeouts:
|
||||
responseHeaderTimeout: "1s"
|
||||
```
|
||||
|
||||
##### `forwardingTimeouts.idleConnTimeout`
|
||||
|
||||
_Optional, Default=90s_
|
||||
|
||||
`idleConnTimeout`, is the maximum amount of time an idle (keep-alive) connection
|
||||
will remain idle before closing itself.
|
||||
Zero means no limit.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
## Dynamic configuration
|
||||
[http.serversTransports.mytransport.forwardingTimeouts]
|
||||
idleConnTimeout = "1s"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
## Dynamic configuration
|
||||
http:
|
||||
serversTransports:
|
||||
mytransport:
|
||||
forwardingTimeouts:
|
||||
idleConnTimeout: "1s"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: ServersTransport
|
||||
metadata:
|
||||
name: mytransport
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
forwardingTimeouts:
|
||||
idleConnTimeout: "1s"
|
||||
```
|
||||
|
||||
### Weighted Round Robin (service)
|
||||
|
||||
The WRR is able to load balance the requests between multiple services based on weights.
|
||||
@@ -669,6 +991,39 @@ The `address` option (IP:Port) point to a specific instance.
|
||||
- address: "xx.xx.xx.xx:xx"
|
||||
```
|
||||
|
||||
#### PROXY Protocol
|
||||
|
||||
Traefik supports [PROXY Protocol](https://www.haproxy.org/download/2.0/doc/proxy-protocol.txt) version 1 and 2 on TCP Services.
|
||||
It can be enabled by setting `proxyProtocol` on the load balancer.
|
||||
|
||||
Below are the available options for the PROXY protocol:
|
||||
|
||||
- `version` specifies the version of the protocol to be used. Either `1` or `2`.
|
||||
|
||||
!!! info "Version"
|
||||
|
||||
Specifying a version is optional. By default the version 2 will be used.
|
||||
|
||||
??? example "A Service with Proxy Protocol v1 -- Using the [File Provider](../../providers/file.md)"
|
||||
|
||||
```toml tab="TOML"
|
||||
## Dynamic configuration
|
||||
[tcp.services]
|
||||
[tcp.services.my-service.loadBalancer]
|
||||
[tcp.services.my-service.loadBalancer.proxyProtocol]
|
||||
version = 1
|
||||
```
|
||||
|
||||
```yaml tab="YAML"
|
||||
## Dynamic configuration
|
||||
tcp:
|
||||
services:
|
||||
my-service:
|
||||
loadBalancer:
|
||||
proxyProtocol:
|
||||
version: 1
|
||||
```
|
||||
|
||||
#### Termination Delay
|
||||
|
||||
As a proxy between a client and a server, it can happen that either side (e.g. client side) decides to terminate its writing capability on the connection (i.e. issuance of a FIN packet).
|
||||
|
@@ -26,7 +26,7 @@ spec:
|
||||
serviceAccountName: traefik-ingress-controller
|
||||
containers:
|
||||
- name: traefik
|
||||
image: traefik:v2.3
|
||||
image: traefik:v2.4
|
||||
args:
|
||||
- --api.insecure
|
||||
- --accesslog
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user