Cloud Native 9 min read

How to Implement Canary Releases with Ingress‑Nginx Annotations in Kubernetes

This guide explains how to use Ingress‑Nginx annotations such as canary‑by‑header, canary‑weight, canary‑by‑cookie, and canary‑by‑header‑value to perform traffic splitting, blue‑green deployments, and A/B testing in Kubernetes, with complete YAML examples and test results.

Full-Stack DevOps & Kubernetes
Full-Stack DevOps & Kubernetes
Full-Stack DevOps & Kubernetes
How to Implement Canary Releases with Ingress‑Nginx Annotations in Kubernetes

Introduction

Ingress‑Nginx is a Kubernetes ingress controller that supports configuring annotations to achieve various canary release and testing scenarios.

Nginx Ingress Annotations

The following annotations can be used for canary routing: nginx.ingress.kubernetes.io/canary-by-header: Routes traffic based on a request header. Setting the header to always forces all traffic to the canary version; never disables canary routing. nginx.ingress.kubernetes.io/canary-by-header-value: Specifies the exact header value that triggers canary routing. nginx.ingress.kubernetes.io/canary-weight: Routes traffic based on a percentage weight (0‑100). For example, a weight of 60 sends 60% of requests to the canary service. nginx.ingress.kubernetes.io/canary-by-cookie: Routes traffic based on a cookie value. always routes to canary, never routes to the stable version.

Deploy Services

Two services are defined: a test version and a canary version.

apiVersion: v1
kind: Service
metadata:
  name: hello-service
  labels:
    app: hello-service
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    app: hello-service
---
apiVersion: v1
kind: Service
metadata:
  name: canary-hello-service
  labels:
    app: canary-hello-service
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    app: canary-hello-service

Routing by Weight

Ingress configuration using a weight of 30%:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: canary
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "30"
spec:
  rules:
  - host: canary-service.abc.com
    http:
      paths:
      - backend:
          serviceName: canary-hello-service
          servicePort: 80

Test command:

for i in $(seq 1 10); do curl http://canary-service.abc.com; echo '
'; done

Result shows roughly 30% of requests hitting the canary version ("hello world-version2") and the rest hitting the stable version ("hello world-version1").

Routing by Request Header

Ingress configuration for header‑based routing:

annotations:
  kubernetes.io/ingress.class: nginx
  nginx.ingress.kubernetes.io/canary: "true"
  nginx.ingress.kubernetes.io/canary-by-header: "test"

Without the custom header, all requests go to the stable version. Adding -H 'test:always' forces traffic to the canary version.

for i in $(seq 1 5); do curl http://canary-service.abc.com; echo '
'; done
# all stable
for i in $(seq 1 5); do curl -H 'test:always' http://canary-service.abc.com; echo '
'; done
# all canary

Routing by Specific Header Value

Ingress configuration adds a header value match:

annotations:
  kubernetes.io/ingress.class: nginx
  nginx.ingress.kubernetes.io/canary: "true"
  nginx.ingress.kubernetes.io/canary-by-header: "test"
  nginx.ingress.kubernetes.io/canary-by-header-value: "abc"

Requests with -H 'test:abc' are routed to the canary service; other values go to the stable service.

Routing by Cookie

Cookie‑based canary routing configuration:

annotations:
  kubernetes.io/ingress.class: nginx
  nginx.ingress.kubernetes.io/canary: "true"
  nginx.ingress.kubernetes.io/canary-by-cookie: "like_music"

Requests with -b 'like_music=always' are sent to the canary version; otherwise they go to the stable version.

Annotation Matching Order

When multiple canary annotations are present, Nginx evaluates them in the following order:

canary-by-header > canary-by-cookie > canary-weight

Summary

Traffic can be split in two main ways:

By weight using nginx.ingress.kubernetes.io/canary-weight (e.g., 30% canary, 70% stable).

By user‑specific criteria such as request header, header value, or cookie using the corresponding annotations.

These techniques enable fine‑grained canary releases, blue‑green deployments, and A/B testing within a Kubernetes cluster.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

KubernetesannotationsNginxIngressCanaryTrafficSplitting
Full-Stack DevOps & Kubernetes
Written by

Full-Stack DevOps & Kubernetes

Focused on sharing DevOps, Kubernetes, Linux, Docker, Istio, microservices, Spring Cloud, Python, Go, databases, Nginx, Tomcat, cloud computing, and related technologies.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.