Ingress Controllers (NGINX, Traefik, HAProxy) – Traffic Routing in Kubernetes
Bavithran M
Senior Cloud & DevOps Engineer | AWS & Azure Certified | Kubernetes & Automation Advocate | Training | Mentoring | Uplifting Many IT Professionals
In Kubernetes, exposing applications to the outside world is one of the most critical tasks. While Services (ClusterIP, NodePort, LoadBalancer) can expose workloads, they lack advanced features like:
?? Traffic routing based on hostnames and paths
?? TLS termination for HTTPS connections
?? Load balancing and request redirection
This is where Ingress Controllers come in! ??
An Ingress Controller acts as a reverse proxy and load balancer inside a Kubernetes cluster, handling external traffic and routing it to the correct services based on rules defined in an Ingress resource.
What You’ll Learn in This Guide:
? What is Ingress and why is it important?
? How Ingress Controllers (NGINX, Traefik, HAProxy) work
? Step-by-step scenarios to deploy, configure, and test Ingress
? Advanced use cases: Path-based routing, Host-based routing, and TLS termination
? Troubleshooting common Ingress issues
Let’s dive in! ??
?? What is Kubernetes Ingress?
Ingress is an API object in Kubernetes that:
? Manages external HTTP/HTTPS traffic into the cluster
? Routes requests to different services based on paths or domains
? Handles TLS termination (SSL certificates for HTTPS)
? Supports advanced load balancing strategies
How Ingress Works in Kubernetes
1?? A user requests https://example.com/app1
2?? The Ingress Controller receives the request
3?? It matches the request with an Ingress rule
4?? The request is forwarded to the correct Kubernetes Service
5?? The Service routes it to the correct Pod
?? Ingress simplifies external access to applications while providing powerful routing capabilities!
?? Understanding Ingress Controllers: NGINX, Traefik, HAProxy
An Ingress Controller is a pod running inside Kubernetes that processes Ingress rules and routes traffic accordingly.
Ingress Controller and the Features
NGINX Ingress: Standard, widely used Fast, stable, TLS support, path-based routing
Traefik Ingress: Cloud-native environments Auto-discovery, dynamic config, metrics
HAProxy Ingress: High-performance traffic routing Fast processing, load balancing, security
?? The choice of Ingress Controller depends on your application needs!
?? Scenario 1: Deploying and Using NGINX Ingress Controller
?? Overview
We will deploy NGINX Ingress Controller, configure an Ingress resource, and test external access.
?? Use Case:
? Exposes multiple applications using a single LoadBalancer IP
? Routes traffic based on the request path (/app1, /app2)
Step 1: Install NGINX Ingress Controller
For Bare-Metal Clusters, use Helm:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install nginx-ingress ingress-nginx/ingress-nginx
Verify the deployment:
kubectl get pods -n kube-system -l app.kubernetes.io/name=ingress-nginx
Step 2: Deploy Two Sample Applications
Create a Deployment for app1
apiVersion: apps/v1
kind: Deployment
metadata:
name: app1
spec:
replicas: 2
selector:
matchLabels:
app: app1
template:
metadata:
labels:
app: app1
spec:
containers:
- name: app1
image: hashicorp/http-echo
args:
- "-text=Welcome to App1"
Expose app1 with a Service
apiVersion: v1
kind: Service
metadata:
name: app1-service
spec:
selector:
app: app1
ports:
- port: 80
targetPort: 5678
Apply:
kubectl apply -f app1.yaml
kubectl apply -f app1-service.yaml
Repeat the same for app2
Modify labels and service names accordingly.
Step 3: Create an Ingress Resource
Ingress Configuration (ingress.yaml)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- host: myapp.local
http:
paths:
- path: /app1
pathType: Prefix
backend:
service:
name: app1-service
port:
number: 80
- path: /app2
pathType: Prefix
backend:
service:
name: app2-service
port:
number: 80
Apply the Ingress:
kubectl apply -f ingress.yaml
Verify:
kubectl get ingress
Output:
NAME CLASS HOSTS ADDRESS PORTS
app-ingress <none> myapp.local <external-ip> 80
Step 4: Test Ingress Routing
If using Minikube, map the domain:
minikube tunnel
Modify /etc/hosts:
127.0.0.1 myapp.local
Test routing:
curl https://myapp.local/app1
curl https://myapp.local/app2
Expected Output:
Welcome to App1
Welcome to App2
? Ingress successfully routes traffic based on the request path!
?? Scenario 2: Configuring TLS with Ingress (HTTPS Traffic)
?? Overview
We will secure the Ingress using TLS/SSL certificates.
?? Use Case:
? Encrypt traffic with HTTPS
领英推荐
? Ensure secure communication with clients
Step 1: Generate a TLS Certificate
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=myapp.local"
Create a Kubernetes Secret for TLS:
kubectl create secret tls my-tls-secret --key tls.key --cert tls.crt
Step 2: Update the Ingress to Use TLS
Modify ingress.yaml:
spec:
tls:
- hosts:
- myapp.local
secretName: my-tls-secret
Apply the updated Ingress:
kubectl apply -f ingress.yaml
Test HTTPS Access:
curl -k https://myapp.local/app1
? Ingress now secures traffic with TLS!
?? Scenario 3: Multi-Domain Ingress Routing (Serving Multiple Applications with Different Domains)
?? Overview
Imagine you’re running multiple applications that need to be served under different domains (e.g., app1.example.com and app2.example.com).
?? Use Case:
? Route traffic based on hostnames instead of paths.
? Ideal for multi-tenant environments (SaaS applications, microservices, etc.).
? Helps serve multiple domains using a single Ingress Controller.
Step 1: Deploy Two Applications (App1 and App2)
We will reuse the previous app1 and app2 Deployments and Services, ensuring each has a separate Service.
Verify the services:
kubectl get svc
Expected output:
NAME TYPE CLUSTER-IP PORT(S)
app1-service ClusterIP 10.100.1.50 80/TCP
app2-service ClusterIP 10.100.1.51 80/TCP
Step 2: Create a Multi-Domain Ingress Resource
Now, let’s create an Ingress to route requests based on hostnames.
Ingress Configuration (multi-domain-ingress.yaml)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-domain-ingress
spec:
rules:
- host: app1.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app1-service
port:
number: 80
- host: app2.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app2-service
port:
number: 80
Apply the Ingress:
kubectl apply -f multi-domain-ingress.yaml
Verify:
kubectl get ingress
Expected Output:
NAME CLASS HOSTS ADDRESS PORTS
multi-domain-ingress <none> app1.example.com,app2.example.com <external-ip> 80
Step 3: Test Multi-Domain Routing
Since we are working on a local cluster, we need to modify our local DNS resolution (unless we have real DNS records pointing to our cluster).
For Minikube Users:
Start Minikube’s Ingress tunnel:
minikube tunnel
Modify the /etc/hosts file (Linux/macOS) or C:\Windows\System32\drivers\etc\hosts (Windows):
127.0.0.1 app1.example.com
127.0.0.1 app2.example.com
For Cloud-Based Kubernetes (AWS/GCP/Azure):
Step 4: Verify the Ingress Routing
Test app1:
curl https://app1.example.com
Expected Output:
Welcome to App1
Test app2:
curl https://app2.example.com
Expected Output:
Welcome to App2
? Success! The Ingress Controller now routes traffic based on different domains!
?? Bonus: Enabling TLS for Multi-Domain Ingress
If you want to secure both domains with TLS, you need to generate a multi-domain TLS certificate.
Step 1: Create a TLS Certificate for Both Domains
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout multi-tls.key -out multi-tls.crt \
-subj "/CN=app1.example.com" \
-addext "subjectAltName = DNS:app1.example.com,DNS:app2.example.com"
Step 2: Store the Certificate in a Kubernetes Secret
kubectl create secret tls multi-domain-tls --key multi-tls.key --cert multi-tls.crt
Step 3: Modify Ingress to Use TLS
Modify multi-domain-ingress.yaml:
spec:
tls:
- hosts:
- app1.example.com
- app2.example.com
secretName: multi-domain-tls
Apply the changes:
kubectl apply -f multi-domain-ingress.yaml
Step 4: Test Secure HTTPS Access
curl -k https://app1.example.com
curl -k https://app2.example.com
? Success! TLS is now enabled for both domains!
?? Key Takeaways
?? Let’s Discuss!
Which Ingress Controller do you use for traffic routing? Have you implemented multi-domain or multi-path ingress in production? Let’s discuss in the comments!
Follow Bavithran M for more DevOps, Kubernetes, and cloud-native insights.
Found this useful? Share it with your network!