As I've left my job, I've decided to stop spending money on cloud providers for now. I think I've learnt enough from this project to be on my own.
Infinitely scalable, multi-cloud, secure and network-agnostic declarative Kubernetes configuration that focuses on stability and simplicity, while not compromising on modularity.
Sequel to bouquet that uses Talos Linux instead of k0s, OpenTofu for provisioning resources and many more improvements.
- When
tofu destroyis run, it won't destroy the Tailscale entries. This is because the entry is not made by OpenTofu itself, but comes from the node. See this issue for more information.
### Generating the image (Hetzner Cloud)
cd packer
cp secrets.hcl.example secrets.hcl
# Edit secrets.hcl and add your secrets
vim secrets.hcl
# Build the image
cd ..
just hcloud-image-build
### Deploying the cluster
cd tofu
mv secrets.tfvars.example secrets.tfvars
# Edit secrets.tfvars and add your secrets
vim secrets.tfvars
# Configure nodes (make sure to replace the Image IDs and URLs with the correct ones)
vim nodes.tfvars
cd ..
just deploy
### Deploying Kubernetes manifests
just deploy-manifests
### Do this after Cilium is up
just delete-ciliumjob
### Destroying the cluster
just destroyThe Kubernetes manifests are organized in the manifests/ directory and contain all the infrastructure components and applications. For detailed information about those, please refer to the manifests documentation.
-
iris
- Cloud: Hetzner Cloud
- Region: Nuremberg
- OS: Talos Linux
- Role: Agent node
- Machine: CAX21 (Ampere Altra) with 4 cores, 8GB RAM, 80GB storage
-
rose
- Cloud: Hetzner Cloud
- Region: Helsinki
- OS: Talos Linux
- Role: Control plane node
- Machine: CAX21 (Ampere Altra) with 4 cores, 8GB RAM, 80GB storage
-
lily
- Cloud: Hetzner Cloud
- Region: Falkenstein
- OS: Talos Linux
- Role: Agent node
- Machine: CAX21 (Ampere Altra) with 4 cores, 8GB RAM, 80GB storage
graph LR
classDef dashed stroke-dasharray: 5 5, stroke-width:1px
subgraph Core [core]
direction TB
core_rose["rose (control plane)"]
core_talos_api_up["Talos API (TCP 50000*)"]:::dashed
core_cilium_wireguard["Cilium WireGuard (internal mesh) (UDP 51871)"]
core_talos_api_down["Talos API (TCP 50000*)"]:::dashed
core_iris["iris (worker)"]
core_lily["lily (worker)"]
core_iris <--> core_talos_api_down
core_lily <--> core_talos_api_down
core_talos_api_down <--> core_cilium_wireguard
core_cilium_wireguard <--> core_talos_api_up
core_talos_api_up <--> core_rose
end
subgraph Access [access]
direction TB
ext_tailscale["Tailscale (siderolabs/tailscale)<br>External access and fallback (UDP 41641)"]
end
subgraph Storage [storage]
direction TB
storage_longhorn{"Longhorn"}:::dashed
%% Kept Longhorn as per original chart text
storage_s3["Backups (S3) (Oracle<br>MinIO Instance)"]
storage_longhorn -.-> storage_s3
end
%% Connections between subgraphs
Storage <--> Core
Access <--> Core
