DEV Community

janak0ff
janak0ff

Posted on

Resolve Pod Deployment Issue

A junior DevOps team member encountered difficulties deploying a stack on the Kubernetes cluster. The pod fails to start, presenting errors. Let's troubleshoot and rectify the issue promptly.

  1. There is a pod named webserver, and the container within it is named nginx-container, its utilizing the nginx:latest image.

  2. Additionally, there's a sidecar container named sidecar-container using the ubuntu:latest image.

Identify and address the issue to ensure the pod is in the running state and the application is accessible.


Introduction

Have you ever deployed a Kubernetes pod only to see it stuck in a failing state? Don't worry—this happens to everyone! In fact, troubleshooting is one of the most valuable skills you can develop as a DevOps engineer.

In this beginner-friendly guide, we'll walk through a real-world scenario where a pod fails to start and learn how to identify and fix the issue step by step.


What You'll Learn

  • How to check pod status and diagnose issues
  • How to read and understand error messages
  • How to fix common Kubernetes deployment issues
  • How to verify your fixes work correctly
  • Essential troubleshooting commands every DevOps engineer should know

Table of Contents

  1. Understanding the Problem
  2. Prerequisites
  3. Step 1: Check Pod Status
  4. Step 2: Get Detailed Information
  5. Step 3: Analyze Error Messages
  6. Step 4: Fix the Issue
  7. Step 5: Verify Your Fix
  8. Common Kubernetes Issues and Solutions
  9. Essential Troubleshooting Commands
  10. Best Practices
  11. Conclusion

Understanding the Problem

The Scenario

A junior DevOps team member tried to deploy a pod but it's failing to start. The pod is named webserver and should have two containers:

  1. Main Container: nginx-container using nginx:latest image
  2. Sidecar Container: sidecar-container using ubuntu:latest image

The pod is currently showing errors and not starting properly.

What Are We Looking For?

NAME        READY   STATUS             RESTARTS   AGE
webserver   1/2     ImagePullBackOff   0          2m18s
Enter fullscreen mode Exit fullscreen mode

This tells us:

  • 1/2 READY: Only one of two containers is ready
  • ImagePullBackOff: Kubernetes is having trouble pulling an image
  • RESTARTS: 0: The pod hasn't restarted yet

Prerequisites

Before we start, make sure you have:

  • ✅ A Kubernetes cluster (Minikube, kind, or cloud-based)
  • kubectl configured and working
  • ✅ Basic understanding of Kubernetes pods

Step 1: Check Pod Status

The first thing to do is check the status of your pods.

Command

kubectl get pods
Enter fullscreen mode Exit fullscreen mode

Expected Output

NAME        READY   STATUS             RESTARTS   AGE
webserver   1/2     ImagePullBackOff   0          2m18s
Enter fullscreen mode Exit fullscreen mode

Understanding the Output

Column Meaning Our Value
NAME Pod name webserver
READY Ready containers / Total containers 1/2 - One container is not ready
STATUS Current pod status ImagePullBackOff - Image can't be pulled
RESTARTS Number of restarts 0 - No restarts yet
AGE Pod age 2m18s - Created 2 minutes ago

What Does This Tell Us?

  • The pod was created (AGE: 2m18s)
  • One container is running (READY: 1/2)
  • The other container is failing because it can't pull the image (ImagePullBackOff)

Step 2: Get Detailed Information

Now let's get more details about what's actually happening.

Command

kubectl describe pod webserver
Enter fullscreen mode Exit fullscreen mode

Key Sections to Look For

Containers Section:

Containers:
  nginx-container:
    Container ID:   
    Image:          nginx:latests
    Image ID:       
    Port:           <none>
    Host Port:      <none>
    State:          Waiting
      Reason:       ImagePullBackOff
    Ready:          False
    Restart Count:  0
    Mounts:
      /var/log/nginx from shared-logs (rw)
Enter fullscreen mode Exit fullscreen mode

Sidecar Container (Running):

  sidecar-container:
    Container ID:  containerd://c6f35b248c85...
    Image:         ubuntu:latest
    Image ID:      docker.io/library/ubuntu@sha256:...
    State:          Running
    Ready:          True
