Nginx¶
The Nginx Ingress Controller 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. You can read more about these canary annotations on the official canary annotations documentation page. The canary Ingress ignores any other non-canary nginx annotations. Instead, it leverages the annotation settings from the primary Ingress.
The Rollout controller will always set the following two annotations on the canary Ingress (using your configured or the default nginx.ingress.kubernetes.io
prefix):
canary: true
to indicate that this is the canary Ingresscanary-weight: <num>
to indicate what percentage of traffic to send to the canary. If all traffic is routed to the stable Service, this is set to0
You can provide additional annotations to add to the canary Ingress via the additionalIngressAnnotations
field to enable features like routing by header or cookie.
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:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
spec:
...
strategy:
canary:
canaryService: canary-service # required
stableService: stable-service # required
trafficRouting:
nginx:
# Either stableIngress or stableIngresses must be configured, but not both.
stableIngress: primary-ingress
stableIngresses:
- primary-ingress
- secondary-ingress
- tertiary-ingress
annotationPrefix: customingress.nginx.ingress.kubernetes.io # optional
additionalIngressAnnotations: # optional
canary-by-header: X-Canary
canary-by-header-value: iwantsit
The stable 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 Service. 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 Service 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 annotationPrefix
field. The canary Ingress uses that prefix instead of the default nginx.ingress.kubernetes.io
if the field set.
Using Argo Rollouts with multiple NGINX ingress controllers per service¶
Starting with v1.5, argo rollouts supports multiple Nginx ingress controllers pointing at one service with canary deployments. If only one ingress controller is needed, utilize the existing key stableIngress
. If multiple ingress controllers are needed (e.g., separating internal vs external traffic), use the key stableIngresses
instead. It takes an array of string values that are the names of the ingress controllers. Canary steps are applied identically across all ingress controllers.
Using Argo Rollouts with custom NGINX ingress controller names¶
As a default, the Argo Rollouts controller only operates on ingresses with the kubernetes.io/ingress.class
annotation or spec.ingressClassName
set to nginx
. A user can configure the controller to operate on Ingresses with different class name by specifying the --nginx-ingress-classes
flag. A user can list the --nginx-ingress-classes
flag multiple times if the Argo Rollouts controller should operate on multiple values. This solves the case where a cluster has multiple Ingress controllers operating on different class values.
If the user would like the controller to operate on any Ingress without the kubernetes.io/ingress.class
annotation or spec.ingressClassName
, a user should add the following --nginx-ingress-classes ''
.