Before we dive into the steps, a quick word on ReplicaSets. Initially, I was confused by seeing both ReplicationControllers and ReplicaSets mentioned, but after some research, I realized that ReplicaSets are the modern, recommended approach. According to Kubernetes documentation, the ReplicationController is:
"Legacy API for managing workloads that can scale horizontally. Superseded by the Deployment and ReplicaSet APIs."
For this reason, I'll only be using ReplicaSets in this example.
ReplicaSet (from the docs)
A ReplicaSet's purpose is to maintain a stable set of replica Pods running at any given time. As such, it is often used to guarantee the availability of a specified number of identical Pods. Typically, you would define a Deployment and let that Deployment manage ReplicaSets automatically.
Step-by-Step: Creating and Managing a ReplicaSet
1. Creating the ReplicaSet YAML file
First, I created a directory to store my YAML file:
mkdir day-08
cd day-08
nano rs.yaml
Inside rs.yaml
, I defined the ReplicaSet configuration to create 3 replicas of an nginx pod:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
Some important keys in this ReplicaSet YAML configuration:
-
apiVersion: Specifies the API version used, which here is
apps/v1
, suitable for ReplicaSets in Kubernetes. -
kind: Defines the resource type, which is
ReplicaSet
. -
metadata:
- name: Sets a unique name for the ReplicaSet (in this case, "nginx").
-
spec:
- replicas: Indicates the desired number of pod replicas to run, set here to 3.
-
selector: Uses
matchLabels
to match pods with the labelapp: nginx
, identifying the pods that this ReplicaSet will manage. - template:
-
metadata:
- labels: Defines labels for pods created by this ReplicaSet. These labels must match the selector labels to ensure proper management.
-
spec:
- containers: Lists container details for each pod, in this case, a single container:
- name: Name of the container (also "nginx").
-
image: Specifies the container image to use (
nginx
). -
ports: Configures the container's ports, with
containerPort
set to expose port 80.
After saving and exiting the editor, I applied the ReplicaSet to the cluster:
kubectl apply -f rs.yaml
To confirm that the 3 replicas were up and running, I used k9s
(or you can use kubectl get rs
and kubectl get pods
for a quick check).
2. Scaling the ReplicaSet
I then wanted to increase the number of replicas:
- Scaling replicas to 6 from the command line: To dynamically scale up to 6 replicas without modifying the YAML file:
kubectl scale --replicas=6 rs/nginx
I then verified the new count with k9s
Deployments (from the docs)
A Deployment manages a set of Pods to run an application workload, usually one that doesn't maintain state. A Deployment provides declarative updates for Pods and ReplicaSets. You describe a desired state in a Deployment, and the Deployment Controller changes the actual state to the desired state at a controlled rate..
Deployments, ReplicaSets, and Pods: How They Work Together
In Kubernetes, a Deployment is a higher-level abstraction that adds functionality on top of a ReplicaSet. Here’s how they work together:
Deployment: A Deployment manages and oversees the ReplicaSets. When you create a Deployment, it automatically generates and manages one or more ReplicaSets, which in turn manage the actual Pods. This structure enables powerful features like rolling updates, rollbacks, and scaling.
ReplicaSet: The ReplicaSet ensures that the desired number of Pods are running at all times. It serves as an intermediary, managing the pods based on the Deployment’s instructions.
Pods: The smallest deployable unit in Kubernetes, Pods contain your containerized application. They are created, maintained, and monitored by the ReplicaSet under the Deployment’s guidance.
In essence, the Deployment acts as the top-level controller, managing the ReplicaSet layer, which then directly handles the Pods. This layered approach provides a robust way to handle containerized applications in production, making scaling and updating more efficient.
Creating a Deployment
To create a Deployment using the nginx
image with 3 replicas, follow these steps:
- Create the YAML file: Open a terminal and move into the directory we created earlier:
cd day-08
Now, create a new YAML file for the Deployment:
nano deployment.yml
-
Write the Deployment configuration:
Inside the
nano
editor, paste the following configuration (watch out for correct indentation if you are copying it from here):
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: v1
tier: backend
template:
metadata:
labels:
app: v1
tier: backend
spec:
containers:
- name: nginx
image: nginx:1.23.0
ports:
- containerPort: 80
Save and exit the editor by pressing CTRL + X
, then Y
, and finally ENTER
.
- Apply the Deployment: Run the following command to apply the configuration and create the Deployment:
kubectl apply -f deployment.yml
After running the apply
command, you should see your Deployment created successfully. To confirm, use the following command:
kubectl get deployments
In k9s
, the deployment should appear as shown below:
This command lists all deployments in your current context, allowing you to verify that nginx-deployment
is active and correctly configured.
Updating the Deployment Image and Annotating the Change Cause in Kubernetes
In Kubernetes, managing updates to Deployments effectively involves more than just changing an image version. Documenting these changes is important for maintaining an organized rollout history and providing context for each deployment update.
Step 1: Update the Image
First, we’ll update the nginx
container image in our nginx-deployment
Deployment. Here, we set the version to 1.16.0
:
kubectl set image deploy/nginx-deployment nginx=nginx:1.23.4
Kubernetes will initiate a rolling update across all replicas of the nginx-deployment
. This ensures that each replica gradually switches to the specified image version, minimizing downtime.
Step 2: Verify the Rollout
After setting the image, it’s important to check that the update has been applied to all replicas:
kubectl describe deployment nginx-deployment | grep Image
Or, to list the Pods and their images:
kubectl get pods -o wide
These commands help confirm that the Deployment’s replicas are now running the correct image version.
Step 3: Annotate the Deployment with the Change Cause
Since the --record
flag is deprecated, we’ll use the kubectl annotate
command to document the reason for this deployment update manually. This adds context to the change, allowing it to appear in the rollout history:
kubectl annotate deployment nginx-deployment kubernetes.io/change-cause="Pick up patch version" --overwrite=true
The --overwrite=true
flag is included to ensure the annotation is updated if there’s already an existing annotation for change-cause
.
Step 4: Check the Rollout History
Finally, let’s view the rollout history to confirm that our annotation has been recorded. This step also helps validate that our deployment is tracking each update effectively:
kubectl rollout history deployment/nginx-deployment
This command shows each revision, including the change cause for each update. Proper annotation is invaluable for future reference, as it makes rollback decisions easier and provides insight into the deployment history.
Scaling, Viewing Deployment History, and Rolling Back Changes
After updating and annotating the image version, it’s crucial to know how to manage the Deployment’s scale, view the history of updates, and roll back if necessary. This section will walk through these final tasks:
Step 5: Scale the Deployment to 5 Replicas
Scaling up a Deployment adjusts the number of Pods to meet the demand. Here’s how to scale nginx-deployment
to 5 replicas:
kubectl scale deployment nginx-deployment --replicas=5
This command increases the number of Pods under nginx-deployment
to five, ensuring more instances of your application are available.
Step 6: Roll Back to a Previous Revision
If needed, you can roll back to a specific revision. To revert to revision 1, for example, use:
kubectl rollout undo deployment/nginx-deployment --to-revision=1
This command rolls the Deployment back to the specified version, ideal for cases where a previous configuration is preferable.
Step 7: Confirm the Image Version for All Pods
Finally, verify that all Pods are running the correct image version (nginx:1.23.0
):
kubectl describe deployment nginx-deployment | grep Image
kubectl get pods -o wide
These commands help confirm that each replica in the nginx-deployment
Deployment is using the specified image version.
These steps wrap up the complete process of deploying, updating, scaling, and managing a Deployment in Kubernetes.
If you are still with me at this point, thank you for reading.
I appreciate it.
Tags and Mentions
@piyushsachdeva
Day 8 video
Top comments (0)