8000 feat(crd): specify PodSpec in spec.templates.podTemplates[].spec by belaytzev · Pull Request #2084 · Altinity/clickhouse-operator · GitHub
[go: up one dir, main page]

Skip to content

feat(crd): specify PodSpec in spec.templates.podTemplates[].spec - #2084

Open
belaytzev wants to merge 4 commits into
Altinity:0.28.0from
belaytzev:feat/specify-podspec-in-podtemplates
Open

belaytzev wants to merge 4 commits into
Altinity:0.28.0from
belaytzev:feat/specify-podspec-in-podtemplates

Conversation

@belaytzev
@belaytzev belaytzev commented Sep 22, 2026 •
Copy link
Copy Markdown

Problem

spec.templates.podTemplates[].spec is declared as a bare type: object with
x-kubernetes-preserve-unknown-fields: true and carries a # TODO specify PodSpec.
Everything under it is therefore accepted without validation — a misspelled
resorces: or a stray field is silently ignored, and the mistake only surfaces
later as a StatefulSet that does not look like what was written.

This closes that TODO for ClickHouseInstallation / ClickHouseInstallationTemplate.

How the schema was produced

Generated with controller-gen from corev1.PodSpec of k8s.io/api v0.30.14 —
the version this operator builds against — rather than written by hand. That matters
for the awkward types: Quantity and IntOrString come out as proper
x-kubernetes-int-or-string nodes (45 of them), and there are no $ref / oneOf
constructs that a structural schema would reject.

Only deploy/builder/templates-install-bundle/...-crd-01-chi-chit.yaml was edited by
hand. In every generated file the same block replaces the # TODO specify PodSpec
node of the CHI and CHIT CRDs; nothing else in those files changed.

Why descriptions are stripped

The schema is generated with crd:maxDescLen=0. This is not cosmetic:

with descriptions without
PodSpec block 7410 lines, 385 KiB 3567 lines, 107 KiB
kubectl apply -f (client-side) fails works

With descriptions the CRD grows past the 256 KiB limit of the
kubectl.kubernetes.io/last-applied-configuration annotation, and a plain
kubectl apply -f deploy/operator/clickhouse-operator-install-bundle.yaml — the
install path documented in the README — fails with:

metadata.annotations: Too long: must have at most 262144 bytes

Only --server-side would work. Stripping descriptions keeps the documented install
path intact; the cost is that kubectl explain no longer prints help text for the
PodSpec fields. Happy to switch to the full version if you would rather have the
descriptions and require server-side apply.

Fields left schemaless

Even without descriptions, the full PodSpec pushed the CHI and CHIT CRDs to ~334 KB.
That is over the 262144-byte ConfigMap limit, so the Helm chart's CRD hook can't ship
them, and dev/test_helm_chart.sh fails on "every CRD fits one ConfigMap".

affinity, volumes and ephemeralContainers (~112 KB together) keep
x-kubernetes-preserve-unknown-fields: true, same as the whole spec before this PR.
ephemeralContainers can't be set at pod creation anyway. Everything else is still
validated: containers, initContainers, securityContext, tolerations,
topologySpreadConstraints and so on. Both CRDs are now ~222 KB.

Verification

Against a kwok v1.36.1 apiserver, using the regenerated bundle:

  • kubectl apply -f deploy/operator/clickhouse-operator-install-bundle.yaml — applies cleanly, client-side
  • a CHI whose podTemplate uses securityContext, initContainers, tolerations and topologySpreadConstraints — accepted
  • podTemplates[0].spec.containers[0].resorces — rejected:
    strict decoding error: unknown field "spec.templates.podTemplates[0].spec.containers[0].resorces"
    

Scope

ClickHouseKeeperInstallation carries the same TODO; left out deliberately to keep
this reviewable. Happy to follow up with it.

Context

This started as datreeio/CRDs-catalog#737, where the schema was patched in the
catalog instead. @eyarz rightly pointed out that the catalog should mirror the vendor
CR and the fix belongs here.

`podTemplates[].spec` carried a `# TODO specify PodSpec` and
`x-kubernetes-preserve-unknown-fields: true`, so anything under it was
accepted unvalidated: a misspelled `resorces:` or a stray field silently
did nothing until the StatefulSet came out wrong.

The schema is generated from `corev1.PodSpec` of k8s.io/api v0.30.14 --
the version this operator builds against -- with controller-gen, so
Quantity and IntOrString get proper `x-kubernetes-int-or-string` instead
of hand-written approximations.

Descriptions are stripped (`crd:maxDescLen=0`). With them the CRD grows
past the 256 KiB `kubectl.kubernetes.io/last-applied-configuration`
annotation limit and a plain `kubectl apply -f` -- the install path in
the README -- fails with `metadata.annotations: Too long`. Without them
the ClickHouseInstallation CRD goes from ~130 to ~187 KiB and
client-side apply keeps working; only `kubectl explain` output for those
fields is lost.

Verified against a kwok v1.36.1 apiserver:
  - `kubectl apply -f deploy/operator/clickhouse-operator-install-bundle.yaml` succeeds
  - a CHI using securityContext, initContainers, tolerations and
    topologySpreadConstraints is accepted
  - `podTemplates[0].spec.containers[0].resorces` is rejected with
    `unknown field` for both CHI and CHIT

ClickHouseKeeperInstallation carries the same TODO and is left for a
separate change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Alexey Belaytzev <github@accounts.ti1orn.com>
@belaytzev
belaytzev force-pushed the feat/specify-podspec-in-podtemplates branch from bc4f092 to f4fdd51 Compare October 31, 2026 19:46
@belaytzev
belaytzev changed the base branch from 0.27.4 to 0.28.0 October 31, 2026 19:47
@belaytzev
Copy link
Copy Markdown
Author

Retargeted from 0.27.4 to 0.28.0: 0.27.4 was released two days after this PR was opened.

Rebased as a single commit on 0.28.0 (00a2fd33). The PodSpec block itself is unchanged: k8s.io/api is still v0.30.14 on 0.28.0. It replaces the # TODO specify PodSpec node in the CHI and CHIT CRDs in the template and in every generated file; nothing else in those files changed. Re-running dev/build_manifests.sh on your side should give an identical result. If it doesn't, tell me and I'll regenerate.

With the new backup fields the CHI CRD is ~187 KiB (was ~130 KiB), still under the 256 KiB client-side apply limit. Re-checked against kwok v1.36.1: the bundle applies with plain kubectl apply -f, a valid CHI is accepted, and containers[0].resorces is rejected with unknown field for both CHI and CHIT.

CI hasn't run on this PR yet. It probably needs approval for fork workflows.

belaytzev and others added 3 commits November 1, 2026 13:11
…n PodSpec

With the full PodSpec schema the CHI and CHIT CRDs grow to ~334 KB and
no longer fit one ConfigMap (262144 bytes), so the Helm chart's CRD hook
cannot ship them: dev/test_helm_chart.sh fails on
"every CRD fits one ConfigMap".

affinity, volumes and ephemeralContainers take ~112 KB of the schema.
They now carry x-kubernetes-preserve-unknown-fields, as the whole spec
did before. ephemeralContainers cannot be set at pod creation anyway.
containers, initContainers, securityContext, tolerations and the rest
stay validated. Both CRDs drop to ~222 KB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Alexey Belaytzev <github@accounts.ti1orn.com>

This branch has not been deployed

No deployments
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

0