Navigating the Kubernetes Seas: A story of Resource Optimization

Raghavendra Tandon
OneFootball Tech
Published in
8 min readMar 12, 2024

Hey, fellow code enthusiasts and tech adventurers! Welcome aboard for an exciting journey through the vast world of Kubernetes, where the power of computing shapes the seas we navigate. Here, we’ll chase our fortune, not with traditional tools, but with the magic of managing resources effectively.

Let’s assemble our diverse team, from the swift Golang ships slicing through code, to the agile Node and React vessels skimming the digital waves, and the wise Python ship, slow but insightful, contemplating each line of code. Together, we’ll conquer the challenges of Kubernetes, mastering the art of scalability with unmatched agility.

Armed with our code as our compass and driven by the force of technology, we’re off. Our treasure isn’t tangible wealth but the prized achievement of optimal performance and smooth expansion. Let’s embark on this adventure to the lands of Kubernetes, facing down bugs and embracing innovation with every step. Crew ready? It’s time to set sail!

Setting the Stage: The Essentials of Kubernetes Resource Management

This class diagram represents the critical aspects of Kubernetes resource management, focusing on resource requests and limits as the two key concepts guiding application deployment and performance.
This class diagram represents the critical aspects of Kubernetes resource management, focusing on resource requests and limits as the two key concepts guiding application deployment and performance.

In the complex landscape of Kubernetes, resource management serves as the critical compass that guides application deployment and performance. At its core, this involves two key concepts: resource requests and limits.

Requests define the essential CPU and memory required for an application to operate efficiently, ensuring it has the minimum resources necessary to function without disruption. This is akin to plotting a safe and steady course for a ship, guaranteeing it has enough supplies to reach its destination.

Limits, on the other hand, prevent applications from consuming more than their fair share of resources, maintaining the equilibrium within the Kubernetes ecosystem. By setting these caps, we safeguard the cluster from any single application’s excessive resource usage, which could otherwise jeopardize the stability and performance of other applications.

Mastering the configuration of resource requests and limits is crucial for engineers. It’s not just about maintaining operational efficiency; it’s about optimizing resource utilization to ensure applications can scale effectively and sustain performance under varying loads. This balance between allocation and restriction is the key to navigating the Kubernetes environment successfully, ensuring applications are well-provisioned for their journey while keeping resource consumption in check.

For engineers navigating the Kubernetes seas, understanding and applying these resource management principles is essential for crafting resilient, scalable, and efficient applications, making it a fundamental aspect of Kubernetes strategy.

This pie chart simplifies the core concepts of Kubernetes resource management, highlighting the equal importance of resource requests and limits in ensuring efficient application operation and cluster stability.
This pie chart simplifies the core concepts of Kubernetes resource management, highlighting the equal importance of resource requests and limits in ensuring efficient application operation and cluster stability.
depicts the strategic balance between resource requests and limits in Kubernetes, illustrating how they contribute to operational efficiency and resource optimization.
depicts the strategic balance between resource requests and limits in Kubernetes, illustrating how they contribute to operational efficiency and resource optimization.

The Fleet: Tailoring Resource Strategies for Diverse Applications

Golang Galleon: Charting a Course with Precision

For the Golang vessel, renowned for its efficiency, setting conservative resource requests ensures smooth sailing without draining the reserves.

apiVersion: v1
kind: Pod
metadata:
name: golang-app
spec:
containers:
- name: golang-container
image: your-golang-image:latest
resources:
requests:
cpu: "200m"
memory: "100Mi"
limits:
cpu: "500m"
memory: "200Mi"

Node or React Raft: Adapting to the Changing Tides

The Node or React application, facing the ever-changing tides of web traffic, requires a resource strategy that can adapt swiftly.

apiVersion: v1
kind: Pod
metadata:
name: frontend-app
spec:
containers:
- name: frontend-container
image: your-frontend-image:latest
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "300m"
memory: "100Mi"

Python Pinnace: Conjuring Efficiency with Care

The Python application demands a meticulous balance to weave its computational magic efficiently, ensuring it does not plunge into the depths of inefficiency or OOM errors.

