Skip to content

Commit 12dd52c

Browse files
committed
Add new blog post: K8s homelab
Signed-off-by: ricekot <github@ricekot.com>
1 parent 71000ce commit 12dd52c

6 files changed

+62
-2
lines changed

_posts/2024/2024-06-02-k8s-at-home.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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.
48.6 KB
Loading
81.7 KB
Loading

assets/images/homelab-2024-nodes.png

23.9 KB
Loading

assets/images/homelab-2024.jpg

1.61 MB
Loading

index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ <h1 class="post-title p-name" itemprop="name headline">
2222
<div class="content e-content">
2323
{{ site.posts.first.excerpt }}
2424
<a href="{{ site.posts.first.url }}">
25-
<center><table style="table-layout: auto; width: 100%">
25+
<center><table style="table-layout: auto; width: 80%">
2626
<tbody>
2727
<tr><td align="center">
2828
Continue reading
2929
</td></tr>
3030
{% if site.posts.first.image %}
3131
<tr><td align="center">
32-
<img src = "/assets/images/levo-dashboard-k8s-context.png">
32+
<img src = "{{ site.posts.first.image }}">
3333
</td></tr>
3434
{% endif %}
3535
</tbody>

0 commit comments

Comments
 (0)