In the previous tutorial I mentioned that a deployment is not created when a multi-container pod is created from the manifest file. Hence, the containers are not being monitored for failures. As best practice, pods should always be created using Deployments so that the pods are monitored for failure. In this way, the pods are restarted on failure. A deployment can be created using Kubernetes Deployment Controller object. Before we create a deployment, let's first understand what it is.
Kubernetes Deployment Controller Object
Kubernetes' deployment controller object is used for monitoring, management of upgrade, downgrade and scaling of services (e.g. pods) without downtime during the process. Deployment object keeps the service running by maintaining multiple replicatsets. You describe a desired state, and the Deployment controller changes the actual state to the desired state at a controlled rate. See Kubernetes deployment controller object documentation for details.
Creating a Deployment from Manifest File
apiVersion: apps/v1beta1
metadata:
name: deployment-example
spec:
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.9.2
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 100Mi
From the manifest file, let’s create the deployment:
$kubectl create -f deployment.yaml
This will create a deployment along with 2 nginx containers (replicas:2). Let’s see the deployment objects and the nginx containers with kubectl get comands.
$ kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deployment-example 2 2 2 2 20m $kubectl get pods NAME READY STATUS RESTARTS AGE deployment-example-2172232893-22gxh 1/1 Running 1 21m deployment-example-2172232893-2mmgg 1/1 Running 1 21m $ kubectl get replicasets NAME DESIRED CURRENT READY AGE deployment-example-1421084195 2 2 2 22m
Note that each time a deployment is created, replicasets are also created and managed by the deployment controller object.
Updating a Deployment With a New Image
$ kubectl set image deployment/deployment-example nginx=nginx:1.9.9 deployment "deployment-example" image updated
Here the nginx image has been updated from 1.9.2 to 1.9.9 and as you run the update command, another replicaset was created to handle the upgrade without disrupting the service
$ kubectl get rs NAME DESIRED CURRENT READY AGE deployment-example-1421084195 0 0 0 3m deployment-example-4191391954 2 2 2 3m
You can rollback to the previous image 1.9.2 if need be
$ kubectl set image deployment/deployment-example nginx=nginx:1.9.2 deployment "deployment-example" image updated
As the image was rolled back, notice how the number of containers were swapped from replicasets deployment-example-4191391954 to deployment-example-1421084195 below. This is to maintain the services running without disruption during the upgrade process.
$ kubectl get rs NAME DESIRED CURRENT READY AGE deployment-example-1421084195 2 2 2 19m deployment-example-4191391954 0 0 0 19m
Alternatively, you can use the rollback undo command to rollback the image.
kubectl rollout undo deployment/nginx
Scaling the Deployment Controller Object
To increase the number of pods running, use the scale command as below. Here you are scaling from 2 to 4 pods.
$ kubectl scale --replicas=4 deployment/deployment-example $ kubectl get pods NAME READY STATUS RESTARTS AGE deployment-example-1421084195-2qchb 1/1 Running 0 11m deployment-example-1421084195-4wx4c 1/1 Running 0 7s deployment-example-1421084195-c2dd9 1/1 Running 0 11m deployment-example-1421084195-d6knv 1/1 Running 0 7s
This is an equivalent command to the above. Here you scale from 4 to 6 pods.
$ kubectl scale deployment deployment-example --replicas=6 deployment "deployment-example" scaled $ kubectl get pods NAME READY STATUS RESTARTS AGE deployment-example-1421084195-2qchb 1/1 Running 0 22m deployment-example-1421084195-4wx4c 1/1 Running 0 10m deployment-example-1421084195-c2dd9 1/1 Running 0 22m deployment-example-1421084195-d6knv 1/1 Running 0 10m deployment-example-1421084195-p7l3m 1/1 Running 0 3s deployment-example-1421084195-v1jhl 1/1 Running 0 3s
Pausing and Resuming a Deployment
It is sometimes desirable to pause a deployment to make an update to the image or some other changes before resuming deployment. While a pause is in effect, the pods will run as usual, but no new modifications will be applied until a resume is performed.
$ kubectl rollout pause deployment/deployment-example deployment "deployment-example" paused
$ kubectl set image deploy/deployment-example nginx=nginx:1.9.8 deployment "deployment-example" image updated $ kubectl get deploy NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deployment-example 6 6 0 6 51m
Now let’s resume the deployment:
$ kubectl rollout resume deployment/deployment-example deployment "deployment-example" resumed
This is work in progress after the resume command.
$ kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deployment-example 6 8 3 5 52m
Here is the final state after the resume command. Notice how the Current, Up-to-date and available figures are different compared to get deployment command above.
$ kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deployment-example 6 6 6 6 53m
Conclusion
This is a tutorial on how to use Kubernetes deployment controller object. With deployments, you can create your applications and monitor them, manage the lifecycle of the application such as scale up and scale down, upgrade/downgrade your application images, all with no interruption to your applications.