3 Using the NGINX Ingress Controller

This chapter includes two examples to test ingress rules with the NGINX Ingress Controller.

You can create ingress rules, using one, or more Kubernetes Ingress, VirtualServer, or VirtualServerRoute Custom Resource Definitions (CRDs). These definitions set up the ingress configuration.

Example 3-1 Single Application Routing Test

This example creates an ingress rule that directs incoming traffic to an NGINX application.

  1. Create a Deployment and associated Service in a CRD YAML file:

    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: container-registry.oracle.com/olcne/nginx:1.17.7 
            ports:
            - containerPort: 80
    ---
    kind: Service
    apiVersion: v1
    metadata:
      name: nginx-service
    spec:
      selector:
        app: nginx
      ports:
      - name: http
        port: 80
        targetPort: 80
  2. Create the Deployment and Service using:

    kubectl apply -f filename.yaml
  3. Create an Ingress CRD in a YAML file for the NGINX service.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: example-ingress
    spec:
      ingressClassName: nginx
      rules:
      - http:
          paths:
            - path: /
              pathType: Prefix 
              backend:
                service: 
                  name: nginx-service
                  port:
                    number: 80 
  4. You can then create the Ingress using:

    kubectl apply -f filename.yaml
  5. You can see the Ingress is created using:

    kubectl get ingress

    The output looks similar to:

    NAME              CLASS   HOSTS   ADDRESS           PORTS   AGE
    example-ingress   nginx   *       203.0.113.11      80      7m16s

    The ADDRESS shown is also the address for the load balancer. You can confirm this using:

    kubectl get service --namespace ingress-nginx

    The output looks similar to:

    NAME                                   TYPE           CLUSTER-IP       EXTERNAL-IP       PORT(S)                      AGE
    myingress-nginx-controller             LoadBalancer   10.106.167.143   203.0.113.11      80:31036/TCP,443:32343/TCP   7d1h
    myingress-nginx-controller-admission   ClusterIP      10.105.9.191     <none>            443/TCP                      7d1h
  6. You can show the ingress rules using:

    kubectl describe ingress example-ingress

    The output looks similar to:

    Name:             example-ingress
    Labels:           <none>
    Namespace:        default
    Address:          203.0.113.11
    Ingress Class:    nginx
    Default backend:  <default>
    Rules:
      Host        Path  Backends
      ----        ----  --------
      *           
                  /   nginx-service:80 (10.244.1.4:80,10.244.3.4:80,10.244.4.3:80 + 1 more...)
    Annotations:  <none>
    Events:
      Type    Reason  Age                From                      Message
      ----    ------  ----               ----                      -------
      Normal  Sync    14m (x2 over 15m)  nginx-ingress-controller  Scheduled for sync

    This shows that all traffic is to be routed to the nginx-service.

  7. Use the curl command to create a request to the NGINX application. Use the IP address of the load balancer and the Ingress.

    curl http://203.0.113.11

    The output looks similar to:

    <!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>
  8. You can delete the Ingress, Deployment, and Service using:

    kubectl delete ingress example-ingress
    kubectl delete service nginx-service
    kubectl delete deployment nginx-deployment

Example 3-2 Two Applications and URL Redirection Test

