diff --git a/README.md b/README.md index 08d700d..27467c8 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ accidentally modify the cluster. - joins worker nodes such as Raspberry Pi and Pimox Debian arm64 nodes - configures Calico-compatible pod CIDR - configures containerd to pull from the in-cluster NodePort registry - - creates retained host directories under `/var/openebs/local` + - creates retained host directories under `/data/openebs/local` 3. `bootstrap/platform` - installs a minimal Calico deployment through the Tigera operator @@ -90,7 +90,7 @@ On the Debian host: minor, currently `v1.36` - SSH access to worker nodes - SSH access to the OCI edge host -- enough persistent storage for `/var/openebs/local` and `/var/lib/docker` +- enough persistent storage for `/data/openebs/local` and `/data/docker` After a clean Debian reinstall, bootstrap the host package set and desktop configuration first: @@ -143,7 +143,8 @@ cd ~/my-homelab-configs ``` The script first deploys external Gitea to the Raspberry Pi with Docker Compose -so Git stays outside the Kubernetes rebuild blast radius. It then detects the +under `/data/homelab-gitea`, backed by the Raspberry Pi SSD, so Git stays +outside the Kubernetes rebuild blast radius. It then detects the Pimox host at `192.168.100.80` in auto mode. When SSH, `qm`, and `vmbr0` are available, it applies `bootstrap/provisioning`, creates or reuses the Debian 13 arm64 template, creates or reuses one worker VM clone, discovers the guest IP @@ -156,9 +157,12 @@ applies the edge stack. Set `LAB_PIMOX_PIPELINE=false` to skip Pimox automation. Set `LAB_PIMOX_WORKER_COUNT=0` to create or refresh only the template. The pipeline keeps the template on its configured `local` storage, creates new worker VM -clones on `nvme_storage` by default, checks that the Pimox bridge already -exists, refuses `local` as worker clone storage, and refuses to edit Orange Pi -host networking. +clones on `nvme_storage` by default when that Pimox storage is available, +checks that the Pimox bridge already exists, refuses `local` as worker clone +storage, and refuses to edit Orange Pi host networking. The current stable bulk +storage path is the HP Debian laptop's `data-vg`, mounted under `/data`; do not +place worker root disks on the Orange Pi USB/NVMe path unless it has been +revalidated. `LAB_PIMOX_SKIP_WORKER_INDEXES` defaults to an empty value, so the pipeline owns worker index `1` and VMID `9010` when `LAB_PIMOX_WORKER_COUNT=1`. Set @@ -171,9 +175,9 @@ attaches to both WAN and LAN bridges. Run `./lab.sh openwrt` after `vmbr1` already exists on the Orange Pi. The pipeline downloads the OpenWrt ARM SystemReady EFI image, writes basic WAN/LAN/firewall config into the image, imports it as VM `9100`, attaches `vmbr0` as WAN and `vmbr1` as LAN, and stores -the VM disk on `nvme_storage`. It leaves the VM stopped and not enabled for -host boot by default. It does not use the Debian Kubernetes golden-node template -for OpenWrt. +the VM disk on the selected non-local Pimox storage. It leaves the VM stopped +and not enabled for host boot by default. It does not use the Debian Kubernetes +golden-node template for OpenWrt. The website and demos images default to `linux/arm64` because both deployments are pinned to the Raspberry Pi worker. Override with `WEBSITE_IMAGE_PLATFORMS` @@ -195,7 +199,7 @@ translation endpoints such as `save_idea.php`, `visitor_ideas.php`, Set `LAB_GITEA_DEPLOY=false` to skip the external Gitea deployment step when the Raspberry Pi service is already managed manually. The default Gitea target is -`jv@192.168.100.89`, install directory `/opt/homelab-gitea`, HTTP port `3000`, +`jv@192.168.100.89`, install directory `/data/homelab-gitea`, HTTP port `3000`, and SSH port `32222`. ## Validation @@ -212,10 +216,10 @@ kubectl -n website-production get pods -o wide kubectl -n demos-static get pods -o wide kubectl -n heimdall get pods -o wide -ssh jv@192.168.100.89 'cd /opt/homelab-gitea && sudo docker compose ps' +ssh jv@192.168.100.89 'cd /data/homelab-gitea && sudo docker compose ps' docker info --format '{{.DockerRootDir}}' -df -h / /var/openebs/local /var/lib/docker +df -h / /data /data/openebs/local /data/docker ``` The website should be reached through the configured public hostname, not the raw @@ -225,11 +229,15 @@ hostname. ## Adding Nodes For Pimox on Orange Pi 5 Plus, `./lab.sh up` can create the Debian 13 arm64 -template and worker VM clones automatically. Defaults are intentionally tied to -the observed host: Pimox SSH host `192.168.100.80`, bridge `vmbr0`, template VMID -`9000` on `local` storage, two 4 GiB worker VMs starting at VMID `9010`, worker -clone storage `nvme_storage`, and no CPU affinity because this Pimox is pinned -to Debian Bullseye. Details and override variables are in +template and worker VM clones automatically when the Orange Pi storage path is +healthy. Defaults are intentionally tied to the observed host: Pimox SSH host +`192.168.100.80`, bridge `vmbr0`, template VMID `9000` on `local` storage, two +4 GiB worker VMs starting at VMID `9010`, worker clone storage `nvme_storage`, +and no CPU affinity because this Pimox is pinned to Debian Bullseye. The NVMe +that was previously attached to the Orange Pi now belongs to the HP Debian +laptop as LVM volume group `data-vg`, so treat Orange Pi VM storage as optional +until a stable Pimox-backed datastore is configured. Details and override +variables are in `bootstrap/provisioning/README.md`. Worker indexes are stable. Index `1` maps to VMID `9010`, node name @@ -281,7 +289,8 @@ duplicate those PV manifests when you want storage on another node. - `homelab.dev/node-role=edge-app`, `homelab.dev/storage=local`, and `homelab.dev/workload-class=edge` on the Raspberry Pi worker - `homelab.dev/node-role=app`, `homelab.dev/storage=nvme`, and - `homelab.dev/workload-class=platform` on automated Pimox worker clones + `homelab.dev/workload-class=platform` on automated Pimox worker clones when + those workers are enabled Override `control_plane_node_labels`, `worker_node_labels`, `LAB_RASPBERRY_NODE_LABELS_JSON`, or `LAB_PIMOX_WORKER_NODE_LABELS_JSON` when @@ -517,15 +526,17 @@ through dedicated Traefik hostnames instead of a Tailscale sidecar. ## Storage OpenEBS provides the platform storage provisioner. Stateful Kubernetes apps use -retained local PV paths such as `/var/openebs/local/registry`; these paths are +retained local PV paths such as `/data/openebs/local/registry`; these paths are intentionally outside kubeadm reset paths so data can survive cluster destroy/create cycles. Those critical volumes are declared explicitly as retained local PVs so a rebuilt cluster binds back to the same host paths instead of creating fresh directories. -For the current lab, `/var/openebs/local` and `/var/lib/docker` are expected to -live on larger storage than the root filesystem. This keeps retained PVs, -container layers, Buildx state, and image caches from filling `/`. +For the current lab, the HP Debian laptop's NVMe is managed by LVM volume group +`data-vg` and mounted under `/data`. OpenEBS retained hostpath data lives under +`/data/openebs/local`, and Docker data should live under `/data/docker` where +the host is configured that way. This keeps retained PVs, container layers, +Buildx state, and image caches from filling `/`. ## Gitea @@ -534,9 +545,9 @@ always-on Docker Compose service from `infra/gitea/docker-compose.yml`, not as a Kubernetes workload. This keeps Git available when the Kubernetes cluster is destroyed and rebuilt. -The default data path is `/opt/homelab-gitea/data` on the Raspberry Pi SD card. -That is acceptable for the current temporary setup; move -`LAB_GITEA_INSTALL_DIR` to an SSD mount when the SSD is added. +The default data path is `/data/homelab-gitea/data` on the Raspberry Pi SSD. +The Raspberry Pi Docker root is also expected to live on the SSD-backed `/data` +mount rather than the SD card. Public source browsing stays available through `https://lab2025.duckdns.org/git/`. Registration is disabled and anonymous users @@ -671,7 +682,7 @@ for platform or provisioning updates. `./lab.sh nuke` resets kubeadm, containerd runtime state, CNI files, Calico links, iptables rules, and local OpenTofu state. It does not delete retained data -under `/var/openebs/local`. +under `/data/openebs/local`. For multi-node labs, set `WORKER_SSH_TARGETS` to a space-separated list of SSH targets. It defaults to an empty string so the Raspberry Pi Gitea host is not diff --git a/apps/container-registry/registry-storage.yaml b/apps/container-registry/registry-storage.yaml index f6e222a..3c5c44b 100644 --- a/apps/container-registry/registry-storage.yaml +++ b/apps/container-registry/registry-storage.yaml @@ -11,7 +11,7 @@ spec: persistentVolumeReclaimPolicy: Retain storageClassName: openebs-hostpath-retain local: - path: /var/openebs/local/registry + path: /data/openebs/local/registry nodeAffinity: required: nodeSelectorTerms: diff --git a/apps/website/blog.php b/apps/website/blog.php index bca35b7..0a137ea 100644 --- a/apps/website/blog.php +++ b/apps/website/blog.php @@ -443,7 +443,7 @@ function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $so Orange Pi 5 Plus Pimox pimox-worker app nodes - workers on nvme_storage + template VMs; storage optional Argo CD, Kyverno, website, n8n Redis cache and app workloads diff --git a/apps/website/lang/en.php b/apps/website/lang/en.php index db7959d..7044076 100644 --- a/apps/website/lang/en.php +++ b/apps/website/lang/en.php @@ -126,14 +126,14 @@ return [ 'blog_q7' => 'Can the current cluster actually handle all that, or are we about to smoke the Pi?', 'blog_a7' => 'The Pi survives because the demos are intentionally local-first and now ship as a separate static artifact. The website pod stays a portfolio shell, the demos-static pod serves static bundles, and the user browser does the expensive work. If I later ship real ONNX object detection, Transformers.js, or full video transcoding models, those must lazy-load in the browser or move to a beefier node. The Raspberry Pi is brave, but it is not a GPU wearing a tiny hat.', 'blog_q8' => 'So the lab can now build its own worker nodes?', - 'blog_a8' => 'Yes, and now with fewer crossed fingers. Debian runs a provisioning layer with dnsmasq, nginx, PXE boot files, GRUB, and a Debian 13 arm64 preseed. OpenTofu talks to Pimox through qm, creates VM 9000 on local storage, boots it from the network, installs the OS, runs golden-node prep, disables swap, verifies cgroups, installs containerd and kubeadm tooling, then seals it as a template. Worker clones are idempotent by VMID and now land on nvme_storage, so local storage stays reserved for the template.', + 'blog_a8' => 'Yes, and now with fewer crossed fingers. Debian runs a provisioning layer with dnsmasq, nginx, PXE boot files, GRUB, and a Debian 13 arm64 preseed. OpenTofu talks to Pimox through qm, creates VM 9000 on local storage, boots it from the network, installs the OS, runs golden-node prep, disables swap, verifies cgroups, installs containerd and kubeadm tooling, then seals it as a template. Worker clones are idempotent by VMID when a stable non-local Pimox datastore is available.', 'blog_q9' => 'And OpenWrt is joining the story too?', 'blog_a9' => 'Only as a simple firewall, not as a networking science project. The pipeline can create an opt-in OpenWrt ARM SystemReady VM, attach vmbr0 as WAN and vmbr1 as LAN, and configure the LAN side without rewriting Orange Pi host networking. DHCP stays optional, and VLANs wait until there is a managed switch and a local test window.', 'blog_q10' => 'What changed on the observability and scheduling side?', 'blog_a10' => 'Monitoring moved from "someday" to "running," and scheduling moved from "whatever fits" to explicit worker placement. Prometheus Stack, Grafana, Loki, Promtail, node-exporter, and kube-state-metrics give the lab useful signals; the next useful step is choosing the few alerts that would actually wake me up for the right reasons.', 'blog_stack_title' => 'Technologies and why they are here', 'blog_stack_1' => 'Debian Linux is the steady adult in the room: control plane host, deployment workstation, PXE/preseed server, and the place where OpenTofu, Docker, kubeadm, and the scripts do their thing.', - 'blog_stack_2' => 'Raspberry Pi keeps the external Gitea service close to the lab, while Pimox on the Orange Pi 5 Plus provides the app-worker pool. The Debian template stays on local storage and Kubernetes worker clones go to nvme_storage.', + 'blog_stack_2' => 'Raspberry Pi keeps the external Gitea service close to the lab on SSD-backed /data, while Pimox on the Orange Pi 5 Plus can provide an app-worker pool when its VM storage is stable. The HP Debian laptop now owns the NVMe-backed data-vg storage for Kubernetes data paths.', 'blog_stack_3' => 'OpenTofu makes the cluster, platform, apps, edge, and provisioning layers repeatable, because "I swear I remember the command" is not a disaster recovery strategy.', 'blog_stack_4' => 'Calico handles pod networking, and OpenEBS hostpath storage keeps the important data around after rebuilds, because deleting everything by accident is only funny once.', 'blog_stack_5' => 'Argo CD is the GitOps referee and now runs on app workers: manifests live in Git, the cluster follows along, and manual drift gets side-eyed back into place.', @@ -146,7 +146,7 @@ return [ 'blog_stack_12' => 'The Pimox worker pipeline uses qm over SSH to create an OVMF/virtio-scsi Debian 13 arm64 VM, wait for qemu-guest-agent, seal it, and convert VM 9000 into a reusable template on local storage.', 'blog_stack_13' => 'The golden image bakes in Kubernetes prerequisites: swap disabled, cgroup boot options checked, kernel modules loaded, containerd configured for systemd cgroups, kubeadm/kubelet/kubectl installed, and qemu-guest-agent enabled.', 'blog_stack_14' => 'Worker clone automation is count-based and idempotent: LAB_PIMOX_WORKER_COUNT=1 means ensure VM 9010 exists, not create a fresh worker on every run. New workers are refused if the target storage is local.', - 'blog_stack_15' => 'OpenWrt is handled separately from the Debian golden-node template. The lab downloads the upstream ARM SystemReady EFI image, imports it as VM 9050 on nvme_storage, and keeps it disabled unless LAB_OPENWRT_VM=true is set.', + 'blog_stack_15' => 'OpenWrt is handled separately from the Debian golden-node template. The lab downloads the upstream ARM SystemReady EFI image, imports it onto selected non-local Pimox storage, and keeps it disabled unless LAB_OPENWRT_VM=true is set.', 'blog_stack_16' => 'The monitoring layer now includes Prometheus Stack, Grafana, Loki, Promtail, node-exporter, and kube-state-metrics, with placement guardrails so platform add-ons stop defaulting to the control plane.', 'blog_stack_17' => 'The portfolio website keeps Apache at the core, runs PHP through PHP-FPM with OPcache, pre-renders read-heavy pages into static HTML during the image build, and leaves PHP for write and translation endpoints.', 'blog_stack_18' => 'The supply-chain path now uses BuildKit SBOM attestations, Cosign signatures, a cluster-published public key, and an audit-first Kyverno ImageValidatingPolicy that can be promoted to deny unsigned local-registry pods.', @@ -169,7 +169,7 @@ return [ 'blog_activity_8' => 'Changed Gitea backups to dump from the Raspberry Pi Docker container and store archives on the Debian host.', 'blog_activity_9' => 'Validated the full main-branch deployment path: fetch main, apply OpenTofu layers, build and push arm64 images, refresh Argo CD, and confirm the runner completes successfully.', 'blog_activity_10' => 'Built the Debian 13 arm64 Pimox template end to end with PXE, preseed, qemu-guest-agent discovery, cgroup validation, swap disabled, and a final seal step.', - 'blog_activity_11' => 'Added NVMe-backed Pimox worker clone automation so VM 9000 stays on local storage while worker nodes are created on nvme_storage.', + 'blog_activity_11' => 'Added Pimox worker clone automation so VM 9000 stays on local storage while worker nodes use a selected non-local datastore.', 'blog_activity_12' => 'Added an opt-in OpenWrt VM path for a simple firewall between vmbr0 and vmbr1, with guardrails that avoid Orange Pi host networking changes.', 'blog_activity_13' => 'Installed the monitoring stack and moved platform add-ons such as Argo CD, Kyverno, and prometheus-stack work toward app-worker placement instead of treating the control plane as spare capacity.', 'blog_activity_14' => 'Reworked the website image to keep Apache as the web server while moving PHP execution to PHP-FPM, enabling OPcache, and validating the runtime through Gitea Actions instead of local image builds.', @@ -188,7 +188,7 @@ return [ 'blog_todo_8' => 'Turn the installed observability stack into useful operations views: a few high-signal dashboards, alerts for node health, storage pressure, certificate expiry, and failed app syncs.', 'blog_todo_9' => 'Schedule backup restore drills for external Gitea and OpenEBS volumes, then write the exact restore runbook.', 'blog_todo_10' => 'Tighten TLS, SSH, and token rotation around the OCI edge, Gitea, registry, and runner credentials.', - 'blog_todo_11' => 'Document the new storage split: local for the Pimox template, nvme_storage for VM workers, OpenEBS for Kubernetes app data, and backup targets for anything that must survive a rebuild.', + 'blog_todo_11' => 'Document the new storage split: local for the Pimox template, data-vg on the HP Debian laptop for Kubernetes app data, Raspberry Pi SSD /data for Gitea and Docker, and backup targets for anything that must survive a rebuild.', 'blog_todo_12' => 'Move sensitive app configuration into Sealed Secrets, External Secrets, or another explicit secret-management path.', 'blog_todo_13' => 'After the new disk has breathing room, clone the first Pimox worker from VM 9000, join it with kubeadm, and verify labels, taints, CNI, storage, and workload scheduling.', 'blog_todo_14' => 'Test the OpenWrt VM in a maintenance window before making it a gateway: confirm WAN, LAN, rollback access, DHCP settings, and that Pimox remains reachable.', diff --git a/apps/website/lang/nah.php b/apps/website/lang/nah.php index bd8b5cc..15cbc27 100644 --- a/apps/website/lang/nah.php +++ b/apps/website/lang/nah.php @@ -126,14 +126,14 @@ return [ 'blog_q7' => 'Current cluster huel quipia nochi inin, o tiquchichinos Pi?', 'blog_a7' => 'Pi survives pampa demos cateh intentionally local-first ihuan now ship as separate static artifact. Website pod mocahua portfolio shell, demos-static pod serves static bundles, ihuan browser quichihua expensive work. Tla later onicship real ONNX object detection, Transformers.js, o full video transcoding models, monequi lazy-load ipan browser o yasque beefier node.', 'blog_q8' => 'Axcan lab huel quichihua own worker nodes?', - 'blog_a8' => 'Quena, ihuan axcan ika fewer crossed fingers. Debian quipia provisioning layer ika dnsmasq, nginx, PXE boot files, GRUB, ihuan Debian 13 arm64 preseed. OpenTofu notza Pimox through qm, quichihua VM 9000 ipan local storage, quiboota from network, quinstala OS, quichihua golden-node prep, disables swap, verifies cgroups, installs containerd ihuan kubeadm tooling, then seals it as template. Worker clones cateh idempotent by VMID ihuan now land on nvme_storage.', + 'blog_a8' => 'Quena, ihuan axcan ika fewer crossed fingers. Debian quipia provisioning layer ika dnsmasq, nginx, PXE boot files, GRUB, ihuan Debian 13 arm64 preseed. OpenTofu notza Pimox through qm, quichihua VM 9000 ipan local storage, quiboota from network, quinstala OS, quichihua golden-node prep, disables swap, verifies cgroups, installs containerd ihuan kubeadm tooling, then seals it as template. Worker clones cateh idempotent by VMID tla onca stable non-local Pimox datastore.', 'blog_q9' => 'Ihuan OpenWrt no quisa nican?', 'blog_a9' => 'Zan simple firewall, ahmo networking science project. Pipeline huel quichihua opt-in OpenWrt ARM SystemReady VM, attach vmbr0 quen WAN ihuan vmbr1 quen LAN, ihuan configure LAN side ahmo rewriting Orange Pi host networking. DHCP stays optional, VLANs wait until onca managed switch ihuan local test window.', 'blog_q10' => 'Tlein omopatla ipan observability ihuan scheduling side?', 'blog_a10' => 'Monitoring moved de "someday" to "running," ihuan scheduling moved de "whatever fits" to explicit worker placement. Prometheus Stack, Grafana, Loki, Promtail, node-exporter, ihuan kube-state-metrics quimaca useful signals; next step quitosnequi elegir few alerts in melahuac nechixitisque para right reasons.', 'blog_stack_title' => 'Tlamantli ihuan tleica nemi nican', 'blog_stack_1' => 'Debian Linux quimaca steady adult in room: control plane host, deployment workstation, PXE/preseed server, ihuan canin OpenTofu, Docker, kubeadm, ihuan scripts quichihua tequitl.', - 'blog_stack_2' => 'Raspberry Pi keeps external Gitea service close to lab, while Pimox ipan Orange Pi 5 Plus provides app-worker pool. Debian template mocahua ipan local storage ihuan Kubernetes worker clones yahui ipan nvme_storage.', + 'blog_stack_2' => 'Raspberry Pi keeps external Gitea service close to lab ipan SSD-backed /data, while Pimox ipan Orange Pi 5 Plus huel quimaca app-worker pool tla VM storage stable. HP Debian laptop axcan quipia NVMe-backed data-vg storage para Kubernetes data paths.', 'blog_stack_3' => 'OpenTofu quichihua cluster, platform, apps, edge, ihuan provisioning layers repeatable, pampa "I swear I remember the command" amo disaster recovery strategy.', 'blog_stack_4' => 'Calico handles pod networking, ihuan OpenEBS hostpath storage keeps important data after rebuilds, pampa deleting everything by accident zan funny once.', 'blog_stack_5' => 'Argo CD quimaca GitOps referee ihuan now runs on app workers: manifests cateh ipan Git, cluster follows along, ihuan manual drift gets side-eyed back into place.', @@ -146,7 +146,7 @@ return [ 'blog_stack_12' => 'Pimox worker pipeline uses qm over SSH para create OVMF/virtio-scsi Debian 13 arm64 VM, wait for qemu-guest-agent, seal it, ihuan convert VM 9000 into reusable template on local storage.', 'blog_stack_13' => 'Golden image bakes in Kubernetes prerequisites: swap disabled, cgroup boot options checked, kernel modules loaded, containerd configured for systemd cgroups, kubeadm/kubelet/kubectl installed, ihuan qemu-guest-agent enabled.', 'blog_stack_14' => 'Worker clone automation is count-based ihuan idempotent: LAB_PIMOX_WORKER_COUNT=1 quitosnequi ensure VM 9010 exists, amo create fresh worker every run. New workers refused tla target storage is local.', - 'blog_stack_15' => 'OpenWrt handled separately from Debian golden-node template. Lab downloads upstream ARM SystemReady EFI image, imports it as VM 9050 on nvme_storage, ihuan keeps disabled unless LAB_OPENWRT_VM=true.', + 'blog_stack_15' => 'OpenWrt handled separately from Debian golden-node template. Lab downloads upstream ARM SystemReady EFI image, imports it onto selected non-local Pimox storage, ihuan keeps disabled unless LAB_OPENWRT_VM=true.', 'blog_stack_16' => 'Monitoring layer axcan includes Prometheus Stack, Grafana, Loki, Promtail, node-exporter, ihuan kube-state-metrics, ika placement guardrails para platform add-ons ma amo default to control plane.', 'blog_stack_17' => 'Portfolio website keeps Apache at core, runs PHP through PHP-FPM ika OPcache, pre-renders read-heavy pages into static HTML during image build, ihuan leaves PHP para write ihuan translation endpoints.', 'blog_stack_18' => 'Supply-chain path axcan uses BuildKit SBOM attestations, Cosign signatures, public key ipan cluster, ihuan audit-first Kyverno ImageValidatingPolicy in huel mopromote para deny unsigned local-registry pods.', @@ -169,7 +169,7 @@ return [ 'blog_activity_8' => 'Changed Gitea backups to dump from Raspberry Pi Docker container ihuan store archives on Debian host.', 'blog_activity_9' => 'Validated full main-branch deployment path: fetch main, apply OpenTofu layers, build ihuan push arm64 images, refresh Argo CD, ihuan confirm runner completes successfully.', 'blog_activity_10' => 'Built Debian 13 arm64 Pimox template end to end ika PXE, preseed, qemu-guest-agent discovery, cgroup validation, swap disabled, ihuan final seal step.', - 'blog_activity_11' => 'Added NVMe-backed Pimox worker clone automation para VM 9000 ma mocahua ipan local storage mientras worker nodes mochihuah ipan nvme_storage.', + 'blog_activity_11' => 'Added Pimox worker clone automation para VM 9000 ma mocahua ipan local storage mientras worker nodes use selected non-local datastore.', 'blog_activity_12' => 'Added opt-in OpenWrt VM path para simple firewall between vmbr0 ihuan vmbr1, ika guardrails in avoid Orange Pi host networking changes.', 'blog_activity_13' => 'Installed monitoring stack ihuan moved platform add-ons such as Argo CD, Kyverno, ihuan prometheus-stack toward app-worker placement instead of treating control plane as spare capacity.', 'blog_activity_14' => 'Reworked website image para Apache ma mocahua web server while PHP runs through PHP-FPM, OPcache enabled, ihuan runtime validated through Gitea Actions instead of local image builds.', @@ -188,7 +188,7 @@ return [ 'blog_todo_8' => 'Turn installed observability stack into useful operations views: few high-signal dashboards, alerts para node health, storage pressure, certificate expiry, ihuan failed app syncs.', 'blog_todo_9' => 'Schedule backup restore drills para external Gitea ihuan OpenEBS volumes, then write exact restore runbook.', 'blog_todo_10' => 'Tighten TLS, SSH, ihuan token rotation around OCI edge, Gitea, registry, ihuan runner credentials.', - 'blog_todo_11' => 'Document new storage split: local para Pimox template, nvme_storage para VM workers, OpenEBS para Kubernetes app data, ihuan backup targets para tlein must survive rebuild.', + 'blog_todo_11' => 'Document new storage split: local para Pimox template, data-vg ipan HP Debian laptop para Kubernetes app data, Raspberry Pi SSD /data para Gitea ihuan Docker, ihuan backup targets para tlein must survive rebuild.', 'blog_todo_12' => 'Move sensitive app configuration into Sealed Secrets, External Secrets, o occe explicit secret-management path.', 'blog_todo_13' => 'After new disk has breathing room, clone first Pimox worker from VM 9000, join it ika kubeadm, ihuan verify labels, taints, CNI, storage, ihuan workload scheduling.', 'blog_todo_14' => 'Test OpenWrt VM ipan maintenance window before making it gateway: confirm WAN, LAN, rollback access, DHCP settings, ihuan Pimox remains reachable.', diff --git a/bootstrap/cluster/variables.tf b/bootstrap/cluster/variables.tf index 8b7b3f5..970a78d 100644 --- a/bootstrap/cluster/variables.tf +++ b/bootstrap/cluster/variables.tf @@ -7,7 +7,7 @@ variable "control_plane_node_labels" { type = map(string) default = { "homelab.dev/node-role" = "control-plane" - "homelab.dev/storage" = "local" + "homelab.dev/storage" = "data-vg" "homelab.dev/workload-class" = "control-plane" } } @@ -48,7 +48,7 @@ variable "node_dns_servers" { variable "persistent_volume_dirs" { type = list(string) default = [ - "/var/openebs/local/registry", + "/data/openebs/local/registry", ] } diff --git a/bootstrap/host/group_vars/debian_pc.yml b/bootstrap/host/group_vars/debian_pc.yml index edf50f0..33ea59b 100644 --- a/bootstrap/host/group_vars/debian_pc.yml +++ b/bootstrap/host/group_vars/debian_pc.yml @@ -5,8 +5,8 @@ debian_pc_kubernetes_minor_version: v1.36 debian_pc_enable_passwordless_sudo: true debian_pc_persistent_directories: - - /var/openebs/local/registry - - /var/lib/docker + - /data/openebs/local/registry + - /data/docker - "/home/{{ debian_pc_user }}/git-server" - "/home/{{ debian_pc_user }}/backups/gitea" - "/home/{{ debian_pc_user }}/backups/gitea-restore-drills" @@ -250,4 +250,3 @@ debian_pc_apt_manual_packages: debian_pc_config_archive: "" debian_pc_restore_configs: true - diff --git a/bootstrap/platform/variables.tf b/bootstrap/platform/variables.tf index f64501a..a937034 100644 --- a/bootstrap/platform/variables.tf +++ b/bootstrap/platform/variables.tf @@ -56,7 +56,7 @@ variable "openebs" { version = "4.3.3" namespace = "openebs" retain_storage_class = "openebs-hostpath-retain" - base_path = "/var/openebs/local" + base_path = "/data/openebs/local" } } diff --git a/bootstrap/provisioning/README.md b/bootstrap/provisioning/README.md index 0ecb02c..29cc1cd 100644 --- a/bootstrap/provisioning/README.md +++ b/bootstrap/provisioning/README.md @@ -113,9 +113,12 @@ networking, virtio-scsi disk, `vmbr0`, `local` template storage, 1 socket with defaults to one worker, VMID `9010`, name `pimox-worker-01`, deterministic locally administered MAC address, 1 socket with 2 cores, 4 GiB RAM, `nvme_storage` clone storage, and qemu-guest-agent IP -discovery. New workers are full clones created with -`qm clone --storage`, so the template can remain on `local` while worker disks -land on the NVMe thin pool. Set `LAB_PIMOX_WORKER_REPLACE_EXISTING=true` to +discovery when that Pimox storage is available. New workers are full clones +created with `qm clone --storage`, so the template can remain on `local` while +worker disks land on a non-local Pimox datastore. The USB/NVMe device that was +previously attached to the Orange Pi now backs the HP Debian laptop's `data-vg`, +so revalidate or replace the Pimox datastore before creating worker root disks +there again. Set `LAB_PIMOX_WORKER_REPLACE_EXISTING=true` to destroy and recreate existing worker VMs from the current template. The pipeline refuses `LAB_PIMOX_WORKER_STORAGE=local` so only the template VM lives on local storage. @@ -136,7 +139,7 @@ LAB_PIMOX_WORKER_COUNT=0 ./lab.sh up LAB_PIMOX_WORKER_COUNT=2 ./lab.sh up LAB_PIMOX_SKIP_WORKER_INDEXES=1 LAB_PIMOX_WORKER_COUNT=2 ./lab.sh up LAB_PIMOX_WORKER_BASE_VMID=9020 ./lab.sh up -LAB_PIMOX_WORKER_STORAGE=nvme_storage ./lab.sh up +LAB_PIMOX_WORKER_STORAGE= ./lab.sh up LAB_PIMOX_WORKER_REPLACE_EXISTING=true ./lab.sh up LAB_PIMOX_HOST=192.168.100.80 LAB_PIMOX_BRIDGE=vmbr0 ./lab.sh up ``` @@ -159,7 +162,7 @@ Defaults: - VMID `9100` - VM name `openwrt-firewall` -- disk storage `nvme_storage` +- disk storage `nvme_storage` when that Pimox storage is available - WAN bridge `vmbr0` - LAN bridge `vmbr1` - LAN address `192.168.50.1/24` @@ -172,7 +175,7 @@ Useful overrides: ```bash LAB_OPENWRT_VMID=9100 -LAB_OPENWRT_STORAGE=nvme_storage +LAB_OPENWRT_STORAGE= LAB_OPENWRT_WAN_BRIDGE=vmbr0 LAB_OPENWRT_LAN_BRIDGE=vmbr1 LAB_OPENWRT_LAN_IP=192.168.50.1 @@ -184,6 +187,6 @@ LAB_OPENWRT_VERSION=24.10.6 LAB_OPENWRT_IMAGE_URL=https://downloads.openwrt.org/releases/24.10.6/targets/armsr/armv8/openwrt-24.10.6-armsr-armv8-generic-ext4-combined-efi.img.gz ``` -The pipeline validates `vmbr0`, `vmbr1`, and `nvme_storage` on the Pimox host. +The pipeline validates `vmbr0`, `vmbr1`, and the selected storage on the Pimox host. It refuses `local` as OpenWrt storage and refuses to create or modify host network bridges. diff --git a/infra/gitea/README.md b/infra/gitea/README.md index 8c19a09..2e0a55e 100644 --- a/infra/gitea/README.md +++ b/infra/gitea/README.md @@ -4,14 +4,14 @@ Gitea is bootstrap infrastructure, not a Kubernetes workload. `lab.sh deploy-gitea` copies `docker-compose.yml` to the Raspberry Pi and runs Gitea as an always-on Docker Compose service. The current default stores data on -the Pi SD card under `/opt/homelab-gitea/data`; move -`LAB_GITEA_INSTALL_DIR` to an SSD mount when the SSD is added. +the Raspberry Pi SSD under `/data/homelab-gitea/data`; the Pi Docker root is +also expected to live on the SSD-backed `/data` mount. Defaults: - host: `192.168.100.89` - user: `jv` -- install dir: `/opt/homelab-gitea` +- install dir: `/data/homelab-gitea` - HTTP port: `3000` - SSH port: `32222` - public root URL: `https://lab2025.duckdns.org/git/` diff --git a/lab.sh b/lab.sh index 83c94b9..3ec60d3 100755 --- a/lab.sh +++ b/lab.sh @@ -2037,7 +2037,7 @@ deploy_gitea() { local gitea_host="${LAB_GITEA_HOST:-${LAB_RASPBERRY_HOST:-192.168.100.89}}" local gitea_user="${LAB_GITEA_USER:-${LAB_RASPBERRY_USER:-jv}}" local gitea_key="${LAB_GITEA_SSH_KEY_PATH:-${LAB_RASPBERRY_SSH_KEY_PATH:-/home/jv/.ssh/id_ed25519}}" - local install_dir="${LAB_GITEA_INSTALL_DIR:-/opt/homelab-gitea}" + local install_dir="${LAB_GITEA_INSTALL_DIR:-/data/homelab-gitea}" local image="${LAB_GITEA_IMAGE:-gitea/gitea:1.21.7}" local http_port="${LAB_GITEA_HTTP_PORT:-3000}" local ssh_port="${LAB_GITEA_SSH_PORT:-32222}" @@ -3308,7 +3308,7 @@ EOF rm -f "${REPO_ROOT}"/bootstrap/edge/.terraform.tfstate.lock.info rm -rf "${REPO_ROOT}"/bootstrap/edge/.terraform/ - echo "Destruction complete. Retained data under /var/openebs/local was left intact." + echo "Destruction complete. Retained data under /data/openebs/local was left intact." } case "${1:-}" in