DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Dive Deep Into Resource Requests and Limits in Kubernetes
  • Resource Management in Kubernetes
  • The Open Source Way to Rightsize Kubernetes With One Click
  • The Production-Ready Kubernetes Service Checklist

Trending

  • Beyond Code Coverage: A Risk-Driven Revolution in Software Testing With Machine Learning
  • Breaking Bottlenecks: Applying the Theory of Constraints to Software Development
  • How Trustworthy Is Big Data?
  • Performance Optimization Techniques for Snowflake on AWS
  1. DZone
  2. Data Engineering
  3. AI/ML
  4. Understanding Kubernetes Resource Types

Understanding Kubernetes Resource Types

Kubernetes resource optimization at its finest

By 
Erwin Daria user avatar
Erwin Daria
·
Jun. 30, 22 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
6.9K Views

Join the DZone community and get the full member experience.

Join For Free

Note: This is the first of a five-part series covering Kubernetes resource management and optimization. We start by describing Kubernetes resource types.

Before we dive into Kubernetes resources, let’s clarify what the term “resource” refers to here. Anything we create in a Kubernetes cluster is considered a resource: deployments, pods, services, and more. For this tutorial, we’ll focus on primary resources like CPU and memory, along with other resource types like ephemeral storage and extended resources.

One aspect of cluster management is to assign these resources automatically to containers running in pods so that, ideally, each container has the resources it needs, but no more.

In this article, we’ll highlight logical resources for containers running on a cluster. We’ll break down four common Kubernetes resources developers work with on a daily basis: CPU, memory, ephemeral storage, and extended resources. For each resource, we’ll explore how it’s measured within Kubernetes, review how to monitor each particular resource, and highlight some best practices for optimizing resource use.

Let’s explore each primary Kubernetes resource type in depth. Then let’s see these resource types in action with some code samples.

CPU

A Kubernetes cluster typically runs on multiple machines, each with multiple CPU cores. They sum up to a total number of available cores, like four machines times four cores for a total of 16.

We don’t need to work with whole numbers of cores. We can specify any fraction of a CPU core in 1/1,000th increments (for example, half a core or 500 mill-CPU).

Kubernetes containers run on the Linux kernel, which allows specifying cgroups to limit resources. The Linux scheduler compares the CPU time used (defined by internal time slices) with the defined limit to decide whether to run a container in the next time slice. We can query CPU resources with the kubectl top command, invoking it for a pod or node.

We can optimize our use of processor time by making the program running in a container more efficient, either through improved algorithms and coding or by compiler optimization. The cluster user doesn’t have much influence on the speed or efficiency of precompiled containers.

Memory

The machines in a Kubernetes cluster also each have memory, which again sums up to a cluster total. For example, four machines times 32 GiB is 128 GiB.

The kernel level controls main memory, similar to CPU time with cgroups. If a routine in a container requests memory allocation beyond a hard limit, it signals an out-of-memory error.

Optimizing resource use is largely up to the application’s development effort. One step is to improve garbage collection frequency to keep a heap-based image from allocating memory beyond a hard limit. Again, the kubectl top command can provide information about memory use.

Exploring CPU and Memory

As our first in-depth example, let’s deploy three replicated containers of the popular web server NGINX to a local Kubernetes installation. We’re running a one-node “cluster” on our laptop, which only has two cores and 2 GiB of memory.

The code below defines such a pod deployment and grants each of three NGINX containers one-tenth of a core (100 milli-CPU) and 100 MiB of main memory. The code below also limits their use to double the requested values.

YAML
 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
    app: nginx
  template:
    metadata:
      labels:
        app: nginx
spec:
  containers:
    - name: nginx
    image: nginx
    resources:
      requests:
        cpu: "100m"
        memory: "100Mi"
      limits:
        cpu: "200m"
        memory: "200Mi"
    ports:
    - containerPort: 80


We can deploy into the default namespace like this:

Shell
 
kubectl apply -f nginx.yaml


The local cluster only has a single node. Use this command to return detailed information about it:

Shell
 
kubectl describe nodes docker-desktop


After clipping most of the output, we can examine some information about resource use:

Plain Text
 
[...]
 
Namespace Name                           CPU.  Requests  CPU Limits Memory Requests Memory  Limits  Age
 
--------- ---- ------------ ---------- --------------- ------------- ---
 
default nginx-deployment-585bd9cc5f-djql8 100m  (5%)     200m (10%) 100Mi  (5%)     200Mi   (10%)   66s
 
default nginx-deployment-585bd9cc5f-gz98r 100m  (5%)     200m (10%) 100Mi  (5%)     200Mi   (10%)   66s
 
default nginx-deployment-585bd9cc5f-vmdnc 100m  (5%)     200m (10%) 100Mi  (5%)     200Mi   (10%)   66s
 
[...]
 