This test application creates two NGINX Deployments with customized HTML pages and an Service for each Deployment. An ingress rule is then created to redirect traffic to these services depending on the path entered in the URL.

  1. Create a YAML file that contains the HTML responses to be provided by NGINX instead of the default web server page. A ConfigMap is provided for each Service.

    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: configmap-nginx-a
    data:
      index.html: |
        <html>
          <head>
            <title>NGINX Application A</title>
          </head>
          <body>
            <h1>This is from path /a to service nginx-a.</h1>
          </body>
        </html>
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: configmap-nginx-b
    data:
      index.html: |
        <html>
          <head>
            <title>NGINX Application B</title>
          </head>
          <body>
            <h1>This is from path /b to service nginx-b.</h1>
          </body>
        </html>
  2. You can then create the ConfigMaps using:

    kubectl apply -f filename.yaml
  3. Create two NGINX Deployments and associated Services in a CRD YAML file. Volumes are created on each Deployment to use the ConfigMaps. Each Deployment provides a different HTML page to show which application is returning data.

    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment-a
      labels:
        app: nginx-a
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx-a
      template:
        metadata:
          labels:
            app: nginx-a
        spec:
          containers:
          - name: nginx-a
            image: container-registry.oracle.com/olcne/nginx:1.17.7
            ports:
            - containerPort: 80
            volumeMounts:
            - name: volume-a
              mountPath: /usr/share/nginx/html
          volumes:
          - name: volume-a
            configMap:
              name: configmap-nginx-a
    
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment-b
      labels:
        app: nginx-b
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx-b
      template:
        metadata:
          labels:
            app: nginx-b
        spec:
          containers:
          - name: nginx-b
            image: container-registry.oracle.com/olcne/nginx:1.17.7 
            ports:
            - containerPort: 80
            volumeMounts:
            - name: volume-b
              mountPath: /usr/share/nginx/html
          volumes:
          - name: volume-b
            configMap:
              name: configmap-nginx-b
    ---
    kind: Service
    apiVersion: v1
    metadata:
      name: nginx-service-a
    spec:
      selector:
        app: nginx-a
      ports:
      - name: http
        port: 80
        targetPort: 80
    
    ---
    kind: Service
    apiVersion: v1
    metadata:
      name: nginx-service-b
    spec:
      selector:
        app: nginx-b
      ports:
      - name: http
        port: 80
        targetPort: 80
  4. Create the Deployments and Services using:

    kubectl apply -f filename.yaml
  5. Create an Ingress CRD in a YAML file for the NGINX Services. This Ingress directs any traffic that contains the path /a to nginx-service-a, and traffic that contains the path /b to nginx-service-b. No other traffic is allowed.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: example-ingress
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: / 
    spec:
      ingressClassName: nginx
      rules:
      - http:
          paths:
            - path: /a
              pathType: Prefix 
              backend:
                service: 
                  name: nginx-service-a
                  port:
                    number: 80 
            - path: /b
              pathType: Prefix 
              backend:
                service: 
                  name: nginx-service-b
                  port:
                    number: 80 
  6. You can then create the Ingress using:

    kubectl apply -f filename.yaml
  7. You can show the ingress rules using:

    kubectl describe ingress example-ingress

    The output looks similar to:

    Name:             example-ingress
    Labels:           <none>
    Namespace:        default
    Address:          203.0.113.11
    Ingress Class:    nginx
    Default backend:  <default>
    Rules:
      Host        Path  Backends
      ----        ----  --------
      *           
                  /a   nginx-service-a:80 (10.244.2.8:80,10.244.4.5:80)
                  /b   nginx-service-b:80 (10.244.2.9:80,10.244.4.4:80)
    Annotations:  nginx.ingress.kubernetes.io/rewrite-target: /
    Events:       <none>
  8. Use the curl command to create a request to the nginx-a application by including the /a path in the URL. Use the IP address of the load balancer and the Ingress.

    curl http://203.0.113.11/a

    The output looks similar to:

    <html>
      <head>
        <title>NGINX Application A</title>
      </head>
      <body>
        <h1>This is from path /a to service nginx-a.</h1>
      </body>
    </html>

    The nginx-a Deployment responds with the default HTML page to show it's coming through the nginx-service-a Service.

  9. Use the curl command to create a request to the nginx-b application by including the /b path in the URL.

    curl http://203.0.113.11/b

    The output looks similar to:

    <html>
      <head>
        <title>NGINX Application B</title>
      </head>
      <body>
        <h1>This is from path /b to service nginx-b.</h1>
      </body>
    </html>

    The nginx-b Deployment responds with the default HTML page to show it's coming through the nginx-service-b Service.

  10. Use the curl command to create a request without adding any path to the URL.

    curl http://203.0.113.11

    The output looks similar to:

    <html>
    <head><title>404 Not Found</title></head>
    <body>
    <center><h1>404 Not Found</h1></center>
    <hr><center>nginx</center>
    </body>
    </html>

    As no ingress rule is provided for this URL, no traffic is allowed.

  11. You can delete the Ingress, Deployments, Services, and ConfigMaps using:

    kubectl delete ingress example-ingress
    kubectl delete service nginx-service-a
    kubectl delete service nginx-service-b
    kubectl delete deployment nginx-deployment-a
    kubectl delete deployment nginx-deployment-b
    kubectl delete configmaps configmap-nginx-a
    kubectl delete configmaps configmap-nginx-b