Introduction
Exposing multiple services with LoadBalancer creates multiple cloud load balancers (expensive!). Ingress provides HTTP/HTTPS routing to multiple services using a single load balancer, with features like path-based routing, SSL termination, and virtual hosting.
Understanding Kubernetes Ingress
The Problem Without Ingress:
Service 1 → LoadBalancer ($$$)
Service 2 → LoadBalancer ($$$)
Service 3 → LoadBalancer ($$$)
Total: 3 load balancers, high cost!
The Solution With Ingress:
┌─→ Service 1
Ingress Controller ─┼─→ Service 2
(Single LB) └─→ Service 3
Total: 1 load balancer, low cost!
What is Ingress? Ingress is an API object that manages external HTTP/HTTPS access to services in a cluster. It provides:
- Layer 7 routing (HTTP/HTTPS)
- Single entry point for multiple services
- Advanced routing (path, host, headers)
- SSL/TLS termination
- Load balancing
Why Use Ingress?
- Cost Savings: One load balancer instead of many
- Centralized Management: Single point for routing rules
- Advanced Features: SSL, authentication, rate limiting
- Flexibility: Easy to add/modify routes
- Production Ready: Battle-tested in large deployments
Ingress vs Service Types:
Feature | ClusterIP | NodePort | LoadBalancer | Ingress |
---|---|---|---|---|
External Access | ❌ | ✅ | ✅ | ✅ |
Layer | N/A | L4 (TCP/UDP) | L4 (TCP/UDP) | L7 (HTTP/HTTPS) |
Cost | Free | Free | $$$ per service | $ (single LB) |
Path Routing | ❌ | ❌ | ❌ | ✅ |
Host Routing | ❌ | ❌ | ❌ | ✅ |
SSL Termination | ❌ | ❌ | ❌ | ✅ |
Use Case | Internal | Development | Simple external | Production HTTP |
Ingress Components
1. Ingress Resource (Rules)
- Kubernetes API object
- Defines routing rules
- Specifies backends (services)
- Configuration for SSL, paths, hosts
2. Ingress Controller (Implementation)
- Actual load balancer/proxy
- Reads Ingress resources
- Implements routing rules
- Handles traffic
Popular Ingress Controllers:
Controller | Best For | Features |
---|---|---|
NGINX | General purpose | Most popular, feature-rich |
Traefik | Cloud-native | Auto-discovery, modern |
HAProxy | High performance | Enterprise-grade |
Contour | Envoy-based | Advanced routing |
Kong | API Gateway | Plugins, authentication |
AWS ALB | AWS | Native AWS integration |
GCE | Google Cloud | Native GCP integration |
How Ingress Works:
1. User requests: https://myapp.com/api
2. DNS resolves to Ingress Controller IP
3. Ingress Controller checks Ingress rules
4. Routes to appropriate Service
5. Service forwards to Pod
6. Response flows back
Installing Ingress Controller
Method 1: NGINX Ingress Controller (Cloud)
# Install NGINX Ingress Controller
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml
# Wait for deployment
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=120s
# Verify installation
kubectl get pods -n ingress-nginx
kubectl get svc -n ingress-nginx
# Get external IP
kubectl get svc ingress-nginx-controller -n ingress-nginx
Method 2: Minikube
minikube addons enable ingress
# Verify
kubectl get pods -n ingress-nginx
Method 3: Helm (Recommended for Production)
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 \
--set controller.replicaCount=2 \
--set controller.nodeSelector."kubernetes\.io/os"=linux \
--set defaultBackend.nodeSelector."kubernetes\.io/os"=linux
Verify Installation:
# Check controller is running
kubectl get pods -n ingress-nginx
# Check service
kubectl get svc -n ingress-nginx
# Check ingress class
kubectl get ingressclass
Basic Ingress - Simple Routing
What it does: Routes all traffic to a single service
Example:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: simple-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
Path Types Explained:
PathType | Matching | Example |
---|---|---|
Prefix |
Matches prefix | /api matches /api/users |
Exact |
Exact match only | /api matches /api only |
ImplementationSpecific |
Controller-specific | Varies by controller |
Test:
# Get Ingress IP
kubectl get ingress simple-ingress
# Test (replace with actual IP)
curl http://<INGRESS-IP>/
Host-Based Routing - Virtual Hosting
What it does: Routes traffic based on hostname (like Apache VirtualHost)
Use Case: Multiple applications on different domains
Example:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: virtual-host-ingress
spec:
ingressClassName: nginx
rules:
- host: app1.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app1-service
port:
number: 80
- host: app2.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app2-service
port:
number: 80
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
How it works:
app1.example.com → app1-service
app2.example.com → app2-service
api.example.com → api-service
Test:
# Add to /etc/hosts for testing
echo "<INGRESS-IP> app1.example.com app2.example.com" | sudo tee -a /etc/hosts
# Test
curl http://app1.example.com
curl http://app2.example.com
Path-Based Routing - URL Path Routing
What it does: Routes traffic based on URL path
Use Case: Microservices architecture, API versioning
Example 1: Basic Path Routing
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: path-based-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: 8080
- path: /web
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
- path: /admin
pathType: Prefix
backend:
service:
name: admin-service
port:
number: 3000
How it works:
myapp.example.com/api → api-service:8080
myapp.example.com/web → web-service:80
myapp.example.com/admin → admin-service:3000
Example 2: Path Routing with Rewrite
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rewrite-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /api(/|$)(.*)
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
Rewrite explanation:
Request: /api/users
Rewrite: /users (sent to backend)
Example 3: API Versioning
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-versioning
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: api-v1
port:
number: 8080
- path: /v2
pathType: Prefix
backend:
service:
name: api-v2
port:
number: 8080
- path: /v3
pathType: Prefix
backend:
service:
name: api-v3
port:
number: 8080
Combined Host and Path Routing
Example: Complete Multi-Service Setup
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: combined-routing
spec:
ingressClassName: nginx
rules:
# Frontend application
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 80
# API with versioning
- host: api.example.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: api-v1
port:
number: 8080
- path: /v2
pathType: Prefix
backend:
service:
name: api-v2
port:
number: 8080
# Admin panel
- host: admin.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: admin-panel
port:
number: 3000
# Monitoring
- host: monitoring.example.com
http:
paths:
- path: /grafana
pathType: Prefix
backend:
service:
name: grafana
port:
number: 3000
- path: /prometheus
pathType: Prefix
backend:
service:
name: prometheus
port:
number: 9090
TLS/SSL Configuration
HTTPS with TLS:
apiVersion: v1
kind: Secret
metadata:
name: tls-secret
type: kubernetes.io/tls
data:
tls.crt: <base64-encoded-cert>
tls.key: <base64-encoded-key>
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
ingressClassName: nginx
tls:
- hosts:
- myapp.example.com
secretName: tls-secret
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
Create TLS secret:
kubectl create secret tls tls-secret \
--cert=path/to/tls.crt \
--key=path/to/tls.key
Production Example
Complete multi-service setup:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: production-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- api.example.com
- web.example.com
secretName: example-tls
rules:
- host: api.example.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: api-v1
port:
number: 8080
- path: /v2
pathType: Prefix
backend:
service:
name: api-v2
port:
number: 8080
- host: web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 80
Common Annotations
annotations:
# SSL
nginx.ingress.kubernetes.io/ssl-redirect: "true"
# Rate limiting
nginx.ingress.kubernetes.io/limit-rps: "10"
# CORS
nginx.ingress.kubernetes.io/enable-cors: "true"
# Timeouts
nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"
nginx.ingress.kubernetes.io/proxy-send-timeout: "30"
# Authentication
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
# Whitelist
nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8"
Commands
kubectl get ingress
kubectl describe ingress my-ingress
kubectl delete ingress my-ingress
kubectl get svc -n ingress-nginx
Best Practices
- Use TLS for production
- Implement rate limiting
- Set timeouts appropriately
- Use cert-manager for auto SSL
- Monitor ingress metrics
- Implement authentication where needed
Troubleshooting
Ingress not working:
kubectl describe ingress my-ingress
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller
kubectl get svc -n ingress-nginx
502/503 errors:
- Check backend service exists
- Verify service endpoints
- Check pod health
Conclusion
Ingress provides cost-effective, feature-rich HTTP routing for Kubernetes services.
Next: Helm Package Manager