61 lines
3.1 KiB
Markdown
61 lines
3.1 KiB
Markdown
---
|
|
title: "Homelab Kubernetes Cluster"
|
|
date: 2026-03-17
|
|
draft: false
|
|
description: "Self-hosted k3s cluster on bare-metal with ArgoCD GitOps, Authentik SSO, full observability stack, and ~20 running workloads."
|
|
tags: ["kubernetes", "k3s", "homelab", "infrastructure", "traefik", "authentik", "argocd", "ansible"]
|
|
github: "https://gitea.nik4nao.com/nik/homelab"
|
|
url: ""
|
|
---
|
|
|
|
## Overview
|
|
|
|
A self-hosted Kubernetes cluster running on bare-metal hardware at home. The cluster serves as a
|
|
platform for running personal services, experimenting with cloud-native tooling, and learning
|
|
operational patterns without a cloud bill.
|
|
|
|
## Hardware
|
|
|
|
| Host | Role | Specs |
|
|
|---|---|---|
|
|
| Minisforum UM780 XTX | K3s control-plane | AMD Ryzen 7 8745H |
|
|
| HP ProDesk (nik-debian) | K3s storage agent | NFS server, media pool |
|
|
| Mac Mini M2 | Standalone Docker host (Ollama, Watch Party) | ARM, outside the cluster |
|
|
|
|
## Stack
|
|
|
|
- **Distribution:** k3s
|
|
- **GitOps:** Argo CD — app-of-apps pattern, all cluster state reconciled from git
|
|
- **Ingress:** Traefik v3
|
|
- **TLS:** cert-manager — Let's Encrypt (public) + internal CA (`*.home.arpa`)
|
|
- **Auth:** Authentik SSO — OIDC + forwardAuth proxy, TOTP MFA enforced
|
|
- **DNS:** Pihole (primary + secondary, externalIPs)
|
|
- **Storage:** NFS (Debian) + local-path dynamic provisioner
|
|
- **Secrets:** Sealed Secrets — encrypted at rest, committed to repo
|
|
- **CI/CD:** Gitea Actions + act_runner, Docker buildx multiarch (amd64 + arm64)
|
|
- **Registry:** Gitea built-in container registry
|
|
- **Observability:** kube-prometheus-stack, Grafana, Loki, Tempo, OpenTelemetry Collector
|
|
- **VPN:** WireGuard
|
|
- **IaC:** Ansible (host bootstrap), Helm values + raw manifests (cluster-level), reconciled by Argo CD
|
|
|
|
## Highlights
|
|
|
|
- All cluster state is declared in a Gitea monorepo and reconciled by Argo CD with `selfHeal: true` — changes flow through git, not kubectl
|
|
- App-of-apps pattern: a single root `Application` in Argo CD manages all child Applications, each pointing at a manifest directory or Helm values file
|
|
- Sealed Secrets used for all sensitive credentials committed to the repo — encrypted with the in-cluster controller public key, safe to store in git
|
|
- Authentik SSO protects all web-facing services via Traefik forwardAuth; OIDC integrated with Gitea, Grafana, and Argo CD
|
|
- Full distributed tracing with OpenTelemetry Collector + Tempo — home-services traces visible end-to-end in Grafana
|
|
- Dual-cert TLS strategy: internal CA for `*.home.arpa` services, Let's Encrypt for `*.nik4nao.com` public services; CA installer page serves `ca.crt` and an iOS/macOS mobileconfig profile
|
|
- Multi-arch image builds (amd64 + arm64) via buildx on every push to `main`, pushed to the self-hosted registry
|
|
- DDNS CronJob keeps the public A record in sync via the Porkbun API
|
|
|
|
## Running Workloads
|
|
|
|
Argo CD, Traefik, cert-manager, Sealed Secrets, Pihole, Authentik, Gitea, Prometheus, Grafana,
|
|
Loki, Tempo, OpenTelemetry Collector, Glances, Jellyfin, qBittorrent, JDownloader, Photoview,
|
|
Immich, Home Assistant, HA Gateway, AI Gateway, Discord Bot, Dashy, DDNS CronJob, this portfolio site.
|
|
|
|
## Status
|
|
|
|
Active and in daily use.
|