Populating Deployments in Kubernetes
As we mentioned earlier, Deployment is a convenient way to manage and update pods. Defining a Deployment in Kubernetes is an effective and efficient way to provide declarative updates for the application running in your cluster.
You can create a Deployment by using kubectl imperative commands or by using declarative YAML manifest files. In the following exercise, we're going to deploy an application (we will go with Nginx for this exercise) in Kubernetes and learn how to interact with Deployments using kubectl commands, as well as how to modify the YAML manifest file.
Exercise 3.02: Creating a Deployment
There are two ways to create a Deployment in Kubernetes – using the kubectl create/run command and creating a manifest file in YAML format and then using the kubectl apply command. We can achieve the same goal with those two options. Let's try both and then compare them:
- Create a Deployment using the following command directly:
kubectl create deployment kubeserve --image=nginx:1.7.8
You can expect an output similar to the following:
deployment.apps/kubeserve created
Note
You can also create a Deployment using the kubectl run command. To achieve the same results here, you could use the following commands:
kubectl run nginx --image=nginx:1.7.8
kubectl run nginx --image=nginx:1.7.8 --replicas=3
- You can also create a Deployment by defining the YAML manifest file for your Deployment. Use your preferred text editor to create a file named sample-deployment.yaml with the following content:
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubeserve
labels:
app: kubeserve
spec:
replicas : 3
selector:
matchLabels:
app: kubeserve
template:
metadata:
labels:
app: kubeserve
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
In this YAML definition, the replicas field defines the number of replica pods in this Deployment.
- Use the following command to apply the configuration you've defined in the YAML manifest file:
kubectl apply -f sample-deployment.yaml
The sample output will look as follows:
kubectl apply -f sample-deployment.yaml
- Use the following command to check the Deployments that currently exist in the default namespace:
kubectl get deployments
The output will look as follows:
NAME READY UP-TO-DATE AVAILABLE AGE
aci-helloworld 1/1 1 1 27d
kubeserve 3/3 3 3 26m
In this exercise, we have seen the differences in using the different approaches to create a Deployment. The kubectl create command is widely used for testing. For most enterprise solutions where modern DevOps approaches are implemented, it makes more sense to use YAML definitions to conveniently define configurations, and then track them with source control tools such as Git. When your organization integrates YAML definitions with DevOps tools, it makes the solution more manageable and traceable.
Now that we have seen how to create a Deployment, in the next exercise, we will learn how to modify or update a Deployment that is already running. This is something that you will need to do quite often as the software is updated to new versions, bugs are identified and fixed, the demands on your application change, or your organization moves on to completely new solutions. We will also learn how to roll back a Deployment to an earlier version, which is something that you will want to do if an update does not lead to the expected outcome.
Exercise 3.03: Updating a Deployment
In this exercise, we will update the application that we deployed in the previous exercise to a more recent version and demonstrate how we can roll back the Deployment to a previous version if necessary.
Similar to the two approaches that we saw for creating a Deployment, there are two ways to update an application as well – using the kubectl set image command and updating the YAML manifest file and then using the kubectl apply command. These steps will guide you through both approaches:
- First, let's get the details of the current Deployment using the following command:
kubectl describe deploy kubeserve
You'll get an output similar to the following:
- You can update the image using the following command:
kubectl set image deployment/kubeserve nginx=nginx:1.9.1 –-record
The image subcommand indicates that we want to update the image field of the object, as defined in the YAML manifest that we saw in Step 2 of the previous exercise.
Then, we specify the object in the <object-type>/<object name> format.
The next part, nginx=nginx:1.9.1, tells Kubernetes to look for the specific image tagged as 1.9.1 in the Docker Hub repository of NGINX. You can check out the available tags at https://hub.docker.com/_/nginx?tab=tags.
The --record flag is very helpful when you want to save the updates that have been made by your kubectl commands to the current resource.
By applying this, you'll get an output similar to the following:
deployment.extensions/kubeserve image updated
- Now, let's get the details of the Deployment using the following command:
kubectl describe deploy kubeserve
You should see the following output:
In the preceding screenshot, you can see that the image has been successfully updated to version 1.9.1.
Another way to achieve the same result is to modify the YAML file and then use the kubectl apply command. We will use the same YAML file that we created in the previous exercise. If you do not have the YAML file for an object, you can export the YAML manifest using the following command:
kubectl get deploy kubeserve -o yaml > kubeserve-spec.yaml
This command will output a file named kubeserve-spec.yaml with the manifest that is in effect in the cluster. Then, you can use vim, nano, or any other text editor to edit it and then apply the edited kubeserve-spec.yaml manifest using the kubectl apply command, as shown in the previous exercise, with the addition of the --record flag.
- If you want to perform a rollback, you can use the following command:
kubectl rollout undo deployments kubeserve
You'll see an output similar to the following:
deployment.extensions/kubeserve rolled back
- You can use the kubectl rollout history command to check all the revisions for a specific Deployment, as shown here:
kubectl rollout history deployment kubeserve
You'll see an output similar to the following:
- You can also use the following command to check the details of a specific revision:
kubectl rollout history deployment kubeserve --revision=3
The output for this command will be as follows:
- You can roll back a Deployment to a specific revision by specifying the --to-revision flag:
kubectl rollout undo deployments kubeserve --to-revision=3
You'll see an output similar to the following:
deployment.extensions/kubeserve rolled back
In this exercise, we have learned how to update an already existing Deployment, as well as how to roll back a Deployment to its earlier specs.
Deployments allow us to define a desired state for the replica pod in a declarative way. We will revisit how Deployment works and discover more about it in Chapter 7, Kubernetes Controllers. If you delete the inpidual pod replica intentionally or if the pod fails for any reason, since we define a Deployment with a set number of replicas, the Deployment will keep recreating the pod as many times as you delete it. This is what we call auto-healing. Therefore, you need to delete the Deployment itself, which will also delete all the pods managed by it. We will learn how to do that in the following exercise.
Exercise 3.04: Deleting a Deployment
In this exercise, we will delete the Deployment we created in the previous exercise:
- Get a list of existing Deployments using the following command:
kubectl get deployment
You can expect an output similar to the following:
NAME READY UP-TO-DATE AVAILABLE AGE
aci-helloworld 1/1 1 1 27d
kubeserve 3/3 3 3 26m
melonkedaaf 0/0 0 0 26d
- Let's say that, for the purpose of this exercise, we want to delete the kubeserve Deployment that we created in the previous exercise. Use the following command to delete the Deployment:
kubectl delete deployment kubeserve
The sample output will be similar to the following:
deployment.extensions "kubeserve" deleted
- Get the list of Deployments to check and make sure that the target Deployment has been deleted successfully:
kubectl get deployment
You should see an output similar to the following:
NAME READY UP-TO-DATE AVAILABLE AGE
aci-helloworld 1/1 1 1 27d
kubeserve 0/0 0 0 26d
You can use the kubectl delete command to delete any other object as well. However, as we mentioned earlier, in cases such as pods managed by Deployments, it is pointless to delete inpidual pods as the Deployment will just recreate them, so you need to delete the Deployment.
Activity 3.01: Editing a Live Deployment for a Real-Life Application
Imagine that you are a SysOps engineer who has been asked to manage a cluster and deploy a web application. You have deployed it to your Kubernetes cluster and made it available to the public. You have been monitoring this application ever since it was deployed successfully, and you've detected that the web application has been experiencing throttling issues during peak times. Based on your monitoring, the solution that you want to implement is to assign more memory and CPU to this application. Therefore, you need to edit the Deployment so that you can allocate enough CPU and memory resources to run the application and test this application at the end. You need to demonstrate that your web application is up and running and that it can be accessed through a public IP address via a browser of your choice.
To simulate this scenario, we're going to deploy a sample application in a Kubernetes cluster and show you how to edit a live Deployment. Editing a live Deployment is something that you will need to do when fixing issues or for testing purposes.
You can use the following command to get the YAML manifest file that you're going to use in this activity:
curl https://raw.githubusercontent.com/PacktWorkshops/Kubernetes-Workshop/master/Chapter03/Activity03.01/sample-application.yaml --output sample-application.yaml
This manifest file defines all the different objects that are required to run the application, as well as the application itself.
Note
This manifest has been adapted from an open-source sample provided by Microsoft Azure, available at https://github.com/Azure-Samples/azure-voting-app-redis.
Perform the following steps to complete this activity:
- First, deploy the target web application using the kubectl apply command and the provided YAML definition file.
- Get the IP address of the service that exposes your application. For this simple scenario, this will be similar to Exercise 2.03, Accessing a Pod via a Service, from the previous chapter. Later chapters will explain how to work with ingress controllers and create ingress resources to expose the frontend applications.
- Use the kubectl edit command to edit the live deployment. You will need to edit the deployment named melonvote-front. The following are the fields that you need to modify to satisfy the requirements of this scenario. You can simply double these values:
a) resources.limits.cpu: This is the resource limit for CPU usage.
b) resources.limits.memory: This is the resource limit for memory usage.
c) resources.requests.cpu: This is the minimum CPU usage requested to get your application up and running.
d) resources.requests.memory: This is the minimum memory usage requested to get your application up and running.
By the end of this activity, you will be able to see the UI of the application that you deployed with Kubernetes:
Note
The solution to this activity can be found at the following address: https://packt.live/304PEoD.