DEV Community

janak0ff
janak0ff

Posted on

Kodekloud Level 1 - Kubernetes : 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-httpd using the httpd image with the latest tag. Ensure to specify the tag as httpd:latest.

  2. Set the app label to httpd_app, and name the container as httpd-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

  1. Understanding Kubernetes Pods
  2. Creating Pods Imperatively vs. Declaratively
  3. Step-by-Step Implementation
  4. Verification and Troubleshooting
  5. 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Step 2: Edit the YAML File

Open the file and modify the container name:

nano pod-httpd.yaml
Enter fullscreen mode Exit fullscreen mode

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: {}
Enter fullscreen mode Exit fullscreen mode

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: {}
Enter fullscreen mode Exit fullscreen mode

Step 3: Apply the Configuration

Create the pod in your cluster:

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

Expected output:

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

Step 4: Verify the Pod Status

Check if the pod is running:

kubectl get pods
Enter fullscreen mode Exit fullscreen mode

Output:

NAME        READY   STATUS    RESTARTS   AGE
pod-httpd   1/1     Running   0          2m7s
Enter fullscreen mode Exit fullscreen mode

Step 5: Detailed Verification

Let's examine the pod in detail:

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

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
Enter fullscreen mode Exit fullscreen mode

Output:

NAME        READY   STATUS    RESTARTS   AGE     LABELS
pod-httpd   1/1     Running   0          2m27s   app=httpd_app
Enter fullscreen mode Exit fullscreen mode

Step 7: Verify Container Name

Extract the container name using jsonpath:

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

Output:

httpd-container
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

Important Notes:

  • apiVersion must match the Kubernetes version
  • metadata.name is the pod name
  • spec.containers[0].image uses the full image name
  • restartPolicy: Never creates a pod rather than a deployment

5. Advanced Verification Techniques

View Pod Logs

kubectl logs pod-httpd
Enter fullscreen mode Exit fullscreen mode

Access the Web Server

Forward a local port to the pod:

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

Then open http://localhost:8080 in your browser.

Exec into the Container

kubectl exec -it pod-httpd -- /bin/bash
Enter fullscreen mode Exit fullscreen mode

Get Pod IP

kubectl get pod pod-httpd -o wide
Enter fullscreen mode Exit fullscreen mode

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}'
Enter fullscreen mode Exit fullscreen mode

6. Troubleshooting Common Issues

Issue 1: Image Pull Error

ImagePullBackOff or ErrImagePull
Enter fullscreen mode Exit fullscreen mode

Solution: Check if the image name is correct and accessible

kubectl describe pod pod-httpd | grep -A 5 Events
Enter fullscreen mode Exit fullscreen mode

Issue 2: Pod Stuck in Pending State

PodPending
Enter fullscreen mode Exit fullscreen mode

Solution: Check for resource constraints or scheduling issues

kubectl describe pod pod-httpd | grep -A 10 Events
Enter fullscreen mode Exit fullscreen mode

Issue 3: CrashLoopBackOff

Container exits immediately
Enter fullscreen mode Exit fullscreen mode

Solution: Check logs for application errors

kubectl logs pod-httpd
Enter fullscreen mode Exit fullscreen mode

Issue 4: Wrong Container Name

If the container name doesn't match requirements:

kubectl edit pod pod-httpd
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode
  • 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 :latest in 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:

  1. Use Namespaces:
kubectl create namespace development
kubectl apply -f pod-httpd.yaml -n development
Enter fullscreen mode Exit fullscreen mode
  1. Add Readiness Probe:
readinessProbe:
  httpGet:
    path: /
    port: 80
  initialDelaySeconds: 5
  periodSeconds: 5
Enter fullscreen mode Exit fullscreen mode
  1. Add Liveness Probe:
livenessProbe:
  httpGet:
    path: /
    port: 80
  initialDelaySeconds: 20
  periodSeconds: 10
Enter fullscreen mode Exit fullscreen mode
  1. Add Environment Variables:
env:
- name: ENVIRONMENT
  value: "production"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

10. Key Takeaways

  1. Pods are the foundation: Understanding pods is crucial for Kubernetes mastery
  2. Declarative > Imperative: Always prefer YAML manifests for production
  3. Labels are powerful: Use them for organization, selection, and grouping
  4. Verification is key: Always verify pod status, labels, and container names
  5. Probes improve reliability: Add health checks for self-healing
  6. 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

Did this guide help you? Drop a comment below with your questions or experiences! 🚀

Top comments (0)