This topic describes how to deploy multiple independent NGINX Ingress controllers in a Container Service for Kubernetes (ACK) cluster to provide different Internet-facing services.

Prerequisites

Background information

You can modify the configurations of the default NGINX Ingress controller to use internal-facing Server Load Balancer (SLB) instances. For more information about deploying NGINX Ingress controllers to meet the requirements of most scenarios, see Configure an Ingress controller to use an internal-facing SLB instance. This topic describes a solution that applies to scenarios where some services must be accessible to external users but other services allow only requests from non-Kubernetes workloads in the same virtual private cloud (VPC). In this case, you can deploy two independent NGINX Ingress controllers and bind them to SLB instances of different network types. 1

Deploy a new NGINX Ingress controller

After an ACK cluster is created, an NGINX Ingress controller with two pods is automatically deployed. An Internet-facing SLB instance is also created as the frontend load balancing Service.

You can perform the following steps to deploy another independent NGINX Ingress controller in the cluster:

  1. Log on to the ACK console.
  2. In the left-side navigation pane of the ACK console, choose Marketplace > App Catalog.
  3. On the Marketplace page, click the App Catalog tab. In the search box, enter ack-ingress-nginx.
    • If your cluster runs a Kubernetes version earlier than 1.20, click ack-ingress-nginx.
    • If your cluster runs Kubernetes 1.20 or later, click ack-ingress-nginx-v1.
  4. On the page that appears, click Deploy.
  5. In the Deploy wizard, select a cluster and a namespace, and then click Next.
  6. On the Parameters wizard page, configure the parameters and click OK.
    The following table describes the parameters of ack-ingress-nginx.
    Parameter Description
    controller.image.repository The image repository of ingress-nginx.
    controller.image.tag The image version of ingress-nginx. For more information, see Nginx Ingress Controller.
    controller.ingressClass The Ingress class of the Ingress controller. The Ingress controller handles only the Ingresses that are annotated with the Ingress class.
    Notice The Ingress class of each Ingress controller must be unique within a cluster. The Ingress class of the default Ingress controller in a cluster is nginx. Therefore, do not set this parameter to nginx.
    controller.replicaCount The number of pods that are provisioned for the Ingress controller.
    controller.service.enabled Specifies whether to use an Internet-facing SLB instance for load balancing. If you do not want to use an Internet-facing SLB instance, set this parameter to false.
    controller.service.internal.enabled Specifies whether to use an internal-facing SLB instance for load balancing. If you want to use an internal-facing SLB instance, set this parameter to true.
    controller.kind The deployment mode of the Ingress controller. Valid values: Deployment and DaemonSet.
    The following table describes the parameters of ack-ingress-nginx-v1.
    Parameter Description
    controller.image.repository The image repository of ingress-nginx.
    controller.image.tag The image version of ingress-nginx. For more information, see Nginx Ingress Controller.
    controller.ingressClassResource.name The Ingress class of the Ingress controller. The Ingress controller handles only the Ingresses that are annotated with the Ingress class.
    Notice This parameter is used as an alternative to the controller.ingressClass parameter that is used for clusters that run Kubernetes versions earlier than 1.22. You can also specify this parameter in the kubernetes.io/ingress.class annotation. The Ingress class of each Ingress controller must be unique within a cluster. The Ingress class of the default Ingress controller in a cluster is nginx. Therefore, do not set this parameter to nginx.
    controller.ingressClassResource.controllerValue The controller class of the Ingress controller.
    Notice The controller class of each Ingress controller must be unique within a cluster. The controller class of the default Ingress controller in a cluster is k8s.io/ingress-nginx. Therefore, do not set this parameter to k8s.io/ingress-nginx.
    controller.replicaCount The number of pods that are provisioned for the Ingress controller.
    controller.service.enabled Specifies whether to use Internet-facing SLB instances and internal-facing SLB instances for load balancing.
    controller.service.external.enabled Specifies whether to use an Internet-facing SLB instance for load balancing. If you do not want to use an Internet-facing SLB instance, set this parameter to false.
    controller.service.internal.enabled Specifies whether to use an internal-facing SLB instance for load balancing. If you want to use an internal-facing SLB instance, set this parameter to true.
    controller.kind The deployment mode of the Ingress controller. Valid values: Deployment and DaemonSet.
  7. View the new NGINX Ingress controller.
    1. In the left-side navigation pane of the ACK console, click Clusters.
    2. On the Clusters page, find the cluster that you want to manage and click the name of the cluster or click Details in the Actions column. The details page of the cluster appears.
    3. In the left-side navigation pane of the cluster details page, choose Applications > Helm.
      On the Helm page, you can find the new NGINX Ingress controller that you deployed.

Test the connectivity

In the following example, an application is created and uses the new NGINX Ingress controller to provide Internet-facing services.

  1. Deploy an NGINX application.
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          run: nginx
      template:
        metadata:
          labels:
            run: nginx
        spec:
          containers:
          - image: nginx
            imagePullPolicy: Always
            name: nginx
            ports:
            - containerPort: 80
              protocol: TCP
          restartPolicy: Always
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        run: nginx
      sessionAffinity: None
      type: NodePort
  2. Use the NGINX Ingress controller to provide Internet-facing services.
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: nginx
      annotations:
        # Set the value to the Ingress class of the new NGINX Ingress controller. 
        kubernetes.io/ingress.class: "<YOUR_INGRESS_CLASS>"
    spec:
      rules:
      - host: foo.bar.com
        http:
          paths:
          - path: /
            backend:
              service: 
                name: nginx
                port:
                  number: 80
            pathType: ImplementationSpecific
    Note You must configure the kubernetes.io/ingress.class annotation.

    After you deploy the application, perform the following steps to query the Ingress IP address and the IP address of the new NGINX Ingress controller:

    • Run the following command to query the IP address of the Internet-facing SLB instance that is associated with the default nginx-ingress-lb Service:
       kubectl -n kube-system get svc nginx-ingress-lb

      Expected output:

      NAME               TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)                      AGE
      nginx-ingress-lb   LoadBalancer   172.19.7.30   192.0.2.0   80:31429/TCP,443:32553/TCP   2d
    • Run the following command to query the IP address of the Internet-facing SLB instance that is associated with the newly created nginx-ingress-lb Service:
      kubectl -n <YOUR_NAMESPACE> get svc nginx-ingress-lb

      Expected output:

      NAME               TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE
      nginx-ingress-lb   LoadBalancer   172.19.6.227   198.51.100.10   80:30969/TCP,443:31325/TCP   39m
    • Run the following command to query the Ingress configuration:
      kubectl get ing

      Expected output:

      NAME      HOSTS         ADDRESS         PORTS     AGE
      nginx     foo.bar.com   198.51.100.10   80        5m

    The output shows that the Ingress IP address is the same as the IP address of the new NGINX Ingress controller.

  3. Access the application through the default NGINX Ingress controller and the new NGINX Ingress controller.
     # Access the application through the default NGINX Ingress controller. The 404 status code is expected. 
      curl -H "Host: foo.bar.com" http://192.0.2.0
    default backend - 404                                                                                                                                                                                        
      # Access the application through the new NGINX Ingress controller. The NGINX welcome page is expected. curl -H "Host: foo.bar.com" http://198.51.100.10
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>

The preceding tests show that services exposed through different NGINX Ingress controllers do not interfere with each other. This solution is suitable for scenarios where some services must be accessible to external users while other services allow only requests from non-Kubernetes workloads within the same VPC.