diff --git a/README.md b/README.md index 216026a..0897d70 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,13 @@ keeps running its other self-hosted services throughout — this installs as ordinary KVM/libvirt packages next to them, sized deliberately small (3 VMs, 2 vCPU/2GB RAM each), not a hypervisor OS taking over the box. +Two setup paths, sharing everything past the cluster itself: +- **`docs/QUICKSTART.md`** — one manually-created VM (`virt-install`, no + Terraform), fastest way to a real cluster to learn Flux/GitOps on. +- **`docs/SETUP.md`** — the full path, Terraform/OpenTofu provisioning all + 3 VMs. Currently the harder, unfinished track (provider schema issues) — + worth doing properly, but don't block on it. + ## The loop ``` diff --git a/docs/QUICKSTART.md b/docs/QUICKSTART.md new file mode 100644 index 0000000..8397160 --- /dev/null +++ b/docs/QUICKSTART.md @@ -0,0 +1,136 @@ +# Quickstart: manual cluster (no Terraform) + +Gets a real k3s cluster running today, by hand, so you can learn/practice +Flux and GitOps immediately instead of waiting on the Terraform/libvirt +provider work in `docs/SETUP.md` to be sorted out. One throwaway VM, created +directly with `virt-install` rather than the `dmacvicar/libvirt` Terraform +provider. When the Terraform track is ready, tear this down (last section) +and provision the "real" 3-node cluster properly instead. + +Shares steps 1–4 of `docs/SETUP.md` as prerequisites — do those first if you +haven't: +- Step 1: KVM/libvirt installed on the T630. +- Step 2: the unprivileged `k8s` user exists, with `~/.ssh/k3s_homelab` + generated. +- Step 3: `openssl rand -hex 32` isn't needed here (no agents joining, so no + cluster token) — skip it. +- Step 4: `cloud-demo` pushed to Forgejo, with the `flux-write` token + generated. + +Everything below runs as `k8s` on the T630 (`sudo -iu k8s`). + +## 1. Create the VM + +```sh +mkdir -p ~/vms +curl -L -o ~/vms/noble-base.img \ + https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img + +# a writable overlay on top of the base image, sized up to 20G +qemu-img create -f qcow2 -F qcow2 -b ~/vms/noble-base.img ~/vms/k3s-manual.qcow2 20G +``` + +Write the cloud-init user-data — paste in the contents of +`~/.ssh/k3s_homelab.pub` where marked: + +```sh +cat > ~/vms/k3s-manual-user-data.yaml <<'EOF' +#cloud-config +hostname: k3s-manual +manage_etc_hosts: true + +users: + - name: k3s + groups: sudo + shell: /bin/bash + sudo: ALL=(ALL) NOPASSWD:ALL + ssh_authorized_keys: + - PASTE ~/.ssh/k3s_homelab.pub CONTENTS HERE + +package_update: true +packages: + - curl + +runcmd: + - curl -sfL https://get.k3s.io | sh -s - server + - mkdir -p /home/k3s/.kube + - k3s kubectl config view --raw > /home/k3s/.kube/config + - chown -R k3s:k3s /home/k3s/.kube +EOF +``` + +This is a single, standalone server — no join token, no agents, no custom +network (uses libvirt's default NAT network + DHCP). A k3s server node +schedules workloads on itself by default, so this alone is a complete, +usable cluster. + +```sh +virt-install \ + --name k3s-manual \ + --memory 2048 \ + --vcpus 2 \ + --disk ~/vms/k3s-manual.qcow2 \ + --import \ + --os-variant ubuntu24.04 \ + --network network=default \ + --cloud-init user-data=~/vms/k3s-manual-user-data.yaml \ + --graphics none \ + --noautoconsole +``` + +## 2. Find its IP and get kubectl talking to it + +Give cloud-init ~2 minutes to finish installing k3s after the VM boots. + +```sh +virsh domifaddr k3s-manual # note the IP under the default network + +ssh k3s@ sudo cat /etc/rancher/k3s/k3s.yaml \ + | sed "s/127.0.0.1//" > ~/.kube/config-manual + +export KUBECONFIG=~/.kube/config-manual +kubectl get nodes # expect 1 Ready node +``` + +## 3. Bootstrap Flux against Forgejo + +Same repo, same token, same target path as the full guide would use — +nothing about this is cluster-specific: + +```sh +flux bootstrap git \ + --url=https://git.boglabob.com/codegit/cloud-demo \ + --branch=main \ + --path=clusters/homelab \ + --username=codegit \ + --password= \ + --token-auth \ + --kubeconfig ~/.kube/config-manual +``` + +## 4. Continue with the shared steps + +From here, `docs/SETUP.md` steps 8 onward apply exactly as written, +regardless of how the cluster was created — verifying the podinfo GitOps +loop, registering the Forgejo Actions runner, exposing apps through Caddy, +the Dashboard, remote kubectl access. Just use `~/.kube/config-manual` as +the kubeconfig throughout instead of the Terraform-provisioned one. + +## Tearing this down + +Once the Terraform track in `docs/SETUP.md` is ready and you `tofu apply` +the real 3-node cluster, remove this one: + +```sh +# as k8s +virsh destroy k3s-manual # stop it +virsh undefine k3s-manual --remove-all-storage # delete VM + its disk +rm ~/.kube/config-manual +rm -rf ~/vms +``` + +Nothing else needs cleaning up — Flux's state lived entirely inside that +VM's cluster and goes away with it. The Forgejo repo, deploy tokens, and +the Forgejo Actions runner registration are all cluster-independent and +carry over to the real cluster unchanged; just re-run `flux bootstrap` +against its kubeconfig once it's up. diff --git a/docs/SETUP.md b/docs/SETUP.md index f6fe203..b5e8e61 100644 --- a/docs/SETUP.md +++ b/docs/SETUP.md @@ -1,4 +1,13 @@ -# Setup walkthrough +# Setup walkthrough (full, Terraform-driven) + +This is the "do it properly" path — Terraform/OpenTofu provisioning all 3 +VMs via the `dmacvicar/libvirt` provider. It's also the one currently +blocked on getting that provider's HCL right (0.8.x vs 0.9.x schema — see +conversation history). If you want a real cluster to learn Flux/GitOps on +*right now* without waiting on that, see `docs/QUICKSTART.md` instead — a +single manually-created VM, no Terraform, with teardown instructions for +switching over once this track is sorted. Steps 1–4 below are shared +between both guides. Assumes: the T630 is an existing Debian box already running other self-hosted services — this project installs alongside those as ordinary