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:
- Create a pod named
pod-nginxusing thenginximage with thelatesttag. Ensure to specify the tag asnginx:latest. - Set the
applabel tonginx_app, and name the container asnginx-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)
- ✅
kubectlconfigured (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 │
└─────────────────────────────┘
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
🔧 Step-by-Step Guide
Step 1: Check Your Kubernetes Cluster
Before creating anything, let's verify our cluster is healthy:
kubectl cluster-info
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/...
kubectl get nodes
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
Step 2: Create the YAML Manifest
YAML is a human-readable data format used to define Kubernetes resources.
vi pod-nginx.yaml
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
Think of it like a recipe:
-
apiVersion– What version of the recipe format -
kind– What we're making (a Pod) -
metadata– The name and labels of our dish -
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
Output:
pod/pod-nginx created
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
Output:
NAME READY STATUS RESTARTS AGE
pod-nginx 1/1 Running 0 30s
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
Output:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
pod-nginx 1/1 Running 0 55s 10.22.0.9 jump-host <none>
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
Output:
NAME READY STATUS RESTARTS AGE LABELS
pod-nginx 1/1 Running 0 55s app=nginx_app
This confirms: Our label app=nginx_app has been applied!
Step 6: Inspect Your Pod
kubectl describe pod pod-nginx
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
The Events section shows the Pod's journey:
- ✅ Scheduled – Pod assigned to a node
- ✅ Pulling – Downloading the nginx image
- ✅ Pulled – Image downloaded
- ✅ Created – Container created
- ✅ Started – Container is running!
Step 7: View Container Logs
kubectl logs pod-nginx
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
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
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
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
📊 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
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
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 ✓
Issue 3: CrashLoopBackOff
# Check logs
kubectl logs pod-nginx
# Check previous logs
kubectl logs pod-nginx --previous
🚀 What's Next?
Now that you've created your first Pod:
- Expose the Pod with a Service
kubectl expose pod pod-nginx --port=80 --type=NodePort
- Scale up with a Deployment
- Access the Pod with port-forwarding
kubectl port-forward pod-nginx 8080:80
# Now visit localhost:8080 in your browser!
🎉 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:
- ✅ Checked cluster status
- ✅ Created a YAML manifest
- ✅ Deployed a Pod
- ✅ Verified it was running
- ✅ Inspected the Pod
- ✅ 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
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
Top comments (0)