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-httpdusing thehttpdimage with thelatesttag. Ensure to specify the tag ashttpd:latest.Set the
applabel tohttpd_app, and name the container ashttpd-container.
Introduction
Welcome to the world of Kubernetes! In this blog post, I'll walk you through a real-world scenario that DevOps engineers face daily - creating and managing pods in a Kubernetes cluster. We'll explore a hands-on task from KodeKloud that demonstrates how to deploy a simple HTTP server pod with specific requirements.
Whether you're preparing for your CKA certification or just starting your Kubernetes journey, this guide will help you understand the fundamentals of pod creation, labeling, and container management.
The Scenario
Imagine you're part of the Nautilus DevOps team, and you've been tasked with creating a pod with the following specifications:
-
Pod Name:
pod-httpd -
Image:
httpd:latest(Apache HTTP Server) -
Label:
app=httpd_app -
Container Name:
httpd-container
The kubectl utility on the jump-host has already been configured to work with the Kubernetes cluster.
What We'll Cover
- Understanding Kubernetes Pods
- Creating Pods Imperatively vs. Declaratively
- Step-by-Step Implementation
- Verification and Troubleshooting
- Best Practices and Pro Tips
1. Understanding Kubernetes Pods
Before diving into the implementation, let's understand what we're working with:
What is a Pod?
A Pod is the smallest deployable unit in Kubernetes. Think of it as a wrapper for one or more containers that share:
- Network namespace (same IP address)
- Storage volumes
- Lifecycle management
In our case, we're creating a single-container pod running Apache HTTP Server.
Key Concepts
| Concept | Purpose |
|---|---|
| Pod | Atomic unit of deployment |
| Container | Running instance of a Docker image |
| Labels | Key-value pairs for organizing and selecting objects |
| Image Tag | Specific version of the container image |
2. Two Approaches to Create a Pod
Approach A: Imperative Command
The quick and dirty way (great for testing):
kubectl run pod-httpd \
--image=httpd:latest \
--labels=app=httpd_app \
--restart=Never \
--port=80
Pros: Fast, one-liner
Cons: Less control, harder to version control
Approach B: Declarative YAML Manifest
The professional way (recommended for production):
kubectl run pod-httpd \
--image=httpd:latest \
--labels=app=httpd_app \
--restart=Never \
--port=80 \
--dry-run=client -o yaml > pod-httpd.yaml
Pros: Version controllable, repeatable, auditable
Cons: Requires understanding YAML syntax
3. Step-by-Step Implementation
Let's walk through the complete process:
Step 1: Generate the YAML Manifest
First, we'll generate a base YAML file:
kubectl run pod-httpd \
--image=httpd:latest \
--labels=app=httpd_app \
--restart=Never \
--port=80 \
--dry-run=client -o yaml > pod-httpd.yaml
Step 2: Edit the YAML File
Open the file and modify the container name:
nano pod-httpd.yaml
Before (generated):
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
app: httpd_app
name: pod-httpd
spec:
containers:
- image: httpd:latest
name: pod-httpd # ← This needs to change
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Never
status: {}
After (modified):
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
app: httpd_app
name: pod-httpd
spec:
containers:
- image: httpd:latest
name: httpd-container # ← Updated container name
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Never
status: {}
Step 3: Apply the Configuration
Create the pod in your cluster:
kubectl apply -f pod-httpd.yaml
Expected output:
pod/pod-httpd created
Step 4: Verify the Pod Status
Check if the pod is running:
kubectl get pods
Output:
NAME READY STATUS RESTARTS AGE
pod-httpd 1/1 Running 0 2m7s
Step 5: Detailed Verification
Let's examine the pod in detail:
kubectl describe pod pod-httpd
Key information from the describe output:
- Status: Running
- Node: jump-host/10.244.244.241
- Labels: app=httpd_app
- Container: httpd-container (using httpd:latest)
- Events: Shows successful pull and start
Step 6: Verify Labels
Check that labels are correctly applied:
kubectl get pods --show-labels
Output:
NAME READY STATUS RESTARTS AGE LABELS
pod-httpd 1/1 Running 0 2m27s app=httpd_app
Step 7: Verify Container Name
Extract the container name using jsonpath:
kubectl get pod pod-httpd -o jsonpath='{.spec.containers[0].name}'
Output:
httpd-container
4. Understanding the YAML Manifest
Let's break down each section of our YAML file:
apiVersion: v1 # Kubernetes API version
kind: Pod # Resource type
metadata: # Metadata about the pod
name: pod-httpd # Pod name (must match spec)
labels: # Labels for organization
app: httpd_app # Label key-value pair
spec: # Pod specification
containers: # List of containers
- image: httpd:latest # Container image
name: httpd-container # Container name
resources: {} # Resource limits (none specified)
dnsPolicy: ClusterFirst # DNS policy
restartPolicy: Never # Restart policy (create once)
Important Notes:
-
apiVersionmust match the Kubernetes version -
metadata.nameis the pod name -
spec.containers[0].imageuses the full image name -
restartPolicy: Nevercreates a pod rather than a deployment
5. Advanced Verification Techniques
View Pod Logs
kubectl logs pod-httpd
Access the Web Server
Forward a local port to the pod:
kubectl port-forward pod/pod-httpd 8080:80
Then open http://localhost:8080 in your browser.
Exec into the Container
kubectl exec -it pod-httpd -- /bin/bash
Get Pod IP
kubectl get pod pod-httpd -o wide
Check YAML with Specific Fields
# Check pod name
kubectl get pod pod-httpd -o jsonpath='{.metadata.name}'
# Check image
kubectl get pod pod-httpd -o jsonpath='{.spec.containers[0].image}'
# Check labels
kubectl get pod pod-httpd -o jsonpath='{.metadata.labels}'
6. Troubleshooting Common Issues
Issue 1: Image Pull Error
ImagePullBackOff or ErrImagePull
Solution: Check if the image name is correct and accessible
kubectl describe pod pod-httpd | grep -A 5 Events
Issue 2: Pod Stuck in Pending State
PodPending
Solution: Check for resource constraints or scheduling issues
kubectl describe pod pod-httpd | grep -A 10 Events
Issue 3: CrashLoopBackOff
Container exits immediately
Solution: Check logs for application errors
kubectl logs pod-httpd
Issue 4: Wrong Container Name
If the container name doesn't match requirements:
kubectl edit pod pod-httpd
Or recreate the pod with correct name:
kubectl delete pod pod-httpd
kubectl run pod-httpd --image=httpd:latest --labels=app=httpd_app --restart=Never --dry-run=client -o yaml > pod-httpd.yaml
# Edit to change container name
kubectl apply -f pod-httpd.yaml
7. Best Practices and Pro Tips
✅ DO:
- Use declarative YAML: Version control your manifests
- Add resource limits: Prevent resource exhaustion
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- Use labels strategically: For easier management and selection
-
Use
--dry-run: Validate before applying - Add health checks: Implement liveness and readiness probes
❌ DON'T:
-
Don't use
:latestin production: Pin specific versions - Don't ignore resource limits: Can cause cluster instability
- Don't create pods without labels: Makes management harder
- Don't use imperative commands in production: Harder to track changes
Pro Tips:
- Use Namespaces:
kubectl create namespace development
kubectl apply -f pod-httpd.yaml -n development
- Add Readiness Probe:
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
- Add Liveness Probe:
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 20
periodSeconds: 10
- Add Environment Variables:
env:
- name: ENVIRONMENT
value: "production"
8. Complete Production-Ready Manifest
Here's what a production-ready version might look like:
apiVersion: v1
kind: Pod
metadata:
name: pod-httpd
namespace: production
labels:
app: httpd_app
environment: production
version: "1.0"
spec:
containers:
- name: httpd-container
image: httpd:2.4.54 # Pin to specific version
ports:
- containerPort: 80
name: http
protocol: TCP
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
env:
- name: ENVIRONMENT
value: "production"
- name: LOG_LEVEL
value: "info"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 5
restartPolicy: Always
9. Cleanup
When you're done with the pod:
# Delete the pod
kubectl delete pod pod-httpd
# Or delete using the YAML file
kubectl delete -f pod-httpd.yaml
# Verify deletion
kubectl get pods
10. Key Takeaways
- Pods are the foundation: Understanding pods is crucial for Kubernetes mastery
- Declarative > Imperative: Always prefer YAML manifests for production
- Labels are powerful: Use them for organization, selection, and grouping
- Verification is key: Always verify pod status, labels, and container names
- Probes improve reliability: Add health checks for self-healing
- Resource limits are essential: Prevent resource exhaustion and ensure stability
Conclusion
Congratulations! You've successfully created your first Kubernetes pod with specific requirements. This exercise demonstrates the fundamental skills needed for Kubernetes administration:
- Creating pods using both imperative and declarative approaches
- Understanding pod specifications and YAML structure
- Applying labels for organization
- Verifying pod status and configuration
- Troubleshooting common issues
The task we completed mirrors real-world scenarios that DevOps engineers face daily. As you continue your Kubernetes journey, these foundational skills will serve you well in more complex deployments involving services, deployments, configmaps, and persistent volumes.
Resources
- Official Kubernetes Documentation
- Kubernetes Pod Documentation
- KodeKloud Kubernetes Course
- Kubernetes Best Practices
Did this guide help you? Drop a comment below with your questions or experiences! 🚀
Top comments (0)