Self-hosted service
ricsanfre/pi-cluster avatar
ricsanfre/pi-cluster

pi-cluster: a K3s home cluster rebuilt from Git every time

Pi Kubernetes Cluster. Homelab kubernetes cluster automated with Ansible, Terraform and FluxCD

585 stars94 forksHCLMIT

At a glance

What is it?
pi-cluster is an educational project that builds a hybrid x86 and ARM Kubernetes cluster at home from Raspberry Pis and refurbished mini PCs, with the entire deployment automated by Ansible, OpenTofu and FluxCD. Its value is the automation, since the cluster can be torn down and recreated in minutes, and its cost is that a homelab stack is not the stack you run at work.
Who is it for?
Adopt pi-cluster as a learning and experimentation environment if you want a Kubernetes cluster that can be destroyed and recreated on demand, since the whole point of the automation is that the cluster is disposable. Do not adopt it as a production pattern, because the tooling choices are homelab choices and the documentation is written for one specific home topology.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly HCL, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

An educational project where the cluster is disposable

The pi-cluster repository describes itself as a Pi Kubernetes Cluster, a homelab Kubernetes cluster automated with Ansible, Terraform and FluxCD, and the README is explicit that this is an educational project to build a hybrid x86 and ARM Kubernetes cluster at home using Raspberry Pi and refurbished x86 mini PCs.

The stated goal is to learn to deploy basic Kubernetes services and to automate the deployment and configuration using infrastructure as code and GitOps methodologies. The documentation covers the entire process from cluster design and architecture through to step-by-step manual configuration guides, and it is published on the project website rather than in the repository.

What lives in the repository is the source code for those manual tasks: cloud-init configuration files, the Ansible source code in playbooks and roles, and the packaged Kubernetes applications in Helm and kustomize form that are deployed with FluxCD.

The payoff is stated plainly. Since the deployment is completely automated, the cluster can be redeployed in minutes as many times as needed, for testing new cluster configurations, for new software versions, or simply to get out of any mess you might cause while playing with the cluster. That last clause is the one that tells you the audience. This is a project for breaking things on purpose, and the automation exists so that breaking things is cheap.

The licence is MIT, the default branch is master, the last push was on 2026-10-20, and the recent releases are v1.12.0 from 2026-07-06, v1.11.0 from 2025-08-28 and v1.10.0 from 2025-01-16.

Four tools, each with one job in the chain

The scope section names the four tools that make the automation work, and it is worth being precise about which is which, because they run at different stages of the machine's life.

cloud-init handles the automated OS initial installation. It is the first thing that runs on a fresh machine, before anything else in the stack exists, and it is what turns a USB image into a configured node.

Ansible handles the OS configuration, external services installation, and the k3s installation and bootstrapping. This is the layer where roles configure the operating system, install the outside services the cluster depends on, and bring up the Kubernetes distribution itself.

OpenTofu, or Terraform, handles the provisioning of external services such as Vault, DNS and S3 buckets. The distinction from Ansible matters: Ansible configures machines you already own, OpenTofu creates resources that exist outside the machines, like a DNS record or a bucket in an object store.

FluxCD is the GitOps tool for deploying applications to Kubernetes. It is the only one of the four that runs inside the cluster, and it is the layer that keeps the running workloads in step with what is in Git.

That ordering is the architecture. cloud-init makes the node usable, Ansible configures it and installs K3s, OpenTofu provisions the outside world the cluster talks to, and FluxCD reconciles the applications inside the cluster from Git. The result is that the cluster has two reconciliation loops, one for the machines and one for the workloads, and the repository holds the source for both.

K3s, Cilium, Envoy Gateway and the cluster's plumbing

The technology stack table in the README is the most detailed part of the document, and it names the components with a one-line role for each.

The Kubernetes distribution is K3S, described as a lightweight distribution of Kubernetes, with containerd as the container runtime integrated with it. The node operating system is Ubuntu, and the router and firewall runs OpenWRT.

