Files
cluster-autoscaler-with-capi/AGENTS.md
T
kacerrandClaude Opus 5.5 6ef55778ff lab1 workers on both PVE nodes: per-node template + MD, balanced CA
PVE is now the 2-node cluster homelab (pv1-1 + pv1-2), no shared storage:
- template 101 copied to pv1-2 as 9101; MDs lab1-workers-pv1-1 (max 6) and
  lab1-workers-pv1-2 (max 12), PMTs pinned with allowedNodes; pool .31-.50;
  lab1-workers renamed for symmetry (decision #18, #7 superseded)
- CA: balancing-label node.cluster.x-k8s.io/pool (+ pool label, capacity labels
  with os/arch, maxPods on the MDs), scan-interval 1m, v 2, default QPS (#19).
  Scale test: 16 pods -> 4 + 4 across both nodes.
- runbook, image-builder copy procedure, fixes tables, future task to report
  three CA clusterapi bugs upstream, lab facts, changelog, execution log

Plan: docs/plans/2026-09-29-2315-pv1-2-workers.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 11:07:17 +02:00

108 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AGENTS.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 cluster `homelab`: nodes `pv1-1` (192.168.0.8) and `pv1-2` (192.168.0.10); API
`https://192.168.0.8:8006`, token `capmox@pve!capi` (privsep 0). VMIDs are cluster-wide.
- 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), VMID 101 on `pv1-1` and copy
9101 on `pv1-2` (local-lvm can't clone cross-node → one worker MD per PVE node). 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
(`.Codex/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
`~/.Codex/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 Codex. `/ship` commits and pushes.