You've set up a Kubernetes Ingress to expose your application, but requests return 404, 502, or connection refused errors. The Ingress resource exists, but traffic isn't reaching your pods. Ingress troubleshooting involves multiple components: the Ingress controller, Ingress resource, backend services, and network configuration.

Understanding Kubernetes Ingress

Ingress is a Kubernetes resource that manages external access to services, typically HTTP/HTTPS. An Ingress controller (like NGINX, Traefik, HAProxy) implements the Ingress rules. When Ingress doesn't work, the problem could be at the controller, the Ingress resource, backend services, or DNS/network configuration.

Diagnosis Commands

Check Ingress resource:

```bash # List Ingress resources kubectl get ingress -n namespace

# Describe Ingress kubectl describe ingress ingress-name -n namespace

# Check Ingress class kubectl get ingress ingress-name -n namespace -o jsonpath='{.spec.ingressClassName}' ```

Check Ingress controller:

```bash # Find Ingress controller pods kubectl get pods -A | grep -E "nginx|traefik|haproxy|ingress"

# Check controller service kubectl get svc -A | grep ingress

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

# Check controller configuration kubectl exec -n ingress-nginx -it ingress-nginx-controller -- nginx -T ```

Check backend services:

```bash # Verify backend service exists kubectl get svc service-name -n namespace

# Check service endpoints kubectl get endpoints service-name -n namespace

# Test service directly kubectl run curl-test --image=curlimages/curl --rm -it --restart=Never -- curl http://service-name.namespace:port/ ```

Check DNS and connectivity:

```bash # Verify DNS resolves to Ingress IP nslookup your-domain.com dig your-domain.com

# Test Ingress IP directly curl -H "Host: your-domain.com" http://ingress-ip/

# Check if port is accessible curl -v http://ingress-ip:80/ ```

Common Solutions

Solution 1: Fix Ingress Controller Issues

Ingress controller must be running:

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

# Check controller pods kubectl get pods -n ingress-nginx

# Check controller service has external IP kubectl get svc -n ingress-nginx ```

If controller not installed:

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

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

Check controller service type:

```yaml # For LoadBalancer (cloud) spec: type: LoadBalancer

# For NodePort (bare metal) spec: type: NodePort ports: - port: 80 nodePort: 30080 ```

Solution 2: Fix Ingress Resource Configuration

Correct Ingress resource syntax:

yaml
# Basic Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  namespace: namespace
spec:
  ingressClassName: nginx
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-service
            port:
              number: 80

Verify path configuration:

```yaml # PathType options: # - Exact: Exact URL match # - Prefix: URL prefix match (most common) # - ImplementationSpecific: Controller decides

# Common mistake: wrong pathType path: /api pathType: Exact # Only matches /api exactly, not /api/v1

# Fix: path: /api pathType: Prefix # Matches /api, /api/v1, /api/users, etc. ```

Solution 3: Fix Backend Service Issues

Backend service must match Ingress backend:

```bash # Check service referenced in Ingress kubectl get svc app-service -n namespace

# Service must exist and have endpoints kubectl get endpoints app-service -n namespace

# Service port must match kubectl get svc app-service -n namespace -o jsonpath='{.spec.ports}' ```

Fix service configuration:

yaml
# Ensure service port matches Ingress backend
apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  ports:
  - port: 80          # Must match Ingress backend.port.number
    targetPort: 8080  # Container port
  selector:
    app: myapp

Solution 4: Fix Ingress Class Issues

Ingress must reference correct class:

```bash # List IngressClasses kubectl get ingressclass

# Check Ingress class reference kubectl get ingress ingress-name -n namespace -o yaml | grep ingressClassName ```

Fix Ingress class:

```yaml spec: ingressClassName: nginx # Must match existing IngressClass

# Or create IngressClass apiVersion: networking.k8s.io/v1 kind: IngressClass metadata: name: nginx spec: controller: k8s.io/ingress-nginx ```

Solution 5: Fix TLS/Certificate Issues

HTTPS Ingress requires certificates:

```bash # Check TLS configuration kubectl get ingress ingress-name -n namespace -o yaml | grep -A 10 tls

# Check secret exists kubectl get secret tls-secret -n namespace

# Verify certificate content kubectl get secret tls-secret -n namespace -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -text -noout ```

Create TLS secret:

```bash # From existing certificate kubectl create secret tls tls-secret \ --cert=path/to/cert.crt \ --key=path/to/cert.key \ -n namespace

# Using cert-manager for automatic certificates kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml ```

Cert-manager example:

yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: app-cert
spec:
  secretName: tls-secret
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
  - app.example.com

Solution 6: Fix DNS Configuration

Domain must resolve to Ingress IP:

```bash # Get Ingress IP kubectl get ingress ingress-name -n namespace

# Should show Address with IP # Verify DNS nslookup app.example.com dig app.example.com +short

# Should return Ingress IP ```

Add DNS record:

```bash # If LoadBalancer Ingress # Add A record: app.example.com -> LOAD_BALANCER_IP

# If NodePort Ingress # Add A record: app.example.com -> NODE_IP # Ensure firewall allows NodePort (30000-32767)

# For multiple nodes, consider DNS load balancing or external LB ```

Solution 7: Fix Host Header Issues

Ingress routes by host header:

```bash # If no host specified in rules, catch-all # If host specified, must send correct header

# Test without DNS curl -H "Host: app.example.com" http://ingress-ip/

# Test with different host (should return 404 if host-specific) curl -H "Host: other.example.com" http://ingress-ip/ ```

Fix for wildcard hosts:

yaml
spec:
  rules:
  - host: "*.example.com"  # Wildcard (not all controllers support)
    http:
      paths:
      - path: /
        backend:
          service:
            name: app-service
            port:
              number: 80

Solution 8: Check Ingress Controller Logs

For deeper debugging:

```bash # NGINX Ingress controller logs kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller

# Check for specific errors kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller | grep -i error

# Check configuration generation kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller | grep -i "app.example.com" ```

Check error pages:

bash
# NGINX error pages location
kubectl exec -n ingress-nginx ingress-nginx-controller -- cat /etc/nginx/nginx.conf

Verification

Test Ingress functionality:

```bash # Test HTTP curl -H "Host: app.example.com" http://ingress-ip/

# Test HTTPS (if configured) curl -k https://app.example.com/

# Test specific paths curl -H "Host: app.example.com" http://ingress-ip/api/

# Verify response from application curl -v -H "Host: app.example.com" http://ingress-ip/ ```

Check Ingress status:

bash
kubectl get ingress -n namespace
kubectl describe ingress ingress-name -n namespace

Common Ingress Issues

IssueSymptomsSolution
No controllerIngress has no AddressInstall Ingress controller
Wrong backend service502/503 errorsFix service name/port
Missing endpoints502 Bad GatewayEnsure pods are ready
Wrong IngressClassIngress not processedFix ingressClassName
TLS certificate invalidSSL errorsFix/create TLS secret
DNS not resolvingConnection refusedAdd DNS record
Host header mismatch404 Not FoundSend correct Host header
Path mismatch404 on some pathsFix path/pathType

Prevention Best Practices

Install and verify Ingress controller before creating resources. Use cert-manager for automatic certificate management. Test Ingress with curl and Host header before DNS changes. Monitor Ingress controller logs. Configure proper health checks. Document DNS and certificate requirements.

Ingress troubleshooting follows a path: controller -> Ingress resource -> backend service -> DNS. Check each layer systematically, starting with the controller running, then the Ingress configuration, then the backend services, and finally DNS resolution.