Resource            Requests    Limits
 
-------- -------- ------
 
cpu 1150m           (57%) 600m  (30%)
 
memory 540Mi        (28%) 940Mi (49%)
 
ephemeral-storage 0 (0%)    0   (0%)
 
hugepages-1Gi 0     (0%)    0   (0%)
 
hugepages-2Mi 0     (0%)    0   (0%)
 
[...]


This information shows the CPU and memory use requests and limits, just as our deployment object specified. It also displays the values as a percentage of the maximum possible allotment.

Next are the current totals for this node, again listed as absolute values and percentages. These numbers include some other containers running in the kube-system namespace that we haven’t shown here, so there will be a discrepancy not covered by the output above.

The above snippet’s last three lines indicate other types of resources beyond CPU and memory, which don’t have set requests or limits in this example.

Ephemeral Storage

One additional Kubernetes resource type is ephemeral storage. This is mounted storage that doesn’t survive the pod’s life cycle. Kubernetes often uses ephemeral storage for caching or logs but never uses it for important data, like user records. We can request or limit ephemeral storage like main memory, but it’s often not as limited a resource.

So what do hugepages-1Gi and hugepages-2Mi mean in the code snippet above? Huge pages are a modern memory feature of the Linux kernel to allocate large main memory pages of configurable size to processes. We can do this for efficiency.

Kubernetes supports assigning such large pages to containers. These form a resource type per page size that we can request separately.

When specifying a request or limit, we set the total amount of memory, not the number of pages.

YAML
 
limits:
hugepages-2Mi: "100Mi"
hugepages-1Gi: "2Gi"


Here, we limit the number of 2 MiB pages to 50 and the number of 1 GiB pages to 2.

Extended Resources

Cluster users can also define their own resource types — per cluster or node — using the extended resource type. Once we’ve defined a type and specified available units, we can use requests and limits, just as with the built-in resources we’ve used so far.

An example is:

YAML
 
limits:
cpu: "200m"
myproject.com/handles: 100


This setting limits the container to 20 percent of a core and 100 of our project’s handles.

Resource Requests and Limits

Notice that resource requests and limits were key to our conversation about ephemeral storage and extended resources. This is because an end user can specify resource requests and limits in an application’s deployment manifest, which imposes some rules about how Kubernetes should treat a container or pod.

Requests indicate how much of a resource a container should have. They help the scheduler assign pods to nodes based on the amount of resources requested and available resources on those nodes.

Limits are used to indicate a hard upper boundary on how much of a resource a container can use, enforced at the operating-system level. Requests and limits are optional, but if we don’t specify a limit, a container can use most of the node’s resources, which can have negative cost or performance implications. So, we must be cautious.

Bear in mind that although a pod can contain more than one container, usually there is only one container per pod. We allocate resources to containers, but all of a pod’s containers draw from a common pool of resources at the node level.

In part two of this tutorial series, we’ll dive deeper into the world of Kubernetes requests and limits.

Considering Quality of Service

The resources system we’ve described so far is a fairly simple way of managing compute resources. Kubernetes offers a simple quality of service (QoS) system on top of this.

QoS describes a technical system’s means of offering different service levels while maintaining the best overall quality, given the hardware’s limitations. The Kubernetes QoS system assigns one of three levels to a pod: Guaranteed, Burstable, and BestEffort. Refer to the Kubernetes documentation to learn how to assign these levels and how they affect pod scheduling.

The Guaranteed level offers exactly the requested and limited resources during the pod’s lifetime and suits applications like monitoring systems that run at a constant load.

The Burstable service level is suitable for pods with a basic use profile that can sometimes increase above the baseline due to increased demand. This level is ideal for databases or web servers, whose load depends on the number of incoming requests.

Finally, BestEffort makes no resource availability guarantee. So, it’s best suited for applications like batch jobs that can repeat if needed or for staging environments that aren’t mission-critical.

Conclusion

Kubernetes clusters maintain hardware resources like CPU time, memory, ephemeral storage, and extended resources and assign them to running containers. Through a system of requests and limits, operators can tailor resource allocation to individual containers and then let the Kubernetes system assign them to nodes appropriately.

Extended resources enable us to define our own resource types and use them similarly. Kubernetes also assigns quality of service designations to pods according to requests and limits. It then uses these designations to make scheduling and termination decisions.

Kubernetes resource optimization is essential to balance costs with the end-user experience. Yet, assigning parameters by hand using this article’s methods can be time-consuming, costly, and difficult to scale.

Kubernetes Machine learning Memory (storage engine) pods Requests

Published at DZone with permission of Erwin Daria. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Dive Deep Into Resource Requests and Limits in Kubernetes
  • Resource Management in Kubernetes
  • The Open Source Way to Rightsize Kubernetes With One Click
  • The Production-Ready Kubernetes Service Checklist

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!