I wanted to build a Homelab for some time but it was taking a backseat as I always had access to cloud environments (eg: cloud accounts, VMware DC etc) and the use cases I was focusing on didn't really warrant for one. But lately, some new developments and opportunities in the industry triggered the need to explore use cases in a bare-metal server environment, ultimately leading to the built of my own homelab, called MetalSNO.
In this post, I will discuss some of my key reasons for building a homelab, the goals I set for it, and the process I followed to building one from scratch. I'll conclude with some reflections on whether it was truly worth it and what I plan to do with it going forward.
Compelling reasons (The Why)
My uses cases for a homelab weren't about hosting plex server, home automation etc (I have them on Raspberry PIs for some years now). My Homelab is really about exploring technologies and concepts that are on par with industry trend. Below are some of the key reasoning I gave to my myself:
- Cost effectiveness (main reason): For my usecases, I needed compute capability with freedom. I compared the cost of running on aws vs hosted dedicated server (eg: equinix) vs in baremetal server at home. Interestingly running Homelab came out to be the most cheapest option for me. Here's a diagram with my cost calculation:
- K8s and VMs on the same platform (Openshift): My past posts have mostly been about modern applications and cloud native tech stacks. So when I came across KubeVirt and Openshift/OKD virtualization (which is based on Kubevirt), it instantly picked my curiosity and I started thinking about the possibilities. So to get my hands on I thought an Openshift-on-baremetal backed Homelab would be nice. More on this coming in future post. In short, I can use Openshift to virtualize baremetal server and host VMs and K8s on the same platform.
- Absence of ESXi: Pre 2024 ESXi was free and it was the defacto for virtualization. Now, post Broadcom's acquisition of VMware, that it is no longer the case and new options are surfacing. Some popular ones are Proxmox, xcp-ng and Openshift (opensource project is OKD). Yes, Openshift. This is what picked my interest as it offers unique capabilities where modern apps based on K8s meets legacy apps based on Virtual Machines. On top, Openshift can be installed on baremetal server.
- The cloud exit trend: It probably started to happen this year or at least I have come across few interesting articles on this topic this year. This mean virtualization may become/becoming a thing again and a homelab might be a good way to understand options, challenges and solutions.
See articles here:
Technical objectives (The What)
- Homelab using Dell R620: I should be able install Openshift on the Dell R620 server without requiring any additional virtualization. Since this is a single server and not a cluster I need to leverage single node Openshift for this.
- A functioning SNO (Single node Openshift): Openshift was the platform of choice because of its ability to run PODs and VMs the same way (which was a topic I wanted to explore). This meets the requirements to run containerized workloads as well as VM based workloads on the same platform the same way (eg: kubectl for both PODs and VMs, declarative definitions for both K8s objects like Ingress, PODs and VMs, single console for both containerized workloads as well as VMs based etc). The platform should function just like any other K8s cluster. The only relax I will do is on the infra resiliency part since this is a single node.
- Remotely turn on or off the remote access to Homelab: There should be a way to remotely enable and disable the remote access to the homelab. When enabled, I should be able to access the Homelab from outside the home network (eg: over the internet). This must be done without exposing home network to the internet or compromising home network firewall. This method should be secured and sit behind protection mechanism (This is on top of Openshift's built in authentication mechanism (eg: password, certificate etc)).
Building an Openshift powered Homelab (The How)
Milestone #1: Hardware
Milestone #2: Virtualization
myhomelab.example.com
). Rather than using a local domain, I decided to purchase a domain from Namecheap for $3.73. TBH, I probably didn't need one. But it came in handy later on when I configured the access to lab. It also future proofs the solution. Milestone #3: Remote access
- Establish a private network over the internet: I accomplished this with Tailscale's default network at no cost.
- Enable selective remote access: I add my laptop (on a different network) and a machine inside my home network to the private network (aka Tailnet) on demand. When remote access isn’t needed, I remove them from it. Neither of the machines is configured to auto-join or stay connected. This is setup to be manually done deliberately and it goes through a token-based authentication process at each joining time. This, too, was done with Tailscale at no cost.
- Route traffic between devices: With both devices connected to the Tailnet, I used SSHuttle on my laptop to route traffic from my laptop to the machine inside my home network, allowing access to services running in the lab such as the OpenShift console, K8s, Load balancer, VMs etc.
- Streamline remote management: While it’s easy to toggle the private network connection on my laptop, the process is less convenient for the VM in the home network. To solve this I configured Cloudflare's browser based ssh terminal to the VM. This was also free.
- A 24/7 machine or VM in the home network: Since this machine's purpose is to provide access to home network for accessing homelab and the homelab is capable for creating/hosting virtual machines, I created a VM using Openshift Virtualization in the homelab for this purpose.
- Onboarded the base domain (e.g., example.com) to Cloudflare: I followed this documentation.
- Created a Cloudflare tunnel: For this I needed to install Cloudflared tool in my network to leverage proxy DNS from Cloudflare. I went to Cloudflare > Dashboard > Zero Trust > Network > Tunnel and initiated a docker based tunnel configuration. I only took the token from the generated command in the Cloudflare console discarding the whole docker run command.
- Cloudflared K8s deployment: I created Cloudflared tool's K8s deployment yaml using the token and deployed it on Openshift K8s. This allows to set up proxy DNS record for any service on the platform that has an IP from home network's range. I installed MetalLB Load Balancer on Openshift and configured it for an IP range/pool/IPAM of the home network. In this case, the load balancer's IP address is used to expose Fedora VM on port 22 (for SSH).
yaml for Cloudflared deployment:apiVersion: apps/v1 kind: Deployment metadata: labels: app: cloudflared name: cloudflared-deployment namespace: default spec: replicas: 2 selector: matchLabels: pod: cloudflared template: metadata: creationTimestamp: null labels: pod: cloudflared spec: containers: - command: - cloudflared - tunnel - --no-autoupdate # In a k8s environment, the metrics server needs to listen outside the pod it runs on.
# The address 0.0.0.0:2000 allows any pod in the namespace. - --metrics - 0.0.0.0:2000 - run args: - --token - <token value> image: cloudflare/cloudflared:latest name: cloudflared livenessProbe: httpGet: # Cloudflared has a /ready endpoint which returns 200 if and only if # it has an active connection to the edge. path: /ready port: 2000 failureThreshold: 1 initialDelaySeconds: 10 periodSeconds: 10MetalLB configs after installing the operator on openshift via operator hub.--- apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: l2-adv-sample1 namespace: metallb-system --- apiVersion: metallb.io/v1alpha1 kind: IPAddressPool metadata: namespace: metallb-system name: homelab-svc-addr-pool spec: protocol: layer2 addresses: - 192.168.1.10-192.168.1.30 # Sample SVC using the pool kind: Service apiVersion: v1 metadata: name: expose-fedora-vm namespace: myvms annotations: metallb.universe.tf/ip-allocated-from-pool: homelab-svc-addr-pool spec: ports: - name: ssh protocol: TCP port: 22 targetPort: 22 type: LoadBalancer selector: kubevirt.io/domain: fedora-vm
- Observe if Cloudflared is deployed correctly: After deploying the Cloudflared and confirming that the pod was running successfully, I verified that the tunnel was in a healthy state in the Cloudflare console.
- Assign a Public Hostname to the Fedora VM: In the Cloudflare console I edited the newly created Cloudflare tunnel entry for the base domain and added a subdomain (eg: fedora.example.com) for the Fedora VM using the private IP assigned to it. Note: Cloudflare $0 subscription only caters tls for first level subdomain; nested subdomain requires premium subscription and $$$.
- Set Up Cloudflare Access Application to Enable Browser-Based SSH: To enable SSH into the Fedora VM via browser I created Cloudflare > Zero Trust > Access > Application > FedoraSSH application. I followed this YouTube guide with some of my own adjustments, like restricting access by a full and single email address, geo-location, password protected key file etc.
- Install the Tailscale Client:
- I installed the Tailscale client on both the remote machine (eg: laptop) and the Fedora VM.
- On Linux, the Tailscale client runs as a service by default, but I chose not to enable it. Instead, I manually start and stop the service as needed.
- Authenticate the Machines:
- After installing the Tailscale tool, the first time I executed the sudo tailscale up command, it prompted for authentication. After successful authentication, Tailscale generated an access token and a refresh token in the background.
- Connect Machines to the Tailnet:
- Once authenticated, I ran the sudo tailscale up command on both the remote machine and the Fedora VM. This adds the machines to my private Tailnet and assigning them ip addresses from the Tailnet network. I verified that both devices appeared in the Tailscale dashboard. I recorded this IP address for further use.
- Connected Machines:
- Once connected to the Tailnet, my laptop (in a work network) and the Fedora VM (in my home network) were both part of the same Tailnet. This allowed me to interact with the Fedora VM (e.g., ping or SSH) directly from the laptop’s terminal. As the FedoraVM is also in my home network I now have access to the services (eg: Openshift) inside my home network via the FedoraVM.
- Turn on access:
- Access the FedoraVM via browser (with 2FA authentication and then a identity verification) > Start the Tailscale service (sudo systemctl start tailscaled) > Join the FedoraVM to the Tailnet (sudo tailscale up).
- On the remote machine do the same tailscale connect.
- When both machines are on the Tailnet start SSHuttle on the remote machine.
- Turn off access:
- On remote machine stop the SSHuttle to stop the traffic flow to FedoraVM > Tailscale down (sudo tailscale down) > and stop tailscaled service (sudo systemctl stop tailscaled). This will remove the remote machine from Tailnet.
- Via browser on the FedoraVM do the same. This will remove FedoraVM from Tailnet.
- And that's it. The homelab remote access is turned off.
Comments
Post a Comment