All Products
Search
Document Center

Container Service for Kubernetes:Best practices for migrating from a self-managed Nginx Ingress to an ALB Ingress

Last Updated:Mar 26, 2026

ALB Ingress is a fully managed ingress solution that eliminates the operations and maintenance (O&M) burden of running a self-managed NGINX Ingress controller and delivers higher elasticity for traffic-intensive workloads. ACK provides an automated migration tool that converts your existing NGINX Ingress configurations—including AlbConfig, IngressClass, and Ingress resources—so you don't need to rewrite them by hand.

This topic walks you through a zero-downtime migration from an NGINX Ingress to an ALB Ingress. The approach uses Alibaba Cloud DNS weight-based routing to shift traffic gradually, keeping the migration transparent to end users.

Note

Alibaba Cloud DNS is one way to achieve transparent migration. The example in this topic is for reference. Other DNS providers with CNAME weight support work similarly.

How it works

The migration runs in three phases:

  1. Configure an ALB Ingress — Run the migration tool to convert NGINX Ingress configurations to ALB Ingress configurations, then add the ALB Ingress endpoint to DNS alongside the existing NGINX Ingress endpoint with a lower initial weight.

  2. Shift traffic gradually — Incrementally increase the ALB Ingress DNS weight while reducing the NGINX Ingress DNS weight. Validate traffic at each step.

  3. Remove NGINX Ingress resources — After all traffic flows through the ALB Ingress, delete NGINX Ingress DNS records and uninstall the NGINX Ingress controller.

image

Before you begin

Review the following before starting the migration:

  • Compare forwarding rules between your NGINX Ingress and the ALB Ingress to confirm they match. Test all configurations before shifting any live traffic.

  • Schedule traffic changes during off-peak hours to minimize user impact.

  • Connect kubectl to your ACK cluster. For more information, see Get a cluster kubeconfig and connect to the cluster using kubectl.

Migration example

The following example walks through all three phases end to end.

A company runs the NGINX Ingress controller in an ACK cluster with an Internet-facing LoadBalancer Service. The controller is backed by an Internet-facing Classic Load Balancer (CLB) instance. The domain name www.example.net has an A record pointing to the CLB IP address, and all inbound requests flow through CLB → NGINX Ingress → backend pods.

image

Step 1: Configure an ALB Ingress

Install the ALB Ingress controller

  1. Log on to the the ACK consoleACK console and install the ALB Ingress controller in your target cluster. For more information, see Manage the ALB Ingress controller. When prompted, set ALB Instance to None. The migration tool automatically creates the AlbConfig, IngressClass, and Ingress resources—do not pre-create an ALB instance.

    Important

    For ACK dedicated clusters, grant the ALB Ingress controller access permissions before deploying Services. See Grant an ACK dedicated cluster access to the ALB Ingress controller.

Run the migration tool

