Chapter 2
Section titled “Chapter 2”Now that we understand that our application container lives inside a Pod, we need a way to manage that Pod reliably.
Managing Your Application with Deployments
Section titled “Managing Your Application with Deployments”In the last chapter, we established that Pods are ephemeral. If a Node fails or a Pod crashes, it’s gone. Relying on a single Pod to run your application is like building a house on sand. This raises several important questions:
- What happens if the Pod running my application crashes? Does my app go down?
- How do I scale my application to handle more traffic? Do I have to create each new Pod manually?
- How do I update my application to a new version without causing downtime for my users?
The answer to all these questions is the Deployment object.
What is a Deployment?
Section titled “What is a Deployment?”A Deployment is a higher-level Kubernetes object that manages a set of identical Pods. Its primary job is to ensure that a specified number of Pods are running at all times and to manage how updates are rolled out to them.
You don’t create Pods manually; you declare your desired state in a Deployment object, and the Deployment takes care of the rest. This is a core principle of Kubernetes: you tell the cluster what you want (e.g., “I want 3 replicas of my web server running version 1.2”), and Kubernetes figures out how to make it happen.
How Deployments Work: The Role of the ReplicaSet
Section titled “How Deployments Work: The Role of the ReplicaSet”A Deployment doesn’t directly manage Pods. Instead, it uses another object called a ReplicaSet.
- You create a Deployment.
- The Deployment creates a ReplicaSet.
- The ReplicaSet’s job is to create and maintain the specified number of Pods. If a Pod dies, the ReplicaSet immediately creates a new one to replace it.
This division of labor is especially important for updates. When you update your application (e.g., change the container image), the Deployment creates a new ReplicaSet for the new version and slowly scales it up while scaling the old ReplicaSet down. This is called a rolling update, and it’s how Kubernetes achieves zero-downtime deployments.
Here is a diagram showing this relationship:
+--------------------------------------------+| Deployment || (Your Desired State: || "3 replicas of my-app:v1") |+--------------------+-----------------------+ | | Manages |+--------------------v-----------------------+| ReplicaSet || (Ensures 3 Pods Exist) |+--+-----------------+-----------------+-----+ | | | | Creates & | Creates & | Creates & | Monitors | Monitors | Monitors | | |+--v--+ +--v--+ +--v--+| Pod | | Pod | | Pod |+-----+ +-----+ +-----+Key Features Provided by Deployments
Section titled “Key Features Provided by Deployments”- Scalability: Need to handle more traffic? You simply update the
replicasfield in your Deployment from 3 to 10. The ReplicaSet will see this change and create 7 new Pods. - Self-Healing: If a Node hosting one of your Pods goes down, the Kubernetes Control Plane detects this. The ReplicaSet sees that it’s now short of its desired replica count and automatically creates a replacement Pod on a healthy Node. You don’t have to do anything.
- Controlled Rollouts and Rollbacks: As mentioned, Deployments allow for seamless rolling updates. If you find a bug in your new version, you can just as easily tell the Deployment to “roll back” to the previous, stable version.
A Look at a Deployment YAML File
Section titled “A Look at a Deployment YAML File”In Kubernetes, you define objects using YAML files. Here is a simplified example of what a Deployment file looks like:
# apiVersion: Specifies the Kubernetes API version to useapiVersion: apps/v1# kind: Specifies the type of objectkind: Deployment# metadata: Data that helps uniquely identify the object, like its namemetadata: name: my-webapp-deployment# spec: This is where you define the DESIRED STATEspec: # replicas: How many identical Pods to run replicas: 3 # selector: How the Deployment finds which Pods to manage selector: matchLabels: app: my-webapp # template: This is the blueprint for the Pods it will create template: metadata: labels: app: my-webapp # This label must match the selector above spec: containers: - name: webserver-container # image: The Docker container image to run image: nginx:1.21.6 ports: - containerPort: 80Don’t worry about memorizing this format. The key fields to understand are:
- replicas: We are asking for 3 Pods.
- selector: This tells the Deployment how to identify the Pods it is supposed to manage (in this case, any Pod with the label
app: my-webapp). - template.spec.containers.image: This specifies the container image that will be placed inside each Pod. This is where you would put your own application’s image (e.g.,
your-username/your-cool-app:1.0).
-
Create a Deployment: Create a file named
deployment.yamlwith the content from the chapter example:deployment.yaml apiVersion: apps/v1kind: Deploymentmetadata:name: my-webapp-deploymentspec:replicas: 3selector:matchLabels:app: my-webapptemplate:metadata:labels:app: my-webappspec:containers:- name: webserver-containerimage: nginx:1.21.6ports:- containerPort: 80Apply it to your cluster:
Terminal window kubectl apply -f deployment.yaml -
Check the Status: Now, check all the objects that were created.
Terminal window # Check the deployment itselfkubectl get deployment# See the ReplicaSet it createdkubectl get replicaset# You can also use 'rs' as a shorthand for 'replicaset'# See the 3 Pods that the ReplicaSet createdkubectl get podsYou should see one Deployment, one ReplicaSet, and three Pods running.
-
Test Self-Healing: Let’s manually delete one of the Pods to simulate a failure. Pick one of the Pod names from the
get podscommand.Terminal window # Replace <pod-name> with one of your actual pod nameskubectl delete pod <pod-name>Now, very quickly, run
kubectl get pods --watch. You will see that the Pod you deleted is “Terminating”, but the ReplicaSet immediately created a new one to bring the count back to 3! This is the self-healing power of a Deployment. -
Test Scaling: Let’s scale our application up to 5 replicas.
Terminal window kubectl scale deployment my-webapp-deployment --replicas=5Check your Pods again (
kubectl get pods), and you’ll see that two new Pods have been created, for a total of 5. -
Perform a Rolling Update: Let’s say you want to update your application to a new version.
You can do this by changing the image in your Deployment.Now let’s update our Nginx version with zero downtime. We can do this directly from the command line.Terminal window # This tells the deployment to use a new image for the containerkubectl set image deployment/my-webapp-deployment webserver-container=nginx:1.23.3To watch the rolling update happen in real-time, use the
rollout statuscommand:Terminal window kubectl rollout status deployment/my-webapp-deploymentIf you run kubectl get pods in another terminal while this is happening, you’ll see the Deployment terminating old Pods and creating new ones gracefully.
-
Clean Up: To delete the entire application (the Deployment, ReplicaSet, and all Pods), just delete the Deployment object.
Terminal window kubectl delete -f deployment.yaml
You are now ready for the next step. We have a robust, scalable application running. But it’s still locked inside the cluster.
Let me know when you’re ready for Chapter 3, where we will finally expose this application to the outside world using Services and Ingress.
Key Takeaways for Chapter 2
Section titled “Key Takeaways for Chapter 2”- You don’t manage individual Pods; you use a Deployment to manage them.
- A Deployment ensures a specified number of Pods (replicas) are running and healthy.
- Deployments use ReplicaSets to achieve this self-healing and scalability.
- Deployments allow for zero-downtime rolling updates when you need to change your application’s version.
- You define the desired state of your Deployment in a YAML file.
Now we have a way to run our application reliably and keep it running. But how do users access it? The Pods are running deep inside the cluster network. Let me know when you’re ready, and in Chapter 3, we’ll cover how to expose your application to the outside world using Services and Ingress.