All Products
Search
Document Center

Container Service for Kubernetes:Create and use an NGINX Ingress

Last Updated:Jun 20, 2026

The NGINX Ingress Controller serves as the ingress gateway for Alibaba Cloud Container Service for Kubernetes (ACK) managed clusters, routing external traffic to internal services with flexible routing rules. By supporting features such as HTTPS encryption, canary releases, and custom configurations through annotations, it provides secure, high-availability, and scalable Layer 7 (L7) network access.

Important

Usage notes

  • Do not delete the default service used by the NGINX Ingress Controller. After the add-on is installed, a default service named nginx-ingress-lb is created in the kube-system namespace. Deleting this service makes the add-on unstable and can cause it to crash.

  • Use Add-ons or OpenAPI to configure custom parameters for the add-on. Modifying the configuration through other methods can cause the add-on to malfunction and interfere with future upgrades.

  • Use the NGINX Ingress ConfigMap for custom configurations. Technical support does not cover issues caused by additional configurations, such as snippets or Lua code.

  • Upgrade the NGINX Ingress Controller add-on promptly to prevent business disruptions caused by bugs or security vulnerabilities in the upstream community version.

Install the NGINX Ingress Controller add-on

During cluster creation

1. Select the add-on

  1. Sign in to the ACK console and click Create Kubernetes Cluster.

  2. In the Component Configurations step, in the Ingress section, select NGINX Ingress.

2. Select a Server Load Balancer (SLB) source

  • New: Automatically creates a multi-zone public or private CLB instance in the cluster's VPC. The instance uses the pay-by-specification billing method and has a specified instance type.

  • Use Existing: Select an existing public CLB instance in the same region as the cluster or a private CLB instance in the same VPC. Ensure the CLB instance is not associated with another cluster.

Install from the Add-ons page

Installing the add-on from the Add-ons page automatically creates a public-facing CLB instance that uses the pay-by-specification billing method and has the Small I (slb.s1.small) instance type. This instance serves as the traffic entry point for the NGINX Ingress.

  1. Log on to the ACK console. In the left navigation pane, click Clusters.

  2. On the Clusters page, click the name of your cluster. In the left navigation pane, click Components and Add-ons.

  3. Find the NGINX Ingress Controller add-on on the Network tab or by using the search bar. In the lower-right corner of the add-on card, click Install.

  4. In the Install Comment NGINX Ingress Controller dialog box, configure the parameters and click OK.

Create a sample application

The sample application deploys two stateless workloads (Deployments) named coffee and tea, and their corresponding Services named coffee-svc and tea-svc.

Console

1. Create resources

  1. Log on to the ACK console. In the left navigation pane, click Clusters.

  2. On the Clusters page, click the name of your cluster. In the left navigation pane, click Workloads > Deployments.

  3. Click Create from YAML. Select Custom from the Sample Template drop-down list. Copy the following content into the template editor and click Create.

    Sample application YAML

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: coffee
      namespace: default
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: coffee
      template:
        metadata:
          labels:
            app: coffee
        spec:
          containers:
          - name: coffee
            image: registry.cn-hangzhou.aliyuncs.com/acs-sample/nginxdemos:latest
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: coffee-svc
      namespace: default
    spec:
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: coffee
      type: ClusterIP
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: tea
      namespace: default
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: tea
      template:
        metadata:
          labels:
            app: tea
        spec:
          containers:
          - name: tea
            image: registry.cn-hangzhou.aliyuncs.com/acs-sample/nginxdemos:latest
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: tea-svc
      namespace: default
    spec:
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: tea
      type: ClusterIP

2. View the result

In the YAML Resource Creation Result dialog box, click View in the Actions column for a resource to confirm that it has been created. 

kubectl

  1. Obtain the KubeConfig for your cluster and use kubectl to connect to the cluster.

  2. Create a file named test-deployment-service.yaml with the following content.

    Sample YAML file

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: coffee
      namespace: default
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: coffee
      template:
        metadata:
          labels:
            app: coffee
        spec:
          containers:
          - name: coffee
            image: registry.cn-hangzhou.aliyuncs.com/acs-sample/nginxdemos:latest
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: coffee-svc
      namespace: default
    spec:
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: coffee
      type: ClusterIP
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: tea
      namespace: default
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: tea
      template:
        metadata:
          labels:
            app: tea
        spec:
          containers:
          - name: tea
            image: registry.cn-hangzhou.aliyuncs.com/acs-sample/nginxdemos:latest
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: tea-svc
      namespace: default
    spec:
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: tea
      type: ClusterIP
  3. Apply the configuration to create the Deployment and Service.

    kubectl apply -f test-deployment-service.yaml
  4. Verify the status of the coffee and tea Deployments.

    kubectl get deployment coffee tea

    Expected output:

    NAME     READY   UP-TO-DATE   AVAILABLE   AGE
    coffee   2/2     2            2           14m
    tea      2/2     2            2           14m
  5. Verify the status of the coffee-svc and tea-svc Services.

    kubectl get service coffee-svc tea-svc

    Expected output:

    NAME         TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)   AGE
    coffee-svc   ClusterIP   192.168.xxx.xxx   <none>        80/TCP    15m
    tea-svc      ClusterIP   192.168.xxx.xxx   <none>        80/TCP    15m

Create NGINX Ingress

This example uses test-nginx-ingress.com as the domain name (host). Replace this with your own registered domain name. The path mapping (paths) is taken from the Create a sample application example. Modify these paths to match your application's configuration.

Console

1. Create an Ingress

  1. Log on to the ACK console. In the left navigation pane, click Clusters.

  2. On the Clusters page, click the name of the target cluster. In the left-side navigation pane, choose Network > Ingresses. Select the default namespace, click Create Ingress, and configure the Ingress as follows.

    • Gateway Type: Nginx Ingress

    • Name: test-nginx-ingress

    • Domain Name: test-nginx-ingress.com (Replace with your registered domain name)

    • Mappings:

      • Path: /coffee

      • Rule: Default (ImplementationSpecific)

      • Service: coffee-svc

      • Port: 80

  3. Click +Add to configure a path for the tea-svc service.

    • Mappings:

      • Path: /tea

      • Rule: Default (ImplementationSpecific)

      • Service: tea-svc

      • Port: 80

  4. Click +Add Rule to add the www.test-nginx-ingress.com domain name (replace with your registered domain name) and configure its path mappings. When you are finished, click OK.

2. Obtain the endpoint

After about one minute, refresh the page. The Nginx Ingress is successfully created when an Elastic IP (EIP) appears in the Endpoint column. This EIP is the public service address of the associated Cloud Load Balancer (CLB) instance.

If the endpoint information does not appear after a few minutes, click the Ingress name and check the Events tab for troubleshooting.

kubectl

  1. Create a file named test-ingress.yaml with the following content.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: test-nginx-ingress
      namespace: default
    spec:
      ingressClassName: nginx
      rules:
      - host: test-nginx-ingress.com # Replace with your registered domain name
        http:
          paths:
          - path: /coffee
            backend:
              service: 
                name: coffee-svc
                port:
                  number: 80
            pathType: ImplementationSpecific
          - path: /tea
            backend:
              service: 
                name: tea-svc
                port:
                  number: 80
            pathType: ImplementationSpecific
      - host: www.test-nginx-ingress.com # Replace with your registered domain name
        http:
          paths:
          - path: /coffee
            backend:
              service: 
                name: coffee-svc
                port:
                  number: 80
            pathType: ImplementationSpecific
          - path: /tea
            backend:
              service: 
                name: tea-svc
                port:
                  number: 80
            pathType: ImplementationSpecific

    Parameter descriptions:

    • name: The name of the Ingress. In this example, the name is test-nginx-ingress.

    • host: The domain name used to access the service. In this example, the domain name is test-nginx-ingress.com. Replace this with your registered domain name.

    • path: The URL path for the rule. For a request to be routed to the backend, it must match the specified host and path. In this example, the paths are /coffee and /tea.

    • backend: Consists of a service name and a service port.

      • Service name: The name of the backend service to which the Ingress forwards traffic. For example, coffee-svc and tea-svc.

      • Service port: The target port on the backend Service. In this example, the port is 80.

  2. Create the Ingress.

    kubectl apply -f test-ingress.yaml
  3. View the Ingress and obtain its Elastic IP (EIP), such as 8.xxx.xxx.117.

    kubectl get ingress

    Expected output:

    NAME                 CLASS   HOSTS                                               ADDRESS         PORTS   AGE
    test-nginx-ingress   nginx   test-nginx-ingress.com,www.test-nginx-ingress.com   8.xxx.xxx.117   80      2m39s
  4. Use the EIP to verify that the Nginx Ingress is working correctly.

    curl http://8.xxx.xxx.117/coffee -H "Host: test-nginx-ingress.com"

    Expected output:

    ...
    <title>Hello World</title>
    ...
    <p><span>Server&nbsp;address:</span> <span>10.xxx.xxx.19:80</span></p>
    <p><span>Server&nbsp;name:</span> <span>coffee-96d4bc87-l29dh</span></p>
    <p class="smaller"><span>Date:</span> <span>08/Aug/2025:02:21:02 +0000</span></p>
    <p class="smaller"><span>URI:</span> <span>/coffee</span></p>
    ...
        <div id="footer">
            <div id="center" align="center">
                Request ID: 42e2d73c85b16b55b6ab52deb7d995d4<br/>
                &copy; NGINX, Inc. 2018
            </div>
        </div>
    ...

