Best practices for Accelerating Kubernetes Deployments.

Tola Ore-Aruwaji
Level Up Coding
Published in
8 min readAug 9, 2021

--

Photo by Jonathan Chng on Unsplash

In this tutorial, we will be looking at scaling Pods, Replica controller, and best practices for accelerating your Kubernetes Deployments.

Kubernetes deployment is a description of the desired state of the pods. You can use deployments to roll out a new application or microservice or update an existing one. Deployments can scale the number of replica pods, enable rollout of updated code in a controlled manner, or roll back to an earlier deployment version if necessary.

If your application is stateless, you can horizontally scale it. A stateless application means that your application doesn't have a state, it doesn’t write any local files / keeps local session data.

If you have two pods and one pod is going to write something locally, then those pods will be out of sync. And that means that each pod will have its own state, and that’s why you cannot kill it. If both pods will have always the same files, they wouldn’t really have their own state and a request to one pod will always lead to the same result as doing requests from the other pod then the pod is probably stateless.

  • Stateless: Your application doesn’t have a state. It doesn’t write any local files / keep local sessions.
  • All traditional databases (MYSQL, PostgreSQL) are stateful. They have database files that can’t be split over multiple instances.

Most web applications can be made stateless:

  • Session management needs to be done outside the container. So, if you want to get hits on your web application, and you want to keep information about your visitors, then you need to use an outside service, you cannot store that kind of data within your container. You can use Memcache, Redis, or even a database to store your sessions.
  • Any files that need to be saved cannot be saved locally on the container because, if you stop your container and you start again, the files will be lost. So you need to save any files you want to store outside the container, either on some shared storage or on an external service (AWS). On AWS you can save it on S3 object storage.
  • Those stateful apps can’t horizontally scale, but you can run them in a single container and vertically scale (allocate more CPU/Memory/Disk)

Scaling in Kubernetes can be done using the Replication Controller.

The Replication controller will ensure that a specified number of pod replicas will run at all times. For example, you can specify that five (5) pod replicas and it’s going to run the same pod, but that 5 times.

  • A pod created with the replication controller will automatically be replaced if they fail, get deleted, or are terminated.

If you tell Kubernetes to run five (5) pods and there are only four pods running, because 1 node crashed, for instance, then Kubernetes will launch another instance of that pod on another node.

  • Using the replication controller is also recommended if you just want to make sure 1 pod is always running, even after reboots. You can then run a replication controller with just 1 replica. This makes sure that the pod is always running even when the node crashes.

In the example below, we are replicating our app 2 times:

The Replication-Controller also has a spec. In this, we have 2 replicas, and this is the replication controller for the App hello world that’s why we have the selector as app:helloworld which is going to select the label with app:helloworld.

Then we have a template for our pod definition. The pod definition also has metadata We also have the label the same one you saw under the selector.

lastly, we have the pod specification. Where we still have one container, with a name docker-demo, and image and we expose port 5000

apiVersion: v1kind: ReplicationControllermetadata:name: hello-world-controllerspec:  replicas: 2  selector:  app: hello-world    template:     metadata:      labels:        app: hello-world    spec:     containers:     - name: docker-demo    image: tolatemitope/docker-demo    ports:    - containerPort: 5000

So what the Replication-Controller is going to do is that it’s going to run two times the pod that is defined in the template.

  • When you are done configuring your file, you can then create it using kubectl create -f replicationcontroller.yaml
  • You can confirm to check if your replication controller is running using kubectl get replicationcontroller
  • With this, you can see how we horizontally scaled the pod. We have multiple pods running, and you can also put a service in front of it like a Load-Balancer that will make your multiple pods accessible to other software or customers. If one pod you configured crashes, the controller will automatically reschedule these pods.
  • If you remove one of your pods, you see that the replication controller will create a new pod.
  • You see that the pod is been terminated, but a new one is being created.
  • You can see below that the pod is terminated, but a new pod has been created. From the image below, a new pod was created 43s since we deleted the last pod.
  • You can always scale those pods, you can say kubectl scale --replicas=4 -f (filename.yaml) and you will eventually see your controller scaled.
  • Go back to your terminal and check you will see that it has been created four pods due to the scaling operation.
  • Another way you can scale is by getting the name of your replication controller using kubectl get rc then scale it using kubectl scale --replicas=1 rc/helloworld-controller and then it’s going to scale it again.
  • Check your pods again you will see that some have been terminated and only one of them is now running.
  • As we discussed earlier, you can see that you can only scale when your pod is stateless. If you have stateful pods, then you will not be able to do this.
  • You can delete your replication controller using kubectl delete rc/helloworld-controller and the last pod will be terminated.
  • These scaling operations are all saved in Kubernetes itself as a backend etcd where it saves all those settings like the number of replicas. You don’t always need to have those in the yaml files.

