Owner's pending work, committed ahead of the pv1-2 change it underlies: - lab1.yaml: worker template lab1-worker-2g (2048 MiB, decision #16), MD rollout maxSurge 0 / maxUnavailable 1, ProxmoxCluster schedulerHints.memoryAdjustment 160 (#17) - cluster-autoscaler values: RBAC for proxmoxmachinetemplates, aggressive scale-down profile, Cilium startup-taint; runbook Steps 4-7 and troubleshooting rows - inflate test pods 512Mi; decisions #16/#17; session note on the memory overcommit - docs/future-tasks.md convention (CLAUDE.md, README) with the namespace-per-cluster task - AGENTS.md; allowlist entries in .claude/settings.json Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
106 lines
6.7 KiB
Markdown
106 lines
6.7 KiB
Markdown
# 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 |
|
||
| Future tasks | `docs/future-tasks.md`, newest on top | work the owner defers: problem, options, cost, changes, owner-run commands |
|
||
| 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.
|