All Products
Search
Document Center

Container Service for Kubernetes:Advanced APIG Ingress Usage

Last Updated:Mar 26, 2026

APIG Ingress is a Kubernetes API object that provides Layer 7 load balancing for managing external access to services in your cluster. Configure its advanced features by adding annotations to your Ingress resources — no custom code required.

Examples in this topic use both nginx.ingress.kubernetes.io and higress.ingress.kubernetes.io annotation prefixes. Each annotation's applicable prefix is shown in the annotation index below.

Annotation index

The following table lists all annotations covered in this topic. Click an annotation name to jump to the section where it is described.

Annotation Type Scope Feature
nginx.ingress.kubernetes.io/canary string ("true") Route Canary release
nginx.ingress.kubernetes.io/canary-by-header string Route Header-based canary release
nginx.ingress.kubernetes.io/canary-by-header-value string Route Header-based canary release
higress.ingress.kubernetes.io/canary-by-query string Route Query parameter-based canary release
higress.ingress.kubernetes.io/canary-by-query-value string Route Query parameter-based canary release
nginx.ingress.kubernetes.io/canary-by-cookie string Route Cookie-based canary release
nginx.ingress.kubernetes.io/canary-weight integer (0–100) Route Weight-based canary release
nginx.ingress.kubernetes.io/canary-weight-total integer Route Weight-based canary release
higress.ingress.kubernetes.io/service-subset string Route Service subset
higress.ingress.kubernetes.io/subset-labels string Route Service subset with custom labels
nginx.ingress.kubernetes.io/enable-cors boolean Route CORS
nginx.ingress.kubernetes.io/cors-allow-origin string Route CORS
nginx.ingress.kubernetes.io/cors-allow-methods string Route CORS
nginx.ingress.kubernetes.io/cors-allow-headers string Route CORS
nginx.ingress.kubernetes.io/cors-expose-headers string Route CORS
nginx.ingress.kubernetes.io/cors-allow-credentials boolean Route CORS
nginx.ingress.kubernetes.io/cors-max-age integer (seconds) Route CORS
nginx.ingress.kubernetes.io/use-regex boolean Route Regular expression match
nginx.ingress.kubernetes.io/rewrite-target string Route Path rewrite
nginx.ingress.kubernetes.io/upstream-vhost string Domain Host rewrite
nginx.ingress.kubernetes.io/ssl-redirect boolean Route HTTP-to-HTTPS redirect
nginx.ingress.kubernetes.io/force-ssl-redirect boolean Route HTTP-to-HTTPS redirect
nginx.ingress.kubernetes.io/permanent-redirect URL Route Permanent redirect
nginx.ingress.kubernetes.io/permanent-redirect-code integer Route Permanent redirect
nginx.ingress.kubernetes.io/temporal-redirect URL Route Temporary redirect
higress.ingress.kubernetes.io/request-header-control-add string Route Request header control
higress.ingress.kubernetes.io/request-header-control-update string Route Request header control
higress.ingress.kubernetes.io/request-header-control-remove string Route Request header control
higress.ingress.kubernetes.io/response-header-control-add string Route Response header control
higress.ingress.kubernetes.io/response-header-control-update string Route Response header control
higress.ingress.kubernetes.io/response-header-control-remove string Route Response header control
nginx.ingress.kubernetes.io/proxy-next-upstream-tries integer Route Retry
nginx.ingress.kubernetes.io/proxy-next-upstream-timeout integer (seconds) Route Retry
nginx.ingress.kubernetes.io/proxy-next-upstream string Route Retry
nginx.ingress.kubernetes.io/whitelist-source-range CIDR/IP Route IP access control
higress.ingress.kubernetes.io/blacklist-source-range CIDR/IP Route IP access control
higress.ingress.kubernetes.io/domain-whitelist-source-range CIDR/IP Domain IP access control
higress.ingress.kubernetes.io/domain-blacklist-source-range CIDR/IP Domain IP access control
higress.ingress.kubernetes.io/route-limit-rpm integer Route Single-gateway throttling
higress.ingress.kubernetes.io/route-limit-rps integer Route Single-gateway throttling
higress.ingress.kubernetes.io/route-limit-burst-multiplier integer Route Single-gateway throttling
higress.ingress.kubernetes.io/rate-limit integer (RPS) Route Global throttling control
higress.ingress.kubernetes.io/rate-limit-fallback-custom-response-code integer Route Global throttling control
higress.ingress.kubernetes.io/rate-limit-fallback-custom-response-body-type string Route Global throttling control
higress.ingress.kubernetes.io/rate-limit-fallback-custom-response-body string Route Global throttling control
higress.ingress.kubernetes.io/rate-limit-fallback-redirect-url URL Route Global throttling control
higress.ingress.kubernetes.io/concurrency-limit integer Route Global concurrency control
higress.ingress.kubernetes.io/concurrency-limit-fallback-custom-response-code integer Route Global concurrency control
higress.ingress.kubernetes.io/concurrency-limit-fallback-custom-response-body-type string Route Global concurrency control
higress.ingress.kubernetes.io/concurrency-limit-fallback-custom-response-body string Route Global concurrency control
higress.ingress.kubernetes.io/concurrency-limit-fallback-redirect-url URL Route Global concurrency control
higress.ingress.kubernetes.io/mirror-target-service string (namespace/name:port) Route Traffic mirroring
higress.ingress.kubernetes.io/mirror-percentage integer (0–100) Route Traffic mirroring
nginx.ingress.kubernetes.io/backend-protocol string (HTTPS, GRPC) Route Backend service protocols
nginx.ingress.kubernetes.io/load-balance string Route Load balancing algorithms
nginx.ingress.kubernetes.io/upstream-hash-by string Route Consistent hashing
higress.ingress.kubernetes.io/warmup integer (seconds) Route Warmup (graceful start)
nginx.ingress.kubernetes.io/affinity string ("cookie") Route Cookie affinity
nginx.ingress.kubernetes.io/affinity-mode string ("balanced" or "persistent") Route Cookie affinity
nginx.ingress.kubernetes.io/session-cookie-name string Route Cookie affinity
nginx.ingress.kubernetes.io/session-cookie-path string Route Cookie affinity
nginx.ingress.kubernetes.io/session-cookie-max-age integer (seconds) Route Cookie affinity
nginx.ingress.kubernetes.io/session-cookie-expires integer (seconds) Route Cookie affinity
higress.ingress.kubernetes.io/connection-policy-tcp-max-connection integer Route Connection pool
higress.ingress.kubernetes.io/connection-policy-tcp-max-connection-per-endpoint integer Route Connection pool
higress.ingress.kubernetes.io/connection-policy-http-max-request-per-connection integer Route Connection pool
higress.ingress.kubernetes.io/tls-min-protocol-version string Domain TLS versions and cipher suites
higress.ingress.kubernetes.io/tls-max-protocol-version string Domain TLS versions and cipher suites
nginx.ingress.kubernetes.io/ssl-cipher string Domain TLS versions and cipher suites
nginx.ingress.kubernetes.io/proxy-ssl-secret string (namespace/name) Route mTLS with backend services
nginx.ingress.kubernetes.io/proxy-ssl-name string Route mTLS with backend services
nginx.ingress.kubernetes.io/proxy-ssl-server-name boolean Route mTLS with backend services

