orchestratord: allow setting a PriorityClass on environmentd and clusterd pods - #38445
orchestratord: allow setting a PriorityClass on environmentd and clusterd pods#38445jazz-mo wants to merge 1 commit into
Conversation
|
Thank you for your submission! We really appreciate it. Like many source-available projects, we require that you sign our Contributor License Agreement (CLA) before we can accept your contribution. I have read the Contributor License Agreement (CLA) and I hereby sign the CLA. You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot. |
|
Review of the change. One blocking item, two suggestions, two nits. BlockingThe new
|
39c0c77 to
885443a
Compare
|
Thanks, this was a good review. All five items are addressed, and the scope changed on the back of the second and third. Blocking: version gateAdded. Your reading of the precedent matches what I found: Negative Helm testFixed, and thank you for naming the pinned version. I had validated
The third mutant is the I used Nothing tests the pod specs or the forwardingAdded a It asserts Two things that make it work, which were not obvious:
Nit: chart parameter tableRegenerated, via the two Nit: blast radius of a bad valueCovered in the description. Its scope shrank, because of the next section: a bad name now blocks environmentd and clusterd, not balancerd and console. Scope changeThe feature now covers environmentd and clusterd only, as two per-component values next to the existing per-component scheduling knobs, rather than one global value over all four pod types. balancerd and console default to two replicas and hold no state, so an eviction there costs a connection rather than a rehydration. environmentd is a single pod and clusterd replicas hold hydrated state. Narrowing it also means reaching for Three things worth knowing that are not in the diffMeasured against a real API server rather than inferred:
The first two are user-facing and no self-managed page covers pod scheduling today. Happy to open an Still open
Not verified locally: |
…terd pods The operator sets no priority class on environmentd or clusterd pods, so they run at priority 0. Any higher-priority pod can evict them when a node fills up. A clusterd replica preempted mid-hydration aborts the deploy, and the chart has no way to raise these pods. Add `environmentd.priorityClassName` and `clusterd.priorityClassName`, next to the per-component node selectors, affinities and tolerations both components already have. Each becomes an orchestratord argument. `environmentd.priorityClassName` sets `priorityClassName` on the environmentd StatefulSet's pod template. `clusterd.priorityClassName` is forwarded to environmentd as `--orchestrator-kubernetes-priority-class-name` and applied there to clusterd pod specs. Both default to unset, which renders no argument and leaves every pod spec unchanged. The forwarded argument is gated on `meets_minimum_version(&V26_40_0)`, matching how `clusterd.affinity` and `clusterd.tolerations` are gated on `V144`. environmentd exits on an unrecognized argument, so an instance pinned to an older `environmentdImageRef` would otherwise fail to start once the value was set. balancerd and console are left out. Both default to two replicas and neither holds state, so an eviction costs a connection rather than a rehydration. The negative chart assertions use `notMatchRegex`. `notContains` compares whole list elements, so it cannot fail against a flag rendered as `--flag=value`. The existing `schedulerName` assertion has the same defect and is fixed here.
885443a to
20af408
Compare
|
Correction on the last nit. You asked for the prerequisite clause in the Both comments now read: # -- PriorityClass to use for environmentd pods spawned by the operator. The
# PriorityClass must already exist. Kubernetes rejects a pod that names one
# it cannot resolve, so a typo here stops these pods being created at all.
priorityClassName:That flows through
|
|
Local gate results, run in
Clippy ran before the last commit, which touched only Buildkite still cannot run this: the branch is on a personal fork, and The orchestratord suite that covers the new test is Nightly only, and a fork PR cannot carry the |
|
Superseded by #38457, which carries this change as a single commit with your review addressed. What changed since your review, in short:
Closing here rather than force pushing again, so the new PR has one clean commit and a description that is not three rounds of edits deep. Sorry for the extra notification. |
Problem
The operator sets no priority class on environmentd or clusterd pods, so they run
at priority 0. Any higher-priority pod can evict them when a node fills up. We
lost a clusterd replica mid-hydration to a cluster-critical DaemonSet rollout,
which aborted the deploy. The chart offers no way to raise these pods.
Solution
Two new chart values,
environmentd.priorityClassNameandclusterd.priorityClassName. They sit next to the per-componentnodeSelector,affinityandtolerationsthat both components already have. Each becomes anorchestratord argument.
environmentd.priorityClassNamesetspriorityClassNameon the environmentd StatefulSet's pod template.clusterd.priorityClassNamereaches clusterd through environmentd, forwarded as--orchestrator-kubernetes-priority-class-name.Both default to unset, which renders no argument and leaves every pod spec
byte-identical.
balancerd and console are left out on purpose. Both default to two replicas and
neither holds state, so an eviction costs a connection rather than a
rehydration. The operator's own pod is out for the same reason. It runs two
replicas behind leader election and a PodDisruptionBudget.
The forwarded clusterd argument is gated on
meets_minimum_version(&V26_40_0), soclusterd.priorityClassNameneeds anenvironmentd at v26.40 or newer.
clusterd.affinityandclusterd.tolerationsare gated on
V144three lines above it. environmentd exits on an unknownargument. Without the gate, an instance pinned to an older
environmentdImageRefwould fail to start once the value was set.Testing
helm unittest misc/helm-charts/operatorcovers both values, absent when unsetand present when set. The negative cases use
notMatchRegexover the argumentlist.
notContainscannot fail here. It compares whole elements, and therendered element always carries
=<value>.test/orchestratord/mzcompose.pygains aPriorityClassNamemodification. Itinstalls the chart against a real PriorityClass, requests a rollout, and waits
for it to complete. It then asserts that environmentd and clusterd pods carry
both
spec.priorityClassNameand the resolvedspec.priority. The resolvedinteger is the assertion that matters. It proves the API server admitted the
class. The string alone only proves the operator copied it. On an older
environmentdImageRefit asserts the split instead: environmentd carries theclass, clusterd does not, and environmentd is running.
For the reviewer
one changes the environmentd StatefulSet spec. Every instance then flips to
UpToDate=Falsewith reasonWaitingForApproval, and waits forspec.requestRolloutto change. That is the operator's standing behaviour forany generation-affecting change. Worth knowing before reaching for this value
during an incident. Nothing moves until you roll.
Kubernetes caps user-created classes at 1000000000.
system-cluster-criticalsits at 2000000000. Moving these pods off 0 takesthem out of the victim queue ahead of ordinary workloads, which covers most of
a cluster. It does not make them immune to the DaemonSet in the Problem
section when they are the only pods on the node worth evicting. Surviving that
needs capacity the DaemonSet does not have to take, so a dedicated node pool,
not a priority class.
preemptionPolicy: Never. During the rollout thatapplies the value, the new generation's pods carry the class. The generation
still serving traffic does not. On a full node the new pods can evict the old
ones.
Neverstops that. The cost is that the new pods wait for capacityinstead of taking it. A rollout on a full cluster then stays Pending until a
node appears.
preemptionPolicyhas to live on the PriorityClass. The APIserver rejects it in a pod spec when the pod names a class.
names a class it cannot resolve. A StatefulSet surfaces that only as a
FailedCreateevent.operator.image.tagtrails the chart version betweenreleases. Install from a git checkout with either value set, and the argument
goes to an orchestratord that does not accept it. Released charts pin a
matching image.
generation.rshas no test module, so the orchestratord suite isthe only automated cover for the gate.
schedulerNamenegative chart test, which carries the samenotContainsdefect. This change edits the block directly beneath it.V154_DEV0is built with an empty prerelease under an.expect("dev.0 is valid prerelease")message, so the pod-annotations gatewants a final 0.154.0. Left alone, since changing it moves a gate this change
does not touch.
schedulerNamefix should goseparately, whether
Chart.yamlneeds the version bump its CONTRIBUTING asksfor (the version looks release-managed by
bin/helm-chart-version-bump, andCNS-136: expose statement logging sample rate in the operator chart #38406 did not bump it), and whether to open an
A-docsissue for thescheduling guidance in the bullets above, since no self-managed page covers it
today.