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
Client: A user accessing your application via a web browser or API client.
DNS: Resolves the domain name to the external IP address of the NGINX Ingress Controller.
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.Kubernetes Services:
Backend Services: Expose your applications (e.g., web servers, APIs) within the cluster.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
Install Minikube: Follow the official Minikube installation guide.
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
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:
- Enable SSL/TLS:
Secure your application by configuring HTTPS. You can obtain certificates using Cert-Manager and Let's Encrypt.
- Use Annotations Wisely:
NGINX Ingress Controller supports various annotations for customization, such as rate limiting, whitelisting, and custom error pages.
- Monitor Ingress Traffic:
Implement monitoring and logging to track traffic patterns, performance, and security threats. Tools like Prometheus and Grafana are beneficial.
- Implement RBAC:
Control access to Kubernetes resources by configuring Role-Based Access Control (RBAC).
- Regularly Update NGINX Ingress Controller:
Keep the Ingress Controller up-to-date to benefit from the latest features and security patches.
- 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:
NGINX Ingress Controller GitHub Repository:
Helm Charts for Ingress NGINX:
Cert-Manager for SSL/TLS:
Monitoring with Prometheus and Grafana:
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)