|
| 1 | +## Intro |
| 2 | + |
| 3 | +Quota trees are a concept that allows users to define and enforce resource limits for arbitrary kubernetes objects based |
| 4 | +on a hierarchical structure of quotas. A quota tree consists of a root node and several child nodes, each representing a |
| 5 | +quota. A quota is a set of rules that specify the maximum amount of resources that a kubernetes object can use. The root |
| 6 | +node of a quota tree defines the global limits for the entire tree. The child nodes can have their own limits, but they |
| 7 | +cannot exceed the limits of their parent node. For example, if the root node has a limit of 2 CPU and 4 GiB of memory, |
| 8 | +then any child node cannot have more than 2 CPU and 4 GiB of memory. |
| 9 | + |
| 10 | +One of the key features of quota trees is the hardLimit attribute, which determines whether a quota can borrow resources |
| 11 | +from its siblings or not. A sibling is another child node that shares the same parent node. If a quota has hardLimit set |
| 12 | +to true, then it can only use the resources defined in its specification. If a quota has hardLimit set to false, then it |
| 13 | +can use any unused resources from its siblings, as long as it does not violate the parent node’s limits. However, if an |
| 14 | +object is defined which neccesitates borrowing from a sibling node, then if another kubernetes object is created which |
| 15 | +uses the borrowees quota (and is within the borrowees limit) then the borrower will be preempted to free these |
| 16 | +resources. |
| 17 | + |
| 18 | +Quota trees are useful for managing and partitioning resources within a kubernetes cluster. They can help users to |
| 19 | +optimize resource utilization, avoid resource starvation, and ensure quality of service for different types of objects. |
| 20 | + |
| 21 | +## Example QuotaSubtree |
| 22 | + |
| 23 | +```yaml |
| 24 | +apiVersion: ibm.com/v1 |
| 25 | +kind: QuotaSubtree |
| 26 | +metadata: |
| 27 | + name: context-root |
| 28 | + namespace: kube-system # this is the namespace where the multi-cluster-app-dispatcher controller lives |
| 29 | + labels: |
| 30 | + tree: quota_context # the tree to which all nodes defined in this QuotaSubtree object belong |
| 31 | +spec: |
| 32 | + children: |
| 33 | + - name: context-root |
| 34 | + quotas: |
| 35 | + hardLimit: true # if context-root has siblings it cannot borrow from them |
| 36 | + requests: |
| 37 | + cpu: 2000m |
| 38 | + memory: 8000Mi |
| 39 | +--- |
| 40 | +apiVersion: ibm.com/v1 |
| 41 | +kind: QuotaSubtree |
| 42 | +metadata: |
| 43 | + name: context-root-children |
| 44 | + namespace: kube-system |
| 45 | + labels: |
| 46 | + tree: quota_context # note that this label is the same as above indicating they belong to the same tree |
| 47 | +spec: |
| 48 | + parent: context-root |
| 49 | + children: |
| 50 | + - name: alpha |
| 51 | + quotas: |
| 52 | + hardLimit: false # objects using 'alpha' can borrow resources from beta (this is the default value) |
| 53 | + requests: |
| 54 | + cpu: 1000m # even though beta has 2000m 'alpha' will only be able to borrow 1000m due to the limit imposed by context root |
| 55 | + memory: 4000Mi |
| 56 | + - name: beta |
| 57 | + quotas: |
| 58 | + hardLimit: true # objects using 'beta' cannot borrow extra resources from 'alpha' |
| 59 | + requests: |
| 60 | + cpu: 2000m |
| 61 | + memory: 4000Mi |
| 62 | +``` |
| 63 | +
|
| 64 | +## Using quota trees in your AppWrappers |
| 65 | +
|
| 66 | +```yaml |
| 67 | +apiVersion: mcad.ibm.com/v1beta1 |
| 68 | +kind: AppWrapper |
| 69 | +metadata: |
| 70 | + name: myGangScheduledApp |
| 71 | + namespace: default |
| 72 | + labels: |
| 73 | + quota_context: "alpha" # this label indicates the tree and the node in that tree "tree_name: node_name" |
| 74 | +spec: |
| 75 | + service: |
| 76 | + spec: {} |
| 77 | + resources: |
| 78 | + metadata: {} |
| 79 | + GenericItems: |
| 80 | + - metadata: {} |
| 81 | + replicas: 1 |
| 82 | + custompodresources: # because AppWrappers are generic they must define the resultant pods that will be needed |
| 83 | + # to fulfill a request as the request values cannot be reliably extracted from the |
| 84 | + # generictemplate below |
| 85 | + - replicas: 1 |
| 86 | + requests: |
| 87 | + cpu: 1000m |
| 88 | + memory: 4000Mi |
| 89 | + limits: |
| 90 | + cpu: 1000m |
| 91 | + memory: 4000Mi |
| 92 | + generictemplate: # the k8 object that is deployed once the resource requirements are met, this can be any native |
| 93 | + # k8 objects or a custom resource |
| 94 | + apiVersion: apps/v1 |
| 95 | + kind: StatefulSet |
| 96 | + metadata: |
| 97 | + name: myGangScheduledApp |
| 98 | + namespace: test1 |
| 99 | + labels: |
| 100 | + app: myGangScheduledApp |
| 101 | + spec: |
| 102 | + selector: |
| 103 | + matchLabels: |
| 104 | + app: myGangScheduledApp |
| 105 | + replicas: 1 |
| 106 | + template: |
| 107 | + metadata: |
| 108 | + labels: |
| 109 | + app: myGangScheduledApp |
| 110 | + size: "1" |
| 111 | + spec: |
| 112 | + containers: |
| 113 | + - name: myGangScheduledApp |
| 114 | + image: registry.access.redhat.com/ubi8/ubi:latest |
| 115 | + command: |
| 116 | + - /bin/sh |
| 117 | + - -c |
| 118 | + - while true; do sleep 10; done |
| 119 | + resources: |
| 120 | + requests: |
| 121 | + cpu: "1000m" |
| 122 | + memory: "4000Mi" |
| 123 | + limits: |
| 124 | + cpu: "1000m" |
| 125 | + memory: "4000Mi" |
| 126 | +``` |
0 commit comments