Ingress Controllers (NGINX, Traefik, HAProxy) – Traffic Routing in Kubernetes

Ingress Controllers (NGINX, Traefik, HAProxy) – Traffic Routing in Kubernetes


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):

  • Ensure that app1.example.com and app2.example.com point to the LoadBalancer’s external IP in DNS records.


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

  • Ingress Controllers (NGINX, Traefik, HAProxy) enable powerful traffic routing inside Kubernetes.
  • Path-based routing directs requests to different apps using a single domain.
  • Multi-domain Ingress lets you expose multiple applications under different domains.
  • TLS termination ensures secure HTTPS traffic for all services.


?? 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!

要查看或添加评论,请登录

Bavithran M的更多文章

社区洞察

其他会员也浏览了