Files
cluster-autoscaler-with-capi/CLAUDE.md
T
kacerrandClaude Opus 5.5 d8efa3b961 Document Ansible-built management cluster (plan step 4)
Phase-1 Step 2 rewritten around ansible/mgmt.yml and cluster-api-operator,
version pins for operator/cert-manager/cloud image, decisions #12-14,
execution log and changelog. Phase-1 Step 2 checked off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 10:41:03 +02:00

6.6 KiB
Raw Blame History

CLAUDE.md

Home-lab research project: cluster-autoscaler + Cluster API on Proxmox VE (phase 1), then a KVM/libvirt provider (phase 2) and Kamaji hosted control planes / "poor man's KaaS" (phase 3). Start with README.md; details live in docs/.

Owner context

Experienced SRE. Be concise and technical; skip basics (k8s internals, Go, Linux, distributed systems).

Lab facts (don't re-derive)

  • PVE node pv1-1, API https://192.168.0.8:8006, token capmox@pve!capi (privsep 0).
  • VM network: vmbr0 is VLAN-aware, VMs in VLAN 4 → always bridge=vmbr0 + tag/vlan: 4, never vmbr0.4@vmbr0 (that is an ip link name, not a bridge).
  • Storage: local (iso, dir) and local-lvm (LVM-thin) → disks are raw, never qcow2.
  • Build host for image-builder: 192.168.4.181 (VLAN 4 must reach it on 8000–9000 during builds).
  • Node template: ubuntu-2404-kube-v1.35.9 (image-builder v0.1.55). Login only via cloud-init.
  • Management cluster: VM 201 lab-mgmt, 192.168.4.21 (ssh ubuntu@), built by the idempotent ansible/mgmt.yml (re-run must be changed=0); admin kubeconfig ~/.kube/lab-mgmt.kubeconfig.
  • Required PVE ACLs: PVEVMAdmin + PVEAuditor on /, PVEDatastoreAdmin on /storage, PVESDNUser on /sdn/zones/localnetwork.

Version rules

  • docs/versions.md is the source of truth. Any version change updates it in the same change.
  • Before proposing any deployment or upgrade, verify versions are current (use the k8s-version-check skill if available). Go module proxy / git ls-remote / Helm index.yaml work even when the GitHub API is unavailable.
  • CAPI core is pinned to v1.12.x because CAPMOX v0.9 is only tested on CAPI 1.11/1.12. This caps workload Kubernetes at 1.35 and cluster-autoscaler at 1.35.x. Don't bump CAPI unless the CAPMOX compatibility table allows it.
  • Always pin versions explicitly (management cluster: ansible/group_vars/all.yml; helm install --version); never rely on "latest".
  • CAPI providers are managed by cluster-api-operator (Provider CRs from ansible/mgmt.yml). Never run clusterctl init/upgrade/move/delete against the management cluster; clusterctl is only for generate cluster (always with --infrastructure proxmox:v0.9.1), describe, get kubeconfig.
  • Check a provider's metadata.yaml contract and CAPI version (go.mod) before adding it to the management cluster — all providers share one CAPI core (known skew: Kamaji CP provider v0.21.0 is on CAPI 1.13).

Facts about providers: verify in source

READMEs lag. For "does provider X support Y" read the API types and templates of the exact tagged release (Go proxy zip: https://proxy.golang.org/<module>/@v/<ver>.zip). Delegate to the upstream-researcher agent for anything non-trivial.

Safety

  • Never commit secrets: PVE token secret, kubeconfigs, clusterctl.yaml (see .gitignore).
  • Cluster inspection is read-only via the cluster-inspector agent and read-only kubeconfigs (.claude/cluster-inspector/, see its README). Mutations (kubectl apply/delete/scale, qm, pveum) are proposed as commands for the owner to run unless explicitly asked to execute them.
  • Don't delete Proxmox VMs/templates or CAPI objects on your own initiative.

Conventions

  • Docs in English, Markdown, Mermaid for diagrams (Gitea renders it).
  • Troubleshooting findings go into the relevant doc's troubleshooting/fixes table: symptom → root cause → fix.
  • Example configs live in configs/ as *.example or non-secret values files.

Project history

Research repo: plans, conversations and decisions are kept in the repo, dated. Timestamps always come from date (+%Y-%m-%d-%H%M for file names, +%Y-%m-%d %H:%M %Z for headings), never guessed. Summaries only, never raw transcripts; mask secrets and check the staged diff before committing.

What Where When
Plans docs/plans/YYYY-MM-DD-HHMM-<slug>.md every plan-mode plan
Execution logs docs/plans-executions/<plan's file name> after each step of an approved plan
Session notes docs/sessions/YYYY-MM-DD-HHMM-<slug>.md research/design/debugging conversations without a plan
Decisions docs/decisions.md (one table) a direction chosen, rejected or reversed
Prompts docs/prompts/YYYY-MM-DD-HHMM-<slug>.md long crafted prompts/specs that kick off work (verbatim)
Reviews docs/reviews/YYYY-MM-DD-HHMM-<slug>.md review findings, most severe first, - [ ] ticked as processed
Changelog CHANGELOG.md, newest on top lab milestone, version change, design direction, new runbook/config — after the owner confirms it works
  • Plans: header # Plan: <title> + **Created:** <timestamp>. Plan mode can only write to ~/.claude/plans/, so right after ExitPlanMode the first action is copying the plan into docs/plans/ and committing it on its own, before any work starts.
  • Execution logs: a - [ ] Step N — <title> checklist on top (the authoritative status; a new session resumes from this file alone), then one section per step in chronological order, committed with that step's work. Light prose; exact commands as fenced blocks (clusterctl, helm, kubectl apply, qm, Packer), each with one line on why it was run that way, including commands the owner reports running on the lab and outputs that mattered (VM IDs, IPs, resolved versions, errors). Call out deviations from the plan; end with "Worth noting". Problems also go into the relevant fixes table, linked from the log.
  • Session notes: write one unprompted when a conversation produced a finding worth keeping (option compared or rejected, compatibility check, root cause, open question) that no plan covers; mention it in the reply. Sections: Question, What was checked (sources, versions with date checked), Findings, Open questions, Follow-ups. Extend the note if the topic continues.
  • Decisions: never rewrite a row; a reversal is a new row and the old one becomes superseded by #N. Design-doc suggestions are proposed until lab work confirms them. Link the plan/session/doc with the reasoning. README "Key decisions so far" stays the short summary.

Git

  • Remote: Gitea gitea.home.hrajfrisbee.cz/kacerr/cluster-autoscaler-with-capi.
  • Docs, configs and history files go straight to main. Phase-3 Go code or anything the owner calls a feature: feat/<slug> branch, git push -u, MR via tea pr create --title … --description … --base main --head <branch> (fallback: print …/compare/main...<branch>). Never merge or delete branches from the CLI.
  • Commit messages end with a Co-Authored-By: trailer for Claude. /ship commits and pushes.