mirror of https://github.com/k3s-io/k3s
Improve resource quota example, add README
parent
a8a3e9d0c7
commit
122681ea03
|
@ -291,7 +291,9 @@ func TestExampleObjectSchemas(t *testing.T) {
|
||||||
"redis-sentinel-service": &api.Service{},
|
"redis-sentinel-service": &api.Service{},
|
||||||
},
|
},
|
||||||
"../examples/resourcequota": {
|
"../examples/resourcequota": {
|
||||||
"resource-quota": &api.ResourceQuota{},
|
"namespace": &api.Namespace{},
|
||||||
|
"limits": &api.LimitRange{},
|
||||||
|
"quota": &api.ResourceQuota{},
|
||||||
},
|
},
|
||||||
"../examples/rethinkdb": {
|
"../examples/rethinkdb": {
|
||||||
"admin-pod": &api.Pod{},
|
"admin-pod": &api.Pod{},
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
Resource Quota
|
||||||
|
========================================
|
||||||
|
This example demonstrates how resource quota and limits can be applied to a Kubernetes namespace.
|
||||||
|
|
||||||
|
This example assumes you have a functional Kubernetes setup.
|
||||||
|
|
||||||
|
Step 1: Create a namespace
|
||||||
|
-----------------------------------------
|
||||||
|
This example will work in a custom namespace to demonstrate the concepts involved.
|
||||||
|
|
||||||
|
Let's create a new namespace called quota-example:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ cluster/kubectl.sh create -f namespace.yaml
|
||||||
|
$ cluster/kubectl.sh get namespaces
|
||||||
|
NAME LABELS STATUS
|
||||||
|
default <none> Active
|
||||||
|
quota-example <none> Active
|
||||||
|
```
|
||||||
|
|
||||||
|
Step 2: Apply a quota to the namespace
|
||||||
|
-----------------------------------------
|
||||||
|
By default, a pod will run with unbounded CPU and memory limits. This means that any pod in the
|
||||||
|
system will be able to consume as much CPU and memory on the node that executes the pod.
|
||||||
|
|
||||||
|
Users may want to restrict how much of the cluster resources a given namespace may consume
|
||||||
|
across all of its pods in order to manage cluster usage. To do this, a user applies a quota to
|
||||||
|
a namespace. A quota lets the user set hard limits on the total amount of node resources (cpu, memory)
|
||||||
|
and API resources (pods, services, etc.) that a namespace may consume.
|
||||||
|
|
||||||
|
Let's create a simple quota in our namespace:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ cluster/kubectl.sh create -f quota.yaml --namespace=quota-example
|
||||||
|
```
|
||||||
|
|
||||||
|
Once your quota is applied to a namespace, the system will restrict any creation of content
|
||||||
|
in the namespace until the quota usage has been calculated. This should happen quickly.
|
||||||
|
|
||||||
|
You can describe your current quota usage to see what resources are being consumed in your
|
||||||
|
namespace.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cluster/kubectl.sh describe quota quota --namespace=quota-example
|
||||||
|
Name: quota
|
||||||
|
Resource Used Hard
|
||||||
|
-------- ---- ----
|
||||||
|
cpu 0m 20
|
||||||
|
memory 0m 1Gi
|
||||||
|
persistentvolumeclaims 0m 10
|
||||||
|
pods 0m 10
|
||||||
|
replicationcontrollers 0m 20
|
||||||
|
resourcequotas 1 1
|
||||||
|
secrets 1 10
|
||||||
|
services 0m 5
|
||||||
|
```
|
||||||
|
|
||||||
|
Step 3: Applying default resource limits
|
||||||
|
-----------------------------------------
|
||||||
|
Pod authors rarely specify resource limits for their pods.
|
||||||
|
|
||||||
|
Since we applied a quota to our project, let's see what happens when an end-user creates a pod that has unbounded
|
||||||
|
cpu and memory by creating an nginx container.
|
||||||
|
|
||||||
|
To demonstrate, lets create a replication controller that runs nginx:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ cluster/kubectl.sh run nginx --image=nginx --replicas=1 --namespace=quota-example
|
||||||
|
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
|
||||||
|
nginx nginx nginx run=nginx 1
|
||||||
|
```
|
||||||
|
|
||||||
|
Now let's look at the pods that were created.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ cluster/kubectl.sh get pods --namespace=quota-example
|
||||||
|
POD IP CONTAINER(S) IMAGE(S) HOST LABELS STATUS CREATED MESSAGE
|
||||||
|
```
|
||||||
|
|
||||||
|
What happened? I have no pods! Let's describe the replication controller to get a view of what is happening.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cluster/kubectl.sh describe rc nginx --namespace=quota-example
|
||||||
|
Name: nginx
|
||||||
|
Image(s): nginx
|
||||||
|
Selector: run=nginx
|
||||||
|
Labels: run=nginx
|
||||||
|
Replicas: 0 current / 1 desired
|
||||||
|
Pods Status: 0 Running / 0 Waiting / 0 Succeeded / 0 Failed
|
||||||
|
Events:
|
||||||
|
FirstSeen LastSeen Count From SubobjectPath Reason Message
|
||||||
|
Mon, 01 Jun 2015 22:49:31 -0400 Mon, 01 Jun 2015 22:52:22 -0400 7 {replication-controller } failedCreate Error creating: Pod "nginx-" is forbidden: Limited to 1Gi memory, but pod has no specified memory limit
|
||||||
|
```
|
||||||
|
|
||||||
|
The Kubernetes API server is rejecting the replication controllers requests to create a pod because our pods
|
||||||
|
do not specify any memory usage.
|
||||||
|
|
||||||
|
So let's set some default limits for the amount of cpu and memory a pod can consume:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ cluster/kubectl.sh create -f limits.yaml --namespace=quota-example
|
||||||
|
limitranges/limits
|
||||||
|
$ cluster/kubectl.sh describe limits limits --namespace=quota-example
|
||||||
|
Name: limits
|
||||||
|
Type Resource Min Max Default
|
||||||
|
---- -------- --- --- ---
|
||||||
|
Container cpu - - 100m
|
||||||
|
Container memory - - 512Mi
|
||||||
|
```
|
||||||
|
|
||||||
|
Now any time a pod is created in this namespace, if it has not specified any resource limits, the default
|
||||||
|
amount of cpu and memory per container will be applied as part of admission control.
|
||||||
|
|
||||||
|
Now that we have applied default limits for our namespace, our replication controller should be able to
|
||||||
|
create its pods.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ cluster/kubectl.sh get pods --namespace=quota-example
|
||||||
|
POD IP CONTAINER(S) IMAGE(S) HOST LABELS STATUS CREATED MESSAGE
|
||||||
|
nginx-t40zm 10.0.0.2 10.245.1.3/10.245.1.3 run=nginx Running 2 minutes
|
||||||
|
nginx nginx Running 2 minutes
|
||||||
|
```
|
||||||
|
|
||||||
|
And if we print out our quota usage in the namespace:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cluster/kubectl.sh describe quota quota --namespace=quota-example
|
||||||
|
Name: quota
|
||||||
|
Resource Used Hard
|
||||||
|
-------- ---- ----
|
||||||
|
cpu 100m 20
|
||||||
|
memory 536870912 1Gi
|
||||||
|
persistentvolumeclaims 0m 10
|
||||||
|
pods 1 10
|
||||||
|
replicationcontrollers 1 20
|
||||||
|
resourcequotas 1 1
|
||||||
|
secrets 1 10
|
||||||
|
services 0m 5
|
||||||
|
```
|
||||||
|
|
||||||
|
You can now see the pod that was created is consuming explicit amounts of resources, and the usage is being
|
||||||
|
tracked by the Kubernetes system properly.
|
||||||
|
|
||||||
|
Summary
|
||||||
|
----------------------------
|
||||||
|
Actions that consume node resources for cpu and memory can be subject to hard quota limits defined
|
||||||
|
by the namespace quota.
|
||||||
|
|
||||||
|
Any action that consumes those resources can be tweaked, or can pick up namespace level defaults to
|
||||||
|
meet your end goal.
|
||||||
|
|
||||||
|
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/examples/resourcequota/README.md?pixel)]()
|
|
@ -0,0 +1,10 @@
|
||||||
|
apiVersion: v1beta3
|
||||||
|
kind: LimitRange
|
||||||
|
metadata:
|
||||||
|
name: limits
|
||||||
|
spec:
|
||||||
|
limits:
|
||||||
|
- default:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 512Mi
|
||||||
|
type: Container
|
|
@ -0,0 +1,4 @@
|
||||||
|
apiVersion: v1beta3
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: quota-example
|
|
@ -0,0 +1,14 @@
|
||||||
|
apiVersion: v1beta3
|
||||||
|
kind: ResourceQuota
|
||||||
|
metadata:
|
||||||
|
name: quota
|
||||||
|
spec:
|
||||||
|
hard:
|
||||||
|
cpu: "20"
|
||||||
|
memory: 1Gi
|
||||||
|
persistentvolumeclaims: "10"
|
||||||
|
pods: "10"
|
||||||
|
replicationcontrollers: "20"
|
||||||
|
resourcequotas: "1"
|
||||||
|
secrets: "10"
|
||||||
|
services: "5"
|
|
@ -1,19 +0,0 @@
|
||||||
{
|
|
||||||
"apiVersion": "v1beta3",
|
|
||||||
"kind": "ResourceQuota",
|
|
||||||
"metadata": {
|
|
||||||
"name": "quota"
|
|
||||||
},
|
|
||||||
"spec": {
|
|
||||||
"hard": {
|
|
||||||
"memory": "1Gi",
|
|
||||||
"cpu": "20",
|
|
||||||
"pods": "10",
|
|
||||||
"services": "5",
|
|
||||||
"replicationcontrollers":"20",
|
|
||||||
"resourcequotas":"1",
|
|
||||||
"secrets":"10",
|
|
||||||
"persistentvolumeclaims":"10"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue