Edge cluster
The edge cluster is the homelab's public-facing Kubernetes cluster. Single-node, single-purpose: terminate inbound traffic from the internet, then forward it to the production cluster over the NetBird mesh using PROXY-protocol-v2 to preserve the real client IP.
Stack
Versions
| Component | Version | Declared in |
|---|---|---|
| Talos Linux | v1.14.3 | talos/edge/topf.yaml |
| Kubernetes | v1.37.1 | talos/edge/topf.yaml |
| Flux | v2.9.6 | k8s/clusters/edge/flux-system/gotk-components.yaml |
These are the versions declared in Git. Flux updates itself as soon as its manifests merge; a Talos or Kubernetes bump only reaches the nodes with the next topf upgrade.
Layers at a glance
| Layer | What | Doc |
|---|---|---|
| Compute | 1× cx33 Hetzner instance (control-plane-1), nbg1 | foundation/hetzner |
| Cluster OS | Talos Linux, single-node config | foundation/talos |
| GitOps | Flux pulling from the same Gitea repo, separate clusters/edge/ path | foundation/flux |
| Network | Cilium (CNI + kube-proxy replacement) | platform/cilium |
| Ingress | Envoy Gateway terminating TLS; forwards to production via PROXY-protocol-v2 | platform/envoy-gateway · topics/envoy-gateway-proxy-protocol-v2 |
| Certs | cert-manager + ACME via cert-manager-webhook-all-inkl | platform/cert-manager |
| Database | CNPG (small, only for sidecar app state) | platform/cloudnative-pg |
| Inter-site | NetBird edge peer routes back to production over WireGuard | fabric/netbird |
Cluster machine
| Role | Name | Spec | Network |
|---|---|---|---|
| Control + worker | control-plane-1 | cx33, Talos image | Public IP + floating IP (edge-1); private 172.30.0.11/24 |
A single node is intentional — the edge cluster's blast radius is its own. If it dies, the production cluster carries on; only public traffic is interrupted.
Networking summary
| Plane | What |
|---|---|
| VPC | edge (172.30.0.0/16), subnet k8s (172.30.0.0/24 in eu-central) |
| Public IP | Floating IP edge-1 — survives instance replacement |
| Inter-site | NetBird edge network — the netbird-client pod joins as a plain mesh peer |
| Cross-network | edge_sidecar_envoy ↔ production public subnet for upstream |
Cloud firewalls are label-selected: talos-control, talos-internal, allow-http, allow-ssh (port 22 carries Git over SSH to Gitea, not a shell). See Hetzner for ports.
What runs here
- Public ingress — the Envoy Gateway that the world hits.
- TLS termination + ACME — cert-manager + the
all-inklwebhook (DNS-01). - The mesh peer — netbird-client, which keeps the node on the NetBird network so the gateway can reach production.
- Three public apps with their own domains — Aushang, Openbeehive and Seitenraum.
Two of those hold state on the node: Openbeehive and Seitenraum each run a single-instance CNPG database and keep uploads on local-path volumes. There is no Longhorn, no second node and no backup on this cluster, so that data lives exactly once. Everything else with persistent state belongs on production.
Reconciliation order
Flux applies the cluster as a set of Kustomizations from k8s/clusters/edge/. Most of the platform has no ordering at all; what is ordered funnels through infra-configs, the gate every app waits for.
9 platform Kustomizations and 4 apps. An arrow means "has to be ready before"; the 7 entries without an incoming arrow start as soon as Flux is running.
Lifecycle commands
# Render for review, diff against the node, apply (from talos/edge)
topf render
topf apply --dry-run
topf apply
# Talos upgrade: one reboot, so a public outage; a single node cannot drain
topf upgrade --drain=false
# Reconcile Flux
flux reconcile kustomization flux-system --kubeconfig ~/.kube/edge
# Provision / drift-check the underlying Hetzner resources
cd tofu/environment/edge && ./tofu.sh plan
Recovery
If the cx33 instance is lost:
tofu applyre-creates the instance with the same name + label set; cloud firewalls reattach automatically.topf apply --auto-bootstrappushes the Talos config and bootstraps etcd;topf upgrade --drain=falseafterwards installs the factory image.- Re-attach the floating IP if it didn't follow.
- Flux reconciles everything else from Git.
The cluster itself is back in the order of minutes, and so is public ingress. The data of Openbeehive and Seitenraum is not: with no backup target on edge, a lost server takes their databases and uploads with it. See Disaster recovery.
See also
- Foundation → Hetzner — provider details
- Foundation → Talos — OS configuration workflow
- Topics → Real client IPs across the chain — the PPv2 wiring this cluster anchors
- Cluster — talos — the bigger sister cluster