Configure DNS resolution

Register a domain name. You only need to add a domain name if it is registered with a third-party provider. Alibaba Cloud automatically adds domain names purchased through its platform to the public authoritative zones in Alibaba Cloud DNS, so you can directly add DNS records.

1. Add a domain name

  1. Go to Alibaba Cloud DNS - Public Zone.

    On the Public Zone tab, click Add Zone.

  2. Enter the domain name you want to add, and select the Public Zone instance you created. For more information about the parameters, see Purchase and bind a domain name.

2. Add a DNS record

  1. Find the target domain name and click Settings in the Actions column. Then, click Add Record. Add a DNS record with the record type A and the host record @. The Record Value is the access address of the NGINX Ingress.

  2. Follow the same steps to add another DNS record with the host record set to www.

  3. Click Probing next to the new DNS record to check its resolution status.

For more information, see Add a website resolution record.

3. Verify the domain name and path

In your browser, visit http://test-nginx-ingress.com/coffee, replacing test-nginx-ingress.com with your actual domain name, to verify that the service path is accessible.

If the request succeeds, the page returns information from the NGINX backend pod, including the server address, server name, Date, and URI fields.

To confirm the result, you can also refer to Methods for testing DNS resolution. If a DNS record does not take effect, see Quickly troubleshoot DNS resolution failures.

Configure HTTPS security

Purchase a commercial certificate, and apply for the certificate. Ensure the certificate is in the Issued state. Then, follow these steps to download the certificate and add a TLS configuration. This enables encrypted HTTPS access to your domain.

Console

1. Download the certificate

  1. Log on to the Certificate Management Service console. In the left-side navigation pane, choose Certificate Management > SSL Certificate Management.

  2. On the Commercial Certificates tab, select the certificate you want to download, and click Download in the bottom-left corner of the certificate list.

  3. In the dialog box that appears, select Nginx as the server type, download the certificate package, and decompress it.

For more details, see Download an SSL certificate.

2. Create a Secret

  1. Log on to the ACK console. In the left navigation pane, click Clusters.

  2. On the Clusters page, click the name of your cluster. In the left navigation pane, click Configurations > Secrets.

  3. On the Secrets page, select the default namespace, click Create in the upper-left corner, configure a new Secret in the panel that appears, and then click OK.

    • Name: nginx-ingress-tls

    • Type: TLS Certificate

    • Certificates: The full contents of the downloaded and decompressed certificate file (.pem).

    • Key: The full contents of the downloaded and decompressed private key file (.key).

3. Add a TLS configuration

  1. In the left-side navigation pane, choose Network > Ingresses. In the Actions column of your target Ingress, click Update.

  2. On the Modify Ingress page, add the following TLS configuration and then click OK.

    • TLS Settings: Enabled

    • Domain Name: test-nginx-ingress.com (Replace this with your actual registered domain name.)

    • Secrets: nginx-ingress-tls