Canary release

Canary releases let you shift traffic to a new service version without taking down the current production version. Enable the feature with nginx.ingress.kubernetes.io/canary: "true", then add one or more targeting annotations to control how traffic is distributed.

When multiple targeting methods are configured on the same Ingress, rules are evaluated in this priority order:

Cookie > Header > Query parameter > Weight

Header-based canary release

Annotation Description
nginx.ingress.kubernetes.io/canary-by-header Routes traffic based on a request header name. Set the header value to always to always route to the canary. Any other value routes to production unless canary-by-header-value also matches.
nginx.ingress.kubernetes.io/canary-by-header-value When combined with canary-by-header, routes to the canary service only if both the header name and value match.

Example 1: Route requests with header `apig: always` to the canary service

Clusters with version 1.19 and later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "apig"
  name: demo-canary
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo-service-canary
                port:
                  number: 80
            path: /hello
            pathType: Exact
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /hello
            pathType: Exact

Clusters with version earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "apig"
  name: demo-canary
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /hello
            backend:
              serviceName: demo-service-canary
              servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /hello
            backend:
              serviceName: demo-service
              servicePort: 80

Example 2: Route to multiple canary versions by header value (`apig: v1` → v1, `apig: v2` → v2)

Clusters with version 1.19 and later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "apig"
    nginx.ingress.kubernetes.io/canary-by-header-value: "v1"
  name: demo-canary-v1
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo-service-canary-v1
                port:
                  number: 80
            path: /hello
            pathType: Exact
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "apig"
    nginx.ingress.kubernetes.io/canary-by-header-value: "v2"
  name: demo-canary-v2
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo-service-canary-v2
                port:
                  number: 80
            path: /hello
            pathType: Exact
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /hello
            pathType: Exact

Clusters with version earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "apig"
    nginx.ingress.kubernetes.io/canary-by-header-value: "v1"
  name: demo-canary-v1
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /hello
            backend:
              serviceName: demo-service-canary-v1
              servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "apig"
    nginx.ingress.kubernetes.io/canary-by-header-value: "v2"
  name: demo-canary-v2
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /hello
            backend:
              serviceName: demo-service-canary-v2
              servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /hello
            backend:
              serviceName: demo-service
              servicePort: 80

Query parameter-based canary release

Annotation Description
higress.ingress.kubernetes.io/canary-by-query Routes traffic based on a URL query parameter name. Set the parameter value to always to route to the canary service.
higress.ingress.kubernetes.io/canary-by-query-value When combined with canary-by-query, routes to the canary service only if both the query parameter name and value match.

Header-based and query parameter-based rules can be combined. When both are configured, a request is routed to the canary service only if both conditions are met simultaneously.

Example 1: Route requests with URL query parameter `canary=gray` to the canary service

Clusters with version 1.19 and later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    higress.ingress.kubernetes.io/canary-by-query: "canary"
    higress.ingress.kubernetes.io/canary-by-query-value: "gray"
  name: demo-canary
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo-service-canary
                port:
                  number: 80
            path: /hello
            pathType: Exact
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /hello
            pathType: Exact

Clusters with version earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    higress.ingress.kubernetes.io/canary-by-query: "canary"
    higress.ingress.kubernetes.io/canary-by-query-value: "gray"
  name: demo-canary
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /hello
            backend:
              serviceName: demo-service-canary
              servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /hello
            backend:
              serviceName: demo-service
              servicePort: 80

Example 2: Route to canary only when both `canary=gray` in URL and `x-user-id: test` in header are present

Clusters with version 1.19 and later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    higress.ingress.kubernetes.io/canary-by-query: "canary"
    higress.ingress.kubernetes.io/canary-by-query-value: "gray"
    nginx.ingress.kubernetes.io/canary-by-header: "x-user-id"
    nginx.ingress.kubernetes.io/canary-by-header-value: "test"
  name: demo-canary
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo-service-canary
                port:
                  number: 80
            path: /hello
            pathType: Exact
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /hello
            pathType: Exact

Clusters with version earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    higress.ingress.kubernetes.io/canary-by-query: "canary"
    higress.ingress.kubernetes.io/canary-by-query-value: "gray"
    nginx.ingress.kubernetes.io/canary-by-header: "x-user-id"
    nginx.ingress.kubernetes.io/canary-by-header-value: "test"
  name: demo-canary
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /hello
            backend:
              serviceName: demo-service-canary
              servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /hello
            backend:
              serviceName: demo-service
              servicePort: 80

Cookie-based canary release

Use nginx.ingress.kubernetes.io/canary-by-cookie to split traffic based on a cookie. Set the cookie value to always to route requests to the canary service; all other requests go to the production service.

Cookie-based canary release does not support custom values. The cookie value must be always.

Example: Route requests with cookie `demo=always` to the canary service

Clusters with version 1.19 and later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-cookie: "demo"
  name: demo-canary
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo-service-canary
                port:
                  number: 80
            path: /hello
            pathType: Exact
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /hello
            pathType: Exact