Enter fullscreen mode Exit fullscreen mode

Events Section:

Events:
  Type     Reason     Age                Message
  ----     ------     ----               -------
  Normal   Scheduled  2m18s              Successfully assigned default/webserver to jump-host
  Normal   Pulling    2m16s              Pulling image "ubuntu:latest"
  Normal   Pulled     2m14s              Successfully pulled image "ubuntu:latest"
  Warning  Failed     52s                Failed to pull image "nginx:latests": not found
  Normal   BackOff    13s                Back-off pulling image "nginx:latests"
Enter fullscreen mode Exit fullscreen mode

What Did We Discover?

  1. nix-container is failing with ImagePullBackOff
  2. The image it's trying to pull is nginx:latests (notice the spelling)
  3. The sidecar container is running fine with ubuntu:latest
  4. The error message says: "not found"

Step 3: Analyze Error Messages

Let's look at the error messages more closely.

Error Messages from Events

Warning  Failed  52s  Failed to pull image "nginx:latests": 
rpc error: code = NotFound desc = failed to pull and unpack image 
"docker.io/library/nginx:latests": failed to resolve reference 
"docker.io/library/nginx:latests": docker.io/library/nginx:latests: not found
Enter fullscreen mode Exit fullscreen mode

Breaking Down the Error

Part of Error Meaning
Failed to pull image "nginx:latests" The image couldn't be downloaded
code = NotFound The image doesn't exist
docker.io/library/nginx:latests The full image path being looked for
not found The image tag doesn't exist

The Problem Identified! 🎯

Image: nginx:latests
Enter fullscreen mode Exit fullscreen mode

The issue: The image tag is misspelled! It should be nginx:latest but is written as nginx:latests (with an extra 's' at the end).

Why this happens:

  • nginx:latest exists on Docker Hub ✓
  • nginx:latests does NOT exist on Docker Hub ✗
  • Kubernetes can't find the image, so it fails

Image Tags: A Quick Refresher

Image Tag Meaning Exists?
nginx:latest The latest stable version ✅ Yes
nginx:1.21 Specific version ✅ Yes
nginx:latests Misspelled tag ❌ No
nginx:alpine Alpine-based version ✅ Yes

Step 4: Fix the Issue

Now that we know the problem, let's fix it!

Option A: Delete and Recreate (Recommended)

1. Delete the faulty pod:

kubectl delete pod webserver
Enter fullscreen mode Exit fullscreen mode

2. Create a corrected YAML file:

Create webserver-pod.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: webserver
  labels:
    app: web-app
spec:
  containers:
  # Main Nginx container
  - name: nginx-container
    image: nginx:latest              # ✅ Fixed from "latests"
    ports:
    - containerPort: 80
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log/nginx

  # Sidecar container
  - name: sidecar-container
    image: ubuntu:latest
    command: ["sh", "-c"]
    args: ["while true; do cat /var/log/nginx/access.log /var/log/nginx/error.log 2>/dev/null; sleep 30; done"]
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log/nginx

  volumes:
  - name: shared-logs
    emptyDir: {}

  restartPolicy: Never
Enter fullscreen mode Exit fullscreen mode

3. Apply the corrected pod:

kubectl apply -f webserver-pod.yaml
Enter fullscreen mode Exit fullscreen mode

Option B: Edit the Existing Pod (Not Always Possible)

Sometimes you can edit a pod directly:

kubectl edit pod webserver
Enter fullscreen mode Exit fullscreen mode

Find the image field and change:

image: nginx:latests
Enter fullscreen mode Exit fullscreen mode

to:

image: nginx:latest
Enter fullscreen mode Exit fullscreen mode

Save and exit. However, many pod properties can't be edited after creation, so deletion and recreation is often the only option.

Option C: One-Liner Quick Fix

If you want to create everything at once:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: webserver
  labels:
    app: web-app
spec:
  containers:
  - name: nginx-container
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log/nginx
  - name: sidecar-container
    image: ubuntu:latest
    command: ["sh", "-c"]
    args: ["while true; do cat /var/log/nginx/access.log /var/log/nginx/error.log 2>/dev/null; sleep 30; done"]
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log/nginx
  volumes:
  - name: shared-logs
    emptyDir: {}
  restartPolicy: Never
