You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit ccf41b4
Browse filesBrowse the repository at this point in the historyBrowse files
feat(arc): bound each node's measured runners by its pod capacity
Measured sizing counted what a node's cpu and memory would hold and nothing else, so a
node whose kubelet max-pods was set lower, to keep a node with a slow disk from running more
jobs at once than it can serve, was still measured at its cpu and memory. The node's
allocatable pods, less the pods on it that are not runner pods, now bound its runners
as well. A node that reports no pod capacity is left as before.
tolerations: the runner pods' tolerations; a node whose only repelling taints they match is eligible, as it is for the pods.
325
325
326
326
Returns:
327
-
A dict with ``errors`` (messages, empty when it could be worked out), ``nodes`` (per eligible node: name, allocatable_cpu, allocatable_memory_gib, requested_cpu, requested_memory_gib, by_cpu, by_memory, runners, and condition, naming any passing condition it was counted despite), ``skipped_nodes`` (name and reason for each node that is not eligible), ``theoretical`` and ``max_runners``, which is None when there are errors.
327
+
A dict with ``errors`` (messages, empty when it could be worked out), ``nodes`` (per eligible node: name, allocatable_cpu, allocatable_memory_gib, requested_cpu, requested_memory_gib, by_cpu, by_memory, by_pods (None when the node reports no pod capacity), runners, and condition, naming any passing condition it was counted despite), ``skipped_nodes`` (name and reason for each node that is not eligible), ``theoretical`` and ``max_runners``, which is None when there are errors.
# A node's pod capacity (the kubelet's max-pods) can be set below what its cpu and memory would hold, to keep a node whose disk is the limit from running more jobs than it can serve. Kubernetes always reports it, so a node without it is a test fixture or an unusual one, and is not limited by it.
Copy file name to clipboardExpand all lines: roles/github_runner_arc/README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -72,7 +72,7 @@ sizing:
72
72
safety_margin: 0.8# optional, default 1
73
73
```
74
74
75
-
That assumes the nodes are alike. Where their free capacity differs a lot, `measured: true` works it out from the cluster instead, each time the role runs. It reads every node the runner pods may be placed on: every node carrying the eligibility label and the profile's `node_selector`, with no `NoSchedule` or `NoExecute` taint other than those Kubernetes adds for a passing condition. The ceiling lasts until the next run, so a node that is not ready, unreachable or cordoned when it is measured still counts, as it will once it is back. For each one it takes the node's allocatable CPU and memory, subtracts what the pods already on it request and the per-node reserve, and divides what is left by one runner pod's requests; the tighter of the two gives the runners that fit there. The sum over the nodes, scaled by the safety margin and rounded down, is the ceiling. Pods in any scale set's namespace are left out, so running runners never lower the ceiling they are sized by, as are pods that have finished. The reserve covers what requests do not show, such as a workload that uses more than it requests. The kubeconfig needs cluster-wide read access to nodes and pods. The role prints each node's figures when it runs.
75
+
That assumes the nodes are alike. Where their free capacity differs a lot, `measured: true` works it out from the cluster instead, each time the role runs. It reads every node the runner pods may be placed on: every node carrying the eligibility label and the profile's `node_selector`, with no `NoSchedule` or `NoExecute` taint other than those Kubernetes adds for a passing condition. The ceiling lasts until the next run, so a node that is not ready, unreachable or cordoned when it is measured still counts, as it will once it is back. For each one it takes the node's allocatable CPU and memory, subtracts what the pods already on it request and the per-node reserve, and divides what is left by one runner pod's requests; the tighter of the two gives the runners that fit there. The sum over the nodes, scaled by the safety margin and rounded down, is the ceiling. Pods in any scale set's namespace are left out, so running runners never lower the ceiling they are sized by, as are pods that have finished. The reserve covers what requests do not show, such as a workload that uses more than it requests. The kubeconfig needs cluster-wide read access to nodes and pods. The role prints each node's figures when it runs. A node's pod capacity also bounds it: the kubelet's `max-pods` (`allocatable.pods`) less the pods already on it that are not runner pods, so a node whose pod limit is set below what its CPU and memory would hold, to keep a node with a slow disk from running more jobs at once than it can serve, is measured at that limit.
Copy file name to clipboardExpand all lines: roles/github_runner_arc/meta/argument_specs.yml
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -14,7 +14,7 @@ argument_specs:
14
14
- max_runners, when set, is the release's maxRunners and takes precedence over its values file and its sizing.
15
15
- scale_set_labels replaces runs_on_label with the whole list of scaleSetLabels; an empty list sets none, so jobs target the release name.
16
16
- tolerations is a list of Kubernetes tolerations for the profile's runner pods, for nodes the eligibility label selects that also carry a taint to keep other workloads off. Measured sizing counts a node whose only repelling taints these match, as the pods can be placed there; without them it leaves such a node out. With burst they come before burst.tolerations.
17
-
- sizing derives a runner ceiling from uniform node figures, or with measured true from each eligible node's allocatable CPU and memory less its current requests and reserve_cpu and reserve_memory_gib.
17
+
- sizing derives a runner ceiling from uniform node figures, or with measured true from each eligible node's allocatable CPU and memory (and pod capacity, the kubelet's max-pods) less its current requests and reserve_cpu and reserve_memory_gib.
18
18
- capabilities names entries of github_runner_arc_capabilities that the profile's runner pods carry, in order.
19
19
- burst, on a profile with sizing and without max_runners or autoscale, lets its runner pods overflow onto nodes carrying burst.node_label_key (any value, or one of burst.node_label_values), with burst.tolerations for their taint, and adds burst.max_runners to the sized maxRunners. With burst.exclusive true (and no sizing, max_runners or autoscale) the pods run on burst nodes only and burst.max_runners is the whole maxRunners.
0 commit comments