Skip to content
pwydePublic

About

Homelab deployed with Talos Linux; managed with Flux, Renovate, and GitHub Actions πŸ€–

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Latest commit

Β 

History

5,602 Commits

Folders and files

Repository files navigation

πŸš€ My Home Operations Repository πŸ’€

... a GitOps-driven homelab managed with Flux, Renovate, and GitHub Actions πŸ€–

TalosΒ  KubernetesΒ  FluxΒ  Pull RequestsΒ  Renovate

AgeΒ  UptimeΒ  NodesΒ  PodsΒ  CPUΒ  MemoryΒ  Alerts


✏ Overview

This mono repository serves as the single source of truth for my home(lab) infrastructure and single-node Kubernetes cluster, following Infrastructure as Code (IaC) and GitOps best practices.

The cluster is automated with the following tools:

  • Talos Linux β€” Immutable, API-driven OS that runs nothing but Kubernetes.
  • Flux β€” Continuous reconciliation of cluster state against this repository.
  • Renovate β€” Automated dependency updates across the entire cluster.
  • GitHub Actions β€” Validation and automation on every commit.

This ensures an immutable and reproducible environment, with changes applied automatically based on repository state.


πŸ“¦ Repository Structure

πŸ“ bootstrap     # One-time cluster bootstrap (helmfile + kustomize)
πŸ“ docker        # Services running via Docker on NAS
πŸ“ kubernetes    # Everything Flux reconciles
β”œβ”€πŸ“ apps        # Workloads, grouped by namespace
β”œβ”€πŸ“ components  # Reusable Kustomize components (alerts, volsync, etc.)
β””β”€πŸ“ flux        # Flux system configuration
πŸ“ talos         # Talos machine configs and per-node overrides

🎑 Cluster

The cluster operates on Talos Linux, an immutable and ephemeral Linux distribution tailored for Kubernetes, deployed on bare-metal Minisforum MS-A2 workstation. Persistent storage is provided by OpenEBS with bulk media offloaded to TrueNAS SCALE over NFS.

Core Components

  • actions-runner-controller β€” Self-hosted GitHub runners for CI/CD workflows.
  • cert-manager β€” Automated SSL certificate management and provisioning.
  • cilium β€” High-performance container networking powered by eBPF.
  • cloudflared β€” Secure tunnel providing Cloudflare-protected access to cluster services.
  • envoy-gateway β€” Modern ingress controller for cluster traffic management.
  • external-dns β€” Automated DNS record synchronization for ingress resources.
  • external-secrets β€” Kubernetes secrets management integrated with 1Password Connect.
  • openebs β€” Persistent container native storage with local Hostpath and ZFS.
  • spegel β€” Stateless cluster-local OCI registry mirror for improved performance.
  • volsync β€” Advanced backup and recovery solution for persistent volume claims.

πŸͺ„ GitOps

Flux continuously monitors the Kubernetes clusters defined in the kubernetes directory and reconciles their state with the configuration stored in the Git repository.

To deploy applications, Flux recursively scans the kubernetes/apps directory and identifies the highest-level kustomization.yaml file within each application directory. Each discovered kustomization.yaml is then applied together with all resources it references.

In most cases, these top-level kustomization.yaml files contain a namespace definition and one or more Flux Kustomization resources (ks.yaml). These Flux Kustomizations manage the deployment of application-specific resources, such as HelmRelease objects and any additional Kubernetes manifests required by the application.

Renovate monitors the entire repository for dependency updates. When updates are available, Renovate automatically creates a pull request. Once a pull request is reviewed and merged, Flux reconciles the updated repository state and applies the corresponding changes to the Kubernetes clusters.

Deployment Workflow

The diagram below provides a high-level overview of how Flux manages application deployments and dependency ordering.

In most scenarios, a HelmRelease depends on one or more other HelmRelease resources. In other cases, a Kustomization depends on one or more other Kustomization resources. Less commonly, an application may require a combination of both HelmRelease and Kustomization dependencies.

Flux evaluates these dependencies and ensures that resources are deployed and upgraded in the correct order. A dependent resource will not be reconciled until all of its declared dependencies have been successfully deployed and are reporting a healthy state.

In the example below, the victoria-logs-collector application depends on victoria-logs, which in turn depends on openebs. As a result, openebs must be successfully deployed and healthy before victoria-logs is installed or upgraded. Likewise, victoria-logs must be healthy before victoria-logs-collector can be deployed or updated.

graph LR
    classDef kustom fill:#43A047,stroke:#2E7D32,stroke-width:3px,color:#fff,font-weight:bold,rx:10,ry:10
    classDef helm fill:#1976D2,stroke:#0D47A1,stroke-width:3px,color:#fff,font-weight:bold,rx:10,ry:10

    A["πŸ“¦ Kustomization<br/>victoria-logs"]:::kustom
    B["πŸ“¦ Kustomization<br/>victoria-logs-collector"]:::kustom
    C["πŸ“¦ Kustomization<br/>openebs"]:::kustom
    D["🎯 HelmRelease<br/>victoria-logs"]:::helm
    E["🎯 HelmRelease<br/>victoria-logs-collector"]:::helm
    F["🎯 HelmRelease<br/>openebs"]:::helm

    A -->|Creates| D
    B -->|Creates| E
    C -->|Creates| F
    A -.->|Depends on| C
    B -.->|Depends on| A
Loading

🌎 Networking

To be documented...

DNS

The cluster runs two separate ExternalDNS instances, each responsible for managing DNS records in a different environment.

The first instance manages public DNS records and synchronizes them to Cloudflare. The second instance synchronizes private DNS records to a UCG Fiber gateway using the ExternalDNS UniFi webhook provider.

This separation is achieved through the use of two ingress classes:

  • internal β€” Used for services that require private DNS records.
  • external β€” Used for services that require public DNS records.

Based on the assigned ingress class, the corresponding ExternalDNS instance automatically discovers the ingress resources and creates or updates DNS records on the appropriate platform. This approach provides clear separation between internal and external services while ensuring that DNS records remain synchronized with the cluster's configuration.


🌩 Cloud Dependencies

While most services are self-hosted, certain critical components rely on cloud services to ensure availability, especially in bootstrapping scenarios.

Service Purpose Cost
1Password Secret management via External Secrets ~€40/yr
Cloudflare DNS and secure access via Cloudflare Tunnel Free
GitHub Repository hosting and CI/CD Free
Mailgun Automatic email delivery Free (Flex Plan)
Name.com Domain registration ~€55/yr
Pushover Infrastructure alerts and notifications $5 (One Time Fee)
Tailscale Secure private remote access Free
~€8/mo

βš™ Hardware

Device Count OS Disk Data Disk RAM OS Function
Minisforum MS-A2 1 1.92TB M.2 3.84TB U.2, 1.92TB M.2 96GB Talos Kubernetes
Inter-Tech 4U-4416 1 2x1TB M.2 2x1TB SSD, 4x12TB HDD, 4x8TB HDD 256GB TrueNAS SCALE NFS & Backup Storage
PiKVM V4 Plus 1 - - - - KVM for Kubernetes
UniFi Cloud Gateway Fiber 1 - - - UniFi OS Firewall & Router
UniFi Aggregation 1 - - - UniFi OS 10G SFP+ Switch
UniFi Pro 24 PoE 1 - - - UniFi OS 1GbE PoE+ Switch
UniFi AC Pro 2 - - - UniFi OS WiFi 5 Access Point

Minisforum MS-A2 Build

Inter-Tech 4U-4416 Build


🀘 Thanks

A special thanks to the Home Operations Discord community for their insights and inspiration. Many ideas stem from shared clusters under the k8s-at-home GitHub topic and the excellent Kubesearch tool.


βš– License

See LICENSE

About

Homelab deployed with Talos Linux; managed with Flux, Renovate, and GitHub Actions πŸ€–

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages