Merge pull request #701 from containous/carry-pr-446
Carry PR 446 - Add sticky session support (round two!)
This commit is contained in:
commit
38b62d4ae3
12 changed files with 116 additions and 48 deletions
|
@ -222,6 +222,17 @@ For example:
|
||||||
- Another possible value for `extractorfunc` is `client.ip` which will categorize requests based on client source ip.
|
- Another possible value for `extractorfunc` is `client.ip` which will categorize requests based on client source ip.
|
||||||
- Lastly `extractorfunc` can take the value of `request.header.ANY_HEADER` which will categorize requests based on `ANY_HEADER` that you provide.
|
- Lastly `extractorfunc` can take the value of `request.header.ANY_HEADER` which will categorize requests based on `ANY_HEADER` that you provide.
|
||||||
|
|
||||||
|
Sticky sessions are supported with both load balancers. When sticky sessions are enabled, a cookie called `_TRAEFIK_BACKEND` is set on the initial
|
||||||
|
request. On subsequent requests, the client will be directed to the backend stored in the cookie if it is still healthy. If not, a new backend
|
||||||
|
will be assigned.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
```toml
|
||||||
|
[backends]
|
||||||
|
[backends.backend1]
|
||||||
|
[backends.backend1.loadbalancer]
|
||||||
|
sticky = true
|
||||||
|
```
|
||||||
## Servers
|
## Servers
|
||||||
|
|
||||||
Servers are simply defined using a `URL`. You can also apply a custom `weight` to each server (this will be used by load-balancing).
|
Servers are simply defined using a `URL`. You can also apply a custom `weight` to each server (this will be used by load-balancing).
|
||||||
|
|
|
@ -711,6 +711,7 @@ Labels can be used on containers to override default behaviour:
|
||||||
- `traefik.backend.maxconn.amount=10`: set a maximum number of connections to the backend. Must be used in conjunction with the below label to take effect.
|
- `traefik.backend.maxconn.amount=10`: set a maximum number of connections to the backend. Must be used in conjunction with the below label to take effect.
|
||||||
- `traefik.backend.maxconn.extractorfunc=client.ip`: set the function to be used against the request to determine what to limit maximum connections to the backend by. Must be used in conjunction with the above label to take effect.
|
- `traefik.backend.maxconn.extractorfunc=client.ip`: set the function to be used against the request to determine what to limit maximum connections to the backend by. Must be used in conjunction with the above label to take effect.
|
||||||
- `traefik.backend.loadbalancer.method=drr`: override the default `wrr` load balancer algorithm
|
- `traefik.backend.loadbalancer.method=drr`: override the default `wrr` load balancer algorithm
|
||||||
|
- `traefik.backend.loadbalancer.sticky=true`: enable backend sticky sessions
|
||||||
- `traefik.backend.circuitbreaker.expression=NetworkErrorRatio() > 0.5`: create a [circuit breaker](/basics/#backends) to be used against the backend
|
- `traefik.backend.circuitbreaker.expression=NetworkErrorRatio() > 0.5`: create a [circuit breaker](/basics/#backends) to be used against the backend
|
||||||
- `traefik.port=80`: register this port. Useful when the container exposes multiples ports.
|
- `traefik.port=80`: register this port. Useful when the container exposes multiples ports.
|
||||||
- `traefik.protocol=https`: override the default `http` protocol
|
- `traefik.protocol=https`: override the default `http` protocol
|
||||||
|
@ -810,6 +811,7 @@ Labels can be used on containers to override default behaviour:
|
||||||
- `traefik.backend.maxconn.amount=10`: set a maximum number of connections to the backend. Must be used in conjunction with the below label to take effect.
|
- `traefik.backend.maxconn.amount=10`: set a maximum number of connections to the backend. Must be used in conjunction with the below label to take effect.
|
||||||
- `traefik.backend.maxconn.extractorfunc=client.ip`: set the function to be used against the request to determine what to limit maximum connections to the backend by. Must be used in conjunction with the above label to take effect.
|
- `traefik.backend.maxconn.extractorfunc=client.ip`: set the function to be used against the request to determine what to limit maximum connections to the backend by. Must be used in conjunction with the above label to take effect.
|
||||||
- `traefik.backend.loadbalancer.method=drr`: override the default `wrr` load balancer algorithm
|
- `traefik.backend.loadbalancer.method=drr`: override the default `wrr` load balancer algorithm
|
||||||
|
- `traefik.backend.loadbalancer.sticky=true`: enable backend sticky sessions
|
||||||
- `traefik.backend.circuitbreaker.expression=NetworkErrorRatio() > 0.5`: create a [circuit breaker](/basics/#backends) to be used against the backend
|
- `traefik.backend.circuitbreaker.expression=NetworkErrorRatio() > 0.5`: create a [circuit breaker](/basics/#backends) to be used against the backend
|
||||||
- `traefik.portIndex=1`: register port by index in the application's ports array. Useful when the application exposes multiple ports.
|
- `traefik.portIndex=1`: register port by index in the application's ports array. Useful when the application exposes multiple ports.
|
||||||
- `traefik.port=80`: register the explicit application port value. Cannot be used alongside `traefik.portIndex`.
|
- `traefik.port=80`: register the explicit application port value. Cannot be used alongside `traefik.portIndex`.
|
||||||
|
|
59
glide.lock
generated
59
glide.lock
generated
|
@ -1,10 +1,10 @@
|
||||||
hash: c0ac205a859d78847e21d3cd63f427ffba985755c6ae84373e4a20364ba39b05
|
hash: c0ac205a859d78847e21d3cd63f427ffba985755c6ae84373e4a20364ba39b05
|
||||||
updated: 2016-09-28T16:50:04.352639437+01:00
|
updated: 2016-09-30T10:57:42.336729457+02:00
|
||||||
imports:
|
imports:
|
||||||
- name: github.com/abbot/go-http-auth
|
- name: github.com/abbot/go-http-auth
|
||||||
version: cb4372376e1e00e9f6ab9ec142e029302c9e7140
|
version: cb4372376e1e00e9f6ab9ec142e029302c9e7140
|
||||||
- name: github.com/boltdb/bolt
|
- name: github.com/boltdb/bolt
|
||||||
version: fff57c100f4dea1905678da7e90d92429dff2904
|
version: 5cc10bbbc5c141029940133bb33c9e969512a698
|
||||||
- name: github.com/BurntSushi/toml
|
- name: github.com/BurntSushi/toml
|
||||||
version: 99064174e013895bbd9b025c31100bd1d9b590ca
|
version: 99064174e013895bbd9b025c31100bd1d9b590ca
|
||||||
- name: github.com/BurntSushi/ty
|
- name: github.com/BurntSushi/ty
|
||||||
|
@ -18,7 +18,7 @@ imports:
|
||||||
- name: github.com/codegangsta/cli
|
- name: github.com/codegangsta/cli
|
||||||
version: 1efa31f08b9333f1bd4882d61f9d668a70cd902e
|
version: 1efa31f08b9333f1bd4882d61f9d668a70cd902e
|
||||||
- name: github.com/codegangsta/negroni
|
- name: github.com/codegangsta/negroni
|
||||||
version: 3f7ce7b928e14ff890b067e5bbbc80af73690a9c
|
version: dc6b9d037e8dab60cbfc09c61d6932537829be8b
|
||||||
- name: github.com/containous/flaeg
|
- name: github.com/containous/flaeg
|
||||||
version: a731c034dda967333efce5f8d276aeff11f8ff87
|
version: a731c034dda967333efce5f8d276aeff11f8ff87
|
||||||
- name: github.com/containous/mux
|
- name: github.com/containous/mux
|
||||||
|
@ -32,11 +32,11 @@ imports:
|
||||||
- pkg/pathutil
|
- pkg/pathutil
|
||||||
- pkg/types
|
- pkg/types
|
||||||
- name: github.com/davecgh/go-spew
|
- name: github.com/davecgh/go-spew
|
||||||
version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9
|
version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
|
||||||
subpackages:
|
subpackages:
|
||||||
- spew
|
- spew
|
||||||
- name: github.com/docker/distribution
|
- name: github.com/docker/distribution
|
||||||
version: 99cb7c0946d2f5a38015443e515dc916295064d7
|
version: 87917f30529e6a7fca8eaff2932424915fb11225
|
||||||
subpackages:
|
subpackages:
|
||||||
- context
|
- context
|
||||||
- digest
|
- digest
|
||||||
|
@ -116,13 +116,13 @@ imports:
|
||||||
- types/time
|
- types/time
|
||||||
- types/versions
|
- types/versions
|
||||||
- name: github.com/docker/go-connections
|
- name: github.com/docker/go-connections
|
||||||
version: 988efe982fdecb46f01d53465878ff1f2ff411ce
|
version: 990a1a1a70b0da4c4cb70e117971a4f0babfbf1a
|
||||||
subpackages:
|
subpackages:
|
||||||
- nat
|
- nat
|
||||||
- sockets
|
- sockets
|
||||||
- tlsconfig
|
- tlsconfig
|
||||||
- name: github.com/docker/go-units
|
- name: github.com/docker/go-units
|
||||||
version: f2145db703495b2e525c59662db69a7344b00bb8
|
version: f2d77a61e3c169b43402a0a1e84f06daf29b8190
|
||||||
- name: github.com/docker/libcompose
|
- name: github.com/docker/libcompose
|
||||||
version: d1876c1d68527a49c0aac22a0b161acc7296b740
|
version: d1876c1d68527a49c0aac22a0b161acc7296b740
|
||||||
subpackages:
|
subpackages:
|
||||||
|
@ -141,7 +141,7 @@ imports:
|
||||||
- version
|
- version
|
||||||
- yaml
|
- yaml
|
||||||
- name: github.com/docker/libkv
|
- name: github.com/docker/libkv
|
||||||
version: 3fce6a0f26e07da3eac45796a8e255547a47a750
|
version: 35d3e2084c650109e7bcc7282655b1bc8ba924ff
|
||||||
subpackages:
|
subpackages:
|
||||||
- store
|
- store
|
||||||
- store/boltdb
|
- store/boltdb
|
||||||
|
@ -151,13 +151,13 @@ imports:
|
||||||
- name: github.com/donovanhide/eventsource
|
- name: github.com/donovanhide/eventsource
|
||||||
version: fd1de70867126402be23c306e1ce32828455d85b
|
version: fd1de70867126402be23c306e1ce32828455d85b
|
||||||
- name: github.com/elazarl/go-bindata-assetfs
|
- name: github.com/elazarl/go-bindata-assetfs
|
||||||
version: 9a6736ed45b44bf3835afeebb3034b57ed329f3e
|
version: 57eb5e1fc594ad4b0b1dbea7b286d299e0cb43c2
|
||||||
- name: github.com/gambol99/go-marathon
|
- name: github.com/gambol99/go-marathon
|
||||||
version: a558128c87724cd7430060ef5aedf39f83937f55
|
version: a558128c87724cd7430060ef5aedf39f83937f55
|
||||||
- name: github.com/go-check/check
|
- name: github.com/go-check/check
|
||||||
version: 11d3bc7aa68e238947792f30573146a3231fc0f1
|
version: 4f90aeace3a26ad7021961c297b22c42160c7b25
|
||||||
- name: github.com/gogo/protobuf
|
- name: github.com/gogo/protobuf
|
||||||
version: 89f1976ff373a3e549675d2f212c10f98b6c6316
|
version: e33835a643a970c11ac74f6333f5f6866387a101
|
||||||
subpackages:
|
subpackages:
|
||||||
- proto
|
- proto
|
||||||
- name: github.com/golang/glog
|
- name: github.com/golang/glog
|
||||||
|
@ -167,17 +167,18 @@ imports:
|
||||||
subpackages:
|
subpackages:
|
||||||
- query
|
- query
|
||||||
- name: github.com/gorilla/context
|
- name: github.com/gorilla/context
|
||||||
version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42
|
version: aed02d124ae4a0e94fea4541c8effd05bf0c8296
|
||||||
- name: github.com/hashicorp/consul
|
- name: github.com/hashicorp/consul
|
||||||
version: d5b7530ec593f1ec2a8f8a7c145bcadafa88b572
|
version: fce7d75609a04eeb9d4bf41c8dc592aac18fc97d
|
||||||
subpackages:
|
subpackages:
|
||||||
- api
|
- api
|
||||||
- name: github.com/hashicorp/go-cleanhttp
|
- name: github.com/hashicorp/go-cleanhttp
|
||||||
version: ad28ea4487f05916463e2423a55166280e8254b5
|
version: 875fb671b3ddc66f8e2f0acc33829c8cb989a38d
|
||||||
- name: github.com/hashicorp/serf
|
- name: github.com/hashicorp/serf
|
||||||
version: b7a120a5fc494f6dd5e858f42fd0fd4022d6320f
|
version: 6c4672d66fc6312ddde18399262943e21175d831
|
||||||
subpackages:
|
subpackages:
|
||||||
- coordinate
|
- coordinate
|
||||||
|
- serf
|
||||||
- name: github.com/jarcoal/httpmock
|
- name: github.com/jarcoal/httpmock
|
||||||
version: 145b10d659265440f062c31ea15326166bae56ee
|
version: 145b10d659265440f062c31ea15326166bae56ee
|
||||||
- name: github.com/libkermit/compose
|
- name: github.com/libkermit/compose
|
||||||
|
@ -219,7 +220,7 @@ imports:
|
||||||
- name: github.com/miekg/dns
|
- name: github.com/miekg/dns
|
||||||
version: 5d001d020961ae1c184f9f8152fdc73810481677
|
version: 5d001d020961ae1c184f9f8152fdc73810481677
|
||||||
- name: github.com/mitchellh/mapstructure
|
- name: github.com/mitchellh/mapstructure
|
||||||
version: ca63d7c062ee3c9f34db231e352b60012b4fd0c1
|
version: d2dd0262208475919e1a362f675cfc0e7c10e905
|
||||||
- name: github.com/moul/http2curl
|
- name: github.com/moul/http2curl
|
||||||
version: b1479103caacaa39319f75e7f57fc545287fca0d
|
version: b1479103caacaa39319f75e7f57fc545287fca0d
|
||||||
- name: github.com/NYTimes/gziphandler
|
- name: github.com/NYTimes/gziphandler
|
||||||
|
@ -227,11 +228,11 @@ imports:
|
||||||
- name: github.com/ogier/pflag
|
- name: github.com/ogier/pflag
|
||||||
version: 45c278ab3607870051a2ea9040bb85fcb8557481
|
version: 45c278ab3607870051a2ea9040bb85fcb8557481
|
||||||
- name: github.com/opencontainers/runc
|
- name: github.com/opencontainers/runc
|
||||||
version: d9fec4c63b089ddfc267194ecb6cda58a13f072c
|
version: 1a81e9ab1f138c091fe5c86d0883f87716088527
|
||||||
subpackages:
|
subpackages:
|
||||||
- libcontainer/user
|
- libcontainer/user
|
||||||
- name: github.com/parnurzeal/gorequest
|
- name: github.com/parnurzeal/gorequest
|
||||||
version: 29ced6f360a5ac3823a3675b4e29fbab336cc186
|
version: 045012d33ef41ea146c1b675df9296d0dc1a212d
|
||||||
- name: github.com/pmezard/go-difflib
|
- name: github.com/pmezard/go-difflib
|
||||||
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
|
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
|
||||||
subpackages:
|
subpackages:
|
||||||
|
@ -239,22 +240,22 @@ imports:
|
||||||
- name: github.com/ryanuber/go-glob
|
- name: github.com/ryanuber/go-glob
|
||||||
version: 572520ed46dbddaed19ea3d9541bdd0494163693
|
version: 572520ed46dbddaed19ea3d9541bdd0494163693
|
||||||
- name: github.com/samuel/go-zookeeper
|
- name: github.com/samuel/go-zookeeper
|
||||||
version: 87e1bca4477a3cc767ca71be023ced183d74e538
|
version: e64db453f3512cade908163702045e0f31137843
|
||||||
subpackages:
|
subpackages:
|
||||||
- zk
|
- zk
|
||||||
- name: github.com/Sirupsen/logrus
|
- name: github.com/Sirupsen/logrus
|
||||||
version: 3ec0642a7fb6488f65b06f9040adc67e3990296a
|
version: a283a10442df8dc09befd873fab202bf8a253d6a
|
||||||
- name: github.com/streamrail/concurrent-map
|
- name: github.com/streamrail/concurrent-map
|
||||||
version: 8bf1e9bacbf65b10c81d0f4314cf2b1ebef728b5
|
version: 65a174a3a4188c0b7099acbc6cfa0c53628d3287
|
||||||
- name: github.com/stretchr/objx
|
- name: github.com/stretchr/objx
|
||||||
version: cbeaeb16a013161a98496fad62933b1d21786672
|
version: cbeaeb16a013161a98496fad62933b1d21786672
|
||||||
- name: github.com/stretchr/testify
|
- name: github.com/stretchr/testify
|
||||||
version: 976c720a22c8eb4eb6a0b4348ad85ad12491a506
|
version: d77da356e56a7428ad25149ca77381849a6a5232
|
||||||
subpackages:
|
subpackages:
|
||||||
- assert
|
- assert
|
||||||
- mock
|
- mock
|
||||||
- name: github.com/thoas/stats
|
- name: github.com/thoas/stats
|
||||||
version: 152b5d051953fdb6e45f14b6826962aadc032324
|
version: 79b768ff1780f4e5b0ed132e192bfeefe9f85a9c
|
||||||
- name: github.com/tv42/zbase32
|
- name: github.com/tv42/zbase32
|
||||||
version: 03389da7e0bf9844767f82690f4d68fc097a1306
|
version: 03389da7e0bf9844767f82690f4d68fc097a1306
|
||||||
- name: github.com/ugorji/go
|
- name: github.com/ugorji/go
|
||||||
|
@ -262,7 +263,7 @@ imports:
|
||||||
subpackages:
|
subpackages:
|
||||||
- codec
|
- codec
|
||||||
- name: github.com/unrolled/render
|
- name: github.com/unrolled/render
|
||||||
version: 3f4913244021dede105b62caecfb01f0c1eebeda
|
version: 198ad4d8b8a4612176b804ca10555b222a086b40
|
||||||
- name: github.com/vdemeester/docker-events
|
- name: github.com/vdemeester/docker-events
|
||||||
version: be74d4929ec1ad118df54349fda4b0cba60f849b
|
version: be74d4929ec1ad118df54349fda4b0cba60f849b
|
||||||
- name: github.com/vdemeester/shakers
|
- name: github.com/vdemeester/shakers
|
||||||
|
@ -284,7 +285,7 @@ imports:
|
||||||
- name: github.com/vulcand/route
|
- name: github.com/vulcand/route
|
||||||
version: cb89d787ddbb1c5849a7ac9f79004c1fd12a4a32
|
version: cb89d787ddbb1c5849a7ac9f79004c1fd12a4a32
|
||||||
- name: github.com/vulcand/vulcand
|
- name: github.com/vulcand/vulcand
|
||||||
version: 643ca8acff8386e3b276f6feb8ba9b5893dbc4a2
|
version: 28a4e5c0892167589737b95ceecbcef00295be50
|
||||||
subpackages:
|
subpackages:
|
||||||
- conntracker
|
- conntracker
|
||||||
- plugin
|
- plugin
|
||||||
|
@ -314,11 +315,11 @@ imports:
|
||||||
- name: gopkg.in/fsnotify.v1
|
- name: gopkg.in/fsnotify.v1
|
||||||
version: a8a77c9133d2d6fd8334f3260d06f60e8d80a5fb
|
version: a8a77c9133d2d6fd8334f3260d06f60e8d80a5fb
|
||||||
- name: gopkg.in/mgo.v2
|
- name: gopkg.in/mgo.v2
|
||||||
version: 22287bab4379e1fbf6002fb4eb769888f3fb224c
|
version: 29cc868a5ca65f401ff318143f9408d02f4799cc
|
||||||
subpackages:
|
subpackages:
|
||||||
- bson
|
- bson
|
||||||
- name: gopkg.in/square/go-jose.v1
|
- name: gopkg.in/square/go-jose.v1
|
||||||
version: aa2e30fdd1fe9dd3394119af66451ae790d50e0d
|
version: e3f973b66b91445ec816dd7411ad1b6495a5a2fc
|
||||||
subpackages:
|
subpackages:
|
||||||
- cipher
|
- cipher
|
||||||
- json
|
- json
|
||||||
|
@ -336,9 +337,9 @@ testImports:
|
||||||
- name: github.com/libkermit/docker-check
|
- name: github.com/libkermit/docker-check
|
||||||
version: cbe0ef03b3d23070eac4d00ba8828f2cc7f7e5a3
|
version: cbe0ef03b3d23070eac4d00ba8828f2cc7f7e5a3
|
||||||
- name: github.com/spf13/pflag
|
- name: github.com/spf13/pflag
|
||||||
version: 08b1a584251b5b62f458943640fc8ebd4d50aaa5
|
version: 5644820622454e71517561946e3d94b9f9db6842
|
||||||
- name: github.com/vbatts/tar-split
|
- name: github.com/vbatts/tar-split
|
||||||
version: bd4c5d64c3e9297f410025a3b1bd0c58f659e721
|
version: 6810cedb21b2c3d0b9bb8f9af12ff2dc7a2f14df
|
||||||
subpackages:
|
subpackages:
|
||||||
- archive/tar
|
- archive/tar
|
||||||
- tar/asm
|
- tar/asm
|
||||||
|
|
|
@ -252,6 +252,7 @@ func (provider *Docker) loadDockerConfig(containersInspected []dockerData) *type
|
||||||
"hasMaxConnLabels": provider.hasMaxConnLabels,
|
"hasMaxConnLabels": provider.hasMaxConnLabels,
|
||||||
"getMaxConnAmount": provider.getMaxConnAmount,
|
"getMaxConnAmount": provider.getMaxConnAmount,
|
||||||
"getMaxConnExtractorFunc": provider.getMaxConnExtractorFunc,
|
"getMaxConnExtractorFunc": provider.getMaxConnExtractorFunc,
|
||||||
|
"getSticky": provider.getSticky,
|
||||||
"replace": replace,
|
"replace": replace,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,18 +262,27 @@ func (provider *Docker) loadDockerConfig(containersInspected []dockerData) *type
|
||||||
}, containersInspected).([]dockerData)
|
}, containersInspected).([]dockerData)
|
||||||
|
|
||||||
frontends := map[string][]dockerData{}
|
frontends := map[string][]dockerData{}
|
||||||
|
backends := map[string]dockerData{}
|
||||||
|
servers := map[string][]dockerData{}
|
||||||
for _, container := range filteredContainers {
|
for _, container := range filteredContainers {
|
||||||
frontendName := provider.getFrontendName(container)
|
frontendName := provider.getFrontendName(container)
|
||||||
frontends[frontendName] = append(frontends[frontendName], container)
|
frontends[frontendName] = append(frontends[frontendName], container)
|
||||||
|
backendName := provider.getBackend(container)
|
||||||
|
backends[backendName] = container
|
||||||
|
servers[backendName] = append(servers[backendName], container)
|
||||||
}
|
}
|
||||||
|
|
||||||
templateObjects := struct {
|
templateObjects := struct {
|
||||||
Containers []dockerData
|
Containers []dockerData
|
||||||
Frontends map[string][]dockerData
|
Frontends map[string][]dockerData
|
||||||
|
Backends map[string]dockerData
|
||||||
|
Servers map[string][]dockerData
|
||||||
Domain string
|
Domain string
|
||||||
}{
|
}{
|
||||||
filteredContainers,
|
filteredContainers,
|
||||||
frontends,
|
frontends,
|
||||||
|
backends,
|
||||||
|
servers,
|
||||||
provider.Domain,
|
provider.Domain,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,7 +301,9 @@ func (provider *Docker) hasCircuitBreakerLabel(container dockerData) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider *Docker) hasLoadBalancerLabel(container dockerData) bool {
|
func (provider *Docker) hasLoadBalancerLabel(container dockerData) bool {
|
||||||
if _, err := getLabel(container, "traefik.backend.loadbalancer.method"); err != nil {
|
_, errMethod := getLabel(container, "traefik.backend.loadbalancer.method")
|
||||||
|
_, errSticky := getLabel(container, "traefik.backend.loadbalancer.sticky")
|
||||||
|
if errMethod != nil && errSticky != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -439,6 +451,13 @@ func (provider *Docker) getWeight(container dockerData) string {
|
||||||
return "1"
|
return "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (provider *Docker) getSticky(container dockerData) string {
|
||||||
|
if _, err := getLabel(container, "traefik.backend.loadbalancer.sticky"); err == nil {
|
||||||
|
return "true"
|
||||||
|
}
|
||||||
|
return "false"
|
||||||
|
}
|
||||||
|
|
||||||
func (provider *Docker) getDomain(container dockerData) string {
|
func (provider *Docker) getDomain(container dockerData) string {
|
||||||
if label, err := getLabel(container, "traefik.domain"); err == nil {
|
if label, err := getLabel(container, "traefik.domain"); err == nil {
|
||||||
return label
|
return label
|
||||||
|
|
|
@ -940,7 +940,6 @@ func TestDockerLoadDockerConfig(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CircuitBreaker: nil,
|
CircuitBreaker: nil,
|
||||||
LoadBalancer: nil,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1027,7 +1026,6 @@ func TestDockerLoadDockerConfig(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CircuitBreaker: nil,
|
CircuitBreaker: nil,
|
||||||
LoadBalancer: nil,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -138,6 +138,7 @@ func (provider *Marathon) loadMarathonConfig() *types.Configuration {
|
||||||
"getMaxConnAmount": provider.getMaxConnAmount,
|
"getMaxConnAmount": provider.getMaxConnAmount,
|
||||||
"getLoadBalancerMethod": provider.getLoadBalancerMethod,
|
"getLoadBalancerMethod": provider.getLoadBalancerMethod,
|
||||||
"getCircuitBreakerExpression": provider.getCircuitBreakerExpression,
|
"getCircuitBreakerExpression": provider.getCircuitBreakerExpression,
|
||||||
|
"getSticky": provider.getSticky,
|
||||||
}
|
}
|
||||||
|
|
||||||
applications, err := provider.marathonClient.Applications(nil)
|
applications, err := provider.marathonClient.Applications(nil)
|
||||||
|
@ -347,6 +348,13 @@ func (provider *Marathon) getProtocol(task marathon.Task, applications []maratho
|
||||||
return "http"
|
return "http"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (provider *Marathon) getSticky(application marathon.Application) string {
|
||||||
|
if sticky, err := provider.getLabel(application, "traefik.backend.loadbalancer.sticky"); err == nil {
|
||||||
|
return sticky
|
||||||
|
}
|
||||||
|
return "false"
|
||||||
|
}
|
||||||
|
|
||||||
func (provider *Marathon) getPassHostHeader(application marathon.Application) string {
|
func (provider *Marathon) getPassHostHeader(application marathon.Application) string {
|
||||||
if passHostHeader, err := provider.getLabel(application, "traefik.frontend.passHostHeader"); err == nil {
|
if passHostHeader, err := provider.getLabel(application, "traefik.frontend.passHostHeader"); err == nil {
|
||||||
return passHostHeader
|
return passHostHeader
|
||||||
|
@ -411,7 +419,9 @@ func (provider *Marathon) hasCircuitBreakerLabels(application marathon.Applicati
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider *Marathon) hasLoadBalancerLabels(application marathon.Application) bool {
|
func (provider *Marathon) hasLoadBalancerLabels(application marathon.Application) bool {
|
||||||
if _, err := provider.getLabel(application, "traefik.backend.loadbalancer.method"); err != nil {
|
_, errMethod := provider.getLabel(application, "traefik.backend.loadbalancer.method")
|
||||||
|
_, errSticky := provider.getLabel(application, "traefik.backend.loadbalancer.sticky")
|
||||||
|
if errMethod != nil && errSticky != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -107,7 +107,6 @@ func TestMarathonLoadConfig(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CircuitBreaker: nil,
|
CircuitBreaker: nil,
|
||||||
LoadBalancer: nil,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
18
server.go
18
server.go
|
@ -537,16 +537,30 @@ func (server *Server) loadConfig(configurations configs, globalConfiguration Glo
|
||||||
log.Errorf("Skipping frontend %s...", frontendName)
|
log.Errorf("Skipping frontend %s...", frontendName)
|
||||||
continue frontend
|
continue frontend
|
||||||
}
|
}
|
||||||
|
|
||||||
lbMethod, err := types.NewLoadBalancerMethod(configuration.Backends[frontend.Backend].LoadBalancer)
|
lbMethod, err := types.NewLoadBalancerMethod(configuration.Backends[frontend.Backend].LoadBalancer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error loading load balancer method '%+v' for frontend %s: %v", configuration.Backends[frontend.Backend].LoadBalancer, frontendName, err)
|
log.Errorf("Error loading load balancer method '%+v' for frontend %s: %v", configuration.Backends[frontend.Backend].LoadBalancer, frontendName, err)
|
||||||
log.Errorf("Skipping frontend %s...", frontendName)
|
log.Errorf("Skipping frontend %s...", frontendName)
|
||||||
continue frontend
|
continue frontend
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stickysession := configuration.Backends[frontend.Backend].LoadBalancer.Sticky
|
||||||
|
cookiename := "_TRAEFIK_BACKEND"
|
||||||
|
var sticky *roundrobin.StickySession
|
||||||
|
|
||||||
|
if stickysession {
|
||||||
|
sticky = roundrobin.NewStickySession(cookiename)
|
||||||
|
}
|
||||||
|
|
||||||
switch lbMethod {
|
switch lbMethod {
|
||||||
case types.Drr:
|
case types.Drr:
|
||||||
log.Debugf("Creating load-balancer drr")
|
log.Debugf("Creating load-balancer drr")
|
||||||
rebalancer, _ := roundrobin.NewRebalancer(rr, roundrobin.RebalancerLogger(oxyLogger))
|
rebalancer, _ := roundrobin.NewRebalancer(rr, roundrobin.RebalancerLogger(oxyLogger))
|
||||||
|
if stickysession {
|
||||||
|
log.Debugf("Sticky session with cookie %v", cookiename)
|
||||||
|
rebalancer, _ = roundrobin.NewRebalancer(rr, roundrobin.RebalancerLogger(oxyLogger), roundrobin.RebalancerStickySession(sticky))
|
||||||
|
}
|
||||||
lb = rebalancer
|
lb = rebalancer
|
||||||
for serverName, server := range configuration.Backends[frontend.Backend].Servers {
|
for serverName, server := range configuration.Backends[frontend.Backend].Servers {
|
||||||
url, err := url.Parse(server.URL)
|
url, err := url.Parse(server.URL)
|
||||||
|
@ -565,6 +579,10 @@ func (server *Server) loadConfig(configurations configs, globalConfiguration Glo
|
||||||
}
|
}
|
||||||
case types.Wrr:
|
case types.Wrr:
|
||||||
log.Debugf("Creating load-balancer wrr")
|
log.Debugf("Creating load-balancer wrr")
|
||||||
|
if stickysession {
|
||||||
|
log.Debugf("Sticky session with cookie %v", cookiename)
|
||||||
|
rr, _ = roundrobin.New(saveBackend, roundrobin.EnableStickySession(sticky))
|
||||||
|
}
|
||||||
lb = rr
|
lb = rr
|
||||||
for serverName, server := range configuration.Backends[frontend.Backend].Servers {
|
for serverName, server := range configuration.Backends[frontend.Backend].Servers {
|
||||||
url, err := url.Parse(server.URL)
|
url, err := url.Parse(server.URL)
|
||||||
|
|
|
@ -1,23 +1,29 @@
|
||||||
[backends]{{range .Containers}}
|
{{$backendServers := .Servers}}
|
||||||
{{if hasCircuitBreakerLabel .}}
|
[backends]{{range $backendName, $backend := .Backends}}
|
||||||
[backends.backend-{{getBackend .}}.circuitbreaker]
|
{{if hasCircuitBreakerLabel $backend}}
|
||||||
expression = "{{getCircuitBreakerExpression .}}"
|
[backends.backend-{{$backendName}}.circuitbreaker]
|
||||||
|
expression = "{{getCircuitBreakerExpression $backend}}"
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if hasLoadBalancerLabel .}}
|
{{if hasLoadBalancerLabel $backend}}
|
||||||
[backends.backend-{{getBackend .}}.loadbalancer]
|
[backends.backend-{{$backendName}}.loadbalancer]
|
||||||
method = "{{getLoadBalancerMethod .}}"
|
method = "{{getLoadBalancerMethod $backend}}"
|
||||||
|
sticky = {{getSticky $backend}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if hasMaxConnLabels .}}
|
{{if hasMaxConnLabels $backend}}
|
||||||
[backends.backend-{{getBackend .}}.maxconn]
|
[backends.backend-{{$backendName}}.maxconn]
|
||||||
amount = {{getMaxConnAmount . }}
|
amount = {{getMaxConnAmount $backend}}
|
||||||
extractorfunc = "{{getMaxConnExtractorFunc . }}"
|
extractorfunc = "{{getMaxConnExtractorFunc $backend}}"
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{$servers := index $backendServers $backendName}}
|
||||||
|
{{range $serverName, $server := $servers}}
|
||||||
|
[backends.backend-{{$backendName}}.servers.server-{{$server.Name | replace "/" "" | replace "." "-"}}]
|
||||||
|
url = "{{getProtocol $server}}://{{getIPAddress $server}}:{{getPort $server}}"
|
||||||
|
weight = {{getWeight $server}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
[backends.backend-{{getBackend .}}.servers.server-{{.Name | replace "/" "" | replace "." "-"}}]
|
|
||||||
url = "{{getProtocol .}}://{{getIPAddress .}}:{{getPort .}}"
|
|
||||||
weight = {{getWeight .}}
|
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
[frontends]{{range $frontend, $containers := .Frontends}}
|
[frontends]{{range $frontend, $containers := .Frontends}}
|
||||||
|
|
|
@ -12,9 +12,11 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{$loadBalancer := Get "" . "/loadbalancer/" "method"}}
|
{{$loadBalancer := Get "" . "/loadbalancer/" "method"}}
|
||||||
|
{{$sticky := Get "false" . "/loadbalancer/" "sticky"}}
|
||||||
{{with $loadBalancer}}
|
{{with $loadBalancer}}
|
||||||
[backends."{{Last $backend}}".loadBalancer]
|
[backends."{{Last $backend}}".loadBalancer]
|
||||||
method = "{{$loadBalancer}}"
|
method = "{{$loadBalancer}}"
|
||||||
|
sticky = {{$sticky}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{$maxConnAmt := Get "" . "/maxconn/" "amount"}}
|
{{$maxConnAmt := Get "" . "/maxconn/" "amount"}}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
{{ if hasLoadBalancerLabels . }}
|
{{ if hasLoadBalancerLabels . }}
|
||||||
[backends.backend{{getFrontendBackend . }}.loadbalancer]
|
[backends.backend{{getFrontendBackend . }}.loadbalancer]
|
||||||
method = "{{getLoadBalancerMethod . }}"
|
method = "{{getLoadBalancerMethod . }}"
|
||||||
|
sticky = {{getSticky .}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{ if hasCircuitBreakerLabels . }}
|
{{ if hasCircuitBreakerLabels . }}
|
||||||
[backends.backend{{getFrontendBackend . }}.circuitbreaker]
|
[backends.backend{{getFrontendBackend . }}.circuitbreaker]
|
||||||
|
|
|
@ -24,6 +24,7 @@ type MaxConn struct {
|
||||||
// LoadBalancer holds load balancing configuration.
|
// LoadBalancer holds load balancing configuration.
|
||||||
type LoadBalancer struct {
|
type LoadBalancer struct {
|
||||||
Method string `json:"method,omitempty"`
|
Method string `json:"method,omitempty"`
|
||||||
|
Sticky bool `json:"sticky,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CircuitBreaker holds circuit breaker configuration.
|
// CircuitBreaker holds circuit breaker configuration.
|
||||||
|
|
Loading…
Reference in a new issue