Sling Academy
Home/DevOps/How to Optimize Resource Allocation in Kubernetes Pods

How to Optimize Resource Allocation in Kubernetes Pods

Last updated: January 30, 2024

Introduction

When working with Kubernetes, orchestrating containers efficiently is critical for the performance and reliability of your applications. This tutorial covers how to optimize resource allocation in Kubernetes pods, ensuring that your clusters run smoothly without wasting resources.

Understanding Resources in Kubernetes

Before we dive into optimization, it’s important to understand Kubernetes’ resource types:

  • CPU – measured in CPU units. In Kubernetes, 1 CPU is equivalent to 1 vCPU/Core for cloud providers and 1 hyperthread for bare-metal Intel processors.
  • Memory – specified in bytes. Kubernetes understands the suffixes like MiB, GiB for mebibyte and gibibyte, respectively.

Resources can be specified for each container in the pod. When declaring resources, you can set ‘requests’ and ‘limits’:

  • Requests: This is the amount of resource Kubernetes will guarantee for the container. If your container tries to use more than the requested amount, it might be throttled, but never killed.
  • Limits: This is the maximum amount of resource the container is allowed to use. If the container exceeds this limit, it may be terminated.

Basic Resource Allocation

apiVersion: v1
kind: Pod
metadata:
  name: basic-allocation-pod
spec:
  containers:
  - name: simple-container
    image: nginx
    resources:
      requests:
        memory: "256Mi"
        cpu: "0.5"
      limits:
        memory: "512Mi"
        cpu: "1"

The above manifest defines a basic pod with an Nginx container. It sets requests and limits for CPU and memory. ‘0.5’ CPU here signifies half a CPU core, while ‘512Mi’ is 512 mebibytes of RAM.

Quality of Service Classes

Kubernetes assigns a Quality of Service (QoS) class to each pod which has implications on the scheduling and eviction of pods:

  • Guaranteed: Every container in the pod must have memory and CPU limits, and they must equal the requests.
  • Burstable: The pod will receive requests and limits, but they don’t need to match.
  • BestEffort: The pod does not have any requests or limits.

Advance Resource Allocation: Overcommitting

Overcommitting resources means allocating more resources to the pods than are actually available on the node. It can be beneficial if your containers do not always use the full amount of requested resources.

apiVersion: v1
kind: Pod
metadata:
  name: overcommit-pod
spec:
  containers:
  - name: busy-container
    image: ubuntu
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo hello; sleep 10;done"]
    resources:
      requests:
        cpu: "0.5"

This pod has a request set, but no limit, making it ‘Burstable’. Because it’s requesting half a CPU, Kubernetes will try to schedule it on a node that can guarantee this.

Managing Node Resources with Resource Quota

Resource quotas are a way to manage cluster resources. They limit the amount of resources a namespace can consume:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: example-quota
spec:
  hard:
    requests.cpu: "400m"
    requests.memory: 1Gi
    limits.cpu: "600m"
    limits.memory: 2Gi

Monitoring and Autoscaling Pods

Deploying metrics-server in your cluster can provide resource utilization data, enabling Horizontal Pod Autoscaler (HPA) to automatically adjust the number of pod replicas based on CPU utilization.

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx-deployment
  minReplicas: 1
  maxReplicas: 10
  targetCPUUtilizationPercentage: 50

This HPA configuration adjusts the number of replicas of ‘nginx-deployment’ between 1 and 10 to maintain an average CPU utilization across all pods at 50%.

Using Node Affinity for Optimal Allocation

Node affinity can constrain which nodes your pod is eligible to be scheduled on, based on labels:

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
  containers:
  - name: with-affinity
    image: nginx

The above pod will only be placed on nodes with the ‘ssd’ label under ‘disktype’.

Conclusion

Optimizing resource allocation within your Kubernetes pods is crucial for maximizing resource utilization and for ensuring the stability of the applications. By using techniques like setting appropriate requests and limits, understanding QoS classes, overcommitting with caution, enforcing quotas, autoscaling, and using node affinities, you can fine-tune your resources to achieve better performance and minimize costs.

Next Article: How to Use Kubernetes Network Policies for Security

Previous Article: How to Implement Blue/Green Deployments in Kubernetes

Series: Kubernetes Tutorials

DevOps

You May Also Like

  • How to reset Ubuntu to factory settings (4 approaches)
  • Making GET requests with cURL: A practical guide (with examples)
  • Git: What is .DS_Store and should you ignore it?
  • NGINX underscores_in_headers: Explained with examples
  • How to use Jenkins CI with private GitHub repositories
  • Terraform: Understanding State and State Files (with Examples)
  • SHA1, SHA256, and SHA512 in Terraform: A Practical Guide
  • CSRF Protection in Jenkins: An In-depth Guide (with examples)
  • Terraform: How to Merge 2 Maps
  • Terraform: How to extract filename/extension from a path
  • JSON encoding/decoding in Terraform: Explained with examples
  • Sorting Lists in Terraform: A Practical Guide
  • Terraform: How to trigger a Lambda function on resource creation
  • How to use Terraform templates
  • Understanding terraform_remote_state data source: Explained with examples
  • Jenkins Authorization: A Practical Guide (with examples)
  • Solving Jenkins Pipeline NotSerializableException: groovy.json.internal.LazyMap
  • Understanding Artifacts in Jenkins: A Practical Guide (with examples)
  • Using Jenkins with AWS EC2 and S3: A Practical Guide