Related Blogs
Key Takeaways
- To deliver resilient apps and infrastructure, shorten time to market, create deployments without downtime, release features & apps faster and operate them with greater flexibility, choosing the right Kubernetes deployment strategies is important.
- All the K8s deployment strategies use one or more of these use cases:
- Create: Roll out new K8s pods and ReplicaSets.
- Update: Declare new desired state and roll out new pods and ReplicaSets in a controlled manner.
- Rollback: Revert the K8s deployment to its previous state.
- Scale: Increase the number of pods and Replica Sets in the K8s deployment without changing them.
- Following factors one should consider while selecting any K8s deployment strategy:
- Deployment Environment
- How much downtime you can spare
- Stability of the new version of your app
- Resources availability and their cost
- Project goals
- Rolling or Ramped deployment method is Kubernetes default rollout method. It scaled down old pods only after new pods became ready. Also one can pause or cancel the deployment without taking the whole cluster offline.
- Recreate Deployment, Blue/Green Deployment, Canary Deployment, Shadow Deployment, and A/B Deployment are other strategies one can use as per requirements.
Kubernetes is a modern-age platform that enables business firms to deploy and manage applications. This container orchestration technology enables the developers to streamline infrastructure for micro-service-based applications that eventually help in managing the workload. Kubernetes empowers different types of deployment resources like updating, constructing, & versioning of CD/CI pipelines. Here, it becomes essential for the Kubernetes deployment team to use innovative approaches for delivering the service because of frequent updates in Kubernetes.
For this, software development companies have to choose the right deployment strategy as it is important for deploying production-ready containerized applications into Kubernetes infrastructure. For this, there are three different options available in the market and they are canary releases, rolling, and blue/green deployments. Kubernetes helps in deploying and autoscaling the latest apps by implementing new code modifications in production environments. To know more about this Kubernetes deployment and its strategies, let’s go through this blog.
1. What is Kubernetes Deployment?
A Deployment allows a description of an application’s life cycle such as images to be used, the number of pods required, and how to update them in the application. In other words, deployment in Kubernetes is a resource object that can be used to specify the desired state of the application as deployment is generally declarative which means that the developers cannot dictate the achievement steps of this phase. Besides, in Kubernetes, a deployment controller can be used to reach the target efficiently.
2. Key Kubernetes Deployment Strategies
The Kubernetes deployment process is known as a declarative statement that helps development teams configure it in the YAML file that specifies the several Kubernetes deployment strategies and life of the application and how it will get updated from time to time. While deploying applications to a K8s cluster the selected deployment strategy would determine which applications have been updated from an older version to a newer version. Also, some Kubernetes deployment strategies involve downtime while some deployments would introduce testing concepts and enable user analysis.
2.1 Rolling Deployment Strategy
- Readiness probes
This type of deployment strategy helps the developers to monitor when any application gets activated and what happens if the probe fails & no traffic is sent to the pod. This approach is mostly used when there is a need for specific types of initialization steps in an application before it goes live. There are chances where applications may be overloaded with traffic and cause probe failure. With this, it also safeguards the application from getting more traffic.
Once the availability of the new version of an application is detected by the readiness probe, the older version gets removed. If there are any challenges then the rollout can be stopped and rollback of the previous version is deployed to avoid downtime of the application across the Kubernetes cluster. This is because each pod in the application gets replaced one by one. Besides this, even the deployment can take some time when the clusters are larger than usual. When a new deployment gets triggered before the previous one is finished, the previous deployment gets ignored and the new version gets updated as per the new deployment.
When there is something specific to the pod and it gets changed, the rolling deployment gets triggered. The change here can be anything from the environment to the image to the label of the pod.
- MaxSurge
It specifies a maximum number of pods that are permitted at the time of deployment.
- MaxUnavailable
It defines the maximum number of pods that are granted by the deployment creation process to be inaccessible while the rollout is being processed.
In this example:
- replicas: 3 indicates that there are initially three replicas of your application running.
- rollingUpdate is the strategy type specified for the deployment.
- maxUnavailable: 1 ensures that during the rolling update, at most one replica is unavailable at a time.
- maxSurge: 1 allows one additional replica to be created before the old one is terminated, ensuring the desired number of replicas is maintained.
apiVersion: E-commerce/v1 kind: Deployment metadata: name: e-commerce-deployment spec: replicas: 3 selector: matchLabels: app: e-commerce template: metadata: labels: app: e-commerce spec: containers: - name: e-commerce-container image: tatvasoft/e-commerce:latest ports: - containerPort: 80 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1 |
apiVersion: E-commerce/v1 kind: Deployment metadata: name: e-commerce-deployment spec: replicas: 3 selector: matchLabels: app: e-commerce template: metadata: labels: app: e-commerce spec: containers: - name: e-commerce-container image: tatvasoft/e-commerce:latest ports: - containerPort: 80 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1
2.2 Recreate Deployment
Here is a digital representation of Recreate Deployment. It’s a two-step process that includes deleting all old pods, and once that is done, new pods are created. It may lead to downtime as users will have to wait until old services are deleted and new ones are created. However, this strategy is still used by Kubernetes for performing deployment.
Recreate deployment strategy helps eliminate all the pods and enables the development team to replace them with the new version. This recreate deployment strategy is used by the developers when a new and old version of the application isn’t able to run at the same time. Here, in this case, the downtime amount taken by the system depends on the time the application takes to shut down its processing and start back up. Once the pods are completely replaced, the application state is entirely renewed.
In this example, the strategy section specifies the type as Recreate, indicating that the old pods will be terminated before new ones are created.
apiVersion: e-commerce/v1 kind: Deployment metadata: name: e-commerce-deployment spec: replicas: 3 selector: matchLabels: app: e-commerce template: metadata: labels: app: e-commerce spec: containers: - name: e-commerce-container Image: tatvasoft/e-commerce:latest ports: - containerPort: 80 strategy: type: Recreate |
apiVersion: e-commerce/v1 kind: Deployment metadata: name: e-commerce-deployment spec: replicas: 3 selector: matchLabels: app: e-commerce template: metadata: labels: app: e-commerce spec: containers: - name: e-commerce-container Image: tatvasoft/e-commerce:latest ports: - containerPort: 80 strategy: type: Recreate
2.3 Blue-Green Deployment
In the Blue-Green Kubernetes deployment strategy, you can release new versions of an app to decrease the risk of downtime. It has two identical environments, one serves as the active production environment, that is, blue, and the other serves as a new release environment, that is, green.
A Blue-Green deployment is one of the most popular Kubernetes deployment strategies that enable the developers to deploy the new application version which is called green deployment with the old one which is called blue deployment. Here, when the developers want to direct the traffic of the old application to the new one, they use a load balancer. In this case, it is utilized as the form of the service selector object. Blue/Green Kubernetes deployments are costly as they require double the resources of normal deployment processes.
Define Blue Deployment (blue-deployment.yaml):
apiVersion: e-commerce/v1 kind: Deployment metadata: name: blue-e-commerce-deployment spec: replicas: 3 selector: matchLabels: app: blue-e-commerce template: metadata: labels: app: blue-e-commerce spec: containers: - name: blue-e-commerce-container image: tatvasoft/blue-e-commerce:latest ports: - containerPort: 80 |
apiVersion: e-commerce/v1 kind: Deployment metadata: name: blue-e-commerce-deployment spec: replicas: 3 selector: matchLabels: app: blue-e-commerce template: metadata: labels: app: blue-e-commerce spec: containers: - name: blue-e-commerce-container image: tatvasoft/blue-e-commerce:latest ports: - containerPort: 80
Define Green Deployment (green-deployment.yaml):
apiVersion: e-commerce/v1 kind: Deployment metadata: name: green-e-commerce-deployment spec: replicas: 3 selector: matchLabels: app: green-e-commerce template: metadata: labels: app: green-e-commerce spec: containers: - name: green-app-container image: tatvasoft/green-e-commerce:latest ports: - containerPort: 80 |
apiVersion: e-commerce/v1 kind: Deployment metadata: name: green-e-commerce-deployment spec: replicas: 3 selector: matchLabels: app: green-e-commerce template: metadata: labels: app: green-e-commerce spec: containers: - name: green-app-container image: tatvasoft/green-e-commerce:latest ports: - containerPort: 80
Define a Service (service.yaml):
apiVersion: v1 kind: Service metadata: name: e-commerce-service spec: selector: app: blue-e-commerce # or green-app, depending on which environment you want to expose ports: - protocol: TCP port: 80 targetPort: 80 |
apiVersion: v1 kind: Service metadata: name: e-commerce-service spec: selector: app: blue-e-commerce # or green-app, depending on which environment you want to expose ports: - protocol: TCP port: 80 targetPort: 80
Define an Ingress (ingress.yaml):
apiVersion: e-commerce/v1 kind: Ingress metadata: name: e-commerce-ingress spec: rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: e-commerce-service port: number: 80 |
apiVersion: e-commerce/v1 kind: Ingress metadata: name: e-commerce-ingress spec: rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: e-commerce-service port: number: 80
Now, the blue environment serves traffic. Whenever you are switching to green env, you can make an update in the service selector to match the green deployment labels. After this update is made, Kubernetes will begin routing traffic in the green environment.
2.4 Canary Deployment
In this strategy, you can route a small group of users to the latest version of an app, running in a smaller set of pods. It tests functions on a small group of users and avoids impacting the whole user base. Here’s the visual representation of the canary deployment strategy.
A Canary deployment is a strategy that the Kubernetes app developers can use to test a new version of the application when they aren’t fully confident about the functionality of the new version created by the team. This canary deployment approach helps in managing the deployment of a new application version with the old one. Here, the previous version of the application tends to serve the majority of the application users, and the newer application version is supposed to serve a small number of test users. This lets the new deployment rollout maximum number of users when it is successful.
For instance, in the Kubernetes cluster with 100 running pods, 95 could be for v1.0.0 while 5 could be for v2.0.0 of the application. This means that around 95% of the users will be directed to the app’s old version while 5% of them will be directed to the new one.
Version 1.0 Deployment (v1-deployment.yaml):
apiVersion: e-commerce/v1 kind: Deployment metadata: name: e-commerce-v1-deployment spec: replicas: 3 selector: matchLabels: app: e-commerce-v1 template: metadata: labels: app: e-commerce-v1 spec: containers: - name: e-commerce-v1-container image: tatvasoft/e-commerce-v1:latest ports: - containerPort: 80 |
apiVersion: e-commerce/v1 kind: Deployment metadata: name: e-commerce-v1-deployment spec: replicas: 3 selector: matchLabels: app: e-commerce-v1 template: metadata: labels: app: e-commerce-v1 spec: containers: - name: e-commerce-v1-container image: tatvasoft/e-commerce-v1:latest ports: - containerPort: 80
Version 2.0 Deployment (v2-deployment.yaml):
apiVersion: e-commerce/v1 kind: Deployment metadata: name: e-commerce-v2-deployment spec: replicas: 1 # A smaller number for canary release selector: matchLabels: app: e-commerce-v2 template: metadata: labels: app: e-commerce-v2 spec: containers: - name: e-commerce-v2-container image: tatvasoft/e-commerce-v2:latest ports: - containerPort: 80 |
apiVersion: e-commerce/v1 kind: Deployment metadata: name: e-commerce-v2-deployment spec: replicas: 1 # A smaller number for canary release selector: matchLabels: app: e-commerce-v2 template: metadata: labels: app: e-commerce-v2 spec: containers: - name: e-commerce-v2-container image: tatvasoft/e-commerce-v2:latest ports: - containerPort: 80
Service (service.yaml):
apiVersion: v1 kind: Service metadata: name: e-commerce-service spec: selector: app: e-commerce-v1 # Initially pointing to the version 1.0 deployment ports: - protocol: TCP port: 80 targetPort: 80 |
apiVersion: v1 kind: Service metadata: name: e-commerce-service spec: selector: app: e-commerce-v1 # Initially pointing to the version 1.0 deployment ports: - protocol: TCP port: 80 targetPort: 80
Gradually Shift Traffic to Version 2.0 (canary-rollout.yaml):
apiVersion: e-commerce/v1 kind: Deployment metadata: name: canary-rollout spec: replicas: 3 selector: matchLabels: app: e-commerce-v1 # Initially pointing to the version 1.0 deployment template: metadata: labels: app: e-commerce-v1 spec: containers: - name: e-commerce-v1-container Image: tatvasoft/e-commerce-v1:latest ports: - containerPort: 80 --- apiVersion: e-commerce/v1 kind: Deployment metadata: name: canary-rollout spec: replicas: 2 selector: matchLabels: app: e-commerce-v2 # Gradually shifting to the version 2.0 deployment template: metadata: labels: app: e-commerce-v2 spec: containers: - name: e-commerce-v2-container image: tatvasoft/e-commerce-v2:latest ports: - containerPort: 80 |
apiVersion: e-commerce/v1 kind: Deployment metadata: name: canary-rollout spec: replicas: 3 selector: matchLabels: app: e-commerce-v1 # Initially pointing to the version 1.0 deployment template: metadata: labels: app: e-commerce-v1 spec: containers: - name: e-commerce-v1-container Image: tatvasoft/e-commerce-v1:latest ports: - containerPort: 80 --- apiVersion: e-commerce/v1 kind: Deployment metadata: name: canary-rollout spec: replicas: 2 selector: matchLabels: app: e-commerce-v2 # Gradually shifting to the version 2.0 deployment template: metadata: labels: app: e-commerce-v2 spec: containers: - name: e-commerce-v2-container image: tatvasoft/e-commerce-v2:latest ports: - containerPort: 80
This example gradually shifts traffic from version 1.0 to version 2.0 by updating the number of replicas in the Deployment. Adjust the parameters based on your needs, and monitor the behavior of your application during the canary release.
2.5 Shadow Deployment
Shadow deployment is a strategy where a new version of an app is deployed alongside the new production version, primarily monitoring and testing the product.
Shadow deployment is another type of canary deployment that allows you to test the latest release of the workload. This strategy of deployment helps you to split the traffic between a new and current version, without users even noticing it.
When the performance and stability of the new version meet in-built requirements, operators will trigger a full rollout of the same.
One of the primary benefits of shadow deployment is that it can help you test the new version’s non-functional aspects like stability, performance, and much more.
On the other hand, it has a downside as well. This type of deployment strategy is complex to manage and needs two times more resources to run than a standard deployment strategy.
2.6 A/B Deployment
Just like Canary deployment, the A/B deployment strategy helps you to target a desired subsection of users based on some target parameters like HTTP headers or cookies.
It can distribute traffic amongst different versions. It is a technique that is widely used to test the conversion of a given feature and then the version converting the most popular.
In this strategy, data is usually collected based on the user behavior and is used to make better decisions. Here users are left uninformed that testing is being done and a new version will be made available soon.
This deployment can be automated using tools like Flagger, Istio, etc.
3. Resource Utilization Strategies:
Here are a few resource utilization strategies to follow:
3.1 Resource Limits and Requests:
Each container in the pod in Kubernetes can define limits and resource requests for both memory and CPU. These settings are crucial for resource isolation and allocation.
Resource Requests:
- A particular amount of resources that Kubernetes guarantees to the container.
- If the container exceeds the requested resources, it might feel throttled.
Resource Limits:
- It helps in setting an upper limit on the exact amount of resources that a container can utilize.
- In case this limit is exceeded, it might terminate or face other consequences.
So, it is necessary to set these values appropriately to ensure fair resource allocation among various containers on the same node.
Ex. In the following example, the pod specifies resource requests of 64MiB memory and 250 milliCPU (0.25 CPU cores). It also sets limits to 128MiB memory and 500 milliCPU. These settings ensure that the container gets at least the requested resources and cannot exceed the specified limits.
apiVersion: e-commerce/v1 kind: Pod metadata: name: e-commerce spec: containers: - name: e-commerce-container image: e-commerce:v1 resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" |
apiVersion: e-commerce/v1 kind: Pod metadata: name: e-commerce spec: containers: - name: e-commerce-container image: e-commerce:v1 resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m"
3.2 Horizontal Pod Autoscaling (HPA)
In this technique, you get a feature of automatic adjustment of the number of replicas of a running pod that is based on particular metrics.
Target Metrics:
- HPZ can scale depending on different metrics like memory usage, CPU utilization, and custom metrics.
- The targetAverageUtilization field determines the required average utilization for CPU or memory.
Scaling Policies:
- Define the maximum and minimum number of pod replicas for social deployment.
- Scaling the decisions that are made based on whether the metrics break the decided thresholds.
HPA is useful for handling different loads and ensuring decided resource utilization by managing the number of pod instances in real-time.
Ex. This HPA example targets a Deployment named example-deployment and scales based on CPU utilization. It is configured to maintain a target average CPU utilization of 80%, scaling between 2 and 10 replicas.
apiVersion: e-commerce/v1 kind: HorizontalPodAutoscaler metadata: name: example-hpa spec: scaleTargetRef: apiVersion: e-commerce/v1 kind: Deployment name: e-commerce-deployment minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: cpu targetAverageUtilization: 80 |
apiVersion: e-commerce/v1 kind: HorizontalPodAutoscaler metadata: name: example-hpa spec: scaleTargetRef: apiVersion: e-commerce/v1 kind: Deployment name: e-commerce-deployment minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: cpu targetAverageUtilization: 80
3.3 Vertical Pod Autoscaling
While HPA adjusts the number of replicas, VPA will focus on dynamically adjusting the resource requests of each pod.
Observation and Adaptation:
- VPA observes the real resource usage of pods and adjusts resource requests based on that.
- It optimizes both memory and CPU requests based on historical information.
Update Policies:
- With the updateMode function, you can determine how aggressively VPA should update resource requests.
- With alternatives like Auto, Off, and Recreate, the updated policies help the users officially.
- It also helps in fine-tuning resource allocation for adapting to the actual runtime behavior.
Ex. This VPA example targets a Deployment named example-deployment and is configured to automatically adjust the resource requests of the containers within the deployment based on observed usage.
apiVersion: e-commerce/v1 kind: VerticalPodAutoscaler metadata: name: e-commerce-vpa spec: targetRef: apiVersion: "e-commerce/v1" kind: "Deployment" name: "e-commerce-deployment" updatePolicy: updateMode: "Auto" |
apiVersion: e-commerce/v1 kind: VerticalPodAutoscaler metadata: name: e-commerce-vpa spec: targetRef: apiVersion: "e-commerce/v1" kind: "Deployment" name: "e-commerce-deployment" updatePolicy: updateMode: "Auto"
3.4 Cluster Autoscaler
The cluster autoscaler is responsible for dynamically adjusting the node pool size in response to the resource requirements of your workloads.
Node Scaling:
- When a node lacks resources and cannot accommodate new pods, the Cluster Autoscaler adds more nodes to the cluster.
- Conversely, when nodes are not fully utilized, the Cluster Autoscaler scales down the cluster by removing unnecessary nodes.
Configuration:
- Configuration parameters such as minimum and maximum node counts vary depending on the cloud provider or underlying infrastructure.
The Cluster Autoscaler plays a crucial role in ensuring an optimal balance between resource availability and cost-effectiveness within a Kubernetes cluster.
Ex. This example includes a simple Deployment and Service. Cluster Autoscaler would dynamically adjust the number of nodes in the cluster based on the resource requirements of the pods managed by the Deployment.
apiVersion: e-commerce/v1 kind: Service metadata: name: e-commerce-service spec: selector: app: e-commerce ports: - protocol: TCP port: 80 targetPort: 8080 --- apiVersion: e-commerce/v1 kind: Deployment metadata: name: e-commerce-deployment spec: replicas: 3 selector: matchLabels: app: e-commerce template: metadata: labels: app: e-commerce spec: containers: - name: e-commerce-container image: e-commerce:v1 resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" |
apiVersion: e-commerce/v1 kind: Service metadata: name: e-commerce-service spec: selector: app: e-commerce ports: - protocol: TCP port: 80 targetPort: 8080 --- apiVersion: e-commerce/v1 kind: Deployment metadata: name: e-commerce-deployment spec: replicas: 3 selector: matchLabels: app: e-commerce template: metadata: labels: app: e-commerce spec: containers: - name: e-commerce-container image: e-commerce:v1 resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m"
4. How to Deploy Kubernetes?
Most of the Kubernetes deployments and functions are specified in YAML (or JSON) files. These are developed using ‘kubectl apply’.
For example, when it comes to Ngnix deployment, the YAML is called ‘web deployment’ with four copies of replicas. This will look like the code given below:
$ kubectl set image deployment mywebsite nginx=nginx:1.22.1 |
$ kubectl set image deployment mywebsite nginx=nginx:1.22.1
In the above example, the metadata shows that the ‘web-deployment’ was developed with four copies of pods which are replicas of each other (replicas: 4), and the selector defines how the deployment process will find the pods using the label (app: nginx). Besides this, here the container (nginx) runs its image at version 1.17.0, and the deployment opens port 80 for the pod’s usage.
In addition to this, here, the environment variables for the containers get declared with the use of the ‘envFrom’ or ‘env’ field in the configuration file. After the deployment gets specified, it gets developed from the YAML file with: kubectl apply -f https://[location/web-deployment.yaml]
5. Update Kubernetes Deployment
When it comes to Kubernetes deployment, the developers can use the set command to make changes to the image, configuration fields, or resources of an object.
For instance, to update a deployment from nginx version 1.22.0 to 1.22.1, the following command can be considered.
apiVersion: apps/v1; kind: Deployment metadata: name: web-deployment spec: selector: matchLabels: app: nginx replicas: 4 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.17.0 ports:- containerPort: 80 |
apiVersion: apps/v1; kind: Deployment metadata: name: web-deployment spec: selector: matchLabels: app: nginx replicas: 4 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.17.0 ports:- containerPort: 80
6. Final Words
In this blog, we saw that there are multiple ways a developer can deploy an application. When the developer wants to publish the application to development/staging environments, a recreated or ramped deployment is a good choice. But when production is considered, a blue/green or ramped deployment is an ideal choice. When choosing the right Kubernetes deployment strategy, if the developer isn’t sure about the stability of the platform, a proper survey of all the different ways is required. Each deployment strategy comes with its pros and cons, but which to choose depends on the type of project and resources available.
FAQs:
What is the Best Deployment Strategy in Kubernetes?
There are mainly 8 different Kubernetes deployment strategies:
Rolling Deployment, Ramped slow rollout, Recreate Deployment, Best-effort controlled rollout, canary deployment, A/B testing, and Shadow deployment.
You can choose the one that’s most suitable to your business requirements.
What Tool to Deploy k8s?
Here’s the list of tools to deploy by Kubernetes professionals:
- Kubectl
- Kubens
- Helm
- Kubectx
- Grafana
- Prometheus
- Istio
- Vault
- Kubeflow
- Kustomize, and many more
What is the Difference Between Pod and Deployment in Kubernetes?
A Kubernetes pod is the smallest unit of Kubernetes deployment. It is a cluster of one or more containers that has the same storage space, and even similar network resources.
On the other hand, Kubernetes deployment is the app’s life cycle that includes the pods of that app. It’s a way to communicate your desired state of Kubernetes deployments.
What is the Life Cycle of Kubernetes Deployment?
There are majorly ten steps to follow in a Kubernetes deployment life cycle:
- Containerization
- Container Registry
- YAML or JSON writing
- Kubernetes deployment
- Rollbacks and Rolling Updates
- Scaling of the app
- Logging and Monitoring
- CI/CD
Mohit Savaliya
Mohit Savaliya is looking after operations at TatvaSoft and leverages his technical background to understand Microservices architecture. He showcases his technical expertise through bylines, collaborating with development teams and brings out the best trending topics in Cloud and DevOps.
Subscribe to our Newsletter
Signup for our newsletter and join 2700+ global business executives and technology experts to receive handpicked industry insights and latest news
Build your Team
Want to Hire Skilled Developers?
Comments
Leave a message...