I have been looking for a long time for a solution I could call it my home cloud. The answer was to buy a Synology 918+ NAS with 4 vCPUs and 8 GBs of RAM. It runs Docker images but, as I discovered later on, it's not able to run Kubernetes. On my first try, I created a VM inside the NAS and then installed K8s on it, it didn't take me long to realise that it was taking 1-2 vCPU only to run the master layer. This didn't leave much room for other containers to run. Not good. On my second try, I gave MicroK8s a go, still the CPU consumption is too high.
The answer came with K3s, it's a fantastic K8s distribution, very lean, and it runs on 0.5 vCPU of constant usage. So far, I haven't had any compatibility issues.
As my first useful deployment, I decided to build a PiHole service to keep my devices free from ads.
I used Helm to deploy this solution, so you will need:
- Some VM / Device using Ubuntu 20.04 in the same network you want to block ads on.
- Kubectl
- Helm 3
K3s is a Kubernetes distribution made for Edge by Rancher. Installation instructions are here.
It comes with Traefik by default, as I am not really familiar with it and I wanted to try Rancher's MetalLB, I disabled Traefik along side with the internal servicelb component.
For my "home cloud" I installed K3s over Ubuntu 20.04 by simply typing this as root:
# curl -sfL https://get.k3s.io | sh -s - server --no-deploy traefik --no-deploy servicelb
It does everything, even creates all the init files for K3s to come up after machine restart.
To see the kube config for this cluster:
sudo k3s kubectl config view --raw
Copy / paste this output into the ~/.kube/config
file in the computer you are going to use to install the rest of the components.
Skip this section if you installed K3s with the command above.
If you, like me, installed K3s using other methods, you will still need to disable Traefik.
# Remove traefik helm chart resource:
kubectl -n kube-system delete helmcharts.helm.cattle.io traefik
# Stop the k3s service:
sudo service k3s stop
# Edit service file
sudo vi /etc/systemd/system/k3s.service
# To disable traefik and servicelb, add the last two lines, it will look something like this:
# ExecStart=/usr/local/bin/k3s \
# server \
# --no-deploy traefik \
# --no-deploy servicelb \
# Then reload the service file:
sudo systemctl daemon-reload
# Remove the manifest file from auto-deploy folder:
sudo rm /var/lib/rancher/k3s/server/manifests/traefik.yaml
# Start the K3s service:
sudo service k3s start
This can be done from the same K3s server or from a remote client.
First, create the configuration. There is an example of the required ConfigMap on this git repository at ./metallb_config.yml . There, you need to change the last lines where it tells MetalLB the range of free IPs that it will use in your local LAN. Save the changes and close the file.
Now we can proceed with MetalLB installation. You may want to change v0.9.3
to the latest version available.
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/namespace.yaml
kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"
kubectl apply -f metallb_config.yml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yaml
Once K3s and MetalLB is ready, we are going to proceed to install PiHole. I normally use Helm everywhere I go, I found this Helm chart I liked at https://github.com/MoJo2600/pihole-kubernetes.
Before installing PiHole, we need to deal with Ubuntu's local DNS resolution on the server. It seems to come by default with Ubuntu latest versions and conflicts with PiHole.
-
Double-check that the port is being used:
$ sudo lsof -i :53
-
If that command returns any output, it will show something similar to this:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME systemd-r 610 systemd-resolve 12u IPv4 19377 0t0 UDP localhost:domain systemd-r 610 systemd-resolve 13u IPv4 19378 0t0 TCP localhost:domain (LISTEN)
-
If that is the case, go to the file
/etc/systemd/resolved.conf
, uncomment the lines DNS and DNSStubListener. Add your DNS server onDNS
and change DNSStubListener tono
. The final result will be similar to this one:[Resolve] DNS=1.1.1.1 #FallbackDNS= #Domains= #LLMNR=no #MulticastDNS=no #DNSSEC=no #DNSOverTLS=no #Cache=no DNSStubListener=no #ReadEtcHosts=yes
-
Create a symbolic link for /run/systemd/resolve/resolv.conf with /etc/resolv.conf as the destination
$ sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
-
Reboot your system.
I like this approach better than the first one I took consisting on disabling systemd-resolve. After a while, during some updates, DNS stopped working.
Finally, have a look into the ./pihole_values.yml
file, you may want to customise some configuration for your installation.
Once you are happy with your configuration, add its Mojo2600 repo to our local repository list:
helm repo add mojo2600 https://mojo2600.github.io/pihole-kubernetes/
helm repo update
And install the Helm chart:
helm install pihole mojo2600/pihole -f ./pihole_values.yml
After few seconds, in the list of K3s available resources you should see:
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/pihole-b597ff7d4-lz99c 1/1 Running 0 136m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 19d
service/pihole-udp LoadBalancer 10.43.205.93 192.168.0.120 53:32652/UDP,67:32764/UDP 11d
service/pihole-tcp LoadBalancer 10.43.252.64 192.168.0.120 80:31734/TCP,443:32616/TCP,53:32042/TCP 11d
That EXTERNAL-IP column should show the first IP on the range you configured in ./metallb_config.yml. Once the pod is up and running, everything should be ready to serve the first DNS requests.
To ensure that everything works, you can use nslookup
:
$ nslookup www.google.com 192.168.0.120
Server: 192.168.0.120
Address: 192.168.0.120#53
Non-authoritative answer:
Name: www.google.com
Address: 216.58.204.228
That should be it! Enjoy!
I am the only user at home that does not enjoy adverts... I know, right?. What I do to avoid complaints from my partner and friends is to disable DHCP on PiHole and configure DNS on all the devices I use day-to-day to point to PiHole MetalLB IP address.