Ingress Resources

Ingress resources define HTTP and HTTPS routing rules for your Kubernetes Services. They specify how external traffic should be routed to Services based on hostnames, URL paths, and other HTTP attributes. Understanding Ingress resource structure and configuration options is essential for effectively routing web traffic in Kubernetes.

Ingress Resource Structure

An Ingress resource has three main sections:

  1. Metadata - Name, namespace, annotations
  2. Spec - Routing rules, TLS configuration, ingress class
  3. Status - Assigned IP, load balancer info (populated by controller)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: default
  annotations:
    # Controller-specific annotations
spec:
  ingressClassName: nginx
  rules:
    # Routing rules
  tls:
    # TLS configuration

Basic Ingress Resource

Here’s a minimal Ingress resource:

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

This routes all HTTP traffic to web-service on port 80.

Ingress Rules

Rules define how traffic is routed. Each rule can specify:

  • Host - HTTP hostname to match
  • Paths - URL paths to match
  • Backend - Service to route traffic to
graph TB A[HTTP Request] --> B{Matches Host?} B -->|Yes| C{Matches Path?} B -->|No| D[Default Backend or 404] C -->|Yes| E[Route to Backend Service] C -->|No| D style B fill:#fff4e1 style C fill:#fff4e1 style E fill:#e8f5e9 style D fill:#ffe1e1

Host-Based Rules

Route traffic based on the HTTP Host header:

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

Routing:

  • api.example.comapi-service
  • www.example.comweb-service
graph TB A[api.example.com] --> B[Ingress] C[www.example.com] --> B B --> D[API Service] B --> E[Web Service] style B fill:#e8f5e9 style D fill:#fff4e1 style E fill:#fff4e1

Path-Based Rules

Route traffic based on URL paths:

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

Path matching order:

  • Longest path matches first
  • /api/usersapi-service (matches /api prefix)
  • /admin/dashboardadmin-service (matches /admin prefix)
  • /web-service (catch-all)
graph TB A[example.com/api/users] --> B[Ingress] C[example.com/admin/dashboard] --> B D[example.com/] --> B B --> E[API Service] B --> F[Admin Service] B --> G[Web Service] style B fill:#e8f5e9 style E fill:#fff4e1 style F fill:#fff4e1 style G fill:#fff4e1

Path Types

Kubernetes supports three path types:

Prefix

Matches the path and all subpaths:

- path: /api
  pathType: Prefix

Matches: /api, /api/, /api/users, /api/v1/users

Exact

Matches only the exact path:

- path: /api
  pathType: Exact

Matches: /api only (not /api/ or /api/users)

ImplementationSpecific

Behavior depends on the Ingress Controller:

- path: /api
  pathType: ImplementationSpecific

Best practice: Use Prefix for most cases, Exact when you need precise matching.

Default Backend

A default backend handles requests that don’t match any rule:

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

Routing:

  • example.com/api/*api-service
  • example.com/* (other paths) → default-service
  • Other hosts → default-service

TLS Configuration

Configure SSL/TLS termination:

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

The TLS secret must exist and contain the certificate:

kubectl create secret tls example-tls \
  --cert=tls.crt \
  --key=tls.key
graph LR A[HTTPS Request] --> B[Ingress TLS Termination] B --> C[Decrypts with Certificate] C --> D[Routes to HTTP Backend] style A fill:#e1f5ff style B fill:#e8f5e9 style C fill:#fff4e1 style D fill:#fff4e1

Multiple TLS Hosts

You can configure multiple TLS hosts:

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

Resource Backend

Instead of routing to a Service, you can route to a resource (like a ConfigMap for static content):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: resource-backend-ingress
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - path: /static
        pathType: Prefix
        backend:
          resource:
            apiVersion: v1
            kind: ConfigMap
            name: static-content

Note: Resource backends are less common and controller support varies.

Annotations

Annotations provide controller-specific configuration:

NGINX Ingress Controller

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: annotated-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "10m"
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80

Common NGINX annotations:

  • nginx.ingress.kubernetes.io/rewrite-target - URL rewriting
  • nginx.ingress.kubernetes.io/ssl-redirect - Redirect HTTP to HTTPS
  • nginx.ingress.kubernetes.io/proxy-body-size - Max request body size
  • nginx.ingress.kubernetes.io/rate-limit - Rate limiting
  • nginx.ingress.kubernetes.io/cors-enable - Enable CORS

Complete Example

Here’s a complete Ingress with multiple hosts, paths, and TLS:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: complete-ingress
  namespace: production
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - api.example.com
    - www.example.com
    secretName: example-tls
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /v1
        pathType: Prefix
        backend:
          service:
            name: api-v1-service
            port:
              number: 80
      - path: /v2
        pathType: Prefix
        backend:
          service:
            name: api-v2-service
            port:
              number: 80
  - host: www.example.com
    http:
      paths:
      - path: /blog
        pathType: Prefix
        backend:
          service:
            name: blog-service
            port:
              number: 80
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

Ingress Status

The Ingress controller updates the status with the assigned IP:

kubectl get ingress example-ingress
NAME              CLASS   HOSTS                    ADDRESS         PORTS
example-ingress   nginx   api.example.com          203.0.113.1     80, 443

The ADDRESS field shows the external IP assigned by the Ingress Controller.

Best Practices

  1. Use descriptive names - Ingress names should indicate purpose
  2. Organize by namespace - Use namespaces to group related Ingress resources
  3. Use pathType Prefix - Most common and predictable behavior
  4. Order paths correctly - More specific paths before general ones
  5. Use TLS secrets - Store certificates in Kubernetes Secrets
  6. Document annotations - Controller-specific annotations should be documented
  7. Test routing - Verify all routing rules work as expected
  8. Monitor Ingress - Watch for routing issues and controller health
  9. Use ingressClassName - Explicitly specify which controller to use
  10. Plan hostnames - Design hostname structure before implementation

Troubleshooting

Ingress Not Created

  1. Check API version: Ensure networking.k8s.io/v1 is available
  2. Verify permissions: Ensure you have permission to create Ingress resources
  3. Check YAML syntax: Validate YAML syntax
  4. Review spec: Ensure spec section is correct

Rules Not Matching

  1. Check hostname: Verify DNS points to Ingress Controller IP
  2. Verify path matching: Check pathType and path are correct
  3. Test with curl: curl -H "Host: example.com" http://<ingress-ip>/api
  4. Check controller logs: Review Ingress Controller logs
  5. Verify Service exists: Ensure backend Service exists and has Endpoints

TLS Not Working

  1. Check secret exists: kubectl get secret <secret-name>
  2. Verify secret type: Should be kubernetes.io/tls
  3. Check TLS hosts: Ensure TLS hosts match rule hosts
  4. Verify certificate: Test certificate with openssl
  5. Check controller TLS support: Ensure controller supports TLS

404 Errors

  1. Verify path matching: Check path and pathType
  2. Check default backend: Verify default backend is configured
  3. Test Service directly: Bypass Ingress to test Service
  4. Review controller logs: Check for routing errors
  5. Verify Endpoints: Ensure backend Service has Endpoints

See Also