Skip to content

8.14 Ingress in Kubernetes

Abstract

Ingress exposes HTTP/HTTPS applications using routing rules.

It helps route external traffic to internal Kubernetes Services using:

  • host-based routing
  • path-based routing
  • TLS termination
  • one external entry point for many applications

In production, Ingress is preferred over creating many separate LoadBalancer Services.


Why Ingress Is Needed

Assume an online store application:

Component Kubernetes Object Access Type
Web application Deployment + Pods Internal Pods
Web Service NodePort / LoadBalancer External traffic
MySQL database Pod + ClusterIP Service Internal only

Example flow:

User
www.my-online-store.com
NodePort / LoadBalancer
wear-service
wear Pods
mysql-service
MySQL Pod

Note

A database should normally be exposed using ClusterIP, not NodePort or LoadBalancer.


Problem with NodePort

A NodePort exposes an application on a high port such as:

http://<node-ip>:30080

Issues:

  • users must remember a port number
  • port range is usually 30000-32767
  • not ideal for HTTPS
  • difficult to manage multiple applications
  • not clean for production URLs

Warning

NodePort is useful for testing, labs, and simple access, but it is not usually the final production access pattern.


Problem with Many LoadBalancers

A LoadBalancer Service can expose one application externally.

Example:

wear-service       → cloud load balancer 1
video-service      → cloud load balancer 2
payment-service    → cloud load balancer 3

Problems:

  • each Service may create a separate cloud load balancer
  • cloud cost increases
  • TLS configuration becomes scattered
  • URL/path routing becomes harder
  • firewall and DNS management becomes complex

Danger

Creating one cloud load balancer per microservice can become expensive and operationally difficult.


What Ingress Provides

Ingress gives one controlled entry point for HTTP/HTTPS traffic.

User
DNS
LoadBalancer / NodePort
Ingress Controller
Ingress Rules
Kubernetes Services
Pods

Ingress can route:

Request Backend Service
my-online-store.com/wear wear-service
my-online-store.com/watch watch-service
wear.my-online-store.com wear-service
watch.my-online-store.com watch-service

Success

Ingress centralizes routing, TLS, and HTTP traffic management.


Ingress vs Service

Feature Service Ingress
Exposes Pods internally Yes No
Provides stable ClusterIP Yes No
Load balances to Pods Yes Uses Services
External L4 access NodePort / LoadBalancer Via controller Service
HTTP path routing No Yes
Host/domain routing No Yes
TLS termination Limited Yes

Note

Ingress does not replace Services. Ingress routes traffic to Services, not directly to Pods.


Ingress Has Two Parts

Ingress requires two things:

Component Purpose
Ingress Controller Actual reverse proxy/load balancer
Ingress Resource Routing rules written in YAML

Examples of Ingress Controllers:

  • NGINX Ingress Controller
  • HAProxy
  • Traefik
  • Contour
  • GCE Ingress
  • Istio Gateway

Warning

Kubernetes does not deploy an Ingress Controller by default. Creating an Ingress resource alone will not work unless a controller is installed.


High-Level Production Design

DNS: www.my-online-store.com
Cloud Load Balancer
Ingress Controller Service
Ingress Controller Pod
Ingress Resource Rules
wear-service / video-service
Application Pods

Tip

Use one external load balancer for the Ingress Controller, then manage application routing inside Kubernetes using Ingress resources.


Ingress Controller

An Ingress Controller is usually deployed as:

  • Deployment
  • Service
  • ConfigMap
  • ServiceAccount
  • Roles / ClusterRoles
  • RoleBindings / ClusterRoleBindings

For example, an NGINX Ingress Controller includes:

nginx-ingress-controller Deployment
nginx-ingress Service
nginx-configuration ConfigMap
nginx-ingress-serviceaccount ServiceAccount
RBAC permissions

Note

The controller watches Ingress resources and dynamically updates the reverse proxy configuration.


Minimal NGINX Ingress Controller Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-ingress-controller
spec:
  replicas: 1
  selector:
    matchLabels:
      name: nginx-ingress
  template:
    metadata:
      labels:
        name: nginx-ingress
    spec:
      serviceAccountName: nginx-ingress-serviceaccount
      containers:
      - name: nginx-ingress-controller
        image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.21.0
        args:
        - /nginx-ingress-controller
        - --configmap=$(POD_NAMESPACE)/nginx-configuration
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        ports:
        - name: http
          containerPort: 80
        - name: https
          containerPort: 443

Warning

This is a simplified learning example. For production, install the controller using the official Helm chart or vendor-supported manifests.


Ingress Controller ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configuration

Use the ConfigMap for controller-level configuration such as:

  • SSL settings
  • proxy timeouts
  • body size limits
  • logging options
  • redirects
  • custom NGINX options

Tip

Keep controller configuration separate from the controller image using a ConfigMap.


Expose the Ingress Controller

The Ingress Controller must be exposed outside the cluster.

Example using NodePort:

apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
  - port: 443
    targetPort: 443
    protocol: TCP
    name: https
  selector:
    name: nginx-ingress

In cloud environments, this Service is commonly type LoadBalancer.

Success

In production cloud clusters, expose the Ingress Controller through a managed load balancer.


Ingress Controller RBAC

Ingress Controllers need permissions to watch Kubernetes objects.

Common required resources:

  • Ingresses
  • Services
  • Endpoints
  • Secrets
  • ConfigMaps

Example ServiceAccount:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nginx-ingress-serviceaccount

Danger

Do not give the Ingress Controller full cluster-admin permissions unless absolutely required.


Ingress Resource

An Ingress Resource defines routing rules.

Basic structure:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-wear
spec:
  rules:
  - http:
      paths:
      - path: /wear
        pathType: Prefix
        backend:
          service:
            name: wear-service
            port:
              number: 80

Create it:

kubectl apply -f ingress-wear.yaml

View it:

kubectl get ingress
kubectl describe ingress ingress-wear

Default Backend

A default backend handles traffic that does not match any rule.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-default
spec:
  defaultBackend:
    service:
      name: wear-service
      port:
        number: 80

Note

A default backend is useful for returning a clean 404 page or routing unmatched traffic to a default application.


Path-Based Routing

Use path-based routing when the same domain serves multiple applications.

Example:

www.my-online-store.com/wear   → wear-service
www.my-online-store.com/watch  → watch-service
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-wear-watch
spec:
  rules:
  - host: www.my-online-store.com
    http:
      paths:
      - path: /wear
        pathType: Prefix
        backend:
          service:
            name: wear-service
            port:
              number: 80
      - path: /watch
        pathType: Prefix
        backend:
          service:
            name: watch-service
            port:
              number: 80

Example

This is useful when one domain hosts multiple application paths.


Host-Based Routing

Use host-based routing when each application has a separate domain or subdomain.

Example:

wear.my-online-store.com   → wear-service
watch.my-online-store.com  → watch-service
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-host-routing
spec:
  rules:
  - host: wear.my-online-store.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: wear-service
            port:
              number: 80

  - host: watch.my-online-store.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: watch-service
            port:
              number: 80

Tip

Host-based routing is cleaner when applications are logically separate.


Path Routing vs Host Routing

www.my-online-store.com/wear
www.my-online-store.com/watch

Best for:

  • one domain
  • multiple app paths
  • simple public URLs
wear.my-online-store.com
watch.my-online-store.com

Best for:

  • separate applications
  • separate teams
  • cleaner domain ownership

TLS with Ingress

Ingress can terminate HTTPS using a Kubernetes TLS Secret.

Create TLS Secret:

kubectl create secret tls online-store-tls \
  --cert=tls.crt \
  --key=tls.key

Ingress with TLS:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-tls
spec:
  tls:
  - hosts:
    - www.my-online-store.com
    secretName: online-store-tls

  rules:
  - host: www.my-online-store.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: wear-service
            port:
              number: 80

Success

In production, use HTTPS for public applications and automate certificate renewal with tools like cert-manager.


Ingress Traffic Flow

Client
DNS: www.my-online-store.com
External Load Balancer
Ingress Controller Service
Ingress Controller Pod
Ingress Resource Rule
Kubernetes Service
Application Pod

Note

Ingress routing is Layer 7 HTTP/HTTPS routing. It understands hosts and paths.


Required Backend Services

Ingress routes traffic to Kubernetes Services.

Example Service:

apiVersion: v1
kind: Service
metadata:
  name: wear-service
spec:
  selector:
    app: wear
  ports:
  - port: 80
    targetPort: 80

Warning

If the backend Service has no endpoints, Ingress will route traffic but the request will fail.

Check endpoints:

kubectl get endpoints wear-service

Production Best Practices

Recommended

  • Use an Ingress Controller supported by your platform
  • Run multiple controller replicas
  • Use TLS for external traffic
  • Automate certificates with cert-manager
  • Use ClusterIP Services behind Ingress
  • Keep backend Services private
  • Use host-based routing for separate applications
  • Use path-based routing for related apps under one domain
  • Apply resource requests and limits to the controller
  • Monitor controller latency, errors, and reloads

Security Best Practices

Danger

Ingress is an external entry point into the cluster. Misconfiguration can expose internal applications.

Recommended controls:

  • enable HTTPS
  • restrict admin endpoints
  • use WAF or cloud security controls when required
  • configure allowed hosts explicitly
  • avoid wildcard hosts unless needed
  • use NetworkPolicies behind Ingress
  • keep controller image updated
  • limit Ingress Controller RBAC permissions

Do's

  • Deploy an Ingress Controller before creating Ingress rules
  • Route traffic to Services, not Pods
  • Use ClusterIP for backend Services
  • Use TLS Secrets for HTTPS
  • Use meaningful hostnames
  • Validate endpoints before debugging Ingress
  • Use kubectl describe ingress for troubleshooting
  • Use production-grade controller installation methods

Don'ts

  • Don't expose every app with a separate LoadBalancer
  • Don't use NodePort as the final production design
  • Don't expose databases through Ingress
  • Don't give Ingress Controller excessive RBAC
  • Don't store TLS private keys in Git
  • Don't create Ingress resources without a controller
  • Don't forget DNS must point to the Ingress Controller endpoint

Troubleshooting Checklist

If Ingress is not working, check:

  • Is an Ingress Controller installed?
  • Is the controller Pod running?
  • Is the controller Service exposed?
  • Does DNS point to the controller endpoint?
  • Is the Ingress resource created?
  • Is the correct ingressClassName used?
  • Does the backend Service exist?
  • Does the backend Service have endpoints?
  • Are TLS Secrets valid?
  • Are NetworkPolicies blocking traffic?
  • Are controller logs showing routing errors?

Useful Commands

kubectl get ingress
kubectl describe ingress <ingress-name>
kubectl get svc
kubectl get endpoints <service-name>
kubectl get pods -n ingress-nginx
kubectl logs -n ingress-nginx <ingress-controller-pod>
kubectl get ingressclass
kubectl describe ingressclass <class-name>

Common Mistakes

Mistake Result
No Ingress Controller installed Ingress resource exists but does nothing
Wrong Service name Backend not found
Service has no endpoints 502 / 503 errors
DNS points to wrong IP Request never reaches cluster
TLS Secret missing HTTPS fails
Wrong path type Routing does not match as expected
Missing IngressClass Controller may ignore the Ingress

Bug

If kubectl get ingress shows the resource but traffic does not work, always check the Ingress Controller logs and backend Service endpoints.


IngressClass

Modern clusters often use IngressClass.

Example:

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: nginx
spec:
  controller: k8s.io/ingress-nginx

Ingress using a class:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-wear
spec:
  ingressClassName: nginx
  rules:
  - host: www.my-online-store.com
    http:
      paths:
      - path: /wear
        pathType: Prefix
        backend:
          service:
            name: wear-service
            port:
              number: 80

Note

If multiple Ingress Controllers exist, ingressClassName tells Kubernetes which controller should process the Ingress.


Summary

Quote

  • Services expose applications inside or outside the cluster
  • Ingress provides HTTP/HTTPS routing using hosts and paths
  • Ingress requires an Ingress Controller
  • Ingress resources define routing rules
  • Use ClusterIP Services behind Ingress
  • Use TLS for production applications
  • Ingress centralizes routing, SSL, and external access management