Clusters with version earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-cookie: "demo"
  name: demo-canary
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /hello
            backend:
              serviceName: demo-service-canary
              servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /hello
            backend:
              serviceName: demo-service
              servicePort: 80

Weight-based canary release

Annotation Description Default
nginx.ingress.kubernetes.io/canary-weight Percentage of requests routed to the canary version. Integer from 0 to 100.
nginx.ingress.kubernetes.io/canary-weight-total Total weight across all versions. 100

Example: Split traffic across three versions — canary v1 at 30%, canary v2 at 20%, production at 50%

Clusters with version 1.19 and later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "30"
  name: demo-canary-v1
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo-service-canary-v1
                port:
                  number: 80
            path: /hello
            pathType: Exact
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "20"
  name: demo-canary-v2
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo-service-canary-v2
                port:
                  number: 80
            path: /hello
            pathType: Exact
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /hello
            pathType: Exact

Clusters with version earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "30"
  name: demo-canary-v1
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /hello
            backend:
              serviceName: demo-service-canary-v1
              servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "20"
  name: demo-canary-v2
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /hello
            backend:
              serviceName: demo-service-canary-v2
              servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /hello
            backend:
              serviceName: demo-service
              servicePort: 80

Service subset

Service subsets let you route traffic to specific Pods within a Service — useful when one Service is backed by multiple Deployments running different code versions.

Use the pod label convention for APIG Ingress

Set higress.ingress.kubernetes.io/service-subset to specify which Pod group receives requests. By default, APIG Ingress maps the subset value to Pod labels prefixed with opensergo.io/canary:

  • Value "" or base: routes to Pods with label opensergo.io/canary: "" or Pods that have no opensergo.io/canary-prefixed label.

  • Any other string (e.g., gray): routes to Pods with label opensergo.io/canary-gray: gray.

Example: Route `x-user-id: test` requests to the gray Deployment of go-httpbin

First, apply the Service and Deployments:

# Kubernetes Service
apiVersion: v1
kind: Service
metadata:
  name: go-httpbin
  namespace: default
spec:
  ports:
    - port: 8080
      protocol: TCP
  selector:
    app: go-httpbin
---
# Base Deployment — no opensergo.io/canary label
apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-httpbin-base
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: go-httpbin
  template:
    metadata:
      labels:
        app: go-httpbin
    spec:
      containers:
        - image: registry.cn-hangzhou.aliyuncs.com/apig/go-httpbin
          args:
            - "--version=base"
          imagePullPolicy: Always
          name: go-httpbin
---
# Gray Deployment — has label opensergo.io/canary-gray: gray
apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-httpbin-gray
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: go-httpbin
  template:
    metadata:
      labels:
        app: go-httpbin
        opensergo.io/canary-gray: gray
    spec:
      containers:
        - image: registry.cn-hangzhou.aliyuncs.com/apig/go-httpbin
          args:
            - "--version=gray"
          imagePullPolicy: Always
          name: go-httpbin

Then configure the Ingress resources:

Clusters with version 1.19 and later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "x-user-id"
    nginx.ingress.kubernetes.io/canary-by-header-value: "test"
    # Forward to Pods with label opensergo.io/canary-gray: gray
    higress.ingress.kubernetes.io/service-subset: gray
  name: demo-canary
  namespace: default
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: go-httpbin
                port:
                  number: 8080
            path: /test
            pathType: Exact
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    # Forward to Pods with no opensergo.io/canary-prefixed label
    higress.ingress.kubernetes.io/service-subset: ""
  name: demo
  namespace: default
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: go-httpbin
                port:
                  number: 8080
            path: /test
            pathType: Exact

Clusters with version earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "x-user-id"
    nginx.ingress.kubernetes.io/canary-by-header-value: "test"
    # Forward to Pods with label opensergo.io/canary-gray: gray
    higress.ingress.kubernetes.io/service-subset: gray
  name: demo-canary
  namespace: default
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /test
            backend:
              serviceName: go-httpbin
              servicePort: 8080
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    # Forward to Pods with no opensergo.io/canary-prefixed label
    higress.ingress.kubernetes.io/service-subset: ""
  name: demo
  namespace: default
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /test
            backend:
              serviceName: go-httpbin
              servicePort: 8080

Use custom labels

To target Pods by any arbitrary label — not the opensergo.io/canary convention — set both higress.ingress.kubernetes.io/service-subset and higress.ingress.kubernetes.io/subset-labels.

When subset-labels is configured, the subset is no longer mapped to opensergo.io/canary-prefixed labels.

Example: Route `x-user-id: test` requests to Pods with label `version: gray`

