Change:
Since resource QoS is implemented, limitrange also supports request constraint, we can add an example for that.
cc

Discussion:
----------------------------------------- This example requires a running Kubernetes cluster.  See the [Getting Started guides](../../../docs/getting-started-guides/) for how to get started. <del> Change to the `<kubernetes>/examples/limitrange` directory if you're not already there. </del> <ins> Change to the `<kubernetes>` directory if you're not already there. </ins> Step 1: Create a namespace -----------------------------------------

```console $ kubectl create -f docs/admin/limitrange/namespace.yaml <del> namespaces/limit-example </del> <ins> namespace "limit-example" created </ins> $ kubectl get namespaces <del> NAME            LABELS             STATUS default         <none>             Active limit-example   <none>             Active </del> <ins> NAME            LABELS    STATUS    AGE default         <none>    Active    5m limit-example   <none>    Active    53s </ins> ``` Step 2: Apply a limit to the namespace

```console $ kubectl create -f docs/admin/limitrange/limits.yaml --namespace=limit-example <del> limitranges/mylimits </del> <ins> limitrange "mylimits" created </ins> ``` Let's describe the limits that we have imposed in our namespace.

```console $ kubectl describe limits mylimits --namespace=limit-example Name:   mylimits <del> Type      Resource  Min  Max Default ----      --------  ---  --- --- Pod       memory    6Mi  1Gi - Pod       cpu       250m   2 - Container memory    6Mi  1Gi 100Mi Container cpu       250m   2 250m </del> <ins> Namespace:  limit-example Type        Resource      Min      Max      Request      Limit      Limit/Request ----        --------      ---      ---      -------      -----      ------------- Pod         cpu           200m     2        -            -          - Pod         memory        6Mi      1Gi      -            -          - Container   cpu           100m     2        200m         300m       - Container   memory        3Mi      1Gi      100Mi        200Mi      - </ins> ``` In this scenario, we have said the following: <del> 1. The total memory usage of a pod across all of its container must fall between 6Mi and 1Gi. 2. The total cpu usage of a pod across all of its containers must fall between 250m and 2 cores. 3. A container in a pod may consume between 6Mi and 1Gi of memory.  If the container does not specify an explicit resource limit, each container in a pod will get 100Mi of memory. 4. A container in a pod may consume between 250m and 2 cores of cpu.  If the container does not specify an explicit resource limit, each container in a pod will get 250m of cpu. </del> <ins> 1. If a max constraint is specified for a resource (2 CPU and 1Gi memory in this case), then a limit must be specified for that resource across all containers. Failure to specify a limit will result in a validation error when attempting to create the pod. Note that a default value of limit is set by *default* in file `limits.yaml` (300m CPU and 200Mi memory). 2. If a min constraint is specified for a resource (100m CPU and 3Mi memory in this case), then a request must be specified for that resource across all containers. Failure to specify a request will result in a validation error when attempting to create the pod. Note that a default value of request is set by *defaultRequest* in file `limits.yaml` (200m CPU and 100Mi memory). 3. For any pod, the sum of all containers memory requests must be >= 6Mi and the sum of all containers memory limits must be <= 1Gi; the sum of all containers CPU requests must be >= 200m and the sum of all containers CPU limits must be <= 2. </ins> Step 3: Enforcing limits at point of creation -----------------------------------------

```console $ kubectl run nginx --image=nginx --replicas=1 --namespace=limit-example <del> CONTROLLER   CONTAINER(S)   IMAGE(S)   SELECTOR    REPLICAS nginx        nginx          nginx      run=nginx   1 </del> <ins> replicationcontroller "nginx" created </ins> $ kubectl get pods --namespace=limit-example <del> POD           IP           CONTAINER(S)   IMAGE(S)   HOST          LABELS      STATUS    CREATED          MESSAGE nginx-ykj4j   10.246.1.3                             10.245.1.3/   run=nginx   Running   About a minute nginx          nginx                                Running   54 seconds $ kubectl get pods nginx-ykj4j --namespace=limit-example -o yaml | grep resources -C 5 </del> <ins> NAME          READY     STATUS    RESTARTS   AGE nginx-aq0mf   1/1       Running   0          35s $ kubectl get pods nginx-aq0mf --namespace=limit-example -o yaml | grep resources -C 8 </ins> ``` ```yaml <ins> resourceVersion: "127" selfLink: /api/v1/namespaces/limit-example/pods/nginx-aq0mf uid: 51be42a7-7156-11e5-9921-286ed488f785 spec: </ins> containers: <del> - capabilities: {} image: nginx </del> <ins> - image: nginx </ins> imagePullPolicy: IfNotPresent name: nginx resources: limits: <del> cpu: 250m </del> <ins> cpu: 300m memory: 200Mi requests: cpu: 200m </ins> memory: 100Mi terminationMessagePath: /dev/termination-log volumeMounts: ``` <del> Note that our nginx container has picked up the namespace default cpu and memory resource limits. </del> <ins> Note that our nginx container has picked up the namespace default cpu and memory resource *limits* and *requests*. </ins> Let's create a pod that exceeds our allowed limits by having it have a container that requests 3 cpu cores. ```console $ kubectl create -f docs/admin/limitrange/invalid-pod.yaml --namespace=limit-example <del> Error from server: Pod "invalid-pod" is forbidden: Maximum CPU usage per pod is 2, but requested 3 </del> <ins> Error from server: error when creating "docs/admin/limitrange/invalid-pod.yaml": Pod "invalid-pod" is forbidden: [Maximum cpu usage per Pod is 2, but limit is 3., Maximum cpu usage per Container is 2, but limit is 3.] </ins> ``` Let's create a pod that falls within the allowed limit boundaries. ```console $ kubectl create -f docs/admin/limitrange/valid-pod.yaml --namespace=limit-example <del> pods/valid-pod $ kubectl get pods valid-pod --namespace=limit-example -o yaml | grep -C 5 resources </del> <ins> pod "valid-pod" created $ kubectl get pods valid-pod --namespace=limit-example -o yaml | grep -C 6 resources </ins> ``` ```yaml <ins> uid: 162a12aa-7157-11e5-9921-286ed488f785 spec: </ins> containers: <del> - capabilities: {} image: gcr.io/google_containers/serve_hostname </del> <ins> - image: gcr.io/google_containers/serve_hostname </ins> imagePullPolicy: IfNotPresent <del> name: nginx </del> <ins> name: kubernetes-serve-hostname </ins> resources: limits: cpu: "1" memory: 512Mi <del> securityContext: capabilities: {} </del> <ins> requests: cpu: "1" memory: 512Mi </ins> ``` <del> Note that this pod specifies explicit resource limits so it did not pick up the namespace default values. </del> <ins> Note that this pod specifies explicit resource *limits* and *requests* so it did not pick up the namespace default values. Note: The *limits* for CPU resource are not enforced in the default Kubernetes setup on the physical node that runs the container unless the administrator deploys the kubelet with the folllowing flag: ``` $ kubelet --help Usage of kubelet .... --cpu-cfs-quota[=false]: Enable CPU CFS quota enforcement for containers that specify CPU limits $ kubelet --cpu-cfs-quota=true ... ``` </ins> Step 4: Cleanup ----------------------------

```console $ kubectl delete namespace limit-example <del> namespaces/limit-example </del> <ins> namespace "limit-example" deleted </ins> $ kubectl get namespaces <del> NAME      LABELS    STATUS default   <none>    Active </del> <ins> NAME      LABELS    STATUS    AGE default   <none>    Active    20m </ins> ``` Summary ---------------------------- Cluster operators that want to restrict the amount of resources a single container or pod may consume <del> are able to define allowable ranges per Kubernetes namespace.  In the absence of any hard limits, the Kubernetes system is able to apply default resource limits if desired in order to constrain the amount of resource a pod consumes on a node. </del> <ins> are able to define allowable ranges per Kubernetes namespace.  In the absence of any explicit assignments, the Kubernetes system is able to apply default resource *limits* and *requests* if desired in order to constrain the amount of resource a pod consumes on a node. </ins>

cpu: "2" memory: 1Gi min: <del> cpu: 250m </del> <ins> cpu: 200m </ins> memory: 6Mi type: Pod - default: <del> cpu: 250m </del> <ins> cpu: 300m memory: 200Mi defaultRequest: cpu: 200m </ins> memory: 100Mi max: cpu: "2" memory: 1Gi min: <del> cpu: 250m memory: 6Mi </del> <ins> cpu: 100m memory: 3Mi </ins> type: Container