Allow setting circuitbreaker expression via Kubernetes annotation (#1056)
This commit is contained in:
parent
b22dc213e8
commit
225dbcce0a
5 changed files with 30 additions and 5 deletions
|
@ -1068,6 +1068,10 @@ Annotations can be used on the Kubernetes service to override default behaviour:
|
||||||
|
|
||||||
You can find here an example [ingress](https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-ingress.yaml) and [replication controller](https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik.yaml).
|
You can find here an example [ingress](https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-ingress.yaml) and [replication controller](https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik.yaml).
|
||||||
|
|
||||||
|
Additionally, an annotation can be used on Kubernetes services to set the [circuit breaker expression](https://docs.traefik.io/basics/#backends) for a backend.
|
||||||
|
|
||||||
|
- `traefik.backend.circuitbreaker: <expression>`: set the circuit breaker expression for the backend (Default: nil).
|
||||||
|
|
||||||
## Consul backend
|
## Consul backend
|
||||||
|
|
||||||
Træfɪk can be configured to use Consul as a backend configuration:
|
Træfɪk can be configured to use Consul as a backend configuration:
|
||||||
|
|
|
@ -299,6 +299,8 @@ apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
metadata:
|
metadata:
|
||||||
name: wensleydale
|
name: wensleydale
|
||||||
|
annotations:
|
||||||
|
traefik.backend.circuitbreaker: "NetworkErrorRatio() > 0.5"
|
||||||
spec:
|
spec:
|
||||||
ports:
|
ports:
|
||||||
- name: http
|
- name: http
|
||||||
|
@ -308,6 +310,11 @@ spec:
|
||||||
app: cheese
|
app: cheese
|
||||||
task: wensleydale
|
task: wensleydale
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Notice that we also set a [circuit breaker expression](https://docs.traefik.io/basics/#backends) for one of the backends
|
||||||
|
> by setting the `traefik.backend.circuitbreaker` annotation on the service.
|
||||||
|
|
||||||
|
|
||||||
[examples/k8s/cheese-services.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheese-services.yaml)
|
[examples/k8s/cheese-services.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheese-services.yaml)
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|
|
@ -175,12 +175,18 @@ func (provider *Kubernetes) loadIngresses(k8sClient k8s.Client) (*types.Configur
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if expression := service.Annotations["traefik.backend.circuitbreaker"]; expression != "" {
|
||||||
|
templateObjects.Backends[r.Host+pa.Path].CircuitBreaker = &types.CircuitBreaker{
|
||||||
|
Expression: expression,
|
||||||
|
}
|
||||||
|
}
|
||||||
if service.Annotations["traefik.backend.loadbalancer.method"] == "drr" {
|
if service.Annotations["traefik.backend.loadbalancer.method"] == "drr" {
|
||||||
templateObjects.Backends[r.Host+pa.Path].LoadBalancer.Method = "drr"
|
templateObjects.Backends[r.Host+pa.Path].LoadBalancer.Method = "drr"
|
||||||
}
|
}
|
||||||
if service.Annotations["traefik.backend.loadbalancer.sticky"] == "true" {
|
if service.Annotations["traefik.backend.loadbalancer.sticky"] == "true" {
|
||||||
templateObjects.Backends[r.Host+pa.Path].LoadBalancer.Sticky = true
|
templateObjects.Backends[r.Host+pa.Path].LoadBalancer.Sticky = true
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol := "http"
|
protocol := "http"
|
||||||
for _, port := range service.Spec.Ports {
|
for _, port := range service.Spec.Ports {
|
||||||
if equalPorts(port, pa.Backend.ServicePort) {
|
if equalPorts(port, pa.Backend.ServicePort) {
|
||||||
|
|
|
@ -1288,7 +1288,7 @@ func TestHostlessIngress(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLoadBalancerAnnotation(t *testing.T) {
|
func TestServiceAnnotations(t *testing.T) {
|
||||||
ingresses := []*v1beta1.Ingress{{
|
ingresses := []*v1beta1.Ingress{{
|
||||||
ObjectMeta: v1.ObjectMeta{
|
ObjectMeta: v1.ObjectMeta{
|
||||||
Namespace: "testing",
|
Namespace: "testing",
|
||||||
|
@ -1336,6 +1336,7 @@ func TestLoadBalancerAnnotation(t *testing.T) {
|
||||||
UID: "1",
|
UID: "1",
|
||||||
Namespace: "testing",
|
Namespace: "testing",
|
||||||
Annotations: map[string]string{
|
Annotations: map[string]string{
|
||||||
|
"traefik.backend.circuitbreaker": "NetworkErrorRatio() > 0.5",
|
||||||
"traefik.backend.loadbalancer.method": "drr",
|
"traefik.backend.loadbalancer.method": "drr",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1354,6 +1355,7 @@ func TestLoadBalancerAnnotation(t *testing.T) {
|
||||||
UID: "2",
|
UID: "2",
|
||||||
Namespace: "testing",
|
Namespace: "testing",
|
||||||
Annotations: map[string]string{
|
Annotations: map[string]string{
|
||||||
|
"traefik.backend.circuitbreaker": "",
|
||||||
"traefik.backend.loadbalancer.sticky": "true",
|
"traefik.backend.loadbalancer.sticky": "true",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1463,7 +1465,9 @@ func TestLoadBalancerAnnotation(t *testing.T) {
|
||||||
Weight: 1,
|
Weight: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CircuitBreaker: nil,
|
CircuitBreaker: &types.CircuitBreaker{
|
||||||
|
Expression: "NetworkErrorRatio() > 0.5",
|
||||||
|
},
|
||||||
LoadBalancer: &types.LoadBalancer{
|
LoadBalancer: &types.LoadBalancer{
|
||||||
Method: "drr",
|
Method: "drr",
|
||||||
Sticky: false,
|
Sticky: false,
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
[backends]{{range $backendName, $backend := .Backends}}
|
[backends]{{range $backendName, $backend := .Backends}}
|
||||||
|
{{if $backend.CircuitBreaker}}
|
||||||
|
[backends."{{$backendName}}".circuitbreaker]
|
||||||
|
expression = "{{$backend.CircuitBreaker.Expression}}"
|
||||||
|
{{end}}
|
||||||
[backends."{{$backendName}}".loadbalancer]
|
[backends."{{$backendName}}".loadbalancer]
|
||||||
method = "{{$backend.LoadBalancer.Method}}"
|
method = "{{$backend.LoadBalancer.Method}}"
|
||||||
{{if $backend.LoadBalancer.Sticky}}
|
{{if $backend.LoadBalancer.Sticky}}
|
||||||
|
|
Loading…
Add table
Reference in a new issue