Networking is Cilium, which is both the CNI and the load balancer, which is a notable choice: a stock cluster would run a separate load balancer component, and folding it into the CNI is a common simplification in small clusters. The Kubernetes API load balancer is Kube-VIP, and the Gateway API controller is Envoy Gateway. DNS is CoreDNS, and ExternalDNS handles external DNS synchronisation, which is how a service in the cluster gets a public record.

On top of that, the scope section lists the platform services the cluster runs. Distributed block storage for persistent volumes comes from LongHorn. Object storage is RustFS. Backup and restore is Velero with Restic. Certificate management is Cert-Manager. Secrets management is Vault with External Secrets. Identity and single sign-on is Keycloak.

Observability is a stack rather than a single tool: Prometheus for metrics, and for logging an EFK plus LG combination, meaning Elasticsearch with Fluentd and Fluent Bit feeding Kibana, together with Loki and Grafana. Distributed tracing is Tempo.

And the microservices side of the scope is Istio for the service mesh, Keycloak again for API security with OAuth 2.0 and OpenID Connect, and Kafka for streaming. This is a considerable list for a home cluster, and it is the strongest evidence that the project is a full production-shaped stack rather than a minimal teaching cluster.

The Makefile is the map of the whole system

The Makefile in the repository is the clearest single view of what the project does, because every significant operation has a named target and the target names read as a narrative of the build.

The top of the list is the preparation chain. prepare-ansible depends on ansible-runner-setup and secret-files and is described as bootstrapping the runner and generating the secret files, which tells you that the project generates credentials before it does anything else. ansible-local-setup creates or updates the local UV-based Ansible environment and installs the Galaxy dependencies, and the recipe for it is short: it changes into the ansible directory and runs uv sync --frozen, then makes the galaxy target.

Then come the stages of the build itself: init, secret-files, os-upgrade, external-setup, nodes-setup, dns-setup, pxe-setup, external-services, configure-os-backup, os-backup, k3s-install, k3s-bootstrap, k3s-bootstrap-dev and k3s-reset.

After the cluster exists there is the service layer: external-services-reset, openwrt-certbot-tls, deploy-monitoring-agent, shutdown-k3s-worker, shutdown-k3s-master, shutdown-picluster, deploy-vault, deploy-minio, deploy-rustfs, configure-minio, configure-vault, load-external-services-keys, get-pi-status and install-local-utils.

The reset and shutdown targets are the interesting ones, and they are the clearest expression of the project's philosophy. k3s-reset, external-services-reset and shutdown-picluster are first-class operations, which means the intended way to recover from a broken cluster is to destroy it and build it again. The help target is generated from the target descriptions rather than written by hand, so the list of targets is always the documentation.

What the repository layout shows about how it is organised

The top level of the repository tells you that this is a repository of repositories, which is a structure worth understanding before you read any of it.

There is an ansible/ directory with the playbooks and roles, and an ansible-runner/ directory holding the runner script that the Makefile invokes, so the project runs Ansible through a container rather than on the host. There is a terraform/ directory for the OpenTofu definitions of the external resources, a kubernetes/ directory for the packaged applications, and a boilerplate/ directory that presumably holds the shared fragments the roles reference.

Alongside those are the supporting directories. A dev/ directory for local development, a design/ directory for the architecture decisions, a docs/ directory that holds the documentation source the website is built from, a metal/ directory whose purpose is not described in the documentation, and a test/ directory. There is a .mise.toml, which is a tool version manager configuration, and a CLAUDE.md, which suggests the project is developed with an AI coding assistant in the loop, along with a giscus.json for GitHub discussions embedded in the site.

The separation between the code that runs and the documentation that explains it is deliberate and consistent with the project's stated purpose. The website carries the step-by-step guides, and the repository carries the automation those guides describe. That means a reader who wants to understand the design starts in design/ and the website, and a reader who wants to change the automation starts in ansible/ and terraform/.

