Hello, friends, and welcome to these other friends and welcome to these other
session of the Kubernetes Fundamental series only in C-sharp Corner. I'm Rodrigo
And today I'm going to talk about resource boundaries, which is necessary when you're
trying to implement Kubernetes because your containers are going to require a lot of CPU
and memory and resources, right? So there must be a way for us to limit the resources that those containers are going to use
So that will be the topic for today, okay? Resource management. So, and this is important because we should strive for high compute density
It's not that we're going to use Kubernetes for running 10 containers
or five containers, right? It doesn't make sense to run just a small amount of containers
We want to take advantage of those Kubernetes clusters like all the time, right
So this will increase the cost-benefit of money spent on infrastructure because, as you might know, having a Kubernetes cluster is not going to be cheap, right
Of course, there are some Kubernetes managed Kubernetes options in the cloud, such as AKS or whatnot
However, it's not that you're going to spend too little money to not take advantage of that, right
So resource boundaries, we can set those at the container level. that's the first demo that I want to show you today
that is inside the container specification, we can set the limits that the container should use
So this can be specified on the specification. I mean, in the Jamo file, you know, the manifest file
we are going to create one of those files. and there you can set the resource limits
In other words, you can save the minimum amount of resources that that particular container should use
And on the other hand, we can set the container limits. So in one hand, we have the resource limits
I mean, I'm sorry, the resource requests, and on the other hand, we have the resource limits
Resource request is the minimum amount of resources and resource limits is the maximum amount
Okay. And on the other hand, we have resource quotas. There are objects that we can create and apply to the Kubernetes cluster to limit the amount of resources that can be consumed by a set of pots in a single name space
Because remember, this namespace is like a logical group of objects inside the cluster
So we can set those limits at the namespace level, right? So it makes sense if you think about it because you can use namespaces for, I don't know
maybe you're using this namespace for this application and this other namespace for this other
application, right? Or maybe you're using a namespace for one of your clients and other namespace for other clients
So you want to set those limits. and those boundaries at the namespace level. Okay
When I'm talking about resource types, I'm talking about CPU most of the time, right
This is going to be CPU or memory or storage. Okay, in this session I'm going to focus on CPU and memory
But of course, you can set some boundaries around storage as well
We're not going to see that in this particular. session. And there are other less common resource types, such as network bandwidth and
GPU resources as well. However, I'm going to focus on CPU and memory. As I was mentioning
before, we can use the manifest file specifically inside the container's element to set the
minimum and the maximum resource boundaries, you know, the resources that your containers are going to use
So let's first talk about resource requests. This is the minimum amount, okay
We can use the containers element, and inside the container's element, we can use the resources element, and particularly the request's element
to specify that amount of resources that you want to use. Okay
Those values are going to be used by the scheduler. When that particular component, remember the scheduler
That's one of the control playing elements in a Kubernetes cluster. The scheduler is going to use that information to decide which note to place the bottom
Okay. So that's important because you can have, I don't know, a number of notes in a cluster in some notes
are going to be heavily used and some others want, right? So the scheduler is so intelligent and smart, and it's going to decide
I want to deploy this particular application, I want to deploy this particular pod
in this note, right? Note A or node B or node C, okay
So how in the world we're going to use that? So remember, this is at the manifest level
Of course, I'm showing you this pod, the specification. However, we can use this in a deployment as well, right
Because the deployment object has a pod specification inside it. So inside the container element, as I was mentioning before
we have the resources element. And inside the resources element, we have the requests
element, okay? That's the field that we're going to use, and inside that field we can set
memory, CPU, and whatnot. In this case, this example that I'm showing you right now, it's using
500 millicours, which, in other words, is half of a CPU, okay? So actually, that's a lot of compute
resources for this particular container. But of course, this is just only a demo, right
So please be aware of those measurement units. In this case, I'm using the M, which represents the
millicours And it depends on what resource we talking about right So if we talking about CPU we going to use millicores And if we talking about RAM I mean memory right
So those other units are different. So you better take care about that and see the documentation first before you do that
So okay, so this is great. This is for specifying your minimum amount
of resources and what about limits? This is the maximum amount of resources that a container can consume
Very similar to the requests. This is other field inside the resources element inside the containers of the pot
So in this other case, we also have containers and then resources as well and then limits
right? So we use the resources dot limits field and you can use CPU and memory and whatnot
In this other example, as we can see here on the screen, I'm using 1,000 mili cores, which, in other words, is one CPU
So I'm telling Kubernetes, hey, you know what, this particular container can use the entire CPU, which is a lot, right
But again, this is just a small example of setting your resource boundaries
Okay, 100, I'm sorry, 1,000 millicours is one CPU, okay? So let's do that, okay
Let's go to this terminal. So I'm not using my regular machine
I'm in my laptop because I'm abroad. Anyways, I'm going to create a new deployment or a new pod and I'm going to set some limits. Okay
So let's open up Visual Studio code. Actually, I did that beforehand
So you can see this to expedite this process. Okay. So you know what
Let me cope with this. because I don't want to show you the stress right now
Let me do another my pod file. So my pod dash first, okay
Anyways, forget about this right now and GnX and we're going to use this
And then I'm going to show you the stress container image. So in this particular case, as you can see here
here on the screen, I'm setting those limits for this particular container
I'm telling Kubernetes, hey, you know, this particular container can only use a quarter of a CPU, right
25% of the CPU this is allowed to use. And in terms of memory, as you can see here on the screen, I'm setting 64 megabytes of limits, right
So the MI, that's the unit for megabytes, that's why I told you you have to take a look at the documentation
because it's not a regular MB. This is MI. Okay. So other than that, this is just the regular manifest file for a pod
Let's open up the terminal and let's verify that I don't have any pots
which I do. Hold on because I was doing some other things in here
I could call delete, deploy, man, my app, okay? Forget about this, get pods
Those boats are being terminated right now. Which is actually what I want to do
Let's wait for some... Oh, let's wait a little bit. Come on, come on, come on
Anyways, I want to show you this appointment that I'm going to deploy again
which is using the stress container image because I want to show you what happens
when you have those limits, right? Anyways, my first demo is just using this pod element
Okay, so it was deleted. This is great. Now I'm ready to apply this file, which is my pod dash first, right
And then Cuddle get pods and, you know, the drill. This is creating the pod
It's trying to download the image if it's not already present. And it's running, right
So let me tell you one thing about this. I'm using Minicube as usual, right
MiniCube status because this is just a small laptop, okay? And I don't know what's, you don't have the required permission to complete this task
Anyways, I don't want to use MiniCube status. I want to show you other commands
Anyways, my point here is that I'm using Minicube and I'm using the
hyperbe driver. And when you install Minicube, you don't have a lot of different add-ons
in your Kubernetes installation, okay, in your Kubernetes deployment. So for instance, I'm telling you this
because I want to show you this command, CubeCuttle Top, which is a command
just like the regular H-Stop or top command in the Linux world
that allows you to see how many resources, processes are using, right
So in this case, I can show you top and then pod
to see that this particular pod is using how much memory, how much CPU cores, right
So the thing here is that the top command requires the metric server enabled in your
Minicube installation. So you can actually do that by executing Minicube and then add-ons
And you can see all the different add-ons that you can install and enable in your own
mini-cube installation. And actually, the one that is required is metric server
Okay. As you can see, I already enabled the metric server for this particular mini-cube installation. Okay
So you must do that if you want to execute cubecuttle top
Okay. So you should execute Minicube add-ons and then I think that's enabled and then the name of the add-on, which is Metric Server
I could be wrong in this syntax. You can search for the online help about Minicube
But the gist of this particular topic is that you must enable metric server
in order to execute Cube Cuddle Top, okay? You should do that
Anyways, Cube Cuddle Top, this is great. I want to show you this
And actually, that NGNX container, it has a very small footprint of memory and CPU
It's not very exciting to be running NGNX in a single pod
Okay And actually you can execute top node to see the node resources how are they being used Okay
Anyways, this is great. Let me keep cuddle delete pod, my app
So I want to delete this particular isolated pod. So get pots, no pots at all
And then I want to show you this other manifest file, which is a deployment
Okay, remember deployments? We actually don't deploy isolated pods. That's for sure most of the time
We want to deploy pods by means of a deployment, right? So this is our deployment, a regular deployment, is using this much
labels element to specify that the labels of the pods should be my app. They must be app and the value
should be my app. Okay. And here in the spec, I'm specifying another container image
This particular stress container image allows me to execute some stressful commands, right, for, you know, increasing memory utilization or CPU utilization, right
So I'm executing this command and it's stressing and stressing and stressing this application
all the time in terms of memory, in this case. And as you can see here, I'm specifying some limits
Okay. Let me show you first what happens if I'm setting up this limit, which is 25% of a CPU with 64 megabytes of memory, and I'm specifying five replicas
Okay. Let me show you this, friends. Um, CubeCoddle apply and then dash if my deployment.com. And this is going to be creating right now
Those pods, right? Running, running, running. Running, running. And pending what's going on here
Four pods are running and one is pending. Why in the world is that
So the thing is that I execute top and then pod. You can see that those four pods
those are using 25% of the CPU. there are no other resources left for me to deploy the fifth pot
Make sense? And this is because the limits that I set up in that particular manifest file, right
So in other words, Kubernetes is not allowed and it's not able to deploy the fifth pod
because the first four, those four are using the 100% of the CPU, right
So that's the reason why the fifth path is not running. So Kup Kuddle, get deployments, okay
Kup Kuddle, delete deployments, my app, and let's wait for this to delete
those pots. Let me go back here and those pots are being terminated. Anyways, I don't want to
wait for that and I just want to change the CPU limits for those containers. So each container
is able to use the maximum amount of CPU is going to be 20%, right? So I'm allowed to run five
containers of the same kind because of those limits. So I changed this. Let's go back here to the
terminal and now I'm ready to deploy again that deployment. Okay. Let's get all the pods again
Those boats are being created right now. We are running and now the five of them are running
right. And if I execute a pod, let's wait for the metrics to be fetched by the top command
because as you can see, the metrics are not available yet. So you have to wait for a little bit
I don't know, maybe half a minute or one minute or something. Let's try again
And eventually, I'm going to get those metrics and we're going to see that each container
I mean, each pod is using 20% of the CPU. Right
So, yeah, eventually this is going to receive those metrics. However, metrics are not available yet, which is nice
I mean, we're just going to see those pots running. Anyways, I'm going to return to this in a couple of minutes, okay
So that's great. This is for the container level, friends. Most of the time, this is a real-world situation
where you want to limit those containers that potentially are going to be running
on your Kubernetes cluster, right? On the other hand, we have those resource
quotas objects that we can create. as I mentioned before, resource quotas
they allow me to specify the maximum amount of resources per namespace
Of course, I only have the default namespace right now. Maybe I'm going to create a new namespace and then a resource quota for that particular namespace
However, remember that those objects, they allowed you to specify the maximum amount of
resources per namespace, okay? And you can also use resource quotas to limit the quantity of objects that you can create
This is awesome because you can specify, hey, you know, in this particular namespace, I want
to limit for, I don't know, maybe 100 pods or maybe five services, three deployments
and whatnot, okay? those kind of objects. Remember the primitive objects that we talked about like, I don't know, maybe one month ago
And actually, you can limit a lot of different objects, not only the primitive objects that we talked about here in this series
but other objects as well. Okay? So let's go back here to the terminal
Let's clear up the screen. Cube called Toppot and now I'm receiving those metrics from the pods and as you can see
those pods are using 25, I'm sorry, yes, 20%, no 25, 20% of CPU each one, right
So this is nice. Limits are great and the stress container image is allowing me to, you know
stress those applications, those pods, so we can see that in the Q top command Awesome So returning to the resource quota objects as you can see here on the screen this is another
kind of object that we can create. So in this case, this is a manifest file for our resource quota, as you can see here
this is the resource quota object. Okay, the API version is V1
The kind is resource quota. And of course, we can set that metadata because most of the time we need the name
In this case, is my resource quota, my RQ, right? And then we have the spec field that has hard and then the different resources and objects that you want to limit
You're specifying the quota in this particular field. Okay. So, for instance, CPU and memory, those two are for computing resources, right
Two CPU cores and maybe, I don't know, for gigabytes of RAM
That's the quota for this particular namespace. Of course, you're not specifying the namespace here
However, when you apply the resource quota object, you have to specify the namespace
I'm going to show you that. Okay? In parts 10, this is an object count quota, which is, again, this is awesome
We have a lot of flexibility in terms of this quota specification
So this is great. And then you need to deploy that particular manifest
Again, Kube Kodolapi, just a regular, Kube Kodolapi, file, my quota, dot, terminal, or the name of the file
right and that particular command is going to deploy the resource quota in the current namespace
if you want to deploy that quota in another name space you have to use the flag dash n or double
dash namespace and the name of the namespace where you want to deploy this particular resource quota okay
And again, Cube Cuddle get quota. This is for returning and displaying all the different quotas
As you can see here, the alias is quota, right? You can use actually, I think, resource quota, the entire name as well
However, quota is just an alias. And the final one, it gets all the detailed information about a particular resource quota
It's just a regular Kip Kuddle described, right? Actually, you know what
This is a typo because it should be lowercase. This is great
Thank you. Okay, so cool. Let's do this
Let me copy this because I don't have a template for creating
quotas and I don't want to type everything right my resource quota Jamal let's type this kind
resource quota my research quota two CPUs and four gigs of memory and tempots and whatnot
very easy thing to grasp in here kill color apply right um and then my research quota quota
And then the namespace. Of course, I need to create another namespace
CoupCardle create namespace and I don't know, maybe test. And now we have that test namespace, right
And now I'm able to CubeCodel apply dash F, my resource quota dot demo, and the namespace is test, right
So now that particular quota was deployed in the test, namespace. So I can actually describe quota, my resource quota, which is in the namespace test
and we can see that that heart limit at the right of the screen
I mean, the last column is the hard limits that I set in the management
FIS file and in the middle we can see the used number of objects or the limits of those compute resources, right
In this case, because of the fact that I don't have any kind of object inside that namespace, of course, those values are zero
However, I think I can use my deployment again, right? My deployment.comal, my deployment.comal, namespace, test
Okay? And now, CubeCuttle, describe, blah, blah, blah. And we can see that at this moment, I'm using one of those CPUs
and I'm using half of the parts that I specified in the quota, right
And I'm only using 320 megabytes of those four gigabytes. Anyways, you can easily see that with this kind of resource objects, I mean, resource quota objects, you can set those limits at the namespace level, which is great
Okay? So, I believe this is all I have for today. Okay
Just as an overview, you can set those limits at the container level by using limits inside the pod specification
You can also set those resource requests for specifying the minimum amount of resources that your applications need
and that's for the container level, right? And on the other hand, you have those resource code objects that you can create
and you can apply those at the namespace level. Okay? So, this is great
And I only have one screen right now, friends, because I'm abroad
I don't have my entire, my three monitors, right? So this is all I have for today, so I'm not watching the comments and questions
However, in the next session, session number 11, we're going to see the multi-container pots, right
I'm going to talk about how you can create pods with multiple containers, because most of the time, if you need that, is because one of those containers need the other one for its own logic and functionality
So we're going to see how in the world we can create that in Kubernetes
Okay? So that's everything for today. I thank you very much for your time
and I'll see you next time