Skip to content

Kubernetes_ingress

Ingress is a Kubernetes resource that provides HTTP/HTTPS routing to services within a cluster. It acts as an entry point for external traffic, enabling load balancing, SSL termination, and name-based virtual hosting.

Without Ingress, you would need to expose each service using a NodePort or LoadBalancer, which has limitations:

  • NodePort: Limited port range (30000-32767), no SSL support, manual load balancing
  • LoadBalancer: Requires cloud provider support, expensive (one per service), no path-based routing

Ingress solves these issues by providing:

  • Path-based and host-based routing
  • SSL/TLS termination
  • Single entry point for multiple services
  • Load balancing across service endpoints
┌─────────────────────────────────────────┐
│ Ingress Controller │
│ (e.g., nginx, Traefik, HAProxy) │
└───────────────┬─────────────────────────┘
┌─────────────────────────┼─────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Service A │ │ Service B │ │ Service C │
│ (api) │ │ (web) │ │ (admin) │
└─────────────────┘ └─────────────────┘ └─────────────────┘

The Ingress Controller is responsible for fulfilling Ingress resources. Popular options include:

  • NGINX Ingress Controller: Most popular, feature-rich
  • Traefik: Dynamic configuration, automatic service discovery
  • HAProxy: High performance, enterprise-grade
  • AWS ALB Ingress Controller: For AWS environments
Terminal window
# Add the ingress-nginx repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
# Install the NGINX Ingress Controller
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespace \
--set controller.publishService.enabled=true
Terminal window
# Apply the manifest
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.9.4/deploy/static/provider/cloud/deploy.yaml
# Verify the installation
kubectl get pods -n ingress-nginx
kubectl get svc -n ingress-nginx

Create a simple Ingress to route traffic based on paths:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-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: 80
- path: /web
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80

Key fields:

  • ingressClassName: Specifies which Ingress controller to use
  • rules: Defines routing rules for incoming requests
  • path: URL path to match
  • pathType: How to match the path (Exact, Prefix, ImplementationSpecific)
  • backend: Target service and port

Route traffic based on the Host header:

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

Secure your ingress with TLS certificates:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
ingressClassName: nginx
tls:
- hosts:
- secure.example.com
secretName: tls-secret
rules:
- host: secure.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: secure-service
port:
number: 80
---
apiVersion: v1
kind: Secret
metadata:
name: tls-secret
type: kubernetes.io/tls
data:
# Base64 encoded certificate (use cert-manager for production)
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZ...
tls.key: LS0tLS1CRUdJTiBQUklWQVRF...

Install cert-manager for automatic certificate management:

Terminal window
# Install cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
# Create a ClusterIssuer for Let's Encrypt
kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@example.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
EOF

Then annotate your Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts:
- secure.example.com
secretName: tls-secret
rules:
- host: secure.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: secure-service
port:
number: 80

Handle URL path transformations:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rewrite-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: api-service
port:
number: 80

Common annotations:

  • nginx.ingress.kubernetes.io/rewrite-target: Rewrite the matched URI
  • nginx.ingress.kubernetes.io/use-regex: Enable regex path matching
  • nginx.ingress.kubernetes.io/app-root: Redirect root path to specific path

Protect your services from abuse:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rate-limited-ingress
annotations:
nginx.ingress.kubernetes.io/limit-rps: "100"
nginx.ingress.kubernetes.io/limit-connections: "50"
nginx.ingress.kubernetes.io/limit-rpm: "1000"
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80

Most widely used, production-proven:

# Common annotations
annotations:
nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"
nginx.ingress.kubernetes.io/proxy-read-timeout: "30"
nginx.ingress.kubernetes.io/proxy-send-timeout: "30"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "*"

Dynamic, Kubernetes-native:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik-ingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
spec:
ingressClassName: traefik
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80

Configure a default backend for unmatched requests:

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

Check Ingress status:

Terminal window
# Describe Ingress for details
kubectl describe ingress my-app-ingress
# Get Ingress external IP
kubectl get ingress -o wide
# View Ingress controller logs
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
# Check Ingress controller pods
kubectl get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
  1. Use IngressClass: Always specify ingressClassName instead of annotations
  2. Enable SSL: Use TLS for all production traffic
  3. Set appropriate timeouts: Configure proxy timeouts for long-running requests
  4. Implement rate limiting: Protect services from DoS attacks
  5. Use health checks: Configure readiness/liveness probes for backend services
  6. Monitor ingress traffic: Set up metrics and logging
  7. Use secrets for certificates: Never embed certificates in Ingress resources

Ingress is essential for exposing Kubernetes services to the outside world. It provides:

  • HTTP/HTTPS routing with path and host-based rules
  • TLS/SSL termination with automatic certificate management
  • Load balancing across service endpoints
  • Rate limiting and access control
  • URL rewriting and redirection

Choose an Ingress controller based on your requirements:

  • NGINX: Feature-rich, widely supported
  • Traefik: Dynamic, easy configuration
  • AWS ALB: Native AWS integration