Introduction

Exposing multiple services with LoadBalancer creates multiple cloud load balancers (expensive!). Ingress provides HTTP/HTTPS routing to multiple services using a single load balancer, with features like path-based routing, SSL termination, and virtual hosting.

Understanding Kubernetes Ingress

The Problem Without Ingress:

Service 1 → LoadBalancer ($$$)
Service 2 → LoadBalancer ($$$)
Service 3 → LoadBalancer ($$$)
Total: 3 load balancers, high cost!

The Solution With Ingress:

                    ┌─→ Service 1
Ingress Controller ─┼─→ Service 2
(Single LB)         └─→ Service 3
Total: 1 load balancer, low cost!

What is Ingress? Ingress is an API object that manages external HTTP/HTTPS access to services in a cluster. It provides:

  • Layer 7 routing (HTTP/HTTPS)
  • Single entry point for multiple services
  • Advanced routing (path, host, headers)
  • SSL/TLS termination
  • Load balancing

Why Use Ingress?

  • Cost Savings: One load balancer instead of many
  • Centralized Management: Single point for routing rules
  • Advanced Features: SSL, authentication, rate limiting
  • Flexibility: Easy to add/modify routes
  • Production Ready: Battle-tested in large deployments

Ingress vs Service Types:

Feature ClusterIP NodePort LoadBalancer Ingress
External Access
Layer N/A L4 (TCP/UDP) L4 (TCP/UDP) L7 (HTTP/HTTPS)
Cost Free Free $$$ per service $ (single LB)
Path Routing
Host Routing
SSL Termination
Use Case Internal Development Simple external Production HTTP

Ingress Components

1. Ingress Resource (Rules)

  • Kubernetes API object
  • Defines routing rules
  • Specifies backends (services)
  • Configuration for SSL, paths, hosts

2. Ingress Controller (Implementation)

  • Actual load balancer/proxy
  • Reads Ingress resources
  • Implements routing rules
  • Handles traffic

Popular Ingress Controllers:

Controller Best For Features
NGINX General purpose Most popular, feature-rich
Traefik Cloud-native Auto-discovery, modern
HAProxy High performance Enterprise-grade
Contour Envoy-based Advanced routing
Kong API Gateway Plugins, authentication
AWS ALB AWS Native AWS integration
GCE Google Cloud Native GCP integration

How Ingress Works:

1. User requests: https://myapp.com/api
2. DNS resolves to Ingress Controller IP
3. Ingress Controller checks Ingress rules
4. Routes to appropriate Service
5. Service forwards to Pod
6. Response flows back

Installing Ingress Controller

Method 1: NGINX Ingress Controller (Cloud)

# Install NGINX Ingress Controller
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml

# Wait for deployment
kubectl wait --namespace ingress-nginx \
  --for=condition=ready pod \
  --selector=app.kubernetes.io/component=controller \
  --timeout=120s

# Verify installation
kubectl get pods -n ingress-nginx
kubectl get svc -n ingress-nginx

# Get external IP
kubectl get svc ingress-nginx-controller -n ingress-nginx

Method 2: Minikube

minikube addons enable ingress

# Verify
kubectl get pods -n ingress-nginx

Method 3: Helm (Recommended for Production)

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

helm install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --create-namespace \
  --set controller.replicaCount=2 \
  --set controller.nodeSelector."kubernetes\.io/os"=linux \
  --set defaultBackend.nodeSelector."kubernetes\.io/os"=linux

Verify Installation:

# Check controller is running
kubectl get pods -n ingress-nginx

# Check service
kubectl get svc -n ingress-nginx

# Check ingress class
kubectl get ingressclass

Basic Ingress - Simple Routing

What it does: Routes all traffic to a single service

Example:

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

Path Types Explained:

PathType Matching Example
Prefix Matches prefix /api matches /api/users
Exact Exact match only /api matches /api only
ImplementationSpecific Controller-specific Varies by controller

Test:

# Get Ingress IP
kubectl get ingress simple-ingress

# Test (replace with actual IP)
curl http://<INGRESS-IP>/

Host-Based Routing - Virtual Hosting

What it does: Routes traffic based on hostname (like Apache VirtualHost)

Use Case: Multiple applications on different domains

Example:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: virtual-host-ingress
spec:
  ingressClassName: nginx
  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
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080

How it works:

app1.example.com → app1-service
app2.example.com → app2-service
api.example.com  → api-service

Test:

# Add to /etc/hosts for testing
echo "<INGRESS-IP> app1.example.com app2.example.com" | sudo tee -a /etc/hosts

# Test
curl http://app1.example.com
curl http://app2.example.com

Path-Based Routing - URL Path Routing

What it does: Routes traffic based on URL path

Use Case: Microservices architecture, API versioning

Example 1: Basic Path Routing

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: path-based-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080
      - path: /web
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80
      - path: /admin
        pathType: Prefix
        backend:
          service:
            name: admin-service
            port:
              number: 3000

How it works:

myapp.example.com/api   → api-service:8080
myapp.example.com/web   → web-service:80
myapp.example.com/admin → admin-service:3000

Example 2: Path Routing with Rewrite

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: rewrite-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /api(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080

Rewrite explanation:

Request:  /api/users
Rewrite:  /users (sent to backend)

Example 3: API Versioning

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-versioning
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /v1
        pathType: Prefix
        backend:
          service:
            name: api-v1
            port:
              number: 8080
      - path: /v2
        pathType: Prefix
        backend:
          service:
            name: api-v2
            port:
              number: 8080
      - path: /v3
        pathType: Prefix
        backend:
          service:
            name: api-v3
            port:
              number: 8080

Combined Host and Path Routing

Example: Complete Multi-Service Setup

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: combined-routing
spec:
  ingressClassName: nginx
  rules:
  # Frontend application
  - host: www.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend
            port:
              number: 80
  
  # API with versioning
  - host: api.example.com
    http:
      paths:
      - path: /v1
        pathType: Prefix
        backend:
          service:
            name: api-v1
            port:
              number: 8080
      - path: /v2
        pathType: Prefix
        backend:
          service:
            name: api-v2
            port:
              number: 8080
  
  # Admin panel
  - host: admin.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: admin-panel
            port:
              number: 3000
  
  # Monitoring
  - host: monitoring.example.com
    http:
      paths:
      - path: /grafana
        pathType: Prefix
        backend:
          service:
            name: grafana
            port:
              number: 3000
      - path: /prometheus
        pathType: Prefix
        backend:
          service:
            name: prometheus
            port:
              number: 9090

TLS/SSL Configuration

HTTPS with TLS:

apiVersion: v1
kind: Secret
metadata:
  name: tls-secret
type: kubernetes.io/tls
data:
  tls.crt: <base64-encoded-cert>
  tls.key: <base64-encoded-key>
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - myapp.example.com
    secretName: tls-secret
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

Create TLS secret:

kubectl create secret tls tls-secret \
  --cert=path/to/tls.crt \
  --key=path/to/tls.key

Production Example

Complete multi-service setup:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: production-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - api.example.com
    - web.example.com
    secretName: example-tls
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /v1
        pathType: Prefix
        backend:
          service:
            name: api-v1
            port:
              number: 8080
      - path: /v2
        pathType: Prefix
        backend:
          service:
            name: api-v2
            port:
              number: 8080
  - host: web.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend
            port:
              number: 80

Common Annotations

annotations:
  # SSL
  nginx.ingress.kubernetes.io/ssl-redirect: "true"
  
  # Rate limiting
  nginx.ingress.kubernetes.io/limit-rps: "10"
  
  # CORS
  nginx.ingress.kubernetes.io/enable-cors: "true"
  
  # Timeouts
  nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"
  nginx.ingress.kubernetes.io/proxy-send-timeout: "30"
  
  # Authentication
  nginx.ingress.kubernetes.io/auth-type: basic
  nginx.ingress.kubernetes.io/auth-secret: basic-auth
  
  # Whitelist
  nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8"

Commands

kubectl get ingress
kubectl describe ingress my-ingress
kubectl delete ingress my-ingress
kubectl get svc -n ingress-nginx

Best Practices

  1. Use TLS for production
  2. Implement rate limiting
  3. Set timeouts appropriately
  4. Use cert-manager for auto SSL
  5. Monitor ingress metrics
  6. Implement authentication where needed

Troubleshooting

Ingress not working:

kubectl describe ingress my-ingress
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller
kubectl get svc -n ingress-nginx

502/503 errors:

  • Check backend service exists
  • Verify service endpoints
  • Check pod health

Conclusion

Ingress provides cost-effective, feature-rich HTTP routing for Kubernetes services.

Next: Helm Package Manager

Resources