DEV Community

janak0ff
janak0ff

Posted on

Day 48: Deploy Pods in Kubernetes Cluster

The Nautilus DevOps team is diving into Kubernetes for application management. One team member has a task to create a pod according to the details below:

  1. Create a pod named pod-nginx using the nginx image with the latest tag. Ensure to specify the tag as nginx:latest.
  2. Set the app label to nginx_app, and name the container as nginx-container.

Introduction

Welcome to Day 48 of my 100 Days of DevOps journey! Today, we're taking a big step into the world of Kubernetes – the industry-standard container orchestration platform.

What is Kubernetes?

Think of Kubernetes as a ship captain for your containers:

  • 🚢 Docker is like individual cargo containers
  • 🚢 Kubernetes is the ship that organizes, manages, and deploys them across the ocean

If Docker is about containerization, Kubernetes is about container orchestration at scale.


📋 What We'll Build Today

We're going to create our very first Pod in a Kubernetes cluster. A Pod is the smallest deployable unit in Kubernetes – think of it as a container with a name tag.

Our Task:

  • Pod Name: pod-nginx
  • Image: nginx:latest (a lightweight web server)
  • Label: app=nginx_app (for identification)
  • Container Name: nginx-container

🔧 Prerequisites

Before we begin, you'll need:

  • ✅ Access to a Kubernetes cluster (we're using K3s on jump-host)
  • kubectl configured (the Kubernetes command-line tool)
  • ✅ Basic understanding of YAML

📖 Understanding the Components

What is a Pod?

A Pod is the smallest deployable unit in Kubernetes. Think of it like:

┌─────────────────────────────┐
│          Pod                 │
│  ┌───────────────────────┐   │
│  │   Container           │   │
│  │   (nginx:latest)      │   │
│  │   Port: 80            │   │
│  └───────────────────────┘   │
│                               │
│  Labels: app=nginx_app        │
│  Name: pod-nginx              │
└─────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Key Points:

  • A Pod can have one or more containers
  • All containers in a Pod share the same network
  • Pods are ephemeral (they can be replaced at any time)

What is a Label?

Labels are like tags or stickers you put on containers to identify them:

labels:
  app: nginx_app    # This pod is a web server
  env: production   # It's running in production
  tier: frontend    # It serves the frontend
Enter fullscreen mode Exit fullscreen mode

🔧 Step-by-Step Guide

Step 1: Check Your Kubernetes Cluster

Before creating anything, let's verify our cluster is healthy:

kubectl cluster-info
Enter fullscreen mode Exit fullscreen mode

What this does: Shows information about your Kubernetes cluster

Expected Output:

Kubernetes control plane is running at https://127.0.0.1:6443
CoreDNS is running at https://127.0.0.1:6443/...
Metrics-server is running at https://127.0.0.1:6443/...
Enter fullscreen mode Exit fullscreen mode
kubectl get nodes
Enter fullscreen mode Exit fullscreen mode

What this does: Lists all nodes (servers) in your cluster

Expected Output:

NAME        STATUS   ROLES           AGE   VERSION
jump-host   Ready    control-plane   21m   v1.34.1+k3s1
Enter fullscreen mode Exit fullscreen mode

Step 2: Create the YAML Manifest

YAML is a human-readable data format used to define Kubernetes resources.

vi pod-nginx.yaml
Enter fullscreen mode Exit fullscreen mode

Let's break down the YAML file:

apiVersion: v1                    # ← The API version (v1 is the most stable)
kind: Pod                          # ← We're creating a Pod
metadata:
  name: pod-nginx                  # ← The name of our Pod
  labels:                          # ← Labels for identification
    app: nginx_app                 # ← Our custom label
spec:                              # ← The specification of the Pod
  containers:                      # ← List of containers
  - name: nginx-container          # ← Name of the container
    image: nginx:latest            # ← Which image to use
    ports:                         # ← Ports to expose
    - containerPort: 80            # ← The port the container listens on
Enter fullscreen mode Exit fullscreen mode

Think of it like a recipe:

  1. apiVersion – What version of the recipe format
  2. kind – What we're making (a Pod)
  3. metadata – The name and labels of our dish
  4. spec – The ingredients (containers) and instructions

Step 3: Create the Pod

Now let's create our Pod using the YAML file:

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

Output:

pod/pod-nginx created
Enter fullscreen mode Exit fullscreen mode

Breaking it down:

  • kubectl – The Kubernetes command-line tool
  • apply – Create or update resources
  • -f – Specify a file
  • pod-nginx.yaml – The file containing our Pod definition

Step 4: Watch Your Pod Come to Life

kubectl get pods
Enter fullscreen mode Exit fullscreen mode

Output:

NAME        READY   STATUS    RESTARTS   AGE
pod-nginx   1/1     Running   0          30s
Enter fullscreen mode Exit fullscreen mode

Understanding the columns:

  • NAME – The pod name
  • READY – 1/1 means 1 container is ready out of 1
  • STATUS – Running means it's working!
  • RESTARTS – How many times it's restarted (0 = healthy)
  • AGE – How long it's been running

Step 5: Get More Details

kubectl get pods -o wide
Enter fullscreen mode Exit fullscreen mode

Output:

NAME        READY   STATUS    RESTARTS   AGE   IP          NODE        NOMINATED NODE
pod-nginx   1/1     Running   0          55s   10.22.0.9   jump-host   <none>
Enter fullscreen mode Exit fullscreen mode

New information:

  • IP – The internal IP address of the Pod (10.22.0.9)
  • NODE – Which node the Pod is running on (jump-host)
kubectl get pods --show-labels
Enter fullscreen mode Exit fullscreen mode

Output:

NAME        READY   STATUS    RESTARTS   AGE   LABELS
pod-nginx   1/1     Running   0          55s   app=nginx_app
Enter fullscreen mode Exit fullscreen mode

This confirms: Our label app=nginx_app has been applied!


Step 6: Inspect Your Pod

kubectl describe pod pod-nginx
Enter fullscreen mode Exit fullscreen mode

This gives you everything about your Pod:

Name:             pod-nginx
Namespace:        default
Labels:           app=nginx_app
Status:           Running
IP:               10.22.0.9
Containers:
  nginx-container:
    Image:          nginx:latest
    State:          Running
    Port:           80/TCP
Events:
  Normal  Scheduled  55s   default-scheduler  Successfully assigned pod-nginx to jump-host
  Normal  Pulling    55s   kubelet            Pulling image "nginx:latest"
  Normal  Pulled     50s   kubelet            Successfully pulled image "nginx:latest"
  Normal  Created    50s   kubelet            Created container: nginx-container
  Normal  Started    50s   kubelet            Started container nginx-container
Enter fullscreen mode Exit fullscreen mode

The Events section shows the Pod's journey:

  1. Scheduled – Pod assigned to a node
  2. Pulling – Downloading the nginx image
  3. Pulled – Image downloaded
  4. Created – Container created
  5. Started – Container is running!

Step 7: View Container Logs

kubectl logs pod-nginx
Enter fullscreen mode Exit fullscreen mode

Output:

/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty...
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
...
2026/08/11 06:32:05 [notice] 1#1: start worker processes
Enter fullscreen mode Exit fullscreen mode

This shows what's happening inside the container – just like docker logs.


Step 8: Check Events

kubectl get events --field-selector involvedObject.name=pod-nginx
Enter fullscreen mode Exit fullscreen mode

Output:

LAST SEEN   TYPE     REASON      OBJECT          MESSAGE
55s         Normal   Scheduled   pod/pod-nginx   Successfully assigned pod-nginx to jump-host
55s         Normal   Pulling     pod/pod-nginx   Pulling image "nginx:latest"
50s         Normal   Pulled      pod/pod-nginx   Successfully pulled image "nginx:latest"
50s         Normal   Created     pod/pod-nginx   Created container: nginx-container
50s         Normal   Started     pod/pod-nginx   Started container nginx-container
Enter fullscreen mode Exit fullscreen mode

This shows all events related to our Pod.


📝 Complete Commands Summary

# 1. Check cluster status
kubectl cluster-info
kubectl get nodes

# 2. Create YAML file
cat > pod-nginx.yaml << 'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: pod-nginx
  labels:
    app: nginx_app
spec:
  containers:
  - name: nginx-container
    image: nginx:latest
    ports:
    - containerPort: 80
EOF

# 3. Create the Pod
kubectl apply -f pod-nginx.yaml

# 4. Verify the Pod
kubectl get pods
kubectl get pods -o wide
kubectl get pods --show-labels

# 5. Inspect the Pod
kubectl describe pod pod-nginx

# 6. View logs
kubectl logs pod-nginx

# 7. Check events
kubectl get events --field-selector involvedObject.name=pod-nginx
Enter fullscreen mode Exit fullscreen mode

📊 Pod Status Cheat Sheet

Status Meaning What to Do
Pending Pod is waiting to be scheduled Check node resources
Running Pod is working ✅ Nothing - it's healthy!
Succeeded Pod completed its task Nothing (for batch jobs)
Failed Pod failed Check logs
CrashLoopBackOff Container keeps crashing Check logs and configuration

🎯 Key Learnings

1. The Power of Declarative Configuration

Instead of running manual commands, we describe what we want in YAML, and Kubernetes figures out how to achieve it.

2. Pod Lifecycle

Every Pod goes through a journey:

Created → Scheduled → Pulling → Pulled → Created → Started → Running
Enter fullscreen mode Exit fullscreen mode

3. Labels are Like Tags

Labels help organize and identify resources:

  • app=nginx_app – This is a web server
  • You can filter by labels: kubectl get pods -l app=nginx_app

4. kubectl is Your Best Friend

Command Purpose
kubectl get List resources
kubectl describe Get detailed info
kubectl logs View container logs
kubectl apply Create/update resources
kubectl delete Remove resources

🔧 Troubleshooting Common Issues

Issue 1: Pod Stuck in Pending

# Check why
kubectl describe pod pod-nginx

# Common reasons:
# - Insufficient resources on nodes
# - Node not ready
Enter fullscreen mode Exit fullscreen mode

Issue 2: ImagePullBackOff

# Check the image name
kubectl describe pod pod-nginx | grep -A 5 "Failed"

# Common fix: Check if the image name is correct
# nginx:latest is correct ✓
Enter fullscreen mode Exit fullscreen mode

Issue 3: CrashLoopBackOff

# Check logs
kubectl logs pod-nginx

# Check previous logs
kubectl logs pod-nginx --previous
Enter fullscreen mode Exit fullscreen mode

🚀 What's Next?

Now that you've created your first Pod:

  1. Expose the Pod with a Service
   kubectl expose pod pod-nginx --port=80 --type=NodePort
Enter fullscreen mode Exit fullscreen mode
  1. Scale up with a Deployment
  2. Access the Pod with port-forwarding
   kubectl port-forward pod-nginx 8080:80
   # Now visit localhost:8080 in your browser!
Enter fullscreen mode Exit fullscreen mode

🎉 You Did It!

You've successfully deployed your first Kubernetes Pod! This is the foundation of everything in Kubernetes – from simple applications to complex microservices.

Your Kubernetes Journey:

  1. ✅ Checked cluster status
  2. ✅ Created a YAML manifest
  3. ✅ Deployed a Pod
  4. ✅ Verified it was running
  5. ✅ Inspected the Pod
  6. ✅ Viewed logs and events

📚 Quick Reference

Pod YAML Template

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    app: my-app
spec:
  containers:
  - name: my-container
    image: nginx:latest
    ports:
    - containerPort: 80
Enter fullscreen mode Exit fullscreen mode

Useful kubectl Commands

# Get pods
kubectl get pods
kubectl get pods -o wide
kubectl get pods --show-labels

# Describe pods
kubectl describe pod pod-name

# View logs
kubectl logs pod-name

# Delete a pod
kubectl delete pod pod-name

# Apply YAML
kubectl apply -f file.yaml

# Edit a resource
kubectl edit pod pod-name
Enter fullscreen mode Exit fullscreen mode

Top comments (0)