Advanced Lesson 8 of 14

Ingress

Route external HTTP/HTTPS traffic to your services. Path-based routing, TLS termination, and virtual hosts.

🧒 Simple Explanation (ELI5)

Think of a hotel front desk. Guests (HTTP requests) arrive at one entrance (one public IP). The front desk (Ingress) looks at who they're looking for — "I'm here for the conference" goes to the ballroom, "I need room 301" goes to floor 3. Without a front desk, you'd need a separate entrance for every department (a separate LoadBalancer for every service).

🤔 Why Use Ingress?

🔧 Technical Explanation

Ingress Components

ComponentRole
Ingress ResourceYAML definition of routing rules (host, path → service mapping)
Ingress ControllerActual software that implements the rules (NGINX, Traefik, HAProxy, cloud-native). Must be installed separately.
💡
Key Point

Creating an Ingress resource alone does nothing. You need an Ingress Controller running in your cluster. It watches for Ingress resources and configures routing accordingly.

📊 Visual: Ingress Routing

Ingress Traffic Flow
Internet Traffic
Cloud Load Balancer
Ingress Controller (NGINX)
Routing Rules
/api/* → api-service:80
/web/* → web-service:80
blog.example.com → blog-svc:80

⌨️ Hands-on

Install NGINX Ingress Controller

bash
# Using Helm
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

# Or using kubectl
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.9.4/deploy/static/provider/cloud/deploy.yaml

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

Path-based Routing

yaml
# ingress-path.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-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: 80
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-service
                port:
                  number: 80

TLS / HTTPS

bash
# Create TLS secret
kubectl create secret tls app-tls \
  --cert=tls.crt --key=tls.key
yaml
# ingress-tls.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress-tls
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - myapp.example.com
      secretName: app-tls
  rules:
    - host: myapp.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-service
                port:
                  number: 80
bash
# Apply and verify
kubectl apply -f ingress-tls.yaml
kubectl get ingress
kubectl describe ingress app-ingress-tls
💡
cert-manager

Use cert-manager to automatically provision and renew TLS certificates from Let's Encrypt. Add annotation cert-manager.io/cluster-issuer: letsencrypt-prod and cert-manager handles everything.

🐛 Debugging Scenarios

Scenario 1: Routing Not Working — 404 for All Paths

bash
# Check ingress is created
kubectl get ingress

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

# Check ingress controller logs
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller

# Common causes:
# - ingressClassName missing or wrong
# - Host doesn't match request (check DNS)
# - Backend service name/port wrong
# - Backend service has no endpoints

# Verify backend service works
kubectl get svc api-service
kubectl get endpoints api-service

Scenario 2: HTTPS Not Working

Scenario 3: 502 Bad Gateway

Cause: Ingress controller can reach the Service but the backend pods are unhealthy.

🎯 Interview Questions

Beginner

Q: What is an Ingress in Kubernetes?

An Ingress is a Kubernetes resource that manages external HTTP/HTTPS access to services. It provides routing rules (host-based and path-based), TLS termination, and load balancing at Layer 7 (HTTP). Unlike LoadBalancer Services (one LB per service), Ingress routes multiple services through a single entry point.

Q: What is an Ingress Controller?

An Ingress Controller is the software that implements Ingress rules. It watches for Ingress resources and configures a reverse proxy (NGINX, Traefik, HAProxy) accordingly. Kubernetes doesn't include one by default — you must install it. Popular choices: NGINX Ingress Controller, Traefik, AWS ALB Ingress Controller.

Q: What is the difference between Ingress and a LoadBalancer Service?

LoadBalancer Service: one cloud LB per service, Layer 4 (TCP/UDP), no path-based routing. Ingress: one LB for many services, Layer 7 (HTTP/HTTPS), supports path/host routing, TLS termination, rewrites. Use Ingress for HTTP services; LoadBalancer for non-HTTP (databases, gRPC, custom TCP).

Q: What is TLS termination?

TLS termination means the Ingress controller decrypts HTTPS traffic and forwards plain HTTP to backend services. This centralizes TLS certificate management and offloads encryption overhead from application pods. The traffic between Ingress and pods is typically unencrypted (within the cluster network).

Q: Can you have multiple Ingress resources in a cluster?

Yes. You can have multiple Ingress resources, even for the same hostname with different paths. The Ingress controller merges compatible rules. You can also run multiple Ingress controllers (e.g., NGINX for public, Traefik for internal) using ingressClassName to target specific controllers.

Intermediate

Q: What is the difference between pathType Prefix and Exact?

Prefix: Matches based on URL path prefix split by /. /api matches /api, /api/, /api/users. Exact: Only matches the exact path. /api matches /api only, not /api/users. There's also ImplementationSpecific where behavior depends on the controller.

Q: What annotations are commonly used with NGINX Ingress?

Key annotations: nginx.ingress.kubernetes.io/rewrite-target (URL rewriting), ssl-redirect (force HTTPS), proxy-body-size (max upload size), rate-limit-connections (rate limiting), auth-url (external auth), cors-allow-origin (CORS), proxy-connect-timeout (timeout tuning). Annotations are controller-specific.

Q: How does cert-manager work with Ingress?

cert-manager watches for Ingress resources with specific annotations (e.g., cert-manager.io/cluster-issuer: letsencrypt). It automatically creates a Certificate resource, completes the ACME challenge (HTTP-01 or DNS-01), obtains the certificate from Let's Encrypt, stores it as a TLS Secret, and renews it before expiry. Fully automated TLS.

Q: What is the Gateway API and how does it relate to Ingress?

Gateway API is the successor to Ingress. It provides more expressive routing (header-based, weighted), better role separation (infrastructure provider → cluster admin → developer), and native support for TCP/UDP. It uses Gateway, HTTPRoute, and GatewayClass resources. It's more extensible and avoids the annotation sprawl problem of Ingress.

Q: How do you handle WebSocket connections with Ingress?

NGINX Ingress supports WebSockets by default (HTTP Upgrade headers pass through). For long-lived connections, increase timeouts: nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" and proxy-send-timeout: "3600". Ensure session affinity if multiple Ingress controller replicas exist (or use sticky sessions).

Scenario-Based

Q: Users report "ERR_TOO_MANY_REDIRECTS" when accessing your app via HTTPS. What's happening?

Classic redirect loop: the Ingress controller redirects HTTP→HTTPS, but the backend app also redirects to HTTPS (seeing the forwarded request as HTTP). Fix: 1) Tell the app it's behind a proxy: set X-Forwarded-Proto headers. 2) Configure the app to trust the proxy's headers. 3) Or add annotation nginx.ingress.kubernetes.io/ssl-redirect: "false" if the app handles its own HTTPS logic.

Q: You have apps A, B, C and want api.example.com/a → service-a, /b → service-b, /c → service-c. How?

Create an Ingress with path-based routing. Use pathType: Prefix for each path. Important: add the rewrite-target annotation to strip the prefix before forwarding (so service-a sees / not /a). Test each path independently. Order matters with some controllers — more specific paths should be listed first.

Q: Your Ingress works for domain A but returns 404 for domain B, even though both Ingress resources exist. What do you check?

1) Check DNS: does domain B resolve to the Ingress controller's external IP? 2) Check ingressClassName — both must target the same controller. 3) Check the Ingress controller logs for domain B requests. 4) Verify the backend service for domain B has endpoints. 5) Check for conflicting Ingress rules (same host, different namespaces can cause issues).

Q: Your file upload endpoint returns 413 Request Entity Too Large. How do you fix it?

The NGINX Ingress controller defaults to 1MB max body size. Add annotation: nginx.ingress.kubernetes.io/proxy-body-size: "50m" on the Ingress resource. Also check if your backend has its own body size limit. For very large uploads, consider direct-to-storage uploads (signed URLs) to bypass the Ingress entirely.

Q: How would you implement canary deployments using Ingress?

NGINX Ingress supports canary annotations. Create a second Ingress resource with: nginx.ingress.kubernetes.io/canary: "true" and canary-weight: "10" (routes 10% traffic to canary). You can also route by header: canary-by-header: X-Canary. This allows gradual rollout testing before full deployment. For more advanced needs, use Argo Rollouts or Flagger.

🌍 Real-World Use Case

A multi-tenant SaaS platform uses Ingress to route 200+ customer domains:

📝 Summary

← Back to Kubernetes Course