pihole on a raspberry pi Kubernetes cluster

By Gavin Davies on 18 October 2019

Page image
It’s been a while since I had a victory with computers. I needed this win. I’m now running my own DNS server on my Rpi K8s cluster.

In the words of one Raymond Quentin Smuckes, “it’s been a while since I had a victory with computers”. Yesterday I got Pi-hole running on my Rpi K8s cluster. I needed this win.

Achewood - it's been a while since I had a victory with computers Source: Achewood, the best web comic series ever

A couple of months back, through a Dark-Souls like process of catapulting myself brutally into failure until a glimmer of success dawned I slayed the KuberPiDragon by building a working cluster of three Raspberry Pi 3 computers. It turns out that this was one of the hardest ways to get started with Kubernetes due to Raspiian being relatively niche and the Pi being of ARM architecture, so many containers didn’t work. Anyway, after the battle I tried a few little projects.

First up, I built a simple web container deployment and that worked (eventually)! I then set up Grafana and IngressDB, but I couldn’t get it working smoothly enough and then life got in the way and I got distracted by producing modular markov music and other Eurorack related gubbins.

My Pi cluster - now with a case and colour coded cabling My Pi cluster - now with a case and colour coded cabling

For $DAY_JOB, though, I really need to get to grips with Kubernetes so I rolled up my sleeves and got stuck in.

I recently ditched Virgin Media as an ISP due to their repeated price jacks (and keeping me on hold listening to cursed hold music for ninety minutes. At that point I’m so ragin’ that I don’t care if the service is free!). My new ISP is little better but what you gonna do (brother). So, when the new router arrived I figured I’d take some ownership of my network. You know, now that I’m not terrified of networking any more.

So, I decided to set up Pihole which is a DNS server with integrated ad blocking. Installing Pihole on a Raspberry Pi is apparently straightforward. Furthermore, there are containers built for Pihole that are ARM based. So, sounds like a good candidate!

What for?

Having some control over my DNS is a part of armouring my family against malware and trackers. As my kids get old enough to be aware of the internet, I’ll also want to make sure they don’t stumble across stuff they’re not ready for.

And of course, I don’t want to be constantly marketed to.

Finally, it’s a great learning tool. For example, I properly got to grips with the dig tool as I was testing this, and I understand DNS as a whole a little better than I did before.

Using Dig to test my Pihole installation Using Dig to test my Pihole installation

Oh, and I just like doing stuff like this!

Installing Pihole

There are several Helm charts out there for installing Kubernetes but at this stage I don’t want to use Helm. I do use Helm in $DAY_JOB but I really want to use K8s as vanilla as possible whilst I learn the ropes.

My janky yaml

Let me get in my cringing first:

  1. This is me learning, PLS NO BULLY
  2. I’ve told it to run on a specific node on my Pi cluster on a specific IP
  3. I’ve not configured any kind of persistence yet
  4. I had half a dozen false starts before I got this working
  5. Srsly, pls no bully. I get that the main clever sausages of the Internet spend a lot of time sneering, and I don’t need that. Unless you can bench more than me AND beat me at Swingball.
  6. It’s not production code, STOP HITTING ME THIS IS JUST FOR FUN
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pihole
  labels:
    app: pihole
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pihole
  template:
    metadata:
      labels:
        app: pihole
    spec:
      nodeSelector:
        kubernetes.io/hostname: 'green'
      containers:
      - name: pihole
        image: pihole/pihole:latest
        imagePullPolicy: IfNotPresent
        stdin: true
        tty: true
        ports:
        - containerPort: 80
          name: pihole-http
          protocol: TCP
        - containerPort: 53
          name: dns
          protocol: TCP
        - containerPort: 53
          name: dns-udp
          protocol: UDP
        - containerPort: 443
          name: pihole-ssl
          protocol: TCP
        - containerPort: 67
          name: client-udp
          protocol: UDP
        env:
          - name: TZ
            value: "Europe/London"
          - name: WEBPASSWORD
            value: <redacted>
          - name: 'DNS1'
            value: '127.0.0.1'
          - name: 'DNS2'
            value: '8.8.8.8'
---
apiVersion: v1
kind: Service
metadata:
  name: pihole
  labels:
    name: pihole
spec:
  type: NodePort
  externalIPs:
    - 192.168.0.100
  selector:
    app: pihole
  externalTrafficPolicy: Local
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dnstcp
    port: 53
    protocol: TCP
  - name: web
    port: 80
    protocol: TCP

I applied this using kubectl apply -f deployment-pihole.yaml and then I had my own DNS server on 192.168.0.100 (the Pi with hostname green).

Pihole up and running Pihole up and running and blocking Facebook like a G

What other config?

In addition to the default blocklists on Pihole, I used the big blocklist collection. I also blocked Facebook and Tumblr, because bun dem cesspools.

Rough layout

Here’s roughly what my setup looks like:

Network rough layout Network rough layout

The devices on the network are configured explicitly to use host green for their DNS provider (my ISP don’t allow me to do that on a router, which sucks, and makes me suspect that they’re doing voodoo upstream, so I need to look more into that).

What’s next?

  1. Configure proper persistence via persistent volume claims
  2. Create my own Helm chart
  3. Make sure I’ve secured everything correctly and that it’s not accessible from outside my home
  4. Figure out if my ISP are doing shady things with DNS and if so consider switching to DNS over HTTPS

Recommended reading

My mate Rich said, half-jokingly I think, “Kubernetes is for people who don’t feel that Docker is complicated enough for them” and I have a lot of sympathy for that! However, K8s isn’t going away so I’m gonna stand and fight.

As I said in a previous blog post “I wish tech books had shorter chapters”, I rely on books to learn topics holistically rather than just patch my knowledge together from Stack Overflow. The best two books I’ve so far read on Kubernetes are:

  • Managing Kubernetes - as a sysadmin, I found this by far the most valuable resource I’ve read on it as it shows what all the “building blocks” are.
  • Kubernetes up and Running - more “application level” - a very thorough treatment, but with a few errors in it that misled me in places. I expect the second edition is better.