DEV Community

Cover image for Deploying NGINX as an Ingress Controller in Kubernetes: A Comprehensive Step-by-Step Guide with Architectural Diagram
Nicholas Osi
Nicholas Osi

Posted on

Deploying NGINX as an Ingress Controller in Kubernetes: A Comprehensive Step-by-Step Guide with Architectural Diagram

Using NGINX as an Ingress Controller in Kubernetes: A Step-by-Step Guide

In modern cloud-native applications, managing external access to services within a Kubernetes cluster is crucial. NGINX is a popular choice for an Ingress Controller due to its performance, flexibility, and rich feature set. This technical article provides a comprehensive, step-by-step guide on how to deploy and configure NGINX as an Ingress Controller in a Kubernetes environment. Additionally, we'll outline an architectural diagram to help visualize the setup.

Introduction

Ingress in Kubernetes manages external access to services within a cluster, typically HTTP and HTTPS. An Ingress Controller is responsible for fulfilling the Ingress resource's rules, usually by configuring a load balancer or proxy server. NGINX is widely adopted as an Ingress Controller due to its robust feature set, scalability, and community support.

This guide will walk you through deploying NGINX as an Ingress Controller in a Kubernetes cluster, configuring DNS, deploying a sample application, and setting up Ingress resources to manage traffic routing.

Prerequisites

Before you begin, ensure you have the following:

Kubernetes Cluster: A running Kubernetes cluster. You can set one up locally using Minikube or use managed services like Google Kubernetes Engine (GKE), Amazon Elastic Kubernetes Service (EKS), or Azure Kubernetes Service (AKS).

kubectl: Kubernetes command-line tool installed and configured to communicate with your cluster. Install kubectl.

Helm (Optional but Recommended): Package manager for Kubernetes. It simplifies the installation of applications and services on Kubernetes. Install Helm.

Domain Name: A domain or subdomain that you can configure DNS records for. This will be used to route traffic to your Ingress Controller.

Architecture Overview

Before diving into the setup, it's helpful to understand the overall architecture of NGINX as an Ingress Controller within Kubernetes.

Architectural Diagram Description

  1. Client: A user accessing your application via a web browser or API client.

  2. DNS: Resolves the domain name to the external IP address of the NGINX Ingress Controller.

  3. NGINX Ingress Controller:
    Load Balancer: Exposes the Ingress Controller to the internet.
    NGINX Pods: Handle incoming HTTP/HTTPS requests, terminate SSL/TLS if configured, and route traffic based on Ingress rules.

  4. Kubernetes Services:
    Backend Services: Expose your applications (e.g., web servers, APIs) within the cluster.

  5. Applications: Deployed within Kubernetes pods, managed by deployments or stateful sets.

Step 1: Setting Up Kubernetes Cluster

If you don't have a Kubernetes cluster set up yet, follow the steps below. For this guide, we'll assume you're using Minikube for a local setup. For production environments, consider using managed services like GKE, EKS, or AKS.

Installing Minikube

  1. Install Minikube: Follow the official Minikube installation guide.

  2. Start Minikube:

minikube start --driver=docker


   Ensure you have Docker installed as the driver.

3. Verify the Cluster:


   kubectl cluster-info


   You should see output indicating that the Kubernetes master and services are running.

 Step 2: Install NGINX Ingress Controller

There are multiple ways to install the NGINX Ingress Controller in Kubernetes. Using Helm is the most straightforward method.

Using Helm to Install NGINX Ingress Controller

1. Add the NGINX Ingress Helm Repository:

   helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

   helm repo update

2. Create a Namespace for Ingress:

   kubectl create namespace ingress-nginx

3. Install the Ingress Controller:

   helm install nginx-ingress ingress-nginx/ingress-nginx \
     --namespace ingress-nginx \
     --set controller.publishService.enabled=true

 The `controller.publishService.enabled=true` flag ensures that the external IP is published correctly.*

4. Verify the Installation:

   kubectl get pods -n ingress-nginx

   You should see pods with names starting with `nginx-ingress-controller` in the `Running` state.

5.Retrieve the External IP:

   kubectl get svc -n ingress-nginx

   Look for the `EXTERNAL-IP` of the `nginx-ingress-controller`. For Minikube, you might need to use `minikube service` to access the service.

   minikube service nginx-ingress-ingress-nginx-controller -n ingress-nginx

   This command will open the service in your default web browser.

Alternative: Manual Deployment

If you prefer not to use Helm, you can deploy the NGINX Ingress Controller using Kubernetes manifests.

1. Apply the Mandatory YAML:

   kubectl apply -f 
https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml


2. Verify the Deployment:

   kubectl get pods -n ingress-nginx

 Step 3: Configure DNS

To route traffic to your Ingress Controller, you'll need to configure DNS records pointing your domain or subdomain to the Ingress Controller's external IP.

For Minikube Users

Minikube doesn't provide a real external IP. Instead, you can modify your `/etc/hosts` file to map a domain to Minikube's IP.

