All Articles

What is a Kubernetes Ingress? Explained Simply (2026)

Kubernetes Ingress routes external HTTP/HTTPS traffic to your services. Here's what it is, how it works, and how to set one up — explained simply.

DevOpsBoysApr 11, 20264 min read
Share:Tweet

You have apps running in Kubernetes. Users need to reach them from the internet. That's what Ingress solves.

The Problem Ingress Solves

Without Ingress, you'd need a LoadBalancer Service for every single app:

app-1 → LoadBalancer (IP: 52.1.1.1)   → costs $
app-2 → LoadBalancer (IP: 52.1.1.2)   → costs $
app-3 → LoadBalancer (IP: 52.1.1.3)   → costs $

Three apps = three load balancers = three bills. With Ingress:

One LoadBalancer (IP: 52.1.1.1)
  → /api      → app-1 Service
  → /web      → app-2 Service
  → /admin    → app-3 Service

One load balancer, many apps. Route based on path or hostname.


What is an Ingress?

An Ingress is a Kubernetes resource that defines HTTP/HTTPS routing rules. It tells Kubernetes: "when traffic comes in for this host/path, send it to this Service."

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

This says: traffic for myapp.com/apiapi-service, everything else → frontend-service.


What is an Ingress Controller?

Here's the part that confuses everyone: an Ingress resource does nothing by itself.

You also need an Ingress Controller — a pod that actually reads your Ingress rules and configures a real load balancer or proxy.

Internet → Ingress Controller (NGINX/Traefik/etc.) → reads Ingress rules → routes to Services

The Ingress Controller is the actual traffic handler. The Ingress resource is just the config.

Popular Ingress Controllers:

ControllerBest for
NGINX IngressGeneral purpose, most popular
TraefikAuto-discovery, simple config
AWS ALB IngressEKS + ALB integration
Istio GatewayService mesh, advanced traffic
KongAPI gateway features

Installing NGINX Ingress Controller

bash
# Using Helm
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --create-namespace
 
# Verify
kubectl get pods -n ingress-nginx
kubectl get svc -n ingress-nginx
# You'll see a LoadBalancer service with an external IP

Path Types Explained

yaml
paths:
- path: /api
  pathType: Prefix    # matches /api, /api/users, /api/v1/...
  
- path: /login
  pathType: Exact     # matches ONLY /login, not /login/forgot
  
- path: /.*
  pathType: ImplementationSpecific  # regex, controller-dependent

Use Prefix for most cases. Use Exact when you need strict matching.


Host-Based Routing

Route different domains to different services:

yaml
spec:
  rules:
  - host: api.myapp.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
  - host: admin.myapp.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: admin-service
            port:
              number: 80

This is multi-tenant hosting — same load balancer IP, different hostnames, different apps.


Adding TLS (HTTPS)

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
  - hosts:
    - myapp.com
    secretName: myapp-tls   # cert-manager creates this Secret
  rules:
  - host: myapp.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80

With cert-manager installed, this automatically gets a free Let's Encrypt TLS certificate and renews it.


Common Ingress Annotations

Annotations let you configure the Ingress Controller behavior:

yaml
metadata:
  annotations:
    # NGINX specific
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"
    nginx.ingress.kubernetes.io/rate-limit: "100"
    
    # Timeouts
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"

Ingress vs Service Types

ClusterIPNodePortLoadBalancerIngress
Internal onlyYesNoNoNo
External accessNoYesYesYes
HTTP routingNoNoNoYes
TLS terminationNoNoNoYes
CostFreeFree$$/LB$ (one LB)

Rule of thumb:

  • Internal services (DB, cache) → ClusterIP
  • External services → Ingress + ClusterIP backend
  • Non-HTTP (TCP, UDP) → LoadBalancer Service

Quick Debug Commands

bash
# Check Ingress status
kubectl get ingress -n <namespace>
kubectl describe ingress <name> -n <namespace>
 
# Check if Ingress Controller is running
kubectl get pods -n ingress-nginx
 
# Check Ingress Controller logs
kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller --tail=50
 
# Test routing
curl -H "Host: myapp.com" http://<external-ip>/api

Summary

  • Ingress = routing rules (what goes where)
  • Ingress Controller = the actual proxy that enforces those rules
  • You need BOTH to route traffic
  • One load balancer can serve many apps using host/path routing
  • Add cert-manager for automatic TLS

Ingress is one of the most used Kubernetes resources in production. Once you understand the Controller + Resource split, everything else clicks.


Learn More

Newsletter

Stay ahead of the curve

Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.

Related Articles

Comments