Skip to content

fix(cli): admin-less deploy installs on one node, in any namespace - #595

Merged
bmscomp merged 1 commit into
mainfrom
fix/adminless-first-install
Nov 4, 2026
Merged

bmscomp merged 1 commit into
mainfrom
fix/adminless-first-install

Conversation

@bmscomp

@bmscomp bmscomp commented Nov 4, 2026

Copy link
Copy Markdown
Owner

Why

A namespace admin could not finish kates deploy --adminless on a first try. The kind run in plans/adminless-enhancement.md found it: Apicurio was refused on KafkaTopic kafkasql-journal in namespace kafka, and two brokers stayed Pending for the full 15 minutes while the deploy printed only "2 Pending". One false gap, list podmonitors on a cluster with no such API, also switched off the compliance Role, and with it compliance checks, topology and the disruption guard.

This fixes A2, F1, F2/A6/F4 and F3 from that plan.

What changed

  • Apicurio (A2): the deploy passes its namespace, cluster name, bootstrap address, Kafka namespace and client namespaces, in both profiles. The stray --create-namespace is gone.
  • Compliance Role (F1): the PodMonitor rule renders only where monitoring.coreos.com/v1/PodMonitor exists, and the CLI asks for that grant only then. A failed discovery still asks. ComplianceCheck and ClusterTopologyService ask client.supports on a 403, because a Role without the rule gets 403 and not 404 for an API the cluster does not serve. kates 0.15.9, kates-platform 0.8.24.
  • Sizing (F2, A6, F4): admin-less detects kind, k3d and minikube with no cluster rights, and sizes to 1 controller, 1 broker, 1 Connect and MirrorMaker 2 worker at replication factor 1 where the default would not fit. --ha=false now does the same. An explicit --ha wins, and an installed Kafka decides the size on a re-run. One line says what was chosen and why.
  • Why pods wait (F3): Kafka, Kafka Connect and component waits print the scheduler's reason, read from events matched by pod UID. A refused events read changes nothing.
  • Early stop: the wait gives up after 3 minutes only when 0/N nodes are all short of CPU or memory, the same pods hold the same reason, and no TriggeredScaleUp or Nominated event exists.
  • Fixes the review found: Connect's egress pointed at krafter; Connect ingress and Kafka UI egress blocked Kafka UI from Connect and Apicurio; kafka-ui's kind overlay hard-coded a namespace and a Service that no longer exists; fixed NodePorts would collide on a shared cluster, so admin-less uses ClusterIP.

--ha=false in the full profile also drops the dead kafka.replicas args and gives MirrorMaker 2 one replica.

Deliberately not done

  • No --size or --values flag. The size default is decision 2 in the plan.
  • Full-profile --ha=false keeps its detected pool count. Replacing detected pools renames them, and the chart removes a renamed pool with its data.
  • No readiness wait on Apicurio, Kafka UI or MirrorMaker 2. It would turn deploys that are green today red. A Pending pod there still ends green.
  • Apicurio's journal stays at replication factor 1, the only value safe for every size. It needs the real broker count (plan item 1.6).
  • A zoneless cluster with refused node reads keeps the zone rack. No signal exists without the read; the book gives the .policies way out.
  • A1 (PodMonitors where the API is served) is not fixed. It belongs to the per-chart overlays in plan item 1.3.

Things to check in review

  • Upgrades: --upgrade apicurio rolls it once, because the bootstrap address becomes the FQDN.
  • Offline bundles: on kind, a missing kind or docker binary now fails the deploy.
  • Early stop: a node-adding mechanism that emits neither event, or capacity arriving after 3 minutes, stops the deploy. A rerun recovers.
  • Order in runDeploy: the admin-less report now runs before the wizard.

Testing

Live on a one-node kind cluster (Kubernetes 1.37, 18 CPUs) as a ServiceAccount with admin in its namespace only, Strimzi 1.2.0 installed by an admin:

  • All 7 releases installed; 1 broker and 1 controller; a LOAD test ran DONE at 40,000 records.
  • Connectors RUNNING, MirrorMaker 2 ready, Kafka UI's Connect and Apicurio addresses answered from its pod.
  • A rerun over a partial install finished it. A second team installed alongside with no collisions.
  • With the node filled, the reason printed at once and the deploy stopped at 3 minutes on 0/1 nodes are available: 1 Insufficient cpu. With capacity freed at 75 seconds, the deploy recovered and exited 0.

The run used the published 1.36.0 image, so the Java change has unit tests only (ComplianceCheckTest, ClusterTopologyServiceTest); those two classes pass, the full Java suite was not run locally. k3d, minikube, multi-node clusters and clusters with Prometheus Operator were not run.

Locally: build, vet, go test ./..., pinned golangci-lint 2.14.0, CLI style and compat checks, helm lint and unittest, check-versions.sh, check-chart-matrix.py and book style.

A namespace account could not finish a first install: Apicurio was refused on
the kafka namespace, one missing PodMonitor grant switched off the compliance
Role on clusters with no Prometheus operator, and Kafka's chart defaults left
brokers Pending for 15 minutes with no reason given.

Apicurio now follows the deploy's namespaces and cluster. The compliance Role's
PodMonitor rule and the CLI's check for it follow the API the cluster serves.
Admin-less detects kind, k3d and minikube without cluster rights, and sizes
down to one broker where the stack would not fit, and --ha=false now sizes it.
Readiness waits print why pods are Pending, and stop early when every node is
short and nothing changes for three minutes.
@bmscomp
bmscomp merged commit f2f0936 into main Nov 4, 2026
68 checks passed
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.

1 participant