Skip to content

feat(linstor-scheduler): add optional admission webhook with configurable TLS - #94

Merged
WanzenBug merged 1 commit into
piraeusdatastore:mainfrom
lexfrei:feat/linstor-scheduler-admission
Jul 15, 2026
Merged

WanzenBug merged 1 commit into
piraeusdatastore:mainfrom
lexfrei:feat/linstor-scheduler-admission

Conversation

@lexfrei

@lexfrei lexfrei commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

What this does

I add an optional admission webhook to the linstor-scheduler chart. When enabled, it watches Pod creation and, for Pods that use a PersistentVolumeClaim backed by the LINSTOR CSI driver, sets schedulerName to this scheduler automatically — so the scheduler no longer has to be selected by hand on every workload. It is disabled by default (admission.enabled: false), and with the default the chart renders exactly as before, so this is a complete no-op for existing installs.

This revives and supersedes #68, which added the same webhook but stalled. I have carried its content over and addressed all three review comments from that PR:

  1. The Pod and container security contexts are now configurable via admission.podSecurityContext and admission.securityContext, with the previously hardcoded values kept as defaults.
  2. The webhook TLS secret name is configurable via admission.tls.secretName (empty defaults to <fullname>-admission-tls), so a secret managed outside the chart can be pointed at directly.
  3. TLS provisioning is now an enum admission.createTLS — cert-manager (default, the previous behavior), helm (Helm generates the CA and certificate itself), or "" (bring your own secret) — mirroring the createApiTLS idiom already used by the linstor-cluster chart.

A question before the code review

This chart is marked deprecated: true, and the README already recommends volumeBindingMode: WaitForFirstConsumer for new deployments. I would rather raise that directly than quietly grow a deprecated chart.

The webhook is fully opt-in and a complete no-op when disabled, so it changes nothing for anyone who does not turn it on. It is aimed at clusters that still run this scheduler and want to avoid setting schedulerName on every Pod.

Given the deprecation, would you prefer this to live in the chart at all, or would a standalone manifest / example outside the chart be a better home for it? I am happy either way — I would just like your call on the direction before taking it further.

What is new beyond #68

  • Two more TLS modes alongside cert-manager: helm (self-contained CA + certificate generation) and "" (bring your own). In helm mode the CA is generated once and shared, so the generated TLS Secret's ca.crt and the webhook's caBundle are byte-identical; this is done without lookup, so it also works under helm template and on a first install.
  • A dedicated ServiceAccount and PodDisruptionBudget for the webhook, kept off the base scheduler's (immutable) selectors so the base PDB and HPA stay scoped to the scheduler Pods.
  • Fail-guards that reject an unknown createTLS value, or a bring-your-own configuration with neither a secret nor a caBundle, instead of rendering a silently broken webhook.
  • Readiness and liveness probes on the webhook container.
  • admission.reloadOnCertChange (opt-in Stakater Reloader annotations) so the Pods restart when the TLS secret is renewed — the webhook binary loads its certificate once at startup and does not hot-reload it.
  • A helm-unittest suite covering the three TLS modes, the fail-guards, the selector isolation, and backward compatibility.

Known limitation

The helm TLS mode regenerates the CA and certificate on every helm upgrade (Helm's genCA is non-deterministic), so it suits one-shot installs rather than continuously-reconciled / GitOps setups. cert-manager (the default) or bring-your-own are the right choice there. This is documented in values.yaml and the README.

Supersedes #68.

…able TLS

Add an optional, opt-in admission webhook to the linstor-scheduler chart
that sets schedulerName on Pods using LINSTOR-backed PVCs, so the
scheduler need not be selected by hand on every workload. Disabled by
default and a no-op when off.

Pod and container security contexts and the TLS secret name are
configurable, and TLS can be provisioned via cert-manager (default),
Helm-generated certificates, or a bring-your-own secret. helm mode
generates one shared CA without lookup so the Secret ca.crt and webhook
caBundle match. Includes a dedicated ServiceAccount and
PodDisruptionBudget kept off the base scheduler selectors, fail-guards
for invalid TLS configuration, readiness/liveness probes, opt-in
cert-reload annotations, and a helm-unittest suite.

Assisted-By: Claude <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
@WanzenBug

Copy link
Copy Markdown
Member

Thanks!

@WanzenBug
WanzenBug merged commit 14ec9f2 into piraeusdatastore:main Jul 15, 2026
1 check passed
lexfrei added a commit to cozystack/cozystack that referenced this pull request Jul 16, 2026
…sion webhook (#3201)

## What this PR does

Re-vendors the `linstor-scheduler` chart from upstream **0.3.1**
(appVersion **v0.3.6**). Upstream now ships the admission webhook
natively (contributed via
[piraeusdatastore/helm-charts#94](piraeusdatastore/helm-charts#94)),
so the loose downstream admission templates — which round-tripped every
Pod through an old `k8s.io/api` and silently stripped fields they did
not know about, the `image` volume source and the native-sidecar
`restartPolicy` among them, breaking KubeVirt containerDisk VMs and
native sidecars cluster-wide — are dropped in favour of the upstream
copy.

- The admission webhook comes from the upstream chart now; the previous
downstream copy and its patch are removed. `make update` pulls 0.3.1 and
applies only `cozystack-scheduler-deployment.patch` (the scheduler pod
component label and the distro-suffix-stripped kube-scheduler image tag,
neither of which is upstream yet), so vendoring stays deterministic and
reproducible.
- The upstream admission Deployment keeps the same name but changes its
immutable pod selector, so an in-place upgrade of an existing install
would fail with `field is immutable`. Migration 52 deletes the old
admission Deployment before the upgrade so the new one is recreated
cleanly (`targetVersion` 52 → 53).
- appVersion v0.3.6 also carries the webhook's TLS certificate
hot-reload fix
([piraeusdatastore/linstor-scheduler-extender#22](piraeusdatastore/linstor-scheduler-extender#22)):
the webhook used to load its certificate once at startup, so after the
mounted Secret was rotated it kept serving a stale certificate and —
with `failurePolicy: Ignore` — silently stopped mutating until it was
restarted. It now reloads on rotation, so no external cert-reload
workaround is needed here.
- Wrapper values keep `replicaCount: 2`, now that the admission Pods
have their own PodDisruptionBudget and no longer share the scheduler's.
- Adds a helm-unittest suite covering the admission resources,
PodDisruptionBudget selector isolation, least-privilege RBAC, the TLS
provisioning modes and their rejection paths, the scheduler image-tag
strip, and backward compatibility with the webhook disabled.

Closes #3198.

### Screenshots

N/A — no UI changes.

### Downstream repositories

I walked the trigger map against the diff, file by file. It touches
`packages/system/linstor-scheduler/` and, under
`packages/core/platform/`, only migration 52 and the
`migrations.targetVersion` bump — an internal, release-managed counter,
not a user-facing `spec.components.platform.values.*` key documented on
the website. No trigger matches.

- [x] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:

### Release note

```release-note
fix(linstor-scheduler): the LINSTOR scheduler admission webhook no longer strips unknown Pod fields (the `image` volume source and native-sidecar `restartPolicy`), which had broken KubeVirt containerDisk VMs and native sidecars, and it now reloads its TLS certificate after rotation instead of silently failing. The chart is re-vendored from upstream 0.3.1; an automatic upgrade migration replaces the admission Deployment whose immutable selector changed.
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Expanded the optional Linstor Scheduler admission webhook with richer
configuration, including automated `schedulerName` mutation for LINSTOR
CSI-backed PVC Pods.
* **Improvements**
* Updated the Linstor Scheduler Helm chart to **0.3.1** (scheduler app
**v0.3.6**), including updated admission webhook behavior, safer
defaults, and **2 replicas**.
* Platform migrations now advance to **version 53**, with upgrade-safe
cleanup of the existing admission deployment.
* **Documentation**
* Updated Helm README and post-install notes with detailed guidance for
admission webhook and TLS modes.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants