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:
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
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:
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:
View it:
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:
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:
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
TLS with Ingress
Ingress can terminate HTTPS using a Kubernetes TLS Secret.
Create TLS Secret:
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:
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
ClusterIPServices 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
ClusterIPfor backend Services - Use TLS Secrets for HTTPS
- Use meaningful hostnames
- Validate endpoints before debugging Ingress
- Use
kubectl describe ingressfor 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
ingressClassNameused? - 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
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
ClusterIPServices behind Ingress - Use TLS for production applications
- Ingress centralizes routing, SSL, and external access management