EOF
Enter fullscreen mode Exit fullscreen mode

Step 5: Verify Your Fix

After applying the fix, let's verify everything is working.

1. Check Pod Status

kubectl get pods
Enter fullscreen mode Exit fullscreen mode

Expected Output:

NAME        READY   STATUS    RESTARTS   AGE
webserver   2/2     Running   0          10s
Enter fullscreen mode Exit fullscreen mode

What this tells us:

  • 2/2 READY: Both containers are ready!
  • Running: The pod is running successfully!
  • RESTARTS: 0: No restarts occurred

2. Check Container Details

kubectl describe pod webserver | grep -A 10 "Containers:"
Enter fullscreen mode Exit fullscreen mode

Expected Output:

Containers:
  nginx-container:
    Container ID:   containerd://...
    Image:          nginx:latest
    State:          Running
    Ready:          True
  sidecar-container:
    Container ID:   containerd://...
    Image:          ubuntu:latest
    State:          Running
    Ready:          True
Enter fullscreen mode Exit fullscreen mode

3. Check Container Names

kubectl get pod webserver -o jsonpath='{.spec.containers[*].name}'
Enter fullscreen mode Exit fullscreen mode

Expected Output:

nginx-container sidecar-container
Enter fullscreen mode Exit fullscreen mode

4. Check Container Images

kubectl get pod webserver -o jsonpath='{.spec.containers[*].image}'
Enter fullscreen mode Exit fullscreen mode

Expected Output:

nginx:latest ubuntu:latest
Enter fullscreen mode Exit fullscreen mode

5. Verify the Website is Accessible

First, port forward to access the web server:

kubectl port-forward pod/webserver 8080:80
Enter fullscreen mode Exit fullscreen mode

Expected Output:

Forwarding from 127.0.0.1:8080 -> 80
Enter fullscreen mode Exit fullscreen mode

Then, in another terminal, test access:

curl http://localhost:8080
Enter fullscreen mode Exit fullscreen mode

Expected Output (HTML from Nginx):

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
...
</html>
Enter fullscreen mode Exit fullscreen mode

Common Kubernetes Issues and Solutions

Issue 1: ImagePullBackOff

Error:

ImagePullBackOff
Enter fullscreen mode Exit fullscreen mode

Solution:

  • Check if the image tag is spelled correctly
  • Verify the image exists on Docker Hub or your registry
  • Check network connectivity to the registry
  • Ensure you have permission to access private registries

Example Fix:

# ❌ Wrong
image: nginx:latests

# ✅ Correct
image: nginx:latest
Enter fullscreen mode Exit fullscreen mode

Issue 2: CrashLoopBackOff

Error:

CrashLoopBackOff
Enter fullscreen mode Exit fullscreen mode

Solution:

  • Check pod logs: kubectl logs <pod-name>
  • Check if container has a command
  • Ensure the command doesn't exit immediately
  • Check for application errors

Example Fix:

# ❌ Wrong - No command, exits immediately
- name: sidecar-container
  image: ubuntu:latest

# ✅ Correct - Keeps running
- name: sidecar-container
  image: ubuntu:latest
  command: ["sh", "-c"]
  args: ["while true; do sleep 30; done"]
Enter fullscreen mode Exit fullscreen mode

Issue 3: Container Not Starting

Error:

Container is waiting to start
Enter fullscreen mode Exit fullscreen mode

Solution:

  • Check if container name is correct
  • Check for resource constraints
  • Verify the image is pulling correctly

Issue 4: Pod Pending

Error:

Pending
Enter fullscreen mode Exit fullscreen mode

Solution:

  • Check if there are enough resources on the node
  • Check for node affinity or taints
  • Verify the namespace exists

Issue 5: Container Name Mismatch

Error:

'nginx-container' doesn't exist
Enter fullscreen mode Exit fullscreen mode

Solution:

  • Ensure container names match exactly
  • Check for spelling differences (case sensitive)
  • Verify the YAML has the correct name
# ❌ Wrong - Different name
- name: nginx

# ✅ Correct
- name: nginx-container
Enter fullscreen mode Exit fullscreen mode

Essential Troubleshooting Commands

