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:
# 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: 80Verify 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:
# 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: myappSolution 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:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: app-cert
spec:
secretName: tls-secret
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- app.example.comSolution 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:
spec:
rules:
- host: "*.example.com" # Wildcard (not all controllers support)
http:
paths:
- path: /
backend:
service:
name: app-service
port:
number: 80Solution 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:
# NGINX error pages location
kubectl exec -n ingress-nginx ingress-nginx-controller -- cat /etc/nginx/nginx.confVerification
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:
kubectl get ingress -n namespace
kubectl describe ingress ingress-name -n namespaceCommon Ingress Issues
| Issue | Symptoms | Solution |
|---|---|---|
| No controller | Ingress has no Address | Install Ingress controller |
| Wrong backend service | 502/503 errors | Fix service name/port |
| Missing endpoints | 502 Bad Gateway | Ensure pods are ready |
| Wrong IngressClass | Ingress not processed | Fix ingressClassName |
| TLS certificate invalid | SSL errors | Fix/create TLS secret |
| DNS not resolving | Connection refused | Add DNS record |
| Host header mismatch | 404 Not Found | Send correct Host header |
| Path mismatch | 404 on some paths | Fix 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.