Kubernetes — Orchestration Guide [ A Lovely Symphony 5]
This is part 5 of our Kubernetes Orchestration Guide series. If you came here directly, please see and start from part one to have a better understanding.
In our last article, we learned about important concepts such as using kubectl describe …
to retrieve detailed information about a Kubernetes resource and discovering that you can also use the kubectl apply -f
the command to update Kubernetes objects.
One interesting thing to note in our last article is this: Kubernetes is able to recognize that the execution of
kubectl apply -f
was intended as an update operation instead of a create operation because our name and kind attribute on our configuration files remained the same with our initially created resources.
In this article, we would continue exploring and learning Kubernetes.
Deployments
You would remember from our last article, we tried applying our containerPort
changes on our pod by directly executing kubectl apply -f
and were met with this error:
The Pod "ourapp-container" is invalid: spec: Forbidden: pod updates may not change fields other than `spec.containers[*].image`, `spec.initContainers[*].image`, `spec.activeDeadlineSeconds` or `spec.tolerations` (only additions to existing tolerations
We said we were going to discuss introduce a type of Kubernetes Object that would allow us to make such types of updates without having to delete.
That object type
is called Deployment.
A Deployment is a type of Kubernetes Object used to contain and maintain a set of one or more identical pods.
In reality and most production environments, it is much more frequent to use Deployments instead of Pod due to limitations in pod configuration updates. With a deployment, we can change any piece of configuration information that we want to.
Creating a Deployment
We are going to create a new configuration file that will contain the definition for our Deployment. We would be replacing our usage of our initially created pod with our deployment henceforth.
Create a new file in your project’s root folder and give it a name of ourapp-deployment.yaml
.
apiVersion: apps/v1
kind: Deployment
metadata:
name: ourapp-deployment
spec:
replicas: 1
selector:
matchLabels:
component: web
template:
metadata:
labels:
component: web
spec:
containers:
- name: ourapp
image: covenant/dockerize-nodejs-image
ports:
- containerPort: 5000
Do make sure that the indentations matches as yaml is critical of indentations
Let’s break down our new configuration file
- apiVersion: apiVersion needs no introduction as we’ve covered it extensively in the past, it defines the “scope” under which the object type we are trying to create comes under. In this case, it comes under apps/v1.
- kind: kind also needs no introduction. It is used to denote the type of object we are creating which is a piece of critical information to Kubernetes. In this case, we are creating a Deployment.
- metadata: metadata is used to specify custom information that describes the object. In this case, by specifying name we are informing Kubernetes that our deployment should be called
ourapp-deployment
. - spec: spec is used to define the “specification” for our deployment. This contains various subsets of information used to define our deployment.
- replicas: remember when we said: “A deployment is used to maintain a set of one or more identical pods”. A replica is used to specify the number of pods we want, to be maintained. A value of
1
means we want only one pod to be created and maintained. - selector: this is another attribute we’ve covered in the past. The content of its matchLabel attribute is used for identification when defining association with other objects. In this case, it defines an association between our deployment and the pods that would be created from the template specification.
- template: remember the when we said: “A deployment is used to maintain a set of one or more identical pods”(emphasis on the identical), the template attribute is used to declaratively define the configuration for the one or more(as defined in our replicas attribute) pod which the Deployment is responsible for maintaining.
Do feel free to ask if you have any questions whatsoever on the above.
Now that we have successfully defined our deployment configuration file, let’s go-ahead to create our deployment.
You would recall that from the previous series, we had our “ourapp-container” pod running, let’s delete that.
First we start-up our minikube virtual machine containing our kubernetes cluster by executing this command in your terminal:
minikube start
Next we delete the pod by executing:
kubectl delete pod ourapp-container
Remember, we reverted our config file changes under the conclusion section of our last article and haven’t applied them yet. We are going to apply only the changes we made for our service definition i.e ourapp-node.yaml.
kubectl apply -f ourapp-node.yaml
Next, we create our deployment by using the simple yet powerful kubectl apply -f
command:
kubectl apply -f ourapp-deployment.yaml
You should get a response similar to this:
`deployment.apps "ourapp-deployment" created
We can see our newly created deployment by running this command:
$ kubectl get deployments
We can see the pods which were created as a result of this deployment existence by running:
$ kubectl get po
You should see something similar to this as a result:
NAME READY STATUS RESTARTS AGE
hello-minikube-5857d96c67-s8mdg 1/1 Running 4 83d
ourapp-deployment-77845fcd95-grmn8 1/1 Running 0 4m
Execute minikube ip
to get the IP address of your Kubernetes cluster and open it up in your web browser and you should see a result similar to this
Let me show you something really cool, one of the reasons why i love Kubernetes. Try deleting the pod that was created through the deployment by executing the following command (the random numbers & characters attached to your pod name might slightly differ, in my case “77845fcd95-grmn8”):
$ kubectl delete pod ourapp-deployment-77845fcd95-grmn8
Now, try running kubectl get po
and you will notice something, you will notice that Kubernetes automatically created a new pod for your deployment.
Really super cool, what this means is that if for any reason your app crashes or has any failure, Kubernetes deployment will automatically spawn up a new one to replace it. 😎
Let’s try something else, let’s try to edit the config file to use another containerPort. You would remember that when we tried that with Pod configuration previously, we were hit with this error:
The Pod "ourapp-container" is invalid: spec: Forbidden: pod updates may not change fields other than `spec.containers[*].image`, `spec.initContainers[*].image`, `spec.activeDeadlineSeconds` or `spec.tolerations` (only additions to existing tolerations
Well, let’s try that again in our deployment config. Update your deployment configuration file to read this:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ourapp-deployment
spec:
replicas: 1
selector:
matchLabels:
component: web
template:
metadata:
labels:
component: web
spec:
containers:
- name: ourapp
image: covenant/dockerize-nodejs-image
ports:
- containerPort: 3000
Now try executing:
kubectl apply -f ourapp-deployment.yaml
You would notice that we had no errors this time and instead we got a success message:
deployment.apps "ourapp-deployment" configured
Sticky Notes
- Deployment is a type of object in Kubernetes used to manage one or more identical pods.
- Deployment allows us to carry out any configuration changes.
- Deployments are much more popular and common in most environments due to its flexibility and configuration update abilities.
- Kubernetes Deployment automatically manages and recreates pods in the event of a Pod failing for one reason or the other.
MyCloudSeries is a training and consulting firm with expertise in Cloud Computing and DevOps. We assist organizations in their DevOps strategies, transformation, and implementation. We also provide Cloud Computing Support contact us at www.mycloudseries.com