apiVersion: v1
kind: Pod
metadata:
name: python-app
spec:
containers:
- name: python-container
image: your-python-image:latest
resources:
requests:
cpu: "150m"
memory: "75Mi"
limits:
cpu: "400m"
memory: "150Mi"

Charting a Course: Best Practices and Common Pitfalls

Best Practices for Setting Resource Requests and Limits

1. Start with Profiling: Begin by profiling your application under different load conditions to understand its resource usage. Use this data to set a baseline for requests and a ceiling for limits.

2. Incremental Adjustments: Start with generous limits and gradually tighten them based on actual usage patterns observed over time. This iterative process helps in fine-tuning performance without risking stability.

3. Balance Requests and Limits: Ensure that the gap between requests and limits is reasonable. Too narrow a gap might not leave enough room for spikes in demand, while too wide a gap could lead to inefficient resource utilization.

4. Utilize HPA Effectively: Configure the Horizontal Pod Autoscaler (HPA) to use CPU and Memory metrics (also custom metrics, with KEDA) that accurately reflect your application’s load, ensuring dynamic scaling that aligns with actual performance needs.

This diagram visualizes the recommended steps for setting resource requests and limits in application deployment. It starts with profiling the application under different load conditions, followed by making incremental adjustments based on actual usage, balancing the requests and limits to ensure efficiency, and finally utilizing the Horizontal Pod Autoscaler (HPA) effectively based on accurate CPU and Memory metrics.
This diagram visualizes the recommended steps for setting resource requests and limits in application deployment. It starts with profiling the application under different load conditions, followed by making incremental adjustments based on actual usage, balancing the requests and limits to ensure efficiency, and finally utilizing the Horizontal Pod Autoscaler (HPA) effectively based on accurate CPU and Memory metrics.

Common Pitfalls and How to Avoid Them

1. Over-Provisioning: Setting limits too high can lead to wasteful resource usage. Avoid this by regularly reviewing and adjusting based on usage metrics.

2. Under-Provisioning: Conversely, setting requests too low can cause your applications to be starved of necessary resources, leading to poor performance and potential downtime. Regular monitoring and adjustments are key.

3. Ignoring the ‘Noisy Neighbour’ Problem: Without proper limit settings, a resource-intensive application can monopolize cluster resources. Implement resource quotas and limits to ensure fair resource distribution.

4. Neglecting Pod Evictions: Setting limits too close to node capacity can increase the risk of eviction, especially under high load. Ensure adequate headroom on nodes to accommodate resource spikes.

This pie chart shows the distribution of common resource management pitfalls by impact level, providing a visual representation of how each pitfall contributes to resource management challenges. The chart highlights the need for strategies to mitigate over-provisioning, under-provisioning, and other issues, with a focus on balanced and effective resource utilization.
This pie chart shows the distribution of common resource management pitfalls by impact level, providing a visual representation of how each pitfall contributes to resource management challenges.The chart highlights the need for strategies to mitigate over-provisioning, under-provisioning, and other issues, with a focus on balanced and effective resource utilization.

Implementing Quality of Service (QoS)

Implementing Quality of Service (QoS) in Kubernetes is essential for ensuring the reliable performance of critical applications. By configuring QoS parameters correctly, you can prioritize resources and prevent sudden terminations of containers.

To implement QoS effectively:

  • Define Requests Equal to Limits: For critical applications, it’s recommended to set the resource requests (the amount of resources needed) equal to the resource limits (the maximum amount of resources allowed) for containers in Pods. This ensures that containers won’t be abruptly terminated if other Pods suddenly demand resources.
  • CPU and Memory Limits: It’s best practice to specify CPU and memory limits for all containers. This prevents containers from consuming excessive system resources, which could impact the performance of other processes running on the same node.

When configuring and sizing resource requests and limits:

  • CPU Limits: Instead of setting specific limits on CPU usage, prioritize CPU time by setting CPU requests. This allows workloads to utilize the full CPU capacity without artificial restrictions.
  • Non-CPU Resources: For resources like memory, it’s recommended to set requests equal to limits for predictable behavior. If the requests are not equal to limits, it reduces the Quality of Service (QoS) for the container, making it more likely to be terminated during resource shortages.
  • Avoid Large Differences: Ensure that the difference between the limit and request for non-CPU resources is not too large, as it could lead to node overcommitment and interruptions in workload execution.

It’s crucial to correctly size resource requests, especially when using auto-scaling solutions like Karpenter or Cluster AutoScaler. These tools rely on workload requests to determine node provisioning. Incorrectly sized requests may result in workloads being evicted or terminated due to resource constraints.

Sailing With HPA: Dynamic Scaling on the Horizon

Incorporating the Horizontal Pod Autoscaler (HPA) into our Kubernetes strategy enables our applications to dynamically scale with the demands, akin to enlisting a seasoned sailor to adjust our sails to the winds of traffic, ensuring our fleet is not only seaworthy but poised to conquer the vast oceans of demand.

Navigating the Waters of HPA: Setting Sail with Accurate Targets

Setting the correct targets for HPA is crucial to avoid the pitfalls of under or over-scaling. Let’s explore how accurate targeting benefits your voyage and how missteps can lead to treacherous outcomes.

Setting Correct Targets for HPA: The Beacon of Performance

Benefits and Examples:

  • Balanced Scaling for CPU-Intensive Applications: Correct CPU targets allow HPA to scale the application precisely during varying loads.
  • Memory-Based Scaling for Data-Intensive Workloads: Memory targets help manage applications with variable memory consumption, scaling up before memory constraints lead to errors.

The Risks of Misconfigured HPA Targets: Sailing into Stormy Seas

Consequences and Examples:

  • Under-Scaling Due to High Thresholds: High thresholds may result in HPA reacting too late, causing under-scaling during critical times.
  • Over-Scaling Due to Low Thresholds: Setting targets too low can trigger unnecessary scaling(target is the percentage of requests so pods might always stay in scaled state), leading to over-provisioning and increased costs.

SETTING LOWER TARGETS DOES NOT MEAN FASTER SCALING AT ALL

the process of setting correct HPA targets, illustrating the pathway from identifying application type to achieving balanced scaling for CPU and memory-intensive applications.
the process of setting correct HPA targets, illustrating the pathway from identifying application type to achieving balanced scaling for CPU and memory-intensive applications.

Important questions to ask yourself and remind yourself

There is no golden path or bullet for all applications for setting request/limts and HPA targets to achieve best performance and scalability. Rather these depends on the application business use case

  • How much scalable wrt requests or events is your single pod(or single instance) of application — NO HPA or scaling involved since the first line of defence against scaling is the application itself
  • Scalability first needs to be solved by the application architecture and not resources or the pod count
  • Does the pod/application server a very fluctuating difference of traffic
  • Is the service service a sync or async traffic
  • Is the service API based or event based
  • How does the application behave under different benchmarks
  • Are you sure you are not solving concurrency with HPA scaling
  • Remember, Pod scaling is fast but still takes some amount of time to be ready to serve. hence do not rely entirely on the HPA scaling to handle surge of spikes

We can make applications/platforms scalable but it doesnt mean that it has be to endlessly scalable, there is always a limit. ALWAYS use rate-limiting and other mechanism to protect your application and business from getting impacted from surge of requests or other events. Which can cause a cascading impact to the platform and the business making the problems spread wider.

Charting a Smooth Course: The Importance of Continuous Monitoring

Setting the correct targets for HPA is an iterative process, requiring continuous monitoring and adjustment based on actual application performance and usage patterns.

Optimization as a Continuous Voyage

Our exploration of Kubernetes resource management is an ongoing odyssey, requiring continuous monitoring, adjustment, and a keen eye on performance and cost efficiency. By tailoring our resource management strategies to the unique needs of each application and leveraging tools like HPA, we ensure our deployments navigate the Kubernetes seas with grace and agility.

So, let us sail forth into the Kubernetes horizon, optimizing for performance, stability, and cost efficiency. May your deployments navigate these waters smoothly, guided by the stars of best practices and the winds of scalability.

Sailing into happy and scalable horizons 😜

--

--