Kubernetes Deployment and Replication Set

  • The Replica Set is the next-generation Replication Controller. it supports a new selector that can do selection based on filtering according to a set of values. For example, an environment can either be “dev” or “qa” With your Replication Set, you can do more complex matching.
  • Replica Set, rather than the Replication Controller, is used by the Deployment object.

Let’s talk about Deployments in Kubernetes

  • A deployment is a declaration in Kubernetes that allows you to do app deployments and updates. When using the deployment object, you define the state of your application. Kubernetes will then make sure the clusters match your desired state.
  • Using just the replication controller or replication set might be cumbersome to deploy apps. It might be too much manual work for you to do updates and rollbacks.
  • The Deployment object is easier to use and gives you more possibilities.

So what are those Possibilities:

  • Create a deployment (e.g. deploying an app)
  • Update a deployment (e.g. deploying a new version)
  • Do rolling updates (zero downtime deployments)
  • Roll back to a previous version.
  • Pause / Resume a deployment (e.g roll-out to only a certain percentage)
apiVersion: extensions/v1beta1kind: Deploymentmetadata:name: helloworld-deploymentspec:  replicas: 3  template:    metadata:      labels:        app: helloworld   spec:     containers:     - name: docker-demo    image: tolatemitope/docker-demo    ports:    - containerPort: 5000

For our deployment above, we gave it a name helloworld-deployment with 3 replicas the container specification is similar to what we used earlier for our replication set.

All the replicas are up to date and are running the latest docker-demo version that we asked it to run.

  • You can also get the replica set using kubectl get rs

You don’t need to create the replica set yourself Kubernetes does it for you.

  • Check your pods and get them.
  • Show the labels from your pods.
  • Expose your deployment using kubectl expose deployment hello-world-deployment — type=NordPort
  • Get the service using kubectl get service you will see the service of your newly created deployment.
  • Set a new image using: kubectl set image hello-world-deployment docker-demo=tolatemitope/docker-demo:2
  • Get the rollout status using kubectl rollout status hello-world-deployment

Useful Commands for your Kubernetes Deployments.

  • kubectl get deployments-> Get information on your current deployment.
  • kubectl get rs-> Get information about the replica sets.
  • kubectl get pods --show-labels -> Get pods, and also show labels attached to the pods.
  • kubectl rollout status deployment/(name of deployment) -> Get deployment status.
  • kubectl set image deployment/helloworld-deployment docker-demo=docker-demo:2 -> Run docker-demo with the new image label version 2.
  • kubectl edit deployment/helloworld-deployment -> Edit the deployment object.
  • kubectl rollout status deployment/helloworld-deployment -> Get the status of the rollout.

if you updated your image to the new version, then you can use the rollout status to see how the deployment is progressing.

  • kubectl rollout history deployment/helloworld-deployment -> Get the rollout history.

if you release a new version of your app, for instance, version 3 and you want to reverse back to version 2, you can use:

  • kubectl rollout undo deployment/helloworld-deployment -> Rollback to the previous version.

Rollback to a specific version using:

  • kubectl rollout undo deployment/helloworld-deployment --to-revision=n -> Rollback to a more specific version.

gracias

Enjoyed the read? Leave some ‘claps’ below so others can find this post 🙂

--

--