In the, ‘learn how to manage and create pods’ article, we discussed how to create YAML configuration files that specify resource deployment. In this article, we will build on the material presented earlier to demonstrate how pod deployment is implemented. Kubernetes offers different ways of approaching problems and at times it is difficult to decide the best approach. Deployments offer a mechanism for updating pods and replica sets. One approach to deployment is using pods to deploy containers then adding replication controllers to manage, scale and update the containers. This is an imperative approach to manage software that lacks automation and transparency within a team. The shortcomings of the imperative approach led to the development of deployment object beginning with version 1.2 of Kubernetes. This led to a declarative approach to managing deployments.
Even if some automation is included in the imperative approach, challenges will always arise as highlighted below.
• Manual changes can be overwritten or reversed by other team members
• Tracking service evolution over time is difficult and requires separate documentation.
• Multiple commands are required to achieve a desired state. Even with automation the same commands may lead to different results in different environments
• It is difficult to ensure planned deployments are the ones actually running because only information on current deployment can be obtained
The declarative approach is better in production environments and continuous delivery because it overcomes the shortcomings of the imperative approach and offers benefits listed below:
• Change documentation is simplified through versions of the declarative object which enhances team communication and promotes good development
• Instead of describing the required steps to achieve a state, the actual state is defined. This brings consistency in different environments
• It promotes careful thinking and planning about the desired state
Previously, the introduction of deployment pod management happened through replication controllers. After replication controllers were introduced, the pod management was done by replica sets which are an evolution of replication controllers. Deployments still offer features that were available in replication controllers and additional features that are listed below.
• You can control the update strategy declaratively which is a replacement of kubectl rolling-update which still offers the flexibility of controlling the maximum number of additional and unavailable pods. Once defined in a deployment object, it can be used for multiple updates on different environments
• Deployments handle updates to the extent of checking that rolled out revisions are working and if they are not working, to stop them.
• The update/revise functionality is available which enables concurrent deployment of multiple versions.
• You are able to control the time required for a pod to be considered ready which ensures correct updates and gives containers adequate time to start handling traffic.
• A history of revisions is maintained which is useful for rollback. The event log which is useful for release audit and deployment changes is also available
Managing replica sets is not required, we only need to define deployments that will manage the replica sets. Altering the deployment object enables you to achieve use cases such as creating replica sets, removing deployments and resource management. The next section will discuss use cases that are achieved by manipulating the deployment object.
The first use case is creating a deployment. Deployments are created using YAML or JSON in a similar way to how pods and services are created. Consider the deployment shown below:
apiVersion: apps/v1beta1 # for versions before 1.6.0 use extensions/v1beta1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80
On line 1 and 2, we are specifying the API version and the type of object we are creating. These two lines are the key difference between deployments and replication controllers. Replication controllers can be easily converted to deployments by changing the api and kind attributes. In a replication controller, following the attributes appear as shown below.
apiVersion: v1 kind: ReplicationController
On line 6, we are instructing the deployment to run 3 pods of the provided template. Beginning with line 6,, we are specifying the template that will be used to create pods. Once you specify your deployment object, you create it using the command kubectl create -f and specify the path to your yaml file.
The second use case is updating a deployment. The only trigger that results in a deployment roll out is a change in deployment template through a label or container image update. Scaling will not result in a roll out. In the yaml file presented earlier, the nginx image version was 1.7.9. To update the image to version 1.9.1, we can use the command below.
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 deployment "nginx-deployment" image updated
The roll out status returned by the command is shown below:
kubectl rollout status deployment/nginx-deployment
The third use case is rolling back a deployment. The need for a roll back arises from situations such as unstable deployments and crashes. The default behavior is keeping all the roll out history to enable restore to any time point, but this behavior can be changed via the history limit. A revision is only created when a template element is altered, therefore changes such as scaling will not cause a revision. The implication is only that the template is restored. For example, if during the update of the image version, we erroneously typed the image version as 1.91. In this instance, the roll out will be stuck and the solution to this situation is rolling back to a stable deployment.
kubectl set image deployment/nginx-deployment nginx=nginx:1.91 deployment "nginx-deployment" image updated
Before rolling back, we need to know the revisions that have been applied to the deployment. The command below will return the revision number and changes made in each revision.
kubectl rollout history deployment/nginx-deployment
To rollback to a specific revision, you pass the revision number to ‘–to-revision flag’ as shown below:
kubectl rollout undo deployment/nginx-deployment --to-revision=2 deployment "nginx-deployment" rolled back
In this article, we introduced deployments and discussed the two approaches to pod management. We discussed shortcomings of the imperative approach and the benefits of the declarative approach. We discussed the different use cases that can be accomplished by using the deployment object.