How to Fix Nginx Connection Refused on Kubernetes Pod
The Root Cause
“Nginx Connection Refused” on a Kubernetes Pod typically indicates that the application (Nginx) inside the container is not listening on the port that Kubernetes expects, or that the Service resource is unable to route traffic to the correct Pod. This often stems from a mismatch between the containerPort defined in the Pod/Deployment and the targetPort in the Service, or an incorrect Service selector preventing traffic from reaching the Nginx Pod entirely.
Quick Fix (CLI)
Use these commands to diagnose the issue immediately:
-
Check Pod Logs for Nginx Errors: Identify your Nginx pod name (e.g.,
nginx-deployment-xxx-yyy) and check its logs. Look for startup failures or configuration errors.kubectl get pods -l app=nginx kubectl logs <nginx-pod-name> -
Inspect Pod Status and Events: Examine the Pod’s status, events, and port configurations.
kubectl describe pod <nginx-pod-name> -
Inspect Service Endpoints: Verify if the Service has successfully discovered and linked to your Nginx Pods. If “Endpoints” is
<none>, the Service selector or Pod labels are likely mismatched, or the Pod is not ready.kubectl describe svc <nginx-service-name> -
Verify Nginx Process and Listening Port Inside the Container: If the Pod is running but connection is refused, exec into the container and check if Nginx is actually running and listening on the expected port (e.g., 80).
kubectl exec -it <nginx-pod-name> -- /bin/sh # Inside the container: ps aux | grep nginx netstat -tulnp | grep :80 # Or the expected port exit
Configuration Check
The resolution usually involves modifying one or more of these Kubernetes manifest files:
-
Deployment / Pod Specification (
deployment.yamlorpod.yaml):- Ensure
containerPortmatches the port Nginx is configured to listen on inside the container.
# Example: Deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 # <-- This must match Nginx's internal listen port - Ensure
-
Service Specification (
service.yaml):- Verify
targetPortmatches thecontainerPortdefined in your Pod/Deployment. - Confirm that the
selectorlabels accurately match thelabelsof your Nginx Pods.
# Example: Service.yaml apiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: app: nginx # <-- Must match Pod labels ports: - protocol: TCP port: 80 # Port the Service listens on targetPort: 80 # <-- Must match Pod's containerPort - Verify
-
Nginx Configuration (
nginx.conf): If Nginx is not listening on the expected port (e.g., 80), check its configuration. This file might be:- Mounted via a Kubernetes ConfigMap.
- Baked into the Docker image via the Dockerfile.
Ensure the
listendirective is correct:
# Example: snippet from nginx.conf server { listen 80; # <-- Ensure Nginx listens on the correct port server_name localhost; ... }If you modify
nginx.confvia a ConfigMap, you’ll need to roll out a new deployment to pick up the changes. If it’s in the Dockerfile, rebuild and redeploy the image.
Verification
After applying configuration changes, verify the fix using these steps:
-
Check Service Endpoints (Crucial): This command confirms if your Service has successfully found and connected to healthy Pods. You should see IP addresses listed under
Endpoints.kubectl get ep <nginx-service-name> -
Test Connectivity to the Service: Use
curlto send a request to your Nginx Service’s cluster IP or exposed endpoint (NodePort, LoadBalancer, Ingress).kubectl get svc <nginx-service-name> # If using ClusterIP from another pod: kubectl run -it --rm --image=busybox:latest curl-test -- /bin/sh # Inside busybox: wget -O- <nginx-service-name>:<port> exitOr, if exposed externally (e.g., LoadBalancer):
curl http://<external-ip-of-service>