4. Verify HTTPS access

In your web browser, go to https://test-nginx-ingress.com/coffee (replace this with your actual registered domain name) to verify encrypted HTTPS access to the service path.

Kubectl

  1. Log on to the Certificate Management Service console. In the left-side navigation pane, choose Certificate Management > SSL Certificate Management.

  2. On the Commercial Certificates tab, select the certificate you want to download, and click Download in the bottom-left corner of the certificate list.

  3. In the dialog box that appears, select Nginx as the server type, download the certificate package, and decompress it.

  4. Use the downloaded certificate file (.pem) and private key file (.key) to create a Secret.

    kubectl create secret tls nginx-ingress-tls --cert test-nginx-ingress.com.pem --key test-nginx-ingress.com.key -n default
  5. Add a TLS configuration to the test-nginx-ingress Ingress. Replace test-nginx-ingress.com in the command with your actual registered domain name.

    kubectl patch ingress test-nginx-ingress -p '{"spec":{"tls":[{"hosts":["test-nginx-ingress.com"],"secretName":"nginx-ingress-tls"}]}}'
  6. Verify encrypted HTTPS access to the service path by running the following command with your actual Elastic IP Address.

    curl -v -k https://8.xxx.xxx.117/coffee -H "Host: test-nginx-ingress.com"
    • Parameters:

      • -v: Displays verbose output, including the TLS handshake.

      • -k (or --insecure): Skips certificate verification. Use this option if you are using a self-signed certificate.

    • Expected output:

      ...
      *   Trying 8.xxx.xxx.117:443...
      * Connected to 8.xxx.xxx.117 (8.xxx.xxx.117) port 443
      * ALPN: curl offers h2,http/1.1
      * (304) (OUT), TLS handshake, Client hello (1):
      * (304) (IN), TLS handshake, Server hello (2):
      * (304) (IN), TLS handshake, Unknown (8):
      * (304) (IN), TLS handshake, Certificate (11):
      * (304) (IN), TLS handshake, CERT verify (15):
      * (304) (IN), TLS handshake, Finished (20):
      * (304) (OUT), TLS handshake, Finished (20):
      ...
      <title>Hello World</title>
      ...
      <p><span>Server&nbsp;address:</span> <span>10.xxx.xxx.159:80</span></p>
      <p><span>Server&nbsp;name:</span> <span>coffee-96d4bc87-6cstv</span></p>
      <p class="smaller"><span>Date:</span> <span>14/Aug/2025:09:27:42 +0000</span></p>
      <p class="smaller"><span>URI:</span> <span>/coffee</span></p>
      ...
          <div id="footer">
              <div id="center" align="center">
                  Request ID: fee5fe107106748a35d99a2dbbbc6652<br/>
                  &copy; NGINX, Inc. 2018
              </div>
          </div>
      ...

More configurations

Canary release

To upgrade services, you can use various deployment strategies, such as rolling updates, phased releases, blue-green deployments, and canary releases. For detailed instructions, see Implement phased releases and blue-green deployments using NGINX Ingress.

Backend service protocol

To specify the protocol for a backend service, add the nginx.ingress.kubernetes.io/backend-protocol annotation. The supported protocols are HTTP, HTTPS, gRPC, and gRPCS. For a configuration example, see Configure a gRPC service for NGINX Ingress.

URL rewrite

When you use the NGINX Ingress controller, it forwards requests based on the full path. For example, a request to /service1/api is forwarded to the /service1/api path of the backend pod. If your backend service's path is /api, a path mismatch occurs, resulting in a 404 error. To resolve this issue, you can add the nginx.ingress.kubernetes.io/rewrite-target annotation to rewrite the request path to the correct directory.

For detailed instructions, see Configure URL redirection.

Annotations

NGINX Ingress supports an extensive range of features that you can enable with annotations. For more information, see NGINX Ingress configuration dictionary and Advanced NGINX Ingress configurations.

Observability

Enable Simple Log Service (SLS) during cluster creation to access comprehensive NGINX Ingress access log analysis reports and real-time monitoring dashboards. For details, see Analyze and monitor NGINX Ingress access logs.

High-load scenarios

To improve the performance and stability of the NGINX Ingress Controller in high-load scenarios, see Configure an NGINX Ingress Controller for high-payload scenarios and Suggestions for using an NGINX Ingress Controller.

FAQ

Unreachable external IP from within a cluster

Symptom

Some Pods in the cluster cannot access backend Pods using the external address of the NGINX Ingress Controller (the IP address of the load balancer instance), while others can.

Cause

This issue is caused by the externalTrafficPolicy setting of the controller's Service, which determines how external traffic is handled. When set to local, only backend Pods on the same node as the controller Pod can receive requests. When set to Cluster, access works as expected. When a resource within the cluster accesses the Service using the external IP address of the load balancer, the request is also treated as external traffic.

Solution

  • (Recommended) From within the Kubernetes cluster, access NGINX Ingress using its ClusterIP or service name. The service name of NGINX Ingress is nginx-ingress-lb.kube-system.

  • Run kubectl edit svc nginx-ingress-lb -n kube-system to modify the NGINX Ingress Service. Change the externalTrafficPolicy of the LoadBalancer Service to Cluster. If the cluster's container network plugin is Flannel, requests lose the client source IP. If you use Terway, the client source IP is preserved.

    Example:

    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        service.beta.kubernetes.io/backend-type: eni   # Passes traffic directly to the Elastic Network Interface (ENI).
      labels:
        app: nginx-ingress-lb
      name: nginx-ingress-lb
      namespace: kube-system
    spec:
      externalTrafficPolicy: Cluster

For more information about Service annotations, see Configure Classic Load Balancer (CLB) using annotations.

Large headers or cookies

If a client request contains large request headers or cookies, NGINX Ingress may return an error such as "400 Request Header Or Cookie Too Large /Bad request". To resolve this, increase the buffer sizes by modifying the following settings:

Run kubectl edit cm -n kube-system nginx-configuration to edit the ConfigMap and modify these settings. Example:

client-header-buffer-size: "16k"
large-client-header-buffers: "4 32k" 

After updating the settings, verify that the NGINX data plane reflects the changes. Run kubectl exec <nginx-ingress-pod> -n kube-system -- cat /etc/nginx/nginx.conf | vim - to view the nginx.conf file and confirm the ConfigMap changes are synced.

CORS configuration

Enable Cross-Origin Resource Sharing (CORS) by adding specific annotations to the metadata.annotations section of your Ingress resource. For more information, see Configure CORS for NGINX Ingress.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"     # Enables CORS.
    nginx.ingress.kubernetes.io/cors-allow-origin: "*"  # Allows access from all domains.
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, PATCH, OPTIONS"  # Allowed HTTP methods.
    nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range" # Allowed custom request headers.
    nginx.ingress.kubernetes.io/cors-expose-headers: "Content-Length,Content-Range"  # Exposed response headers.
    nginx.ingress.kubernetes.io/cors-max-age: "86400"  # Preflight request cache duration.
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: example-service
            port:
              number: 80

Client IP pass-through

By default, NGINX Ingress uses the X-Forwarded-For and X-Real-IP headers to pass through the client IP address. However, if a client explicitly sets these headers in the request, the backend server may be unable to obtain the real client IP address.

To enable Layer 7 client IP pass-through for the Ingress, run the kubectl edit cm -n kube-system nginx-configuration command and add the following settings to the ConfigMap.

compute-full-forwarded-for: "true"
forwarded-for-header: "X-Forwarded-For"
use-forwarded-headers: "true"

If NGINX Ingress is behind multiple proxy layers, adjust the configuration based on the proxy-real-ip-cidr parameter. Add the IP addresses of upstream proxies to proxy-real-ip-cidr in CIDR format, separating multiple CIDR blocks with commas. For more information, see Use a WAF.

proxy-real-ip-cidr:  "0.0.0.0/0,::/0"  

In an IPv6 scenario with an upstream Classic Load Balancer (CLB), if the X-Forwarded-For header received by NGINX Ingress is empty, enable Proxy Protocol on the CLB to obtain the client IP address. For more information about Proxy Protocol, see Obtain real client IP addresses through a Layer 4 listener of a CLB instance.

References