What's Actually Happening

Kubernetes Ingress is configured but traffic is not being routed to services. Requests to the Ingress host return errors or no response.

The Error You'll See

```bash $ curl http://myapp.example.com

404 Not Found ```

Service unavailable:

```bash $ curl http://myapp.example.com/api

503 Service Unavailable ```

Connection refused:

```bash $ curl http://myapp.example.com

curl: (7) Failed to connect to myapp.example.com port 80 ```

Ingress not created:

```bash $ kubectl get ingress

No resources found in default namespace. ```

Why This Happens

  1. 1.Ingress controller missing - No Ingress controller deployed
  2. 2.Wrong Ingress class - Ingress class doesn't match controller
  3. 3.Backend service not found - Service name or port wrong
  4. 4.Service has no endpoints - Service has no ready pods
  5. 5.Host DNS not configured - DNS not pointing to Ingress
  6. 6.TLS certificate missing - HTTPS requires certificate

Step 1: Check Ingress Controller

```bash # Check Ingress controller deployment: kubectl get pods -n ingress-nginx

# Common controllers: # - NGINX Ingress: namespace ingress-nginx or nginx-ingress # - Traefik: namespace traefik # - HAProxy: namespace haproxy-ingress

# Check controller service: kubectl get svc -n ingress-nginx

# Check controller logs: kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx

# Check controller config: kubectl get configmap -n ingress-nginx ingress-nginx-controller

# Install NGINX Ingress if missing: kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml

# Or with Helm: helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm install ingress-nginx ingress-nginx/ingress-nginx ```

Step 2: Check Ingress Resource

```bash # Check Ingress exists: kubectl get ingress

# Check Ingress details: kubectl describe ingress my-ingress

# Check Ingress YAML: kubectl get ingress my-ingress -o yaml

# Verify Ingress class: kubectl get ingress my-ingress -o jsonpath='{.spec.ingressClassName}'

# Check rules: kubectl get ingress my-ingress -o jsonpath='{.spec.rules}'

# Check default backend: kubectl get ingress my-ingress -o jsonpath='{.spec.defaultBackend}'

# Example Ingress: apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: nginx rules: - host: myapp.example.com http: paths: - path: / pathType: Prefix backend: service: name: my-service port: number: 80 ```

Step 3: Check Backend Service

```bash # Check service exists: kubectl get svc my-service

# Check service details: kubectl describe svc my-service

# Check service port matches Ingress: kubectl get svc my-service -o jsonpath='{.spec.ports}'

# Check service type: kubectl get svc my-service -o jsonpath='{.spec.type}'

# Service should be ClusterIP (or NodePort/LoadBalancer for direct access)

# Check service selector: kubectl get svc my-service -o jsonpath='{.spec.selector}'

# Verify selector matches pods: kubectl get pods -l app=my-app ```

Step 4: Check Service Endpoints

```bash # Check endpoints: kubectl get endpoints my-service

# Endpoints should have pod IPs: # NAME ENDPOINTS # my-service 10.244.0.5:8080,10.244.0.6:8080

# If no endpoints, pods are not selected or not ready

# Check endpoint details: kubectl describe endpoints my-service

# Check pod readiness: kubectl get pods -l app=my-app

# Pods must be Ready (1/1) to be in endpoints

# Check pod labels match service selector: kubectl get pods --show-labels

# Check pod ports: kubectl get pods -l app=my-app -o jsonpath='{.items[0].spec.containers[0].ports}' ```

Step 5: Check Ingress Class

```bash # List Ingress classes: kubectl get ingressclasses

# Check Ingress class: kubectl describe ingressclass nginx

# Check controller handles the class: kubectl get ingressclass nginx -o yaml

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

# Ingress must reference correct class: spec: ingressClassName: nginx

# Or use annotation (older method): metadata: annotations: kubernetes.io/ingress.class: nginx

# Check default Ingress class: kubectl get ingressclass -o jsonpath='{.items[?(@.metadata.annotations["ingressclass.kubernetes.io/is-default-class"]=="true")].metadata.name}' ```

Step 6: Check DNS Configuration

```bash # Check DNS points to Ingress: dig myapp.example.com

# Should resolve to Ingress controller IP

# Check Ingress controller IP: kubectl get svc -n ingress-nginx ingress-nginx-controller

# For LoadBalancer type, use external IP # For NodePort, use node IP + port

# Check with nslookup: nslookup myapp.example.com

# Test with IP directly: curl -H "Host: myapp.example.com" http://INGRESS_IP

# For local testing: curl --resolve myapp.example.com:80:INGRESS_IP http://myapp.example.com ```

Step 7: Check Ingress Annotations

```bash # Common annotations: # nginx.ingress.kubernetes.io/rewrite-target: / # nginx.ingress.kubernetes.io/ssl-redirect: "false" # nginx.ingress.kubernetes.io/proxy-body-size: "10m"

# Check annotations: kubectl get ingress my-ingress -o jsonpath='{.metadata.annotations}'

# Check annotation effect: kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx | grep -i my-ingress

# Common issues with annotations: # - Wrong annotation format # - Annotation for wrong controller # - Missing required annotation

# Example rewrite: annotations: nginx.ingress.kubernetes.io/rewrite-target: /api/$2 # With path: /something(/|$)(.*) ```

Step 8: Check TLS Configuration

```bash # Check TLS in Ingress: kubectl get ingress my-ingress -o jsonpath='{.spec.tls}'

# TLS example: spec: tls: - hosts: - myapp.example.com secretName: my-tls-secret

# Check secret exists: kubectl get secret my-tls-secret

# Check secret type: kubectl get secret my-tls-secret -o jsonpath='{.type}' # Should be kubernetes.io/tls

# Check secret data: kubectl get secret my-tls-secret -o yaml

# Create TLS secret: kubectl create secret tls my-tls-secret \ --cert=tls.crt \ --key=tls.key

# Test HTTPS: curl -k https://myapp.example.com

# Check certificate: openssl s_client -connect myapp.example.com:443 -servername myapp.example.com ```

Step 9: Check Ingress Controller Config

```bash # NGINX Ingress ConfigMap: kubectl get configmap -n ingress-nginx ingress-nginx-controller -o yaml

# Check controller config: kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --config

# Common ConfigMap settings: data: use-forwarded-headers: "true" compute-full-forwarded-for: "true" proxy-buffer-size: "16k"

# Check controller service: kubectl describe svc -n ingress-nginx ingress-nginx-controller

# For NodePort, check ports: kubectl get svc -n ingress-nginx ingress-nginx-controller -o jsonpath='{.spec.ports}'

# Port format: # 80:31234/TCP (http) # 443:31345/TCP (https) ```

Step 10: Kubernetes Ingress Verification Script

```bash # Create verification script: cat << 'EOF' > /usr/local/bin/check-k8s-ingress.sh #!/bin/bash

INGRESS=${1:-""} NAMESPACE=${2:-"default"}

echo "=== Ingress Controller Status ===" kubectl get pods -n ingress-nginx -o wide 2>/dev/null || kubectl get pods -A -l app.kubernetes.io/name=ingress-nginx

echo "" echo "=== Ingress Controller Service ===" kubectl get svc -n ingress-nginx 2>/dev/null || kubectl get svc -A -l app.kubernetes.io/name=ingress-nginx

echo "" echo "=== Ingress Classes ===" kubectl get ingressclasses

echo "" echo "=== Ingress Resources ===" kubectl get ingress -n $NAMESPACE

if [ -n "$INGRESS" ]; then echo "" echo "=== Ingress Details: $INGRESS ===" kubectl describe ingress $INGRESS -n $NAMESPACE

echo "" echo "=== Backend Service ===" SERVICE=$(kubectl get ingress $INGRESS -n $NAMESPACE -o jsonpath='{.spec.rules[0].http.paths[0].backend.service.name}') kubectl get svc $SERVICE -n $NAMESPACE kubectl get endpoints $SERVICE -n $NAMESPACE

echo "" echo "=== Service Pods ===" SELECTOR=$(kubectl get svc $SERVICE -n $NAMESPACE -o jsonpath='{.spec.selector}') kubectl get pods -n $NAMESPACE -l $(echo $SELECTOR | tr ':' '=' | tr ',' ' ') fi

echo "" echo "=== Ingress Controller Logs (last 20) ===" kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --tail=20 2>/dev/null || echo "No logs found"

echo "" echo "=== DNS Test ===" if [ -n "$INGRESS" ]; then HOST=$(kubectl get ingress $INGRESS -n $NAMESPACE -o jsonpath='{.spec.rules[0].host}') if [ -n "$HOST" ]; then dig $HOST +short fi fi EOF

chmod +x /usr/local/bin/check-k8s-ingress.sh

# Usage: /usr/local/bin/check-k8s-ingress.sh my-ingress default

# Quick check: alias k8s-ingress='kubectl get ingress -A' ```

Kubernetes Ingress Checklist

CheckCommandExpected
Ingress controllerget pods -n ingress-nginxRunning
Ingress resourceget ingressCreated
Ingress classget ingressclassesMatches controller
Backend serviceget svcExists and matches
Service endpointsget endpointsHas pod IPs
DNS resolutiondig hostnamePoints to Ingress IP

Verify the Fix

```bash # After fixing Ingress routing

# 1. Check Ingress controller kubectl get pods -n ingress-nginx // All Running

# 2. Check Ingress resource kubectl get ingress my-ingress // Created with correct class

# 3. Check backend service kubectl get svc my-service // Exists with correct port

# 4. Check endpoints kubectl get endpoints my-service // Has pod IPs

# 5. Test routing curl http://myapp.example.com // Returns application response

# 6. Check logs kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx // No routing errors ```

  • [Fix Kubernetes Service Not Found](/articles/fix-kubernetes-service-not-found)
  • [Fix Kubernetes Pod CrashLoopBackOff](/articles/fix-kubernetes-pod-crashloopbackoff)
  • [Fix Kubernetes Deployment Not Working](/articles/fix-kubernetes-deployment-not-working)