K3s, Pi-hole, Unbound On Raspberry Pi 5: A DIY DNS Powerhouse
Hey there, Plastik Magazine fam! Ever dreamt of having a super-powered, ad-blocking, privacy-boosting DNS server right in your home network? And what if I told you we could build this awesome setup using a Raspberry Pi 5 and Kubernetes? Yeah, you heard that right! For all you Kubernetes newbies out there, don't sweat it. We're gonna walk through setting up a K3s cluster on your shiny new Raspberry Pi 5, and then deploy Pi-hole and Unbound on it. This isn't just about blocking ads; it's about taking control of your network's DNS, boosting privacy, and getting a taste of the amazing world of self-hosting with Kubernetes. So grab your Pi, maybe a beverage, and let's dive into making your home network a whole lot smarter and safer!
Why K3s, Pi-hole, and Unbound on a Raspberry Pi 5?
Alright, guys, let's kick things off by understanding why this particular combination is such a powerhouse for your home network. First up, we've got the Raspberry Pi 5. This little beast isn't just a toy anymore; it's a legitimate mini-computer with impressive specs, making it perfect for always-on services like a DNS server. Its quad-core ARM Cortex-A76 processor, up to 8GB of RAM, and blazing-fast I/O (thanks to PCIe for NVMe support!) mean it can handle Pi-hole and Unbound with ease, plus a whole lot more if you decide to expand your K3s cluster later. It’s energy-efficient too, so you won’t be racking up huge electricity bills keeping it running 24/7. Seriously, the Pi 5 is a game-changer for home lab enthusiasts, and we’re going to put it to good use.
Next, let's talk about K3s. If you’re a Kubernetes newbie, the full-blown Kubernetes experience can feel like trying to land a space shuttle. That’s where K3s comes in – it’s a lightweight, certified Kubernetes distribution built specifically for edge, IoT, and ARM devices like our Raspberry Pi. It strips away the unnecessary enterprise features, making it incredibly fast to install and consume minimal resources. Despite its small footprint, it's still 100% Kubernetes, meaning you get all the benefits of declarative configuration, easy scaling, and robust management that Kubernetes offers. Running Pi-hole and Unbound on K3s means you can manage them like any other Kubernetes workload, benefit from its self-healing capabilities, and easily update or scale them without manual intervention. It's a fantastic way to learn Kubernetes in a practical, low-stakes environment.
Finally, the stars of our show: Pi-hole and Unbound. Pi-hole is a network-wide ad blocker that sits at the DNS level. This means every device connected to your network (phones, tablets, smart TVs, even your fridge if it’s connected!) gets ad-blocking protection without needing individual browser extensions or apps. It also blocks tracking domains, enhancing your privacy significantly. Plus, its beautiful web interface gives you insights into your network’s DNS queries. Paired with Pi-hole, Unbound acts as your very own recursive DNS resolver. Instead of relying on your ISP's DNS servers (which might track your activity or serve you modified results), Unbound fetches DNS records directly from the authoritative root servers. This setup drastically improves your online privacy, enhances security by bypassing potentially compromised upstream servers, and often speeds up DNS lookups because it caches results locally. Together, Pi-hole and Unbound create a robust, private, and advertisement-free browsing experience for your entire home network. This combination, orchestrated by K3s on a Raspberry Pi 5, truly makes for a DIY DNS powerhouse that’s both efficient and incredibly powerful.
Getting Your Raspberry Pi 5 Ready for K3s
Alright, team, before we dive into the cool Kubernetes stuff, we need to get our Raspberry Pi 5 prepped and ready for action. Think of this as laying the groundwork for our awesome DNS project. First things first, you'll want to install an operating system. For K3s, and really for most headless server applications on a Pi, I highly recommend using Raspberry Pi OS Lite (64-bit). The 'Lite' version means it's a minimal install without a desktop environment, which saves precious resources (RAM and CPU) that K3s and our DNS services will appreciate. The 64-bit version is crucial as it allows K3s to run more efficiently and leverage the Pi 5's full potential. You can flash this onto an NVMe SSD (if you've got the appropriate HAT for your Pi 5, which is a fantastic upgrade for speed and reliability!) or a high-quality microSD card using a tool like Raspberry Pi Imager or Balena Etcher. Make sure to enable SSH during the imaging process – it'll save you a ton of hassle later by allowing you to control your Pi remotely without needing a monitor and keyboard.
Once your OS is flashed and your Pi 5 is booted up, the first thing you guys need to do is connect via SSH. Open your terminal and type ssh pi@<your_pi_ip_address>. If you don't know the IP, you can usually find it on your router's client list or by running nmap -sn <your_network_cidr> from another Linux machine. Once logged in, let’s get everything updated. This is super important for security and to ensure we have the latest packages, so run sudo apt update && sudo apt upgrade -y. This might take a little while, but it’s a vital step. After the upgrade, a quick sudo reboot is a good idea to make sure all changes take effect. We also need to install curl if it isn't already there, as K3s uses it for its installation script: sudo apt install curl -y.
Now, for something absolutely critical for a server: a static IP address. Your K3s cluster, and especially your DNS services, need a consistent IP. If your Pi’s IP changes, your network devices won’t be able to find Pi-hole. You can set this up either in your router’s DHCP reservation settings (which is often the easiest and most robust method) or directly on the Pi itself. To configure it on the Pi, you'll edit the dhcpcd.conf file: sudo nano /etc/dhcpcd.conf. Scroll to the bottom and add lines similar to this, replacing the values with your network's specifics:
interface eth0
static ip_address=192.168.1.100/24
static routers=192.168.1.1
static domain_name_servers=1.1.1.1 8.8.8.8
Note: eth0 is for wired Ethernet; if you're using Wi-Fi, it might be wlan0. The static domain_name_servers are just temporary for the Pi to resolve hostnames before Pi-hole is up. Save and exit (Ctrl+X, then Y, then Enter), then sudo reboot to apply the static IP. After rebooting, log back in and verify your IP with ip a. One final tweak: disable swap memory. While K3s can run with swap, it's generally recommended to disable it for Kubernetes nodes as it can lead to unpredictable performance. Run sudo swapoff -a and then sudo sed -i '/ swap / s/^ /# /' /etc/fstab to make it permanent. Your Pi 5 is now officially hardened and ready for K3s! Seriously, these steps are the unsung heroes of a stable and reliable home server setup.
Setting Up K3s: Your Lightweight Kubernetes Cluster
Alright, awesome people, with our Raspberry Pi 5 all prepped and purring, it's time for the really exciting part: installing K3s, our lightweight Kubernetes cluster! This is where the magic begins, turning your little Pi into a powerful orchestration engine. K3s, as we chatted about, is super easy to install, making it perfect for beginners and resource-constrained devices. The official K3s installation script does most of the heavy lifting for us, so you won't be bogged down with complex configurations right off the bat. Seriously, it's almost ridiculously simple, which is why we love it for home lab setups and trying out new things without fear.
To install K3s, simply run the following command on your Raspberry Pi: curl -sfL https://get.k3s.io | sh -. This command fetches the K3s installation script and executes it. The script automatically detects your architecture (ARM64 in our case) and installs all the necessary components: the K3s server, kubectl (the Kubernetes command-line tool), crictl (container runtime interface tool), and containerd (the container runtime). It's a fantastic all-in-one package that gets your cluster up and running in minutes. You'll see a bunch of output as it downloads and installs everything, and once it's done, you'll have a fully functional Kubernetes cluster! How cool is that? This single command transforms your Pi into a robust platform for deploying containerized applications.
After the installation completes, it's a good idea to verify that K3s is running correctly. The K3s service should start automatically. You can check its status with sudo systemctl status k3s. You should see it as active (running). To interact with your cluster, you'll use kubectl. For convenience, K3s places the kubectl config file in a standard location, but it needs to be sourced correctly. Add the KUBECONFIG environment variable to your shell for easy access by running: echo 'export KUBECONFIG=/etc/rancher/k3s/k3s.yaml' >> ~/.bashrc && source ~/.bashrc. Now you can verify your cluster by listing the nodes: kubectl get nodes. You should see your Raspberry Pi listed as a Ready node. This confirms that your Kubernetes brain is active and listening for commands! Take a moment to appreciate this, because you've just deployed a powerful orchestration system.
Now, for those of you who want to peek under the hood a bit more, you can also check the pods running in the kube-system namespace. These are the core components of K3s itself, like CoreDNS (which handles DNS resolution inside the cluster), the K3s server component, and the K3s agent. Run kubectl get pods -n kube-system. You should see several pods, all in a Running state. If any are pending or erroring, give them a minute or check kubectl logs <pod-name> -n kube-system for clues. This is your first step into troubleshooting Kubernetes, which is a valuable skill, guys. The K3s environment on your Pi is now a solid foundation. While we're starting with a single-node cluster, remember that K3s makes it easy to add more Raspberry Pis later to create a multi-node cluster, expanding your capabilities even further. But for Pi-hole and Unbound, a single powerful Pi 5 is more than enough to handle the workload efficiently and reliably, giving you a taste of robust, self-healing services right from your home server. This setup truly maximizes the potential of your Raspberry Pi, leveraging its capabilities for a secure and private network experience.
Deploying Pi-hole on K3s: Your Network-Wide Ad Blocker
Alright, awesome K3s pioneers, it's time to deploy Pi-hole onto our brand-new cluster! This is where we start building that network-wide ad-blocking magic. As a Kubernetes newbie, you might have tried AI-generated manifests that just wouldn't cooperate, which is totally understandable – DNS services in Kubernetes can be a bit tricky, especially when they need to listen on well-known ports like 53. But don't you worry, we're going to use a tried-and-true manifest that balances simplicity for beginners with proper Kubernetes practices. Our goal is to have Pi-hole available for all your devices by having it listen on the Raspberry Pi's main IP address for DNS queries, while still leveraging Kubernetes for deployment and management. We'll set up Pi-hole to run in its own namespace, making it easy to manage and isolate from other services you might deploy later. This approach ensures Pi-hole works as expected, just as if it were running directly on your Pi, but with all the benefits of Kubernetes orchestration.
Here’s a multi-document YAML manifest for deploying Pi-hole. Save this as pihole-deployment.yaml:
---
apiVersion: v1
kind: Namespace
metadata:
name: pihole
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pihole-pvc
namespace: pihole
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi # Adjust as needed, 500MB is usually plenty
storageClassName: local-path # K3s default storage class
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: pihole
namespace: pihole
labels:
app: pihole
spec:
selector:
matchLabels:
app: pihole
template:
metadata:
labels:
app: pihole
spec:
containers:
- name: pihole
image: pihole/pihole:latest # Always use a specific tag in production!
ports:
- containerPort: 53
hostPort: 53 # Pi-hole DNS (UDP/TCP) - binds to host's port 53
name: dns
- containerPort: 80
name: http
env:
- name: TZ
value: