Kubernetes Ingress Routing External Traffic to Services

A LoadBalancer Service gives one Service one public IP address. If you have 10 services that need public access, you would need 10 load balancers and 10 public IPs — expensive and hard to manage. Ingress solves this by acting as a single entry point that routes traffic to multiple Services based on URL path or hostname.

The Problem Ingress Solves

Think of Ingress as the main reception desk of a large office building. One front door, one receptionist. A visitor says "I'm here for the Marketing team" and gets directed to floor 3. Another says "I'm here for Engineering" and goes to floor 7. The building has one address, but visitors reach different teams based on who they ask for.

Internet → yourdomain.com (1 IP address, 1 Ingress)
               ↓
    Path: /api     → backend-service (Pods)
    Path: /shop    → shop-service (Pods)
    Path: /        → frontend-service (Pods)

What an Ingress Controller Is

An Ingress resource is just a configuration object — it describes the routing rules. The actual traffic routing is done by an Ingress Controller, which is a Pod running inside your cluster that reads Ingress resources and configures itself accordingly.

Popular Ingress Controllers:

  • NGINX Ingress Controller — Most widely used, open-source
  • Traefik — Modern, auto-discovers services, has a built-in dashboard
  • AWS ALB Ingress Controller — Uses AWS Application Load Balancer
  • GCE Ingress — Uses Google Cloud Load Balancer (default on GKE)

You must install an Ingress Controller before creating Ingress resources. On Minikube:

minikube addons enable ingress

A Simple Ingress: Path-Based Routing

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: backend-service
            port:
              number: 80
      - path: /shop
        pathType: Prefix
        backend:
          service:
            name: shop-service
            port:
              number: 80
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80

A request to myapp.example.com/api/users reaches the backend-service. A request to myapp.example.com/shop/cart reaches the shop-service. Everything else goes to the frontend.

Host-Based Routing

You can also route based on the full hostname — different domains or subdomains to different services:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-host-ingress
spec:
  rules:
  - host: api.mycompany.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
  - host: shop.mycompany.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: shop-service
            port:
              number: 80

This pattern lets you host multiple websites or APIs on the same cluster and same IP, each with its own domain.

TLS: HTTPS with Ingress

Add TLS termination to your Ingress so traffic from the internet is encrypted. You store the TLS certificate as a Secret and reference it in the Ingress.

# Create a TLS Secret
kubectl create secret tls myapp-tls \
  --cert=path/to/tls.crt \
  --key=path/to/tls.key
spec:
  tls:
  - hosts:
    - myapp.example.com
    secretName: myapp-tls
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80

The Ingress Controller handles TLS termination. Traffic between the Ingress Controller and your backend Services travels inside the cluster (typically unencrypted), while the internet-facing side is HTTPS.

Cert-Manager: Automatic TLS Certificates

Managing TLS certificates manually is tedious. cert-manager is a popular add-on that automatically provisions and renews TLS certificates from Let's Encrypt (a free certificate authority). Once installed and configured, you add one annotation to your Ingress:

annotations:
  cert-manager.io/cluster-issuer: letsencrypt-prod

Cert-manager detects the Ingress, requests a certificate from Let's Encrypt, and stores it as a Secret — all automatically.

Ingress Annotations

Annotations let you configure Ingress Controller-specific features without changing the Ingress spec. Common NGINX annotations:

AnnotationEffect
nginx.ingress.kubernetes.io/ssl-redirect: "true"Redirect HTTP to HTTPS
nginx.ingress.kubernetes.io/proxy-body-size: "10m"Allow up to 10MB request body
nginx.ingress.kubernetes.io/rate-limit: "100"Rate limit to 100 req/sec
nginx.ingress.kubernetes.io/rewrite-target: /Strip the path prefix before forwarding

Viewing and Debugging Ingress

kubectl get ingress
kubectl describe ingress my-app-ingress
kubectl get ingress my-app-ingress -o yaml

The describe output shows which rules are active, what Services they point to, and the address assigned by the Ingress Controller.

Key Points

  • Ingress routes external traffic to multiple Services through one IP address using hostname or path rules.
  • You need an Ingress Controller running in your cluster — NGINX is the most common choice.
  • Path-based routing sends different URL paths to different Services. Host-based routing uses subdomains.
  • TLS termination at the Ingress handles HTTPS for the public side while keeping internal traffic simple.
  • cert-manager automates Let's Encrypt certificate provisioning and renewal.

Leave a Comment