Skip to content

Understand application deployments and how to perform rolling update and rollbacks

Application Deployments

Deployments are intended to replace Replication Controllers. They provide the same replication functions (through Replica Sets) and also the ability to rollout changes and roll them back if necessary. An example configuration is shown below:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 5
  template:
    metadata:
      labels:
        app: nginx-frontend
    spec:
      containers:
      - name: nginx
        image: nginx:1.31.5
        ports:
        - containerPort: 80

The main reason why leverage deployments is to manage a number of identical pods via one administrative unit - the deployment object. Should we need to make changes, we apply this to the deployment object, not individual pods. Because of the declarative nature of deployments, Kubernetes will rectify any changes between desired and running state, and rectify accordingly. For example, if we manually deleted.

We can then describe it with kubectl describe deployment nginx-deployment

Rolling Updates

To update an existing deployment, we have two main options:

  • Rolling Update
  • Recreate

A rolling update, as the name implies, will swap out containers in a deployment with one created by a new image.

Use a rolling update when the application supports having a mix of different pods (aka application versions). This method will also involve no downtime of the service, but will take longer to bring up the deployment to the requested version. Old and new versions of the pod spec will coexist until they're all rotated.

A recreation will delete all the existing pods and then spin up new ones. This method will involve downtime. Consider this a “bing bang” approach

Examples listed in the Kubernetes documentation are largely imperative, but I prefer to be declarative. As an example, create a new yaml file and make the required changes, in this example, the version of the nginx container is incremented.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 5
  template:
    metadata:
      labels:
        app: nginx-frontend
    spec:
      containers:
      - name: nginx
        image: nginx:nginx:1.31.6
        ports:
        - containerPort: 80

We can then apply this file kubectl apply -f updateddeployment.yaml --record=true

Followed by the following:

kubectl rollout status deployment/nginx-deployment

Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 5 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 5 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 5 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 5 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 3 out of 5 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 3 out of 5 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 3 out of 5 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 3 out of 5 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 4 out of 5 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 4 out of 5 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 4 out of 5 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 4 out of 5 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 4 out of 5 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx-deployment" rollout to finish: 4 of 5 updated replicas are available...
deployment "nginx-deployment" successfully rolled out

We can also use the kubectl rollout history to look at the revision history of a deployment

kubectl rollout history deployment/nginx-deployment

deployment.extensions/nginx-deployment
REVISION  CHANGE-CAUSE
1     <none>
2     <none>
4     <none>
5     kubectl apply --filename=updateddeployment.yaml --record=true

Alternatively, we can also do this imperatively:

kubectl --record deployments/nginx-deployment set image deployments/nginx-deployment nginx=nginx:1.31.6

deployment.extensions/nginx-deployment image updated
deployment.extensions/nginx-deployment image updated

Rollback

To rollback to the previous version:

kubectl rollout undo deployment/nginx-deployment 

To rollback to a specific version:

kubectl rollout undo deployment/nginx-deployment --to-revision 5

Source of revision: kubectl rollout history deployment/nginx-deployment

Exam Tip

Standalone Pods (not deployed via a deployment object) will not get rescheduled when deleted. Pods from a deployment object, will, however.

Exam Tip

Avoid deploying standalone Pods. If you only need 1 replica of a instance, deploy a deployment object with a single replica

Exam Tip

Changes made to a deployment object will be reflected in the Pods that it deploys.