Where a homelab cluster is the wrong reference architecture

The first limitation is that a homelab stack is not a production stack, and the differences are not incidental. The nodes are Raspberry Pis and refurbished mini PCs, the distribution is K3s rather than a managed control plane, and the whole cluster lives behind a home OpenWRT router. The documentation and the roles are written against that topology.

The second limitation is the scale of the dependency list for the hardware involved. A three-node Raspberry Pi cluster running LongHorn, Istio, Kafka, Elasticsearch, Loki, Tempo, Vault, Keycloak and Velero is a lot of stateful workload for machines with a few gigabytes of RAM each. The project is clearly written by someone who has done the arithmetic, but a reader copying the service list onto three Pi boards will find that some of it does not fit, and the project does not tell you which parts to drop.

The third limitation is the automation's own assumptions. The Ansible roles target Ubuntu, the OpenWRT role manages the router and firewall, and the PXE target implies network booting. That is a specific and well-chosen environment, but it means the automation is not portable to another base operating system or another network boot setup, and adapting it means rewriting roles rather than changing variables.

The real alternative is to learn the same material on a managed Kubernetes service, where the cluster lifecycle is somebody else's problem and the IaC work is limited to the workloads. The difference in approach is that this project teaches the layer that managed services hide, which is exactly what makes it valuable as a learning exercise and exactly what makes it a poor production reference. The honest reading is that pi-cluster is a teaching environment with a production shape, and using it as the latter without the former is a mistake.

Editorial conclusion

Adopt pi-cluster as a learning and experimentation environment if you want a Kubernetes cluster that can be destroyed and recreated on demand, since the whole point of the automation is that the cluster is disposable. Do not adopt it as a production pattern, because the tooling choices are homelab choices and the documentation is written for one specific home topology. Before you run it, read the getting started material in the project website documentation rather than only the Makefile, because the Makefile assumes an environment the scripts have already prepared, and confirm that your machines match the Ubuntu and OpenWRT assumptions the roles are written against.

Frequently asked questions

What is pi-cluster?

It is an educational project to build a hybrid x86 and ARM Kubernetes cluster at home from Raspberry Pis and refurbished x86 mini PCs, using K3s, with the deployment and configuration automated by cloud-init, Ansible, OpenTofu and FluxCD. The repository holds the source code for those automation steps and the documentation is published on the project website.

Which tools does pi-cluster use and what does each one do?

cloud-init automates the initial OS installation, Ansible handles OS configuration, external service installation and the K3s installation and bootstrapping, OpenTofu or Terraform provisions external services such as Vault, DNS and S3 buckets, and FluxCD is the GitOps tool that deploys applications to Kubernetes.

How do you run the pi-cluster automation?

Through the Makefile, where every operation is a named target. The preparation chain runs prepare-ansible, which depends on ansible-runner-setup and secret-files to bootstrap the runner and generate the secret files, and ansible-local-setup creates or updates the local UV-based Ansible environment and installs the Galaxy dependencies.

Which storage, secrets and observability stack does pi-cluster deploy?

Longhorn for distributed block storage, RustFS for S3 object storage, Velero with Restic for backup and restore, Cert-Manager for certificates, Vault with External Secrets for secrets, Keycloak for single sign-on, Prometheus for metrics, an EFK and LG combination with Loki and Grafana for logs, and Tempo for distributed tracing.

Is pi-cluster suitable as a production reference?

Not as a direct reference, since it targets Raspberry Pis and refurbished mini PCs running K3s behind a home OpenWRT router, and the Ansible roles target Ubuntu with PXE boot assumed. It is built as a disposable learning environment whose value is that the cluster can be torn down and rebuilt in minutes.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. ricsanfre/pi-cluster on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ricsanfre-pi-cluster.svg)](https://hysenlabs.com/projects/ricsanfre-pi-cluster)

Was this useful?