What is a Deployment?
A deployment is an object in Kubernetes that helps you to manage a group of identical pods. A Deployment runs multiple replicas of your application and automatically replaces any instances that fail or become unresponsive.
This way, Deployments ensure that one or more instances of your application are available to serve user requests.
The following are typical use cases for Deployments
- A Deployment can be used to rollout a ReplicaSet. Each rollout updates the revision of the Deployment.
- Provide a new definition to the Pods by simply updating the PodTemplateSpec in the Deployment. As a result, a new ReplicaSet will be created.
- Deploment can be used to Rollback to an earlier Deployment revision in case the existing or the updated revision of the Deployment is not stable.
- Pause the rollout to apply fixes to the PodTemplateSpec and then resume it to start a new rollout.
- Scale up or down for better load management.
Configuring a Deployment
Just like any other resource, the Deployment manifest file consist of four main sections as below.
apiVersion:
kind:
metadata:
[ . . . ]
spec:
replicas:
selector:
[ . . . ]
template:
[ . . . ]
- apiVersion: Defines the Kubernetes API that supports Deployment.
- kind: Specifies the Kubernetes object we wish to create.
- metadata: Contains information about the Deployment object.
- We can specify name and labels associated with the Deployment.
- spec: There are three sections under spec namely replicas, selector and template.
- replicas: Specifies the number of replicas of the pod
- selector: The selector is used to identify which pod the ReplicaSet is responsible for.
- template: Defines the pod template that the ReplicaSet uses when creating pods and adding them to meet the required number of replicas.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.22.1
ports:
- containerPort: 80
Apply the deployment manifest file and verify the status of the deployment.
# kubectl apply -f deployment.yml --record
deployment.apps/nginx-deployment created
# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 17s
- NAME lists the names of the Deployments.
- READY shows how many replicas of the application are available to your users. It follows the pattern ready/desired.
- UP-TO-DATE specifies the number of replicas that have achieved the desired state.
- AVAILABLE displays how many replicas of the application are available to your users.
- AGE specifies how long the application has been running.
To see the ReplicaSet and Pods created by ReplicaSet run the below mentioned commands. The created ReplicaSet ensures that three instance of the nginx application as specified under spec.replicas
are running at any given time.
# kubectl get replicaset
NAME DESIRED CURRENT READY AGE
nginx-deployment-579c9dfc44 3 3 3 14s
# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-579c9dfc44-qmfrb 1/1 Running 0 19s
nginx-deployment-579c9dfc44-f7k4d 1/1 Running 0 19s
nginx-deployment-579c9dfc44-kq46r 1/1 Running 0 19s
To see detailed information about the Deployment run the below command.
# kubectl describe deployment nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Sun, 08 Jan 2023 17:48:11 +0000
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 1
kubernetes.io/change-cause: kubectl apply --filename=deployment.yml --record=true
Selector: app=nginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.22.1
[ . . . ]
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-579c9dfc44 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 34s deployment-controller Scaled up replica set nginx-deployment-579c9dfc44 to 3
Updating the Deployment
A Kubernetes Deployment upgrade can be triggered by updating the Pod template. In such scenarios the Deployment will rollout and create a new ReplicaSet which will be responsible for managing the updated Pod. Changes other than Pods spec.template will not trigger a rollout.
A rollout creates a new ReplicaSet which manages the updated Pods whereas changes made to block other than spec.template won’t result in rollout. This means that the existing ReplicaSet will be responsible for managing application Pods. One such example is scaling the deployment.
To rollout a deployment follow the below steps.
Update the image of the existing Pods from 1.22.1 to 1.23.3
# kubectl set image deployment/nginx-deployment nginx=nginx:1.23.3 --record
deployment.apps/nginx-deployment image updated
Verify the status of Deployment.
# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 4m31s
# kubectl rollout status deployment/nginx-deployment
deployment "nginx-deployment" successfully rolled out
Run kubectl get replicaset to verify that Deployment created a new ReplicaSet and scaling it to three replicas. Additionally, the existing ReplicaSet was scaled down to 0 replicas.
# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-866c5d4565 3 3 3 12s
nginx-deployment-579c9dfc44 0 0 0 3m42s
Describe the deployment to see detailed information of the rollout.
# kubectl describe deployment/nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Sun, 08 Jan 2023 17:48:11 +0000
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 2
kubernetes.io/change-cause: kubectl set image deployment/nginx-deployment nginx=nginx:1.23.3 --record=true
Selector: app=nginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.23.3
[ . . . ]
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-866c5d4565 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 5m31s deployment-controller Scaled up replica set nginx-deployment-579c9dfc44 to 3
Normal ScalingReplicaSet 2m1s deployment-controller Scaled up replica set nginx-deployment-866c5d4565 to 1
Normal ScalingReplicaSet 115s deployment-controller Scaled down replica set nginx-deployment-579c9dfc44 to 2 from 3
Normal ScalingReplicaSet 115s deployment-controller Scaled up replica set nginx-deployment-866c5d4565 to 2 from 1
Normal ScalingReplicaSet 113s deployment-controller Scaled down replica set nginx-deployment-579c9dfc44 to 1 from 2
Normal ScalingReplicaSet 113s deployment-controller Scaled up replica set nginx-deployment-866c5d4565 to 3 from 2
Normal ScalingReplicaSet 111s deployment-controller Scaled down replica set nginx-deployment-579c9dfc44 to 0 from 1
In the events you can see that the new ReplicaSet(nginx-deployment-866c5d4565) was first scaled up to 1 replica and waits for it to achieve the Ready state.
It then scales down the existing/old ReplicaSet(nginx-deployment-579c9dfc44) from 3 to 2 and scales up the new ReplicaSet to 2. It will continue scaling down the old and scaling up the new ReplicaSet till all the Pods have been updated with the latest image. It will not kill an existing Pod until a sufficient number of new Pods have come up and vice-versa.
How many Pods should be scaled down or scaled up at a given point of time is controlled by RollingUpdateStrategy which is set to a default value of 25% max unavailable, 25% max surge.
25% max unavailable means how many Pods can be unavailable during the upgrade procedure. Hence ensuring that at least 75% of the desired Pods are up. This value can be an absolute number or a percentage value.
25% max surge means how many additional Pods can be created above the desired number during the upgrade procedure. This value can be an absolute number or a percentage value.
Rollback an update
Deployment upgrade can be rolled back in case of upgrade failure or because of an unexpected behavior of the application. You can see the revision and details of each revision. Run the below commands.
# kubectl rollout history deployment nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 kubectl apply --filename=deployment.yml --record=true
2 kubectl set image deployment/nginx-deployment nginx=nginx:1.23.3 --record=true
To see more information of a revision.
# kubectl rollout history deployment/nginx-deployment --revision=2
deployment.apps/nginx-deployment with revision #2
Pod Template:
Labels: app=nginx
pod-template-hash=866c5d4565
Annotations: kubernetes.io/change-cause: kubectl set image deployment/nginx-deployment nginx=nginx:1.23.3 --record=true
Containers:
nginx:
Image: nginx:1.23.3
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
By default, a revision is rolled back to an immediate previous revision. However, it is possible to roll back to a specific revision as well.
For example, to rollback from revision 2 to revision 1 run the below command.
# kubectl rollout undo deployment/nginx-deployment
deployment.apps/nginx-deployment rolled back
To rollback to a specific revision use the below command.
# kubectl rollout undo deployment/nginx-deployment –to-revision=<revision_number>
Check the rollout history
# kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
2 kubectl set image deployment/nginx-deployment nginx=nginx:1.23.3 --record=true
3 kubectl apply --filename=deployment.yml --record=true
Also verify the status of the ReplicaSet.
# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-579c9dfc44 3 3 3 14m
nginx-deployment-866c5d4565 0 0 0 10m
You can see in the above output that Pods have been migrated back to the older ReplicaSet.
Scaling a deployment
A deployment can be scaled up or down by updating the replica count either in the manifest file or by passing the replica count via command line.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 5
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.22.1
ports:
- containerPort: 80
Apply the updated manifest file to the cluster.
# kubectl apply -f deployment.yml
deployment.apps/nginx-deployment configured
# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-866c5d4565 0 0 0 16m
nginx-deployment-579c9dfc44 5 5 5 19m
# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-579c9dfc44-sgszk 1/1 Running 0 4m54s
nginx-deployment-579c9dfc44-km7d5 1/1 Running 0 4m53s
nginx-deployment-579c9dfc44-p6dvp 1/1 Running 0 4m51s
nginx-deployment-579c9dfc44-h67qm 1/1 Running 0 4s
nginx-deployment-579c9dfc44-mjvlz 1/1 Running 0 4s
To scale down the replicas run the below command.
# kubectl scale deployment/nginx-deployment --replicas=2
deployment.apps/nginx-deployment scaled
# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-866c5d4565 0 0 0 26m
nginx-deployment-579c9dfc44 2 2 2 29m
# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-579c9dfc44-sgszk 1/1 Running 0 16m
nginx-deployment-579c9dfc44-km7d5 1/1 Running 0 16m
Final Thoughts
In this post, we showed you how to use Kubernetes Deployment to achieve High availability, easy rollout and scaling of application for better traffic management. Deployment is a great option for stateless applications.
More
Learn about ReplicaSet
Learn about Pods
Pingback: Kubernetes: What is a ReplicaSet – Learn and Implement DevOps