DevOps Day 49: From Pods to Deployments - My First Kubernetes Application¶
Today was a massive leap in my Kubernetes journey. I graduated from creating a simple, single Pod to using a Deployment, which I learned is the standard and professional way to run applications in Kubernetes. This task was about creating a Deployment to manage an httpd web server.
This was a huge conceptual shift. I learned that I don't manage containers directly; I manage Pods. And I don't even manage Pods directly; I manage a Deployment that manages the Pods for me. It's a layer of abstraction that provides incredible power, like self-healing and scaling. This document is my very detailed, first-person guide to that entire process, written from the perspective of a complete beginner to Kubernetes.
Table of Contents¶
- The Task
- My Step-by-Step Solution
- Why Did I Do This? (The "What & Why" for a K8s Beginner)
- Deep Dive: A Line-by-Line Explanation of My Deployment YAML File
- Common Pitfalls for Beginners
- Exploring the Essential
kubectlCommands
The Task¶
My objective was to create a Kubernetes Deployment to run a web server. The specific requirements were:
1. The Deployment must be named httpd.
2. It must deploy Pods using the httpd:latest Docker image.
My Step-by-Step Solution¶
The professional way to create resources in Kubernetes is with a YAML manifest file. I followed this declarative approach.
Phase 1: Writing the Deployment Manifest¶
- I connected to the jump host, where
kubectlwas pre-configured to talk to the cluster. - I created a new file named
httpd-deployment.yamlusingvi. - Inside the editor, I wrote the following YAML code, which is a declaration of the Deployment I wanted to create.
apiVersion: apps/v1 kind: Deployment metadata: name: httpd spec: replicas: 1 selector: matchLabels: app: httpd_app template: metadata: labels: app: httpd_app spec: containers: - name: httpd-container image: httpd:latest - I saved and quit the file.
Phase 2: Applying the Manifest and Verifying¶
-
I used
kubectlto send my manifest to the Kubernetes API server.The command responded withkubectl apply -f httpd-deployment.yamldeployment.apps/httpd created, my first sign of success. -
Verification: The final and most important step was to confirm that the Deployment was created and that it, in turn, created a Pod.
- First, I checked the status of the Deployment.
The output showed my
kubectl get deployment httpdhttpddeployment withREADY 1/1, confirming it had successfully created its Pod. - For definitive proof, I listed the Pods.
The output showed a new Pod with a name like
kubectl get podshttpd-6c7c8c88c7-abcdewith aSTATUSofRunning. This Pod was created and is being managed by my Deployment. This was the final proof of success.
- First, I checked the status of the Deployment.
Why Did I Do This? (The "What & Why" for a K8s Beginner)¶
- Kubernetes (K8s): Kubernetes is the "operating system for the cloud." It's an orchestrator that manages containerized applications across a fleet of servers (a "cluster").
- Pod vs. Deployment (The Core Lesson): This was the most important concept I learned.
- A Pod is the smallest unit in Kubernetes. It's a wrapper for my container. A Pod is mortal. If it crashes or the server it's on fails, the Pod is gone.
- A Deployment is a manager for Pods. It's a higher-level object that acts as a controller. My YAML file told the Deployment, "I desire to have 1 Pod running that looks like this." The Deployment's job is to work tirelessly to make that happen. If the Pod it creates dies, the Deployment's controller will notice and automatically create a new one. This is called self-healing, and it's one of the most powerful features of Kubernetes.
- ReplicaSet: I learned that a Deployment doesn't manage Pods directly. When I create a Deployment, it creates another object called a ReplicaSet. The ReplicaSet's only job is to ensure that a specified number of replica Pods are always running. The Deployment then manages the ReplicaSet, which allows for advanced strategies like rolling updates. So the hierarchy is: Deployment -> ReplicaSet -> Pod -> Container.
- Declarative Manifests (YAML): I am not telling Kubernetes how to create the Pod. I am writing a YAML file that describes the desired end state of my system. I give this "blueprint" to Kubernetes, and it's the cluster's job to figure out how to make reality match my blueprint. This is a powerful, version-controllable, and repeatable way to manage infrastructure.
Deep Dive: A Line-by-Line Explanation of My Deployment YAML File¶
The YAML file for a Deployment is more complex than for a Pod because it defines both the manager (the Deployment) and the blueprint for what it manages (the Pod template).
[Image of a Kubernetes Deployment managing multiple Pods]
# 'apiVersion' tells Kubernetes which API to use. 'apps/v1' is the modern,
# stable API group for workload resources like Deployments.
apiVersion: apps/v1
# 'kind' specifies the TYPE of object I want to create.
kind: Deployment
# 'metadata' contains data that identifies the Deployment object itself.
metadata:
name: httpd
# 'spec' (Specification) describes the DESIRED STATE of the Deployment.
spec:
# 'replicas' is the number of identical Pods I want to run. This is the key
# to scalability. I can change this to 3, and the Deployment will automatically
# create two more Pods.
replicas: 1
# 'selector' is CRITICAL. It tells the Deployment's controller HOW to find the
# Pods that it is supposed to be managing.
selector:
# 'matchLabels' is a rule. It says, "Any Pod with the label 'app: httpd_app'
# belongs to me." This link is essential.
matchLabels:
app: httpd_app
# 'template' is the blueprint for the Pods that the Deployment will create.
# This section looks almost exactly like a standalone Pod manifest.
template:
# The Pods created by this template will have their own metadata.
metadata:
# The labels here MUST match the 'matchLabels' in the selector above.
# This is how the Pods get "adopted" by the Deployment.
labels:
app: httpd_app
# This is the specification for the Pods themselves.
spec:
# It describes the containers that will run inside the Pods.
containers:
- name: httpd-container
image: httpd:latest
Common Pitfalls for Beginners¶
- YAML Indentation Errors: YAML is extremely strict about indentation. A single wrong space can make the file invalid.
- Selector/Label Mismatch: This is the most common and frustrating error for beginners. If the spec.selector.matchLabels of the Deployment do not exactly match the spec.template.metadata.labels of the Pod template, the Deployment will create the Pods, but it won't be able to "find" them. The Deployment will get stuck in a loop, endlessly creating new Pods because it thinks its desired replica count is zero.
- Trying to name the Pod: The Deployment automatically generates names for the Pods it creates (e.g., httpd-<random-string>). You define the Pod's blueprint in the template, but not its specific name.
Exploring the Essential kubectl Commands¶
This task introduced me to a new set of commands for managing Deployments.
-
Creating & Updating:
kubectl apply -f [filename.yaml]: The standard way to create or update resources from a manifest file.
-
Viewing & Inspecting:
kubectl get pods: Lists a summary of all Pods.kubectl get deployments(orkubectl get deploy): Lists a summary of all Deployments. The output is great for quickly checking theREADYstatus.kubectl get all: Shows a summary of all the most common resource types (Pods, Deployments, ReplicaSets, Services, etc.).kubectl describe deployment [dep-name]: Describes a Deployment in detail, including its labels, replica count, and recent events. This is great for troubleshooting the Deployment itself.kubectl describe pod [pod-name]: Describes a specific Pod in detail. This is essential for troubleshooting a Pod that is crashing or won't start.
-
Scaling (The Cool Part!):
kubectl scale deployment httpd --replicas=3: This is an imperative command that tells Kubernetes to scale myhttpdDeployment to 3 replicas. The Deployment controller will see this change and immediately create 2 new Pods to match the new desired state.
-
Deleting:
kubectl delete deployment httpd: Deletes the Deployment. Because the Deployment is the "owner" of the ReplicaSet and the Pods, deleting the Deployment will trigger a cascade delete, and the ReplicaSet and all its Pods will also be automatically removed.