Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a k8s guide section on traffic splitting via service weights. #3556

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/configuration/backends/kubernetes.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@ Trying to do so leads to an error and the corresponding Ingress object being ign

<5> `traefik.ingress.kubernetes.io/service-weights`:
Service weights enable to split traffic across multiple backing services in a fine-grained manner.
A canonical use case are canary releases where a new deployment starts to receive a small percentage of traffic (e.g., 1%) and steadily increases over time as confidence in the new deployment improves.

Example:

Expand All @@ -234,6 +233,8 @@ For each path definition, this annotation will fail if:
- the sum of backend weights exceeds 100% or
- the sum of backend weights is less than 100% without one or more omitted backends

See also the [user guide section traffic splitting](/user-guide/kubernetes/#traffic-splitting).

<6> `traefik.ingress.kubernetes.io/whitelist-source-range`:
All source IPs are permitted if the list is empty or a single range is ill-formatted.
Please note, you may have to set `service.spec.externalTrafficPolicy` to the value `Local` to preserve the source IP of the request for filtering.
Expand Down
83 changes: 83 additions & 0 deletions docs/user-guide/kubernetes.md
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,89 @@ For such cases, it is advisable to classify Ingress objects through a label and
To stick with the internal/external example above, all Ingress objects meant for internal traffic could receive a `traffic-type: internal` label while objects designated for external traffic receive a `traffic-type: external` label.
The label selectors on the Træfik Deployments would then be `traffic-type=internal` and `traffic-type=external`, respectively.

## Traffic Splitting

It is possible to split Ingress traffic in a fine-grained manner between multiple deployments using _service weights_.

One canonical use case is canary releases where a deployment representing a newer release is to receive an initially small but ever-increasing fraction of the requests over time.
The way this can be done in Træfik is to specify a percentage of requests that should go into each deployment.

For instance, say that an application `my-app` runs in version 1.
A newer version 2 is about to be released, but confidence in the robustness and reliability of new version running in production can only be gained gradually.
Thus, a new deployment `my-app-canary` is created and scaled to a replica count that suffices for a 1% traffic share.
Along with it, a Service object is created as usual.

The Ingress specification would look like this:

```yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
traefik.ingress.kubernetes.io/service-weights: |
my-app: 99%
my-app-canary: 1%
name: my-app
spec:
rules:
- http:
paths:
- backend:
serviceName: my-app
servicePort: 80
path: /
- backend:
serviceName: my-app-canary
servicePort: 80
path: /
```

Take note of the `traefik.ingress.kubernetes.io/service-weights` annotation: It specifies the distribution of requests among the referenced backend services, `my-app` and `my-app-canary`.
With this definition, Træfik will route 99% of the requests to the pods backed by the `my-app` deployment, and 1% to those backed by `my-app-canary`.
Over time, the ratio may slowly shift towards the canary deployment until it is deemed to replace the previous main application, in steps such as 5%/95%, 10%/90%, 50%/50%, and finally 100%/0%.

A few conditions must hold for service weights to be applied correctly:

- The associated service backends must share the same path and host.
- The total percentage shared across all service backends must yield 100% (see the section on [omitting the final service](#omitting-the-final-service), however).
- The percentage values are interpreted as floating point numbers to a supported precision as defined in the [annotation documentation](/configuration/backends/kubernetes#general-annotations).

### Omitting the Final Service

When specifying service weights, it is possible to omit exactly one service for convenience reasons.

For instance, the following definition shows how to split requests in a scenario where a canary release is accompanied by a baseline deployment for easier metrics comparison or automated canary analysis:

```yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
traefik.ingress.kubernetes.io/service-weights: |
my-app-canary: 10%
my-app-baseline: 10%
name: app
spec:
rules:
- http:
paths:
- backend:
serviceName: my-app-canary
servicePort: 80
path: /
- backend:
serviceName: my-app-baseline
servicePort: 80
path: /
- backend:
serviceName: my-app-main
servicePort: 80
path: /
```

This configuration assigns 80% of traffic to `my-app-main` automatically, thus freeing the user from having to complete percentage values manually.
This becomes handy when increasing shares for canary releases continuously.

## Production advice

### Resource limitations
Expand Down