|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Running a Kubernetes Cluster at Home for Fun" |
| 4 | +description: An overview of the things I did to setup a Kubernetes cluster at home with old laptops. |
| 5 | +image: "/assets/images/homelab-2024.jpg" |
| 6 | +date: 2024-06-02 23:00 +0530 |
| 7 | +--- |
| 8 | + |
| 9 | +This weekend, I set up a Kubernetes cluster at home with some old laptops [just for fun](https://justforfunnoreally.dev/). |
| 10 | + |
| 11 | +<center><table style="table-layout: auto; width: 80%"> |
| 12 | +<tbody><tr><td align="center"> |
| 13 | +<img src = "/assets/images/homelab-2024.jpg" alt="Image of a few laptops standing on their edge, inside plastic desk organizers intended for paper sheets"> |
| 14 | +</td></tr><tr><td align="center"> |
| 15 | +<a href="https://en.wikipedia.org/wiki/Jugaad">जुगाड़</a> until I get or build a proper vertical stand for these laptops |
| 16 | +</td></tr></tbody></table></center> |
| 17 | + |
| 18 | +I used: |
| 19 | +- [Tailscale](https://tailscale.com/) to enable the nodes to talk to each other |
| 20 | +- [K3s](https://k3s.io/) for setting up a K8s cluster |
| 21 | +- [Longhorn](https://longhorn.io/) for replicated persistent storage |
| 22 | +- The [Tailscale Kubernetes operator](https://tailscale.com/kb/1236/kubernetes-operator) to expose K8s services on my tailnet |
| 23 | +- [Helm charts](https://helm.sh/) to manage all deployments. |
| 24 | + |
| 25 | + |
| 26 | +## Some random details |
| 27 | +- The cluster only has two nodes for now ([`mavros` and `luna`]({% post_url 2022/2022-11-08-browse-twitter-at-college %})), both running Linux. |
| 28 | + <center><table style="table-layout: auto; width: 100%"> |
| 29 | + <tbody><tr><td align="center"> |
| 30 | + <img src = "/assets/images/homelab-2024-nodes.png" alt="Image of the output of the 'kubectl get nodes' command"> |
| 31 | + </td></tr><tr><td align="center"> |
| 32 | + Output of the <code>kubectl get nodes</code> command |
| 33 | + </td></tr></tbody></table></center> |
| 34 | +- I reduced the default replica count from `3` to `1` for the Longhorn storage class. |
| 35 | + I don't really need high availability for most data at this point and I will manually increase the number of replicas for any volume that's important to me. |
| 36 | + <center><table style="table-layout: auto; width: 100%"> |
| 37 | + <tbody><tr><td align="center"> |
| 38 | + <img src = "/assets/images/homelab-2024-longhorn-ui.png" alt="A screenshot of the Longhorn Dashboard, containing an overview of the nodes and volumes in the cluster."> |
| 39 | + </td></tr><tr><td align="center"> |
| 40 | + A screenshot of the Longhorn dashboard |
| 41 | + </td></tr></tbody></table></center> |
| 42 | +- As of writing this post, I've only deployed [Gitea](https://gitea.kitty-paradise.ts.net/) (an open-source git-based code-hosting server) to the cluster. |
| 43 | + I've pushed my [ledger]({% post_url 2023/2023-09-03-finance-workflow %}) repository and a repository containing helm charts and values for this homelab project to the instance. |
| 44 | + <center><table style="table-layout: auto; width: 100%"> |
| 45 | + <tbody><tr><td align="center"> |
| 46 | + <img src = "/assets/images/homelab-2024-gitea-explore.png" alt="A screenshot of the Gitea 'Explore' page, containing a list of all repositories in the instance."> |
| 47 | + </td></tr><tr><td align="center"> |
| 48 | + A screenshot of the Gitea "Explore" page |
| 49 | + </td></tr></tbody></table></center> |
| 50 | +- I'm trying to not make any changes to the templates of the helm charts that I'm using to keep the upgrade process as painless as possible. |
| 51 | + For example: one way of exposing K8s services as devices on your tailnet is to change the service type to `LoadBalancer` and set the `loadBalancerClass` to `tailscale`. |
| 52 | + While most helm charts allow setting the service type to `LoadBalancer` via helm values, they do not allow setting a `loadBalancerClass` for these services. |
| 53 | + I was initially patching the service templates in these charts to allow specifying a `loadBalancerClass`. |
| 54 | + However, I later learned that the Tailscale Kubernetes operator also supports exposing services by setting a value for the `ingressClassName` on `Ingress` resources. |
| 55 | + Most charts that create services usually also contain templates to create `Ingress` resources for these services, and setting a value for the `ingressClassName` is much more common than setting a `loadBalancerClass`. |
| 56 | + Hence, so far, exposing services using `Ingress` instead of a tailscale `LoadBalancer` has allowed me to keep using upstream charts with custom values files. |
| 57 | + |
| 58 | +## Some things I'll think about later |
| 59 | +- I want to measure the electricity consumption of the laptops, to get a rough estimate of how much this setup costs in terms of energy usage. |
| 60 | +- Both the nodes are currently using their 500GB internal drives for storage. While I don't think I'm going to need a lot of space in this cluster anytime soon, it would be good to think about a plan to add storage to this cluster easily. I have a few external NTFS drives lying around but Longhorn only supports `ext4` and `xfs` filesystems. |
0 commit comments