Status Commands

Command Purpose
kubectl get pods List all pods
kubectl get pods -n <namespace> List pods in a specific namespace
kubectl get deployments List all deployments
kubectl get all List all resources
kubectl get events View cluster events
kubectl get events --sort-by='.lastTimestamp' Events sorted by time

Detailed Information Commands

Command Purpose
kubectl describe pod <pod-name> Detailed pod information
kubectl describe deployment <name> Detailed deployment information
kubectl logs <pod-name> View pod logs
kubectl logs <pod-name> -c <container> View specific container logs
kubectl logs <pod-name> --previous View previous container logs

Debugging Commands

Command Purpose
kubectl exec -it <pod-name> -- /bin/bash Shell into a pod
kubectl exec -it <pod-name> -c <container> -- /bin/bash Shell into a specific container
kubectl run test --image=busybox --rm -it -- /bin/sh Run a test pod
kubectl port-forward pod/<pod-name> 8080:80 Forward a port to a pod

YAML/JSON Commands

Command Purpose
kubectl get pod <pod-name> -o yaml Pod YAML output
kubectl get pod <pod-name> -o json Pod JSON output
kubectl get pod <pod-name> -o yaml > pod.yaml Save YAML to file

JSONPath Commands

Command Purpose
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].name}' Get container names
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].image}' Get container images
kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses[*].ready}' Check container readiness

Troubleshooting Flowchart

┌──────────────────────────────────────────────────┐
│                 kubectl get pods                │
└────────────────────┬─────────────────────────────┘
                     │
                     ▼
        ┌────────────────────────┐
        │   Pod Status?          │
        └───────────┬────────────┘
                    │
    ┌───────────────┼───────────────┐
    │               │               │
    ▼               ▼               ▼
┌─────────┐  ┌───────────┐  ┌──────────────┐
│Running  │  │ Pending   │  │ ImagePull    │
│         │  │           │  │ BackOff      │
└─────────┘  └───────────┘  └──────────────┘
    │              │               │
    │              │               │
    ▼              ▼               ▼
┌─────────┐  ┌───────────┐  ┌──────────────┐
│Success! │  │Check      │  │Check image   │
│         │  │Resources  │  │tag           │
│         │  │           │  │              │
└─────────┘  └───────────┘  └──────────────┘
Enter fullscreen mode Exit fullscreen mode

Best Practices

✅ DO's

1. Always Check the Logs First

kubectl logs <pod-name>
Enter fullscreen mode Exit fullscreen mode

2. Use describe to Get Detailed Information

kubectl describe pod <pod-name>
Enter fullscreen mode Exit fullscreen mode

3. Test Image Locally Before Deploying

docker pull nginx:latest
docker run -p 8080:80 nginx:latest
curl http://localhost:8080
Enter fullscreen mode Exit fullscreen mode

4. Use Specific Image Tags (Not :latest in Production)

# Development
image: nginx:latest

# Production
image: nginx:1.25.3
Enter fullscreen mode Exit fullscreen mode

5. Check Container Names Carefully

# Container names are case-sensitive!
- name: nginx-container  # ✅
- name: Nginx-Container  # ❌ Different case
Enter fullscreen mode Exit fullscreen mode

6. Use --dry-run to Validate YAML

kubectl apply -f pod.yaml --dry-run=client
Enter fullscreen mode Exit fullscreen mode

7. Save YAML Files to Version Control

# Always save your configurations
git add pod.yaml
git commit -m "Add webserver pod"
Enter fullscreen mode Exit fullscreen mode

❌ DON'Ts

1. Don't Delete Pods Without Checking First

# BAD - Delete without investigation
kubectl delete pod webserver

# GOOD - Describe first
kubectl describe pod webserver
# Then decide what to do
Enter fullscreen mode Exit fullscreen mode

2. Don't Edit Running Pods

# Pods are generally immutable
# Delete and recreate instead
Enter fullscreen mode Exit fullscreen mode

3. Don't Ignore Error Messages

# The error messages tell you what's wrong!
# Read them carefully
Enter fullscreen mode Exit fullscreen mode

4. Don't Use Misspelled Image Tags

# BAD - Misspelled
image: nginx:latests

# GOOD - Correct
image: nginx:latest
Enter fullscreen mode Exit fullscreen mode

5. Don't Forget to Verify Fixes

# Always verify after fixing
kubectl get pods
kubectl describe pod webserver
Enter fullscreen mode Exit fullscreen mode

Real-World Example: Complete Troubleshooting Session

Here's a complete session showing the troubleshooting process:

# Step 1: Check pods
$ kubectl get pods
NAME        READY   STATUS             RESTARTS   AGE
webserver   1/2     ImagePullBackOff   0          2m18s

# Step 2: Get details
$ kubectl describe pod webserver
...
Containers:
  nginx-container:
    Image:          nginx:latests
    State:          Waiting
      Reason:       ImagePullBackOff
...
Events:
  Warning  Failed  Failed to pull image "nginx:latests": not found

# Step 3: Identify the issue
# Problem: "nginx:latests" is misspelled (should be "nginx:latest")

# Step 4: Fix the issue
$ kubectl delete pod webserver
pod "webserver" deleted

$ cat > webserver-pod.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: webserver
  labels:
    app: web-app
spec:
  containers:
  - name: nginx-container
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log/nginx
  - name: sidecar-container
    image: ubuntu:latest
    command: ["sh", "-c"]
    args: ["while true; do cat /var/log/nginx/access.log /var/log/nginx/error.log 2>/dev/null; sleep 30; done"]
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log/nginx
  volumes:
  - name: shared-logs
    emptyDir: {}
  restartPolicy: Never
EOF

$ kubectl apply -f webserver-pod.yaml
pod/webserver created

# Step 5: Verify
$ kubectl get pods
NAME        READY   STATUS    RESTARTS   AGE
webserver   2/2     Running   0          10s

$ kubectl describe pod webserver | grep -A 5 "Containers:"
Containers:
  nginx-container:
    Image:          nginx:latest
    State:          Running
    Ready:          True
  sidecar-container:
    Image:          ubuntu:latest
    State:          Running
    Ready:          True

# Step 6: Test the application
$ kubectl port-forward pod/webserver 8080:80 &
Forwarding from 127.0.0.1:8080 -> 80

$ curl http://localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
</html>

# Success! 🎉
Enter fullscreen mode Exit fullscreen mode

Summary: Key Takeaways

Troubleshooting Steps

  1. Check pod status: kubectl get pods
  2. Get details: kubectl describe pod <name>
  3. Check logs: kubectl logs <name>
  4. Check events: kubectl get events
  5. Identify the issue: Read error messages carefully
  6. Fix the issue: Edit YAML, delete/recreate
  7. Verify: Check status, test accessibility

Common Issues to Look For

Issue What to Check
ImagePullBackOff Image tag spelling, image existence, registry access
CrashLoopBackOff Command existence, application errors, logs
Pending Resource availability, node constraints, namespace
Container mismatch Container names, case sensitivity, YAML formatting

Essential Commands

Situation Command
Check pod status kubectl get pods
Get detailed info kubectl describe pod <name>
View logs kubectl logs <name>
Check events kubectl get events
Delete pod kubectl delete pod <name>
Apply YAML kubectl apply -f <file>
Port forward kubectl port-forward pod/<name> <local>:<remote>

Conclusion

Congratulations! You've successfully learned how to troubleshoot and fix Kubernetes pod deployment issues. This is a critical skill that every DevOps engineer needs.

What You Learned

✅ How to check pod status and identify issues
✅ How to read and understand Kubernetes error messages
✅ How to fix common issues like ImagePullBackOff
✅ How to verify your fixes work correctly
✅ Essential troubleshooting commands and best practices

Key Takeaway

The most important skill in troubleshooting is reading error messages carefully. In this case, the error message clearly told us that nginx:latests was not found. Always start by understanding what the error is telling you before making changes.

Next Steps

Now that you've mastered basic troubleshooting, consider exploring:

  1. Advanced Pod Configuration - Resource limits, health checks
  2. Deployments - Rolling updates, rollbacks
  3. Services - Exposing applications
  4. ConfigMaps and Secrets - Configuration management
  5. StatefulSets - Stateful applications

Resources

Top comments (0)