First, apply the Deployments (the version: gray label is added to the gray Deployment's Pod template):

# go-httpbin Kubernetes Service
apiVersion: v1
kind: Service
metadata:
  name: go-httpbin
  namespace: default
spec:
  ports:
    - port: 8080
      protocol: TCP
  selector:
    app: go-httpbin
---
# Base Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-httpbin-base
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: go-httpbin
  template:
    metadata:
      labels:
        app: go-httpbin
    spec:
      containers:
        - image: registry.cn-hangzhou.aliyuncs.com/apig/go-httpbin
          args:
            - "--version=base"
          imagePullPolicy: Always
          name: go-httpbin
---
# Gray Deployment — uses the custom label version: gray
apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-httpbin-gray
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: go-httpbin
  template:
    metadata:
      labels:
        app: go-httpbin
        version: gray
    spec:
      containers:
        - image: registry.cn-hangzhou.aliyuncs.com/apig/go-httpbin
          args:
            - "--version=gray"
          imagePullPolicy: Always
          name: go-httpbin

Then configure the Ingress resources:

Clusters with version 1.19 and later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "x-user-id"
    nginx.ingress.kubernetes.io/canary-by-header-value: "test"
    # Forward to Pods with label version: gray
    higress.ingress.kubernetes.io/service-subset: gray
    higress.ingress.kubernetes.io/subset-labels: version gray
  name: demo-canary
  namespace: default
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: go-httpbin
                port:
                  number: 8080
            path: /test
            pathType: Exact
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/service-subset: ""
  name: demo
  namespace: default
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: go-httpbin
                port:
                  number: 8080
            path: /test
            pathType: Exact

Clusters with version earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "x-user-id"
    nginx.ingress.kubernetes.io/canary-by-header-value: "test"
    # Forward to Pods with label version: gray
    higress.ingress.kubernetes.io/service-subset: gray
    higress.ingress.kubernetes.io/subset-labels: version gray
  name: demo-canary
  namespace: default
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /test
            backend:
              serviceName: go-httpbin
              servicePort: 8080
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/service-subset: ""
  name: demo
  namespace: default
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /test
            backend:
              serviceName: go-httpbin
              servicePort: 8080

CORS

Cross-origin resource sharing (CORS) controls which external domains can make requests to your service.

Annotation Description Default
nginx.ingress.kubernetes.io/enable-cors Enable or disable CORS.
nginx.ingress.kubernetes.io/cors-allow-origin Allowed third-party origins. Comma-separated; supports * wildcard. * (all origins)
nginx.ingress.kubernetes.io/cors-allow-methods Allowed HTTP methods. Comma-separated; supports * wildcard. GET,PUT,POST,DELETE,PATCH,OPTIONS
nginx.ingress.kubernetes.io/cors-allow-headers Allowed request headers. Comma-separated; supports * wildcard. DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization
nginx.ingress.kubernetes.io/cors-expose-headers Response headers the browser is allowed to access. Comma-separated.
nginx.ingress.kubernetes.io/cors-allow-credentials Whether to allow credentials in CORS requests. true
nginx.ingress.kubernetes.io/cors-max-age How long preflight responses can be cached, in seconds. 1728000

Example: Allow `example.com`, permit only `GET` and `POST`, restrict to header `X-Foo-Bar`, and disallow credentials

Clusters of version 1.19 and later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "example.com"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET,POST"
    nginx.ingress.kubernetes.io/cors-allow-headers: "X-Foo-Bar"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "false"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /hello
            pathType: Exact

Clusters earlier than version 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "example.com"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET,POST"
    nginx.ingress.kubernetes.io/cors-allow-headers: "X-Foo-Bar"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "false"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /hello
            backend:
              serviceName: demo-service
              servicePort: 80

Regular expression match

Standard Kubernetes Ingresses support only Exact and Prefix path matching. APIG Ingress also supports regular expression matching. Enable it with nginx.ingress.kubernetes.io/use-regex: "true", then use a regex pattern as the path value.

Example: Forward any request matching `/app/...` or `/test/...` to the demo service

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
  name: regex-match
  namespace: default
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo
                port:
                  number: 8080
            path: /(app|test)/(.*)
            pathType: Prefix

Clusters running Kubernetes earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
  name: regex-match
  namespace: default
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /(app|test)/(.*)
            backend:
              serviceName: demo
              servicePort: 8080

Path and host rewrite

Rewriting modifies the path or host in a request before APIG Ingress forwards it to the backend service.

Annotation Description
nginx.ingress.kubernetes.io/rewrite-target Target path after rewriting. Supports capture groups.
nginx.ingress.kubernetes.io/upstream-vhost Host header value sent to the backend service.

Path rewrite

All examples below use nginx.ingress.kubernetes.io/rewrite-target to modify the request path.

Example 1: Rewrite `example.com/test` to `example.com/dev` before forwarding

Clusters on Kubernetes 1.19 and Later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: "/dev"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters Before Kubernetes 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: "/dev"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /test
            pathType: Exact
            backend:
              serviceName: demo-service
              servicePort: 80

Example 2: Strip the `/v1` prefix — rewrite `example.com/v1/xxx` to `example.com/xxx`

Clusters on Kubernetes 1.19 and Later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: "/$1"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /v1/(.*)
            pathType: Prefix

Clusters Before Kubernetes 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: "/$1"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /v1/(.*)
            pathType: Prefix
            backend:
              serviceName: demo-service
              servicePort: 80

Example 3: Replace the `/v1` prefix with `/v2` — rewrite `example.com/v1/xxx` to `example.com/v2/xxx`

Clusters on Kubernetes 1.19 and Later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: "/v2/$1"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /v1/(.*)
            pathType: Prefix

Clusters Before Kubernetes 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: "/v2/$1"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /v1/(.*)
            pathType: Prefix
            backend:
              serviceName: demo-service
              servicePort: 80

Host rewrite

Example: Rewrite the host from `example.com` to `test.com` before forwarding

Clusters on Kubernetes 1.19 and Later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/upstream-vhost: "test.com"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters Before Kubernetes 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/upstream-vhost: "test.com"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Redirect

HTTP-to-HTTPS redirect

Annotation Description
nginx.ingress.kubernetes.io/ssl-redirect Redirect HTTP requests to HTTPS.
nginx.ingress.kubernetes.io/force-ssl-redirect Redirect HTTP requests to HTTPS.

APIG Ingress treats ssl-redirect and force-ssl-redirect identically — both force an HTTP-to-HTTPS redirect.

Example: Redirect `http://example.com/test` to `https://example.com/test`

Clusters on Version 1.19 and Later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters Before Version 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Permanent redirect

Annotation Description Default
nginx.ingress.kubernetes.io/permanent-redirect Destination URL for a permanent redirect. Must include the scheme (http:// or https://).
nginx.ingress.kubernetes.io/permanent-redirect-code HTTP status code for the redirect. 301

Example: Permanently redirect `http://example.com/test` to `http://example.com/app`

Clusters on Version 1.19 and Later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/permanent-redirect: "http://example.com/app"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters Before Version 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/permanent-redirect: "http://example.com/app"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Temporary redirect

Use nginx.ingress.kubernetes.io/temporal-redirect to specify the destination URL for a temporary redirect. The URL must include the scheme (http:// or https://).

Example: Temporarily redirect `http://example.com/test` to `http://example.com/app`

Clusters on Version 1.19 and Later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/temporal-redirect: "http://example.com/app"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters Before Version 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/temporal-redirect: "http://example.com/app"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Header control

Header control lets you add, update, or remove HTTP headers as APIG Ingress forwards requests to backend services and responses back to clients.

Request header control

All three annotations share the same multi-header syntax: a single header uses a key-value pair; multiple headers use the YAML | block scalar with one key-value pair per line.

Annotation Description
higress.ingress.kubernetes.io/request-header-control-add Adds a header to the forwarded request. If the header already exists, the value is appended.
higress.ingress.kubernetes.io/request-header-control-update Updates a header in the forwarded request. If the header already exists, the value is overwritten.
higress.ingress.kubernetes.io/request-header-control-remove Removes a header from the forwarded request. Separate multiple header names with commas.

Example 1: Add headers `foo: bar` and `test: true` to all requests to `example.com/test`

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/request-header-control-add: |
      foo bar
      test true
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters running Kubernetes earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/request-header-control-add: |
      foo bar
      test true
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Example 2: Use header control together with canary releases to tag traffic by deployment stage

When apig: v1 is present in the request header, APIG Ingress routes to the canary and adds stage: gray. All other requests go to the base version and receive stage: production.

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "apig"
    nginx.ingress.kubernetes.io/canary-by-header-value: "v1"
    higress.ingress.kubernetes.io/request-header-control-add: "stage gray"
  name: demo-canary-v1
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo-service-canary-v1
                port:
                  number: 80
            path: /hello
            pathType: Exact
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/request-header-control-add: "stage production"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /hello
            pathType: Exact

Clusters running Kubernetes earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "apig"
    nginx.ingress.kubernetes.io/canary-by-header-value: "v1"
    higress.ingress.kubernetes.io/request-header-control-add: "stage gray"
  name: demo-canary-v1
spec:
  ingressClassName: apig
  rules:
    - http:
        paths:
          - path: /hello
            backend:
              serviceName: demo-service-canary-v1
              servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/request-header-control-add: "stage production"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /hello
            backend:
              serviceName: demo-service
              servicePort: 80

Response header control

Annotation Description
higress.ingress.kubernetes.io/response-header-control-add Adds a header to the response before it is forwarded to the client. If the header already exists, the value is appended.
higress.ingress.kubernetes.io/response-header-control-update Updates a header in the response before it is forwarded to the client. If the header already exists, the value is overwritten.
higress.ingress.kubernetes.io/response-header-control-remove Removes a header from the response before it is forwarded to the client. Separate multiple header names with commas.

Example: Remove the `req-cost-time` header from responses to `example.com/test`

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/response-header-control-remove: "req-cost-time"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters running Kubernetes earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/response-header-control-remove: "req-cost-time"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Retry

APIG Ingress automatically retries failed requests at the route level. Configure the maximum number of retries, the timeout, and the conditions that trigger a retry.

Annotation Description Default
nginx.ingress.kubernetes.io/proxy-next-upstream-tries Maximum number of retry attempts. 3
nginx.ingress.kubernetes.io/proxy-next-upstream-timeout Timeout for retries, in seconds. No timeout
nginx.ingress.kubernetes.io/proxy-next-upstream Comma-separated list of retry conditions. error,timeout

Valid retry conditions:

Condition Description
error Connection establishment fails or a 5xx status code is returned.
timeout Connection establishment times out or a 5xx status code is returned.
invalid_header A request error occurs or a 5xx status code is returned.
http_xxx Retry on a specific HTTP status code (e.g., http_502, http_403).
non_idempotent Enable retries for non-idempotent requests (POST, PATCH). By default, these are not retried.
off Disable retries entirely.

Example: Retry up to 2 times within 5 seconds, only on HTTP 502, and also retry non-idempotent requests

Clusters for Kubernetes 1.19 and Later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-next-upstream-tries: "2"
    nginx.ingress.kubernetes.io/proxy-next-upstream-timeout: "5"
    nginx.ingress.kubernetes.io/proxy-next-upstream: "http_502,non_idempotent"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters for Kubernetes Earlier Than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-next-upstream-tries: "2"
    nginx.ingress.kubernetes.io/proxy-next-upstream-timeout: "5"
    nginx.ingress.kubernetes.io/proxy-next-upstream: "http_502,non_idempotent"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

IP access control

APIG Ingress supports IP address allowlists and denylists at both the route level and the domain level. Route-level rules take precedence over domain-level rules.

Route-level IP access control

Annotation Description
nginx.ingress.kubernetes.io/whitelist-source-range Allowlist for a specific route. Accepts IP addresses and CIDR blocks, comma-separated.
higress.ingress.kubernetes.io/blacklist-source-range Denylist for a specific route. Accepts IP addresses and CIDR blocks, comma-separated.

Example 1: Allow access to `example.com/test` only from `1.1.X.X`

Clusters of version 1.19 and later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/whitelist-source-range: 1.1.X.X
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters earlier than version 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/whitelist-source-range: 1.1.X.X
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Example 2: Block access to `example.com/test` from `2.2.2.2`

Clusters of version 1.19 and later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/blacklist-source-range: 2.2.2.2
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters earlier than version 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/blacklist-source-range: 2.2.2.2
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Domain-level IP access control

Annotation Description
higress.ingress.kubernetes.io/domain-whitelist-source-range Allowlist applied to all routes under a domain. Route-level allowlists take precedence. Accepts IP addresses and CIDR blocks, comma-separated.
higress.ingress.kubernetes.io/domain-blacklist-source-range Denylist applied to all routes under a domain. Route-level denylists take precedence. Accepts IP addresses and CIDR blocks, comma-separated.

Example 1: Allow access to all routes under `example.com` from `1.1.X.X` and `2.2.2.2`

Clusters of version 1.19 and later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/domain-whitelist-source-range: 1.1.X.X,2.2.2.2
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact
          - backend:
              service:
                name: app-service
                port:
                  number: 80
            path: /app
            pathType: Exact

Clusters earlier than version 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/domain-whitelist-source-range: 1.1.X.X,2.2.2.2
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80
          - path: /app
            backend:
              serviceName: app-service
              servicePort: 80

Example 2: Combine domain-level and route-level allowlists — restrict `/order` to `3.3.X.X` while allowing `1.1.X.X` and `2.2.2.2` on all other routes

Clusters of version 1.19 and later

# Domain-level allowlist for /test and /app
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/domain-whitelist-source-range: 1.1.X.X,2.2.2.2
  name: demo-domain
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact
          - backend:
              service:
                name: app-service
                port:
                  number: 80
            path: /app
            pathType: Exact
---
# Route-level allowlist overrides domain-level for /order
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/whitelist-source-range: 3.3.X.X
  name: demo-route
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /order
            pathType: Exact

Clusters earlier than version 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/domain-whitelist-source-range: 1.1.X.X,2.2.2.2
  name: demo-domain
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80
          - path: /app
            backend:
              serviceName: app-service
              servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/whitelist-source-range: 3.3.X.X
  name: demo-route
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /order
            backend:
              serviceName: demo-service
              servicePort: 80

Single-gateway throttling

Single-gateway throttling limits the request rate for a specific route on each Cloud-native API Gateway instance. The limit applies per gateway replica, not across the entire cluster.

Important

Rate limits apply per gateway replica. If you run multiple replicas or use a Horizontal Pod Autoscaler (HPA), the effective cluster-wide limit is the configured value multiplied by the number of replicas. For a cluster-wide limit that is not affected by replica count, use global throttling control instead.

Annotation Description Default
higress.ingress.kubernetes.io/route-limit-rpm Maximum requests per minute (RPM) per gateway instance. When the limit is exceeded, the response body is local_rate_limited.
higress.ingress.kubernetes.io/route-limit-rps Maximum requests per second (RPS) per gateway instance. When the limit is exceeded, the response body is local_rate_limited.
higress.ingress.kubernetes.io/route-limit-burst-multiplier Burst limit multiplier. The burst limit equals the RPM or RPS value multiplied by this number. 5

The response status code when throttling is triggered depends on your gateway version:

  • Gateway version earlier than 1.2.23: HTTP 503

  • Gateway version 1.2.23 or later: HTTP 429

Example 1: Limit `example.com/test` to 100 RPM with a burst limit of 200 (multiplier 2)

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/route-limit-rpm: "100"
    higress.ingress.kubernetes.io/route-limit-burst-multiplier: "2"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters running Kubernetes earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/route-limit-rpm: "100"
    higress.ingress.kubernetes.io/route-limit-burst-multiplier: "2"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Example 2: Limit `example.com/test` to 10 RPS with the default burst limit (multiplier 5, burst = 50)

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/route-limit-rps: "10"
    # Default burst multiplier is 5; burst limit = 50
    # higress.ingress.kubernetes.io/route-limit-burst-multiplier: "5"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters running Kubernetes earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/route-limit-rps: "10"
    # Default burst multiplier is 5; burst limit = 50
    # higress.ingress.kubernetes.io/route-limit-burst-multiplier: "5"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Global throttling control

This feature requires APIG Ingress gateway version 1.2.25 or later.

Global throttling control integrates with Sentinel to enforce a cluster-wide RPS limit on a specific route. When the limit is exceeded, the default response is HTTP 429 with body sentinel rate limited. Override this behavior with a custom response or a redirect — but not both.

Custom response

Annotation Description Default
higress.ingress.kubernetes.io/rate-limit Maximum RPS for the route across the gateway cluster.
higress.ingress.kubernetes.io/rate-limit-fallback-custom-response-code HTTP status code when throttling is triggered. 429
higress.ingress.kubernetes.io/rate-limit-fallback-custom-response-body-type Response body format: text (text/plain; charset=UTF-8) or json (application/json; charset=UTF-8). text
higress.ingress.kubernetes.io/rate-limit-fallback-custom-response-body Response body content when throttling is triggered. sentinel rate limited

Example 1: Limit `example.com/test` to 100 RPS with the default throttling response

Clusters of version 1.19 and later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/rate-limit: "100"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters earlier than version 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/rate-limit: "100"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Example 2: Limit `example.com/test` to 100 RPS; return HTTP 503 with body `server is overload` when throttled

Clusters of version 1.19 and later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/rate-limit: "100"
    higress.ingress.kubernetes.io/rate-limit-fallback-custom-response-code: "503"
    higress.ingress.kubernetes.io/rate-limit-fallback-custom-response-body: "server is overload"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters earlier than version 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/rate-limit: "100"
    higress.ingress.kubernetes.io/rate-limit-fallback-custom-response-code: "503"
    higress.ingress.kubernetes.io/rate-limit-fallback-custom-response-body: "server is overload"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Redirection

Use higress.ingress.kubernetes.io/rate-limit-fallback-redirect-url to redirect clients to a fallback URL when throttling is triggered.

Example: Limit `example.com/test` to 100 RPS; redirect to `example.com/fallback` when throttled

Clusters of version 1.19 and later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/rate-limit: "100"
    higress.ingress.kubernetes.io/rate-limit-fallback-redirect-url: "example.com/fallback"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters earlier than version 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/rate-limit: "100"
    higress.ingress.kubernetes.io/rate-limit-fallback-redirect-url: "example.com/fallback"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Global concurrency control

This feature requires APIG Ingress gateway version 1.2.25 or later.

Global concurrency control integrates with Sentinel to enforce a cluster-wide limit on the number of concurrent requests being processed for a specific route. When the limit is exceeded, the default response is HTTP 429 with body sentinel rate limited. Override this with a custom response or a redirect — but not both.

Custom response

Annotation Description Default
higress.ingress.kubernetes.io/concurrency-limit Maximum concurrent requests for the route across the gateway cluster.
higress.ingress.kubernetes.io/concurrency-limit-fallback-custom-response-code HTTP status code when concurrency control is triggered. 429
higress.ingress.kubernetes.io/concurrency-limit-fallback-custom-response-body-type Response body format: text (text/plain; charset=UTF-8) or json (application/json; charset=UTF-8). text
higress.ingress.kubernetes.io/concurrency-limit-fallback-custom-response-body Response body content when concurrency control is triggered. sentinel rate limited

Example 1: Limit concurrent requests to `example.com/test` to 1,000 with the default response

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/concurrency-limit: "1000"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters running Kubernetes earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/concurrency-limit: "1000"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Example 2: Limit concurrent requests to 1,000; return HTTP 503 with body `server is overloaded` when the limit is reached

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/concurrency-limit: "1000"
    higress.ingress.kubernetes.io/concurrency-limit-fallback-custom-response-code: "503"
    higress.ingress.kubernetes.io/concurrency-limit-fallback-custom-response-body: "server is overload"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters running Kubernetes earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/concurrency-limit: "1000"
    higress.ingress.kubernetes.io/concurrency-limit-fallback-custom-response-code: "503"
    higress.ingress.kubernetes.io/concurrency-limit-fallback-custom-response-body: "server is overload"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Redirection

Use higress.ingress.kubernetes.io/concurrency-limit-fallback-redirect-url to redirect clients to a fallback URL when concurrency control is triggered.

Example: Limit concurrent requests to 1,000; redirect to `example.com/fallback` when the limit is reached

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/concurrency-limit: "1000"
    higress.ingress.kubernetes.io/concurrency-limit-fallback-redirect-url: "example.com/fallback"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters running Kubernetes earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/concurrency-limit: "1000"
    higress.ingress.kubernetes.io/concurrency-limit-fallback-redirect-url: "example.com/fallback"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Traffic mirroring

Traffic mirroring copies live request traffic to a shadow service without affecting the original request flow. Use it for operational auditing, traffic testing, or shadow mode validation of new service versions.

Annotation Description Default
higress.ingress.kubernetes.io/mirror-target-service Destination service for mirrored traffic. Format: namespace/name:port. The namespace and port fields are optional — namespace defaults to the Ingress gateway's namespace, and port defaults to the service's first port.
higress.ingress.kubernetes.io/mirror-percentage Percentage of traffic to mirror. Valid values: 0–100. 100
Important

When mirrored traffic is forwarded to the destination service, APIG Ingress automatically appends -shadow to the Host header. For example, example.com becomes example.com-shadow. If the destination service uses the Host header for routing or logging, account for this rewrite in your service configuration.

Example 1: Mirror all traffic from `example.com/test` to `test/app:8080`

Clusters Running Version 1.19 and Later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/mirror-target-service: test/app:8080
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters Running Versions Earlier Than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/mirror-target-service: test/app:8080
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Example 2: Mirror 10% of traffic from `example.com/test` to `test/app:8080`

Clusters Running Version 1.19 and Later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/mirror-target-service: test/app:8080
    higress.ingress.kubernetes.io/mirror-percentage: "10"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters Running Versions Earlier Than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/mirror-target-service: test/app:8080
    higress.ingress.kubernetes.io/mirror-percentage: "10"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Backend service protocols

By default, APIG Ingress forwards requests to backend containers over HTTP. Use the nginx.ingress.kubernetes.io/backend-protocol annotation to switch to HTTPS or gRPC.

If the port name in a Kubernetes Service resource is set to grpc or http2, APIG Ingress automatically uses gRPC or HTTP/2 for that backend — without the annotation. This differs from NGINX Ingress, which requires the annotation in all cases.

Example 1: Forward requests to an HTTPS backend

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /
            pathType: Exact

Clusters running Kubernetes versions earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Example 2: Forward requests to a gRPC backend

Two methods are available: use the annotation for explicit control, or set the Service port name when you prefer convention over configuration.

Method 1 — annotation:

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters running Kubernetes versions earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Method 2 — Service port name (grpc):

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /order
            pathType: Exact
---
apiVersion: v1
kind: Service
metadata:
  name: demo-service
spec:
  ports:
    - name: grpc  # APIG Ingress detects this and automatically uses gRPC
      port: 80
      protocol: TCP
  selector:
    app: demo-service

Clusters running Kubernetes versions earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: demo-service
spec:
  ports:
    - name: grpc
      port: 80
      protocol: TCP
  selector:
    app: demo-service

Load balancing algorithms for backend services

Load balancing algorithms control how Cloud-native API Gateway selects backend nodes when forwarding requests.

Common load balancing algorithms

Use nginx.ingress.kubernetes.io/load-balance to set the algorithm.

Value Description
round_robin Distribute requests across backend nodes in rotation. This is the default.
least_conn Route each request to the node with the fewest active connections.
random Select a backend node at random.
Important

APIG Ingress does not support the exponentially weighted moving average (EWMA) algorithm. If EWMA is configured, it falls back to round_robin.

Example: Use least connections for the demo-service backend

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/load-balance: "least_conn"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /order
            pathType: Exact

Clusters running Kubernetes earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/load-balance: "least_conn"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Load balancing algorithms based on consistent hashing

Consistent hashing ensures that requests with the same key are always routed to the same backend node — useful for session-aware applications or cache locality. Set the hash key using nginx.ingress.kubernetes.io/upstream-hash-by.

Supported hash key types:

Hash key Configuration Description
Request URI $request_uri Includes path parameters.
Host $host The request host header.
Client IP $remote_addr The client IP address.
Request header $http_<header-name> The value of a specific request header.
Query parameter $arg_<param-name> The value of a specific URL query parameter.

Example 1: Route all requests from the same client IP to the same backend node

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/upstream-hash-by: "$remote_addr"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters running Kubernetes earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/upstream-hash-by: "$remote_addr"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Example 2: Route requests with the same `X-Stage` header value to the same backend node

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/upstream-hash-by: "$http_x-stage"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters running Kubernetes earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/upstream-hash-by: "$http_x-stage"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Example 3: Route requests with the same `X-Stage` query parameter value to the same backend node

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/upstream-hash-by: "$arg_x-stage"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters running Kubernetes earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/upstream-hash-by: "$arg_x-stage"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Warmup (graceful start)

The warmup feature gradually increases traffic to a newly started backend node over a specified time window, instead of immediately sending it full load. This gives the node time to initialize caches and JIT-compile code before handling peak traffic.

Use higress.ingress.kubernetes.io/warmup to set the warmup window in seconds. Warmup is disabled by default.

Warmup is only supported with round_robin and least_conn load balancing algorithms.

Example: Warm up demo-service over a 30-second window

Clusters running Kubernetes 1.19 and later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/warmup: "30"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters running Kubernetes earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/warmup: "30"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Cookie affinity (session persistence)

Cookie affinity ensures that all requests from the same client are routed to the same backend node. On the first request, if the client does not have the affinity cookie, APIG Ingress generates one and includes it in the response. Subsequent requests from that client carry the cookie and are always routed to the same node.

Annotation Description Default
nginx.ingress.kubernetes.io/affinity Affinity type. The only valid value is cookie.
nginx.ingress.kubernetes.io/affinity-mode Affinity mode: balanced distributes new sessions evenly across backends; persistent always routes to the same backend for the lifetime of the cookie. balanced
nginx.ingress.kubernetes.io/session-cookie-name Name of the cookie used as the hash key. INGRESSCOOKIE
nginx.ingress.kubernetes.io/session-cookie-path Path of the generated cookie. Must match the Ingress path. /
nginx.ingress.kubernetes.io/session-cookie-max-age Expiration time of the generated cookie, in seconds. Takes precedence over session-cookie-expires. Session-level
nginx.ingress.kubernetes.io/session-cookie-expires Expiration time of the generated cookie, in seconds. Session-level

Example 1: Enable cookie affinity with default settings (cookie name `INGRESSCOOKIE`, path `/`, session-level lifetime)

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/affinity: "cookie"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters running Kubernetes earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/affinity: "cookie"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Example 2: Enable cookie affinity with a custom cookie name `test`, path `/`, and 10-second expiration

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "test"
    nginx.ingress.kubernetes.io/session-cookie-max-age: "10"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters running Kubernetes earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "test"
    nginx.ingress.kubernetes.io/session-cookie-max-age: "10"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

Connection pool

Configure a connection pool between a Cloud-native API Gateway instance and a backend service to control how many connections the gateway opens to that service. This prevents the backend from being overwhelmed and helps maintain stability under load.

Annotation Description
higress.ingress.kubernetes.io/connection-policy-tcp-max-connection Maximum total TCP connections between the gateway instance and the backend service.
higress.ingress.kubernetes.io/connection-policy-tcp-max-connection-per-endpoint Maximum TCP connections between the gateway instance and a single backend Pod.
higress.ingress.kubernetes.io/connection-policy-http-max-request-per-connection Maximum HTTP requests per TCP connection between the gateway instance and the backend service.

Example: Limit the gateway to 10 total connections and 2 connections per Pod for demo-service

Clusters of Version 1.19 and Later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/connection-policy-tcp-max-connection: "10"
    higress.ingress.kubernetes.io/connection-policy-tcp-max-connection-per-endpoint: "2"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters Before Version 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/connection-policy-tcp-max-connection: "10"
    higress.ingress.kubernetes.io/connection-policy-tcp-max-connection-per-endpoint: "2"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

TLS versions and cipher suites

By default, APIG Ingress accepts TLS connections from TLS 1.0 through TLS 1.3, using the following cipher suites:

  • ECDHE-ECDSA-AES128-GCM-SHA256

  • ECDHE-RSA-AES128-GCM-SHA256

  • ECDHE-ECDSA-AES128-SHA

  • ECDHE-RSA-AES128-SHA

  • AES128-GCM-SHA256

  • AES128-SHA

  • ECDHE-ECDSA-AES256-GCM-SHA384

  • ECDHE-RSA-AES256-GCM-SHA384

  • ECDHE-ECDSA-AES256-SHA

  • ECDHE-RSA-AES256-SHA

  • AES256-GCM-SHA384

  • AES256-SHA

Use the following annotations to restrict the TLS version range or cipher suites for a specific domain:

Annotation Description Default
higress.ingress.kubernetes.io/tls-min-protocol-version Minimum TLS version. Valid values: TLSv1.0, TLSv1.1, TLSv1.2, TLSv1.3. TLSv1.0
higress.ingress.kubernetes.io/tls-max-protocol-version Maximum TLS version. Valid values: TLSv1.0, TLSv1.1, TLSv1.2, TLSv1.3. TLSv1.3
nginx.ingress.kubernetes.io/ssl-cipher Allowed cipher suites, comma-separated. Applies only to TLS 1.0–1.2 handshakes.

Example: Restrict `example.com` to TLS 1.2 only

Clusters of version 1.19 and later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/tls-min-protocol-version: "TLSv1.2"
    higress.ingress.kubernetes.io/tls-max-protocol-version: "TLSv1.2"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters earlier than version 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    higress.ingress.kubernetes.io/tls-min-protocol-version: "TLSv1.2"
    higress.ingress.kubernetes.io/tls-max-protocol-version: "TLSv1.2"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80

mTLS authentication with backend services

By default, APIG Ingress uses HTTP to connect to backend services. Using nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" (described in Backend service protocols) enables one-way TLS — the gateway verifies the backend's certificate, but the backend does not verify the gateway's.

For a zero-trust model where both sides verify each other, configure mutual TLS (mTLS). With mTLS, the backend service also verifies a client certificate presented by the gateway.

Annotation Description
nginx.ingress.kubernetes.io/proxy-ssl-secret Client certificate used by the gateway to authenticate itself to the backend service. Format: secretNamespace/secretName.
nginx.ingress.kubernetes.io/proxy-ssl-name Server Name Indication (SNI) value used during the TLS handshake.
nginx.ingress.kubernetes.io/proxy-ssl-server-name Enable or disable SNI during the TLS handshake.

Example: Configure mTLS between the gateway and demo-service using the certificate `default/gateway-cert`

Clusters running Kubernetes 1.19 or later

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    nginx.ingress.kubernetes.io/proxy-ssl-secret: "default/gateway-cert"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: demo-service
                port:
                  number: 80
            path: /test
            pathType: Exact

Clusters running Kubernetes earlier than 1.19

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    nginx.ingress.kubernetes.io/proxy-ssl-secret: "default/gateway-cert"
  name: demo
spec:
  ingressClassName: apig
  rules:
    - host: example.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: demo-service
              servicePort: 80