Skip to main content

Pi Hole is an ad blocker that works across the network. Using it, you can block ads across your entire home. It can even improve the speed of your network Running PiHole + Docker + Kubernetes, however, poses a few interesting challenges.

Running an ad blocker like this is possible on most Linux distributions. The Raspberry Pi is often the preferred method – Guide here

PiHole Docker

PiHole Docker Considerations

Docker is the easiest way to install PiHole. Uninstalling or updating PiHole is simple with Docker. Parts of the network can also be isolated for security. The Raspberry Pi can be replaced in a matter of minutes. You can also save the configuration to a network drive.

IMPORTANT! Stability is very critical when it comes to Pi-Hole.

To connect to the internet, devices on the network require a DNS server. By setting Pi-Hole as the primary DNS server on the router, it must always be available. If it goes down, the devices will be inaccessible. The only way to get the benefits of Pi-Hole on every device is to use it as the primary DNS server.

PiHole Docker

There may be users who prefer to run Pi-Hole directly on the host. If Docker is used, they may argue that it introduces more points of failure. Kubernetes is what I use because it gives me convenient monitoring tools. This allows me to monitor everything remotely.

You may be tempted to run Pi-Hole in host networking mode. Personally, I avoid doing that whenever I can…

Kubernetes Helm Chart

At the time of writing, Pi-Hole does not have an official Kubernetes helm chart (automated installer). However, I was able to get the Pi-Hole helm chart from mojo2600 working well.

MetalLB is mentioned in the README. This is a load balancer for bare-metal clusters. For running a home server, this is an excellent way to assign a static IP without resorting to hostNetwork or NodePorts.

DNSMasq (Custom DNS Names)

The traffic to the home server(s) should never leave the local network. It is faster (no internet requests to the outside world). Furthermore, it is more secure (no data leaves the network).

In most cases, this is done by accessing the server via the LAN IP address. Only when connected to the home network can this be done. If not, use the public domain name. It complicates various other tasks, though. 

In such cases, it is necessary to write software that uses a different URL according to the context. Be sure to type the correct URL or IP address. 

When server software is not written to support both simultaneously, this can even become a problem.

Instead, you can run DNSmasq with Pi-Hole. Using this method, queries from inside the network will receive the local IP address of the server instead of the remote address.

dnsmasq
DNSmasq

In my messy apartment, Home Assistant runs on a server on the local network at 196.148.0.100. This is accessible to the outside world as home.messy-apartment.com. In most cases, typing this URL in the browser would return the public IP address. This is described in creating a server with a custom domain name. However, when inside the network, we can run nslookup home.messy-apartment.com to see:

Server: 196.148.0.101 Address: 196.148.0.101#53 Name: home.messy-apartment.com Address: 196.148.0.101
Code language: CSS (css)
  • The Server has a static IP address at 196.148.0.101.
  • It tells us that the Name lives at the address 196.148.0.101#53

Let’s ask Google about this server (nslookup home.messy-apartment.com 8.8.8.8):

Server: 8.8.8.8 Address: 8.8.8.8#53 Non-authoritative answer: Name: home.messy-apartment.com Address: 174.29.3.162
Code language: CSS (css)

Queries coming from the outside world instead connect to the public IP.

Messy-apartment.com is registered with AWS Route53. PiHole Docker does the same thing. It provides the IP address response to nslookup. But it is accessible to the outside world. So it responds with the public IP address.

Switchboard supports https and client IP addresses are supported by default. The result is that I can type https://home.messy-apartment.com into the browser at home and have a secure/encrypted connection to the local server. Additionally, the server is able to identify my LAN IP address as making the request. This enables features like Home Assistant’s trusted networks & trusted users. Home Assistant can bypass the login process by identifying the request as coming from the LAN.

Embedding (IFrame)

You should be able to easily access the admin tool for Pi Hole. As a hub for the numerous services on my network, I like using Home Assistant. In order to do so, the admin interface is embedded in an iframe. Pi Hole configures lighttpd to deny cross-origin requests, so this is tricky.

A work-around is to edit <mark style="background-color:#e0e0e0" class="has-inline-color">/etc/lighttpd/lighttpd.conf</mark>. From within the docker container:

sed -i "s/\"DENY\"/\"ALLOW\"/" /etc/lighttpd/lighttpd.conf \ && service lighttpd restart
Code language: JavaScript (javascript)

Restarting does not restore this. Attempting to override the value in <mark style="background-color:#e0e0e0" class="has-inline-color">/etc/lighttpd/external.conf</mark> has thusfar been unsuccessful.

My Deployment File(s)

Here are the <mark style="background-color:#e0e0e0" class="has-inline-color">values.yaml</mark> I use with the helm chart:

persistentVolumeClaim: enabled: true admin: existingSecret: pi-hole-secrets serviceTCP: loadBalancerIP: 196.148.0.101 annotations: metallb.universe.tf/allow-shared-ip: pi-hole type: LoadBalancer serviceUDP: loadBalancerIP: 196.148.0.101 annotations: metallb.universe.tf/allow-shared-ip: pi-hole type: LoadBalancer dnsmasq: customDnsEntries: - address=/home.messy-apartment.com/196.148.0.100
Code language: JavaScript (javascript)

Persistent Volume Claim refers to NFS volumes configured with the nfs-client-provisioner chart. The admin.existingSecret uses a pre-existing password for login to the PiHole docker frontend (web UI).

Other than that, the configuration is more or less the same as in the helm chart.