-
Notifications
You must be signed in to change notification settings - Fork 880
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Nginx docs for traffic management (#326)
- Loading branch information
1 parent
032eaf4
commit 9876bf4
Showing
4 changed files
with
86 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Traffic management | ||
|
||
NOTE: This is being implemented for the v0.7 version and everything described below is subject to change. | ||
|
||
Traffic management is controlling the data plane to have intelligent routing rules for an application. These routing rules can manipulate the flow of traffic to different versions of an application enabling Progressive Delivery. These controls limit the blast radius of a new release by ensuring a small percentage of users receive a new version while it is verified. | ||
|
||
There are various techniques to achieve traffic management: | ||
|
||
- Raw percentages (i.e., 5% of traffic should go to the new version while the rest goes to the stable version) | ||
- Header-based routing (i.e., send requests with a specific header to the new version) | ||
- Mirrored traffic where all the traffic is copied and send to the new version in parallel (but the response is ignored) | ||
|
||
## Traffic Management tools in Kubernetes | ||
|
||
The core Kubernetes objects do not have fine-grained tools needed to fulfill all the requirements of traffic management. At most, Kubernetes offers naïve load balancing capabilities through the Service object by offering an endpoint that routes traffic to a grouping of pods based on that Service's selector. Functionality like traffic mirroring or routing by headers is not possible with the default core Service object, and the only way to control the percentage of traffic to different versions of an application is by manipulating replica counts of those versions. | ||
|
||
Service Meshes fill this missing functionality in Kubernetes. They introduce new concepts and functionality to control the data plane through the use of CRDs and other core Kubernetes resources. | ||
|
||
## How does Argo Rollouts enable traffic management? | ||
|
||
Argo Rollouts enables traffic management by manipulating the Service Mesh resources to match the intent of the Rollout. Argo Rollouts currently supports the following service meshes: | ||
|
||
- [Istio](istio.md) | ||
- [Nginx Ingress Controller](nginx.md) | ||
- File a ticket [here](https://github.com/argoproj/argo-rollouts/issues) if you would like another implementation (or thumbs up it if that issue already exists) | ||
|
||
Regardless of the Service Mesh used, the Rollout object has to set a canary Service and a stable Service in its spec. Here is an example with those fields set: | ||
```yaml | ||
apiVersion: argoproj.io/v1alpha1 | ||
kind: Rollout | ||
spec: | ||
... | ||
strategy: | ||
canary: | ||
canaryService: canary-service | ||
stableService: stable-service | ||
networking: | ||
... | ||
``` | ||
The controller modifies these Services to route traffic to the appropriate canary and stable ReplicaSets as the Rollout progresses. These Services are used by the Service Mesh to define what group of pods should receive the canary and stable traffic. | ||
Additionally, the Argo Rollouts controller needs to treat the Rollout object differently when using traffic management. In particular, the Stable ReplicaSet owned by the Rollout remains fully scaled up as the Rollout progresses through the Canary steps. | ||
Since the traffic is controlled independently by the Service Mesh resources, the controller needs to make a best effort to ensure that the Stable and New ReplicaSets are not overwhelmed by the traffic sent to them. By leaving the Stable ReplicaSet scaled up, the controller is ensuring that the Stable ReplicaSet can handle 100% of the traffic at any time*. The New ReplicaSet follows the same behavior as without traffic management. The new ReplicaSet's replica count is equal to the latest SetWeight step percentage multiple by the total replica count of the Rollout. This calculation ensures that the canary version does not receive more traffic than it can handle. | ||
*The Rollout has to assume that the application can handle 100% of traffic if it is fully scaled up. It should outsource to the HPA to detect if the Rollout needs to more replicas if 100% isn't enough. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Istio | ||
|
||
TBD |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# Nginx | ||
|
||
NOTE: This is being implemented for the v0.7 version and everything described below is subject to change. | ||
|
||
The [Nginx Ingress Controller](https://kubernetes.github.io/ingress-nginx/) enables traffic management through one or more Ingress objects to configure an Nginx deployment that routes traffic directly to pods. Each Nginx Ingress contains multiple annotations that modify the behavior of the Nginx Deployment. For traffic management between different versions of an application, the Nginx Ingress controller provides the capability to split traffic by introducing a second Ingress object (referred to as the canary Ingress) with some special annotations. Here are the canary specific annotations: | ||
|
||
- `nginx.ingress.kubernetes.io/canary` indicates that this Ingress is serving canary traffic | ||
- `nginx.ingress.kubernetes.io/canary-weight` indicates what percentage of traffic to send to the canary. | ||
- Other canary-specific annotations deal with routing traffic via headers or cookies. A future version of Argo Rollouts will contain this functionality. | ||
|
||
You can read more about these canary annotations on the official [documenentation page](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#canary). The canary Ingress ignores any other non-canary nginx annotations. Instead, it leverages the annotation settings from the primary Ingress. | ||
|
||
## Integration with Argo Rollouts | ||
There are a couple of required fields in a Rollout to send split traffic between versions using Nginx. Below is an example of a Rollout with those fields: | ||
|
||
```yaml | ||
apiVersion: argoproj.io/v1alpha1 | ||
kind: Rollout | ||
spec: | ||
... | ||
strategy: | ||
canary: | ||
canaryService: canary-service # required | ||
stableService: stable-service # required | ||
networking: | ||
nginx: | ||
primaryIngress: primary-ingress # required | ||
annotationPrefix: example.nginx.com/ # optional | ||
``` | ||
The primary Ingress field is a reference to an Ingress in the same namespace of the Rollout. The Rollout requires the primary Ingress routes traffic to the stable ReplicaSet. The Rollout checks that condition by confirming the Ingress has a backend that matches the Rollout's stableService. | ||
The controller routes traffic to the canary ReplicaSet by creating a second Ingress with the canary annotations. As the Rollout progresses through the Canary steps, the controller updates the canary Ingress's canary annotations to reflect the desired state of the Rollout enabling traffic splitting between two different versions. | ||
Since the Nginx Ingress controller allows users to configure the annotation prefix used by the Ingress controller, Rollouts can specify the optional `annonationPrefix` field. The canary Ingress uses that prefix instead of the default `nginx.ingress.kubernetes.io` if the field set. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters