Initial import: phase docs, configs, Claude conventions

Phase 1-3 runbooks and design notes, version pins, config templates,
project-history conventions, cluster-inspector read-only credentials setup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-27 00:58:52 +02:00
co-authored by Claude Opus 5.5
commit 5fd998c5f9
26 changed files with 1124 additions and 0 deletions
+97
View File
@@ -0,0 +1,97 @@
# Phase 3 — Hosted control planes with Kamaji ("poor man's KaaS")
Goal: create a tenant Kubernetes cluster from one manifest. Its control plane runs as pods in the
management cluster (Kamaji), and its workers are autoscaled Proxmox (later also KVM) VMs.
Status: **design notes**.
## Why Kamaji
With kubeadm control planes every tenant costs ≥ 1 VM (3 for HA) just for apiserver/etcd. Kamaji
runs each tenant control plane as a Deployment in the management cluster, backed by a shared
datastore. That cuts the control plane to a few hundred MB of RAM, gives it seconds to start, and
makes upgrades a rolling Deployment update.
## Architecture
```mermaid
flowchart LR
subgraph MGMT[management cluster - 3 nodes]
CAPI[CAPI core + CAPMOX]
KCP[Kamaji CP provider]
KAM[Kamaji controller]
DS[(kamaji-etcd datastore)]
LB[MetalLB pool on VLAN 4]
subgraph T1[ns tenant-a]
TCP1[TenantControlPlane pods<br/>apiserver, ctrl-mgr, scheduler]
CA1[cluster-autoscaler tenant-a]
end
end
PVE[Proxmox VE]
W1[tenant-a worker VMs]
KCP --> KAM --> TCP1
TCP1 --> DS
LB -. VIP :6443 .- TCP1
CAPI -- MachineDeployment --> PVE --> W1
W1 -- kubelet join via VIP --> TCP1
CA1 -- scales MD --> CAPI
```
CAPI object wiring per tenant:
- `Cluster.spec.controlPlaneRef` → `KamajiControlPlane`, which creates the Kamaji `TenantControlPlane`.
- `Cluster.spec.infrastructureRef` → `ProxmoxCluster` with **`externalManagedControlPlane: true`**,
so the Kamaji provider patches the control plane endpoint. The field exists in CAPMOX v1alpha2.
- Workers: a regular `MachineDeployment` + `KubeadmConfigTemplate` + `ProxmoxMachineTemplate`, with
autoscaler annotations as in phase 1.
- Konnectivity handles apiserver → kubelet traffic, because the control plane isn't on the worker network.
References: [Kamaji + Proxmox infra provider docs](https://kamaji.clastix.io/cluster-api/proxmox-infra-provider/),
CLASTIX Helm chart `capi-kamaji-proxmox` (0.0.4) as a wiring example.
## Management cluster changes vs. phase 1
| Area | Phase 1 | Phase 3 |
| --- | --- | --- |
| Nodes | 1× k3s | 3 nodes: tenant control planes and their datastore live here |
| LoadBalancer | none needed (kube-vip in workload CP) | MetalLB (or kube-vip cloud provider) with an IP pool on VLAN 4, one VIP per tenant |
| Datastore | — | `kamaji-etcd` chart 0.18.1 (etcd 3.6.12); alternatives: PostgreSQL/MySQL via kine |
| Storage | — | CSI for etcd PVCs |
k3s' built-in servicelb (klipper) binds host ports, so it can't hand out many `:6443` endpoints. Use MetalLB.
## Autoscaling per tenant
A cluster-autoscaler instance in `clusterapi` mode serves **one** workload cluster (one kubeconfig).
So each tenant gets its own CA release in its namespace in the management cluster
(`kubeconfig-incluster`, secret `<tenant>-kubeconfig`). Automating that is our first real Go code:
- **tenant-operator** (small controller in this repo): watches `Cluster` objects labelled
`kaas.lab/autoscaling=enabled`, renders a per-tenant cluster-autoscaler Deployment + RBAC, and
cleans up on delete. The alternative is CAAPH (cluster-api-addon-provider-helm), but that installs
into the *workload* cluster, and we want CA in the management cluster.
## Self-service UX
- `ClusterClass` `lab-tenant` with variables: Kubernetes version, worker size, min/max workers, VLAN.
- A tenant cluster is one `Cluster` with `spec.topology` referencing the class.
- A namespace per tenant with RBAC limited to its own `Cluster`; the kubeconfig is handed out from the
`<tenant>-kubeconfig` secret.
## Open questions and risks
- **CAPI version skew:** Kamaji CP provider v0.21.0 is built against CAPI **v1.13.4**, while CAPMOX
v0.9.x is tested on **v1.12**. All providers share one CAPI core, so either find a Kamaji CP
provider release built on 1.12 or wait for CAPMOX to support 1.13+. Check each provider's
`metadata.yaml` contract before installing.
- **Kamaji OSS release model:** OSS publishes edge releases only (latest tag `edge-26.2.5`, Helm chart
`0.0.0+latest`). Stable versioned builds are commercial (CLASTIX), so pin by edge tag and image digest.
- Tenant Kubernetes version range is bounded by the Kamaji release and by our node images. We need
one image-builder template per supported minor.
- Backup and restore of the shared datastore (etcd snapshots) becomes critical: it holds every tenant.
## Exit criteria
- [ ] Tenant cluster created from a single `Cluster` + `ClusterClass`, control plane as pods in mgmt.
- [ ] Workers join via Konnectivity, and CNI works.
- [ ] Per-tenant cluster-autoscaler deployed automatically, scale 0 → N → 0 works.
- [ ] Deleting the `Cluster` removes the control plane, VMs, VIP and autoscaler.