The migration tool reads your existing NGINX Ingress configuration and outputs equivalent ALB Ingress resources.

  1. Create a file named ingress2albconfig.yaml with the following content:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: ingress2albconfig
      namespace: default
    spec:
      template:
        spec:
          containers:
          - name: ingress2albconfig
            image: registry.cn-hangzhou.aliyuncs.com/acs/ingress2albconfig:latest
            command: ["/bin/ingress2albconfig", "print"]
          restartPolicy: Never
          serviceAccount: ingress2albconfig
          serviceAccountName: ingress2albconfig
      backoffLimit: 4
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: system:ingress2albconfig
    rules:
    - apiGroups:
      - networking.k8s.io
      resources:
      - ingresses
      - ingressclasses
      verbs:
      - get
      - list
      - watch
      - update
      - create
      - patch
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: ingress2albconfig
      namespace: default
    ---
    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: system:ingress2albconfig
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: system:ingress2albconfig
    subjects:
      - kind: ServiceAccount
        name: ingress2albconfig
        namespace: default
  2. Apply the manifest to run the Job:

    kubectl apply -f ingress2albconfig.yaml

    Expected output:

    job.batch/ingress2albconfig created
    clusterrole.rbac.authorization.k8s.io/system:ingress2albconfig created
    serviceaccount/ingress2albconfig created
    clusterrolebinding.rbac.authorization.k8s.io/system:ingress2albconfig created
  3. Check that the Job's pod has completed:

    kubectl get pod -l job-name=ingress2albconfig

    Expected output:

    NAME                        READY   STATUS      RESTARTS   AGE
    ingress2albconfig-vw***     0/1     Completed   0          16m
  4. View the generated ALB Ingress configurations in the pod logs:

    kubectl logs ingress2albconfig-vw***   # Replace with the pod name from the previous step.

    The output contains the converted resources. Apply them to the cluster to activate the ALB Ingress:

    apiVersion: alibabacloud.com/v1
    kind: AlbConfig
    metadata:
      creationTimestamp: null
      name: from_nginx
    spec:
      config:
        accessLogConfig: {}
        edition: Standard
        name: from_nginx
        tags:
        - key: converted/ingress2albconfig
          value: "true"
        zoneMappings:
        - vSwitchId: vsw-xxx   # Replace with the ID of your vSwitch.
        - vSwitchId: vsw-xxx   # Replace with the ID of your vSwitch.
      listeners:
      - port: 80
        protocol: HTTP
    ---
    apiVersion: networking.k8s.io/v1
    kind: IngressClass
    metadata:
      creationTimestamp: null
      name: from_nginx
    spec:
      controller: ingress.k8s.alibabacloud/alb
      parameters:
        apiGroup: alibabacloud.com
        kind: AlbConfig
        name: from_nginx
        scope: null
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80}]'
      creationTimestamp: null
      name: from_ingress1
      namespace: default
    spec:
      ingressClassName: from_nginx
      rules:
      - http:
          paths:
          - backend:
              service:
                name: nginx-svc-g1msr
                port:
                  number: 80
            path: /
            pathType: Prefix
    status:
      loadBalancer: {}

Automatically converted annotations

The migration tool converts the NGINX Ingress annotations in the following table to their ALB Ingress equivalents.

Important

Annotations not listed here are silently dropped during conversion. After applying the converted resources, review your ALB Ingress configuration to confirm all required annotations are present.

NGINX Ingress annotation ALB Ingress annotation
nginx.ingress.kubernetes.io/canary alb.ingress.kubernetes.io/canary
nginx.ingress.kubernetes.io/canary-by-header alb.ingress.kubernetes.io/canary-by-header
nginx.ingress.kubernetes.io/canary-by-header-value alb.ingress.kubernetes.io/canary-by-header-value
nginx.ingress.kubernetes.io/canary-by-cookie alb.ingress.kubernetes.io/canary-by-cookie
nginx.ingress.kubernetes.io/canary-weight alb.ingress.kubernetes.io/canary-weight
nginx.ingress.kubernetes.io/use-regex alb.ingress.kubernetes.io/use-regex
nginx.ingress.kubernetes.io/rewrite-target alb.ingress.kubernetes.io/rewrite-target
nginx.ingress.kubernetes.io/ssl-redirect alb.ingress.kubernetes.io/ssl-redirect
nginx.ingress.kubernetes.io/enable-cors alb.ingress.kubernetes.io/enable-cors
nginx.ingress.kubernetes.io/cors-allow-origin alb.ingress.kubernetes.io/cors-allow-origin
nginx.ingress.kubernetes.io/cors-allow-methods alb.ingress.kubernetes.io/cors-allow-methods
nginx.ingress.kubernetes.io/cors-allow-headers alb.ingress.kubernetes.io/cors-allow-headers
nginx.ingress.kubernetes.io/cors-expose-headers alb.ingress.kubernetes.io/cors-expose-headers
nginx.ingress.kubernetes.io/cors-allow-credentials alb.ingress.kubernetes.io/cors-allow-credentials
nginx.ingress.kubernetes.io/backend-protocol alb.ingress.kubernetes.io/backend-protocol
nginx.ingress.kubernetes.io/load-balance alb.ingress.kubernetes.io/backend-scheduler
nginx.ingress.kubernetes.io/upstream-hash-by alb.ingress.kubernetes.io/backend-scheduler-uch-value

After Step 1, the traffic state looks like this:

image

Step 2: Shift traffic gradually to the ALB Ingress

DNS does not allow the same domain name to point to both an A record and a CNAME record simultaneously. CLB instances are addressed by IP (A record), while ALB instances use a default domain name (CNAME record). To route traffic to both ingresses using DNS weights, configure a temporary domain name for the CLB instance so that both endpoints use CNAME records.

Configure a temporary domain name for the CLB instance

  1. Log on to the Alibaba Cloud DNS console.

  2. On the Authoritative DNS Resolution page, find and click the domain name www.example.net.

  3. On the DNS Settings page, click Add DNS Record. In the Add DNS Record panel, configure the following parameters and click OK.

    Parameter Description
    Record Type Select CNAME.
    Hostname Enter the domain prefix. In this example, www.
    DNS Request Source Select Default.
    Record Value Enter the temporary domain name. In this example, web0.example.net.
    TTL Use the default value.
  4. On the DNS Settings tab, find the A record that maps www.example.net to the CLB IP address and click Modify.

  5. In the Modify DNS Record panel, change Hostname to web0 and click OK. After this change, www.example.net maps to web0.example.net, which the A record resolves to the CLB instance IP address.

Add a CNAME record for the ALB instance

  1. Get the ALB instance domain name:

    kubectl get albconfig

    Expected output:

    NAME         ALBID                    DNSNAME                                               PORT&PROTOCOL   CERTID   AGE
    from_nginx   alb-a8mmh2tqbmrm11****   alb-a8mmh2tqbmrm11****.cn-hangzhou.alb.aliyuncs.com                            20m

    The value in the DNSNAME column (for example, alb-a8mmh2tqbmrm11****.cn-hangzhou.alb.aliyuncs.com) is the ALB instance domain name.

  2. On the DNS Settings page, click Add DNS Record. Configure the following parameters and click OK.

    Parameter Description
    Record Type Select CNAME.
    Hostname Enter the domain prefix. In this example, www.
    DNS Request Source Select Default.
    Record Value Enter the ALB instance domain name from the previous step.
    TTL Use the default value.

Configure weights for the CNAME records

  1. On the Domain Name Resolution page, click Weight Settings in the left-side navigation pane.

  2. On the Weighted Round-robin page, click EnableWeight in the Actions column and click Set Weight.

  3. In the Set Weight panel, set the initial weights: CLB DNS record = 100, ALB DNS record = 0.

    域名权重设置

  4. Gradually reduce the CLB weight and increase the ALB weight. After each adjustment, verify that your services are not affected.

  5. Log on to a worker node where the Service pods are running and run the dig command multiple times to confirm traffic distribution: 流量测试1流量测试2

  6. Continue adjusting until the CLB weight reaches 0 and the ALB weight reaches 100.

If your DNS provider does not support weights for CNAME records, see the following alternative traffic-switching approach:

临时流量切换方案

After Step 2, the traffic state looks like this:

image

Step 3: Remove NGINX Ingress resources

After all persistent connections to the NGINX Ingress have closed and no traffic is reaching it, wait for an observation period before releasing resources.

  1. Log on to the Alibaba Cloud DNS console and delete all DNS records associated with the NGINX Ingress.

  2. Uninstall the NGINX Ingress controller:

    1. Log on to the ACK console.

    2. On the Clusters page, click the target cluster. In the left-side navigation pane, choose Network > Ingresses.

    3. Find the NGINX Ingress and choose image > Delete in the Actions column. In the confirmation message, click Confirm Deletion.

    4. In the left-side navigation pane, choose Add-ons. Click the Networking tab, find the Nginx Ingress Controller card, and click Uninstall.

    5. In the confirmation message, click OK.

      Note

      The CLB instance associated with the NGINX Ingress controller is released automatically when the controller is uninstalled. You are no longer charged for the released resources.

After completing Steps 1–3, all traffic runs through the ALB Ingress and the migration is complete.

image

What's next