1. Get Minikube IP

   minikube ip

   Suppose the IP is `192.168.99.100`.

2. Edit `/etc/hosts`:

   Add the following line:

   192.168.99.100   example.com

   Replace `example.com` with your desired domain.

For Cloud Providers (GKE, EKS, AKS)

1. Obtain the External IP:


   kubectl get svc -n ingress-nginx

   Locate the `EXTERNAL-IP` of the `nginx-ingress-controller` service.

2. Update DNS Records:

   - Log in to your DNS provider's management console.
   - Create an `A` record for your domain pointing to the Ingress Controller's external IP.

   *Example:*

   | Type | Name    | Value         |
   |------|---------|---------------|
   | A    | @       | 203.0.113.10  |
   | A    | www     | 203.0.113.10  |


Step 4: Deploy a Sample Application

To demonstrate the Ingress Controller, deploy a simple web application. We'll use NGINX as the backend service.

 Create a Deployment and Service

1. Create a YAML file named `app-deployment.yaml`:

      yaml
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: demo-app
     labels:
       app: demo
   spec:
     replicas: 2
     selector:
       matchLabels:
         app: demo
     template:
       metadata:
         labels:
           app: demo
       spec:
         containers:
         - name: demo-container
           image: nginx:latest
           ports:
           - containerPort: 80
   ---
   apiVersion: v1
   kind: Service
   metadata:
     name: demo-service
   spec:
     type: ClusterIP
     selector:
       app: demo
     ports:
       - port: 80
         targetPort: 80

2. Apply the Deployment

   kubectl apply -f app-deployment.yaml

3. Verify the Deployment:

   kubectl get deployments
   kubectl get pods
   kubectl get svc

   Ensure that the `demo-app` deployment is running with 2 replicas and that the `demo-service` is available.

Step 5: Create Ingress Resources

Now, configure the Ingress resource to route traffic from the Ingress Controller to your backend service based on the request's host and path.

Create an Ingress YAML File

1. Create a file named `demo-ingress.yaml`

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

   Replace `example.com` with your domain name.

2. Apply the Ingress Resource:

   kubectl apply -f demo-ingress.yaml

3. Verify the Ingress:

   kubectl get ingress

   You should see the `demo-ingress` with an address corresponding to the Ingress Controller's external IP.

Step 6: Verify the Setup

Ensure that the Ingress Controller is correctly routing traffic to your application.

Access the Application

1. Open a Web Browser:

   Navigate to `http://example.com` (replace with your domain).

2. Expected Result:

   You should see the default NGINX welcome page served by the `demo-service`.

  Troubleshooting Tips

DNS Propagation: It might take some time for DNS changes to propagate. Use tools like [dig](https://www.tecmint.com/useful-dig-command-examples/) or [nslookup](https://www.nslookup.io/) to verify DNS records.

  dig example.com
Enter fullscreen mode Exit fullscreen mode

Ingress Controller Logs:

kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx

Check Ingress Rules:

kubectl describe ingress demo-ingress

Best Practices

To ensure a robust and secure Ingress setup, consider the following best practices:

  1. Enable SSL/TLS:

Secure your application by configuring HTTPS. You can obtain certificates using Cert-Manager and Let's Encrypt.

  1. Use Annotations Wisely:

NGINX Ingress Controller supports various annotations for customization, such as rate limiting, whitelisting, and custom error pages.

  1. Monitor Ingress Traffic:

Implement monitoring and logging to track traffic patterns, performance, and security threats. Tools like Prometheus and Grafana are beneficial.

  1. Implement RBAC:

Control access to Kubernetes resources by configuring Role-Based Access Control (RBAC).

  1. Regularly Update NGINX Ingress Controller:

Keep the Ingress Controller up-to-date to benefit from the latest features and security patches.

  1. Scale Appropriately:

Ensure the Ingress Controller can handle your traffic load by configuring horizontal pod autoscaling if necessary.

Conclusion

Deploying NGINX as an Ingress Controller in Kubernetes provides a powerful and flexible way to manage external access to your applications. By following this step-by-step guide, you can set up a robust Ingress architecture that efficiently routes traffic, supports SSL/TLS, and scales with your application's needs.

Remember to adhere to best practices to maintain security, performance, and reliability. As your infrastructure grows, consider exploring advanced features of NGINX Ingress Controller and integrating additional tools to enhance your Kubernetes environment.

Additional Resources

Kubernetes Official Documentation:

Ingress

NGINX Ingress Controller GitHub Repository:

kubernetes/ingress-nginx

Helm Charts for Ingress NGINX:

ingress-nginx Helm Chart

Cert-Manager for SSL/TLS:

cert-manager

Monitoring with Prometheus and Grafana:

Prometheus | Grafana

Kubernetes Best Practices:

Kubernetes Best Practices

By leveraging NGINX as your Ingress Controller, you gain granular control over traffic management, enhanced security features, and the scalability needed for modern applications. Happy deploying!

Top comments (0)