Project
K3s Lab
k3s-lab — Reproducible, lightweight k3s clusters for experiments, demos, and CI
- ansible
- argocd
- falco
- grafana
- k3s
- kubernetes
- loki
- prometheus
- tetragon
- trivy
- vault
- Repository
- KevinDeBenedetti/k3s-lab
- Language
- Shell
- Last update
- October 2026
README
k3s-lab
Reusable Kubernetes platform toolkit — Helm charts (OCI), Kustomize bases, and automation for a homelab k3s cluster (bare metal, VMs or VPS).
Overview
k3s-lab is a public, reusable platform toolkit. It publishes versioned Helm charts to GitHub Container Registry (OCI), exposes reusable Kustomize bases and Ansible roles, and contains no sensitive data or cluster-specific configuration.
There are two ways to use it, and the rest of this page is organized around them:
| Path | You want to | Start with |
|---|---|---|
| Try it | See the whole platform running on a cluster, in one command | The platform-deployment umbrella chart |
| Run it | Operate components individually, pin versions, upgrade one piece at a time | Individual charts + your own private config repo (homelab guide) |
Features
- Helm charts (OCI, on GHCR) — one chart per platform component, plus an umbrella chart that aggregates them
- Kustomize bases — reusable namespace, LimitRange, RBAC, ExternalSecret, and IngressRoute templates
- Ansible roles — common (node base), k3s_server, k3s_agent, wireguard
- Lightweight Kubernetes via k3s with automated control-plane and agent bootstrap
- Ingress + automatic HTTPS via Traefik and cert-manager
- Full observability: Prometheus, Grafana, Loki, Promtail (sized for a small single node)
- Runtime security: Falco, Tetragon, Trivy Operator, Kyverno
- Secret management: HashiCorp Vault + External Secrets Operator
- GitOps: ArgoCD
- Daily security watch: the deployed Traefik proxy version is checked against upstream advisories every day, independently of repository activity
- Static CI: ShellCheck, actionlint, kubeconform, Helm lint, resource limits check, Gitleaks — plus Bats tests for every shell library
Quick Start
Try the platform (umbrella chart)
One command installs the stack — ArgoCD, monitoring, Vault, cert-manager, Traefik and external-secrets (verified on a blank k3d cluster with the published 0.16.0 artifact):
helm install platform oci://ghcr.io/kevindebenedetti/charts/platform-deployment \
--version 0.24.0 --namespace platform --create-namespace
One caveat worth knowing up front: on stock k3s or k3d, disable the bundled Traefik first (--k3s-arg "--disable=traefik@server:0"), since its CRDs conflict with this chart's — the same thing this repo's Ansible role does on real nodes. The Kyverno ClusterPolicies also come in a second helm upgrade, for a Helm ordering reason explained (with the command) in the chart's README, which also carries the full verified-install report. Each component can be switched off independently and configured through nested values. Check the releases page (vX.Y.Z tags) for the latest version; every chart and the umbrella's sub-chart pins share that version.
Provision a cluster from scratch (Ansible)
From fresh Debian/Ubuntu machines to a running k3s cluster:
ansible-galaxy install -r ansible/requirements.yml
ansible-playbook -i <your-inventory> ansible/playbooks/site.yml
The full walkthrough — prerequisites, inventory, verification — is in Getting Started.
Run it with GitOps (your own config repo)
For real operation, keep your cluster-specific configuration (inventory, values, pins) in a private repo that consumes k3s-lab, and deploy the individual charts via ArgoCD — pinned, so that every upgrade is an explicit, reviewable change:
# In an ArgoCD ApplicationSet
- repoURL: ghcr.io/kevindebenedetti/charts
chart: platform-traefik
targetRevision: "0.24.0" # pin to a published version — never a range
The full path — inventory, provisioning, kubeconfig, platform install and the checks to keep pins honest — is in Running a homelab.
Repository Structure
k3s-lab/
├── ansible/ # Reusable Ansible roles + playbooks
│ ├── roles/ # common, k3s_server, k3s_agent, wireguard
│ ├── playbooks/ # site.yml, k3s-server.yml, k3s-agent.yml, reset.yml
│ └── requirements.yml # Galaxy dependencies
├── charts/ # Helm charts published to ghcr.io (OCI)
│ ├── platform-deployment/ # ★ Umbrella: the whole platform in one release
│ ├── platform-argocd/ # ArgoCD (GitOps)
│ ├── platform-base/ # Namespaces, LimitRange, shared RBAC
│ ├── platform-cert-manager/ # TLS certificates (cert-manager)
│ ├── platform-external-secrets/ # External Secrets Operator
│ ├── platform-monitoring/ # Prometheus + Grafana + Loki + Promtail
│ ├── platform-security/ # Falco + Tetragon + Trivy + Kyverno
│ ├── platform-traefik/ # Ingress controller (Traefik)
│ ├── platform-vault/ # HashiCorp Vault
├── kubernetes/ # Kustomize bases + reusable components
├── taskfiles/ # Includeable Task fragments (provision, deploy, …)
├── scripts/ # Deployment + validation scripts
├── lib/ # Shared shell libs (tested with Bats)
├── tests/ # Bats tests
└── docs/ # Full documentation
Release Workflow
Releases are fully automated with release-please; versions follow a deliberate 0.x line, and the whole repository shares one version — every chart, the umbrella's pins and the toolkit scripts move together:
| What | Tag | Changelog |
|---|---|---|
everything (charts, scripts, lib/, Ansible, taskfiles) | vX.Y.Z | CHANGELOG.md |
- Merge a change to
main(conventional commits:feat:,fix:, …) - release-please opens a single release PR — changelog + version bump of every
Chart.yamland of the umbrella's pins - Merging it creates the GitHub release and the
vX.Y.Ztag release-chartspublishes every chart whose version is not on GHCR yet (the umbrella last, since its pins resolve to the subcharts just pushed), then renders the umbrella as a post-publish check- Consumers pin
ghcr.io/kevindebenedetti/charts/<chart>at that version (Renovate:dockerdatasource)
Documentation
Full documentation: https://kevindebenedetti.github.io/k3s-lab/
→ Getting Started · Running a homelab · Configuration
License
A question about this project?
The assistant knows my repositories: ask it how this one works.
Other projects
- Dataset GeneratorAutomated web-scraping to LLM-powered question-answer dataset generator with duplicate detection and optional Langfuse export.Python
- Github WorkflowsCollection of reusable GitHub Actions workflows for automating CI/CD and repository tasks.Shell
- DotfilesDotfiles and setup scripts for fast environment provisioning.Shell