What's Actually Happening
Kubernetes Ingress provides HTTP/HTTPS routing to Services. When Ingress doesn't work, requests to the Ingress host don't reach the backend Services. This happens when ingress controller isn't installed, rules are wrong, or backend services aren't ready.
The Error You'll See
```bash $ curl http://my-app.example.com curl: (7) Failed to connect to my-app.example.com port 80: Connection refused
# Or 404/502 from ingress controller $ curl http://my-app.example.com 404 page not found # Ingress controller but no matching rule ```
Why This Happens
- 1.Ingress controller not installed - No nginx-ingress, traefik, etc.
- 2.Ingress rules wrong - Wrong host, path, or backend service
- 3.Backend service not ready - Service has no endpoints
- 4.DNS not configured - Domain doesn't point to ingress IP
- 5.TLS certificate issues - Certificate not valid or missing
- 6.Ingress class mismatch - Ingress uses wrong controller
Step 1: Check Ingress Controller
kubectl get pods -A | grep ingressShould show ingress controller pods:
ingress-nginx-controller-xxx 1/1 Running ingress-nginx nginx-ingressIf missing, install ingress controller:
```bash # NGINX Ingress Controller kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml
# Or with Helm helm install ingress-nginx ingress-nginx/ingress-nginx ```
Step 2: Get Ingress Controller IP
kubectl get svc -A | grep ingressFind the LoadBalancer or NodePort:
ingress-nginx-controller LoadBalancer 10.96.100.100 192.168.1.100 80:30080/TCP,443:30443/TCPIf LoadBalancer IP pending (bare metal):
```bash # Use NodePort kubectl get svc ingress-nginx-controller -o yaml # Node port: 30080, 30443
# Or check host network kubectl get pods -n ingress-nginx -o wide ```
Step 3: Check Ingress Resource
kubectl get ingress
kubectl describe ingress my-ingressOutput:
Name: my-ingress
Namespace: default
Address: 192.168.1.100
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
my-app.example.com
/ my-service:80 (10.244.1.5:8080,10.244.2.3:8080)
Annotations: nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 5m nginx-ingress-controller Ingress default/my-ingress
Normal UPDATE 4m nginx-ingress-controller Ingress default/my-ingressCheck:
- Address shows ingress IP
- Backends show pod IPs (good)
- Backends show <error> (problem)
Step 4: Verify Backend Service
kubectl get svc my-service
kubectl get endpoints my-serviceEndpoints must have pod IPs:
NAME ENDPOINTS AGE
my-service 10.244.1.5:8080,10.244.2.3:8080 5mIf empty, fix service selector or pod readiness.
Step 5: Check Ingress Rules Configuration
kubectl get ingress my-ingress -o yamlCheck:
spec:
rules:
- host: my-app.example.com # Must match your domain
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service # Must exist
port:
number: 80 # Must match service portCommon mistakes: - Wrong hostname (doesn't match DNS) - Wrong service name - Wrong port number
Step 6: Test Ingress Controller Directly
```bash # Get ingress IP INGRESS_IP=$(kubectl get svc ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
# Test with Host header curl -H "Host: my-app.example.com" http://$INGRESS_IP
# Should return app response ```
If this works but real domain fails, DNS is wrong.
Step 7: Check DNS Configuration
```bash # Get ingress IP kubectl get svc ingress-nginx-controller
# Verify DNS points to ingress IP nslookup my-app.example.com dig my-app.example.com
# Should show ingress IP ```
If DNS wrong, update DNS records to point to ingress IP.
Step 8: Check Ingress Class
kubectl get ingressclass
kubectl get ingress my-ingress -o yaml | grep ingressClassNameIf ingress uses specific class:
spec:
ingressClassName: nginxEnsure that class exists and controller watches it.
Step 9: Check TLS Configuration
If using HTTPS:
kubectl get ingress my-ingress -o yaml | grep -A10 tlsCheck:
tls:
- hosts:
- my-app.example.com
secretName: my-tls-secretVerify secret:
kubectl get secret my-tls-secret
kubectl describe secret my-tls-secretStep 10: Check Ingress Annotations
Annotations control ingress controller behavior:
kubectl get ingress my-ingress -o yaml | grep annotations -A10Common annotations:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"Verify the Fix
```bash # Test ingress directly curl -H "Host: my-app.example.com" http://$INGRESS_IP
# Test via DNS (after DNS updated) curl http://my-app.example.com
# Check ingress status kubectl describe ingress my-ingress # Address should show IP, Backends should show endpoints ```
Prevention Tips
When creating ingress:
```yaml # Specify ingress class spec: ingressClassName: nginx
# Use exact path type pathType: Prefix # or Exact, ImplementationSpecific
# Ensure backend service exists first kubectl get svc my-service
# Create TLS secret if using HTTPS kubectl create secret tls my-tls-secret --cert=tls.crt --key=tls.key ```