Running AdGuard Home on Kubernetes in 2023
A Step-by-Step Guide on How To Run AdGuard Home on Kubernetes
Recently, I decided to revisit AdGuard Home. I have been trying more and more to put my self-host workloads on my Kubernetes cluster. When you search for “how to run adguard home on Kubernetes” some old and not so helpful articles pop up. I decided it was time for me to dive deep and figure out how I could get this running on my cluster.
Make sure to check out my GitHub so you can grab the files we are going to deploy. I have several directories with Kubernetes manifest files in them.
First, we need a namespace:
adguard-namespace.yml
apiVersion: v1
kind: Namespace
metadata:
name: adguard
Next, we need the actual deployment:
adguard-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: adguard-deployment
namespace: adguard
spec:
replicas: 1
selector:
matchLabels:
app: adguard
template:
metadata:
labels:
app: adguard
spec:
containers:
- name: adguard-home
image: adguard/adguardhome:latest
env:
- name: AGH_CONFIG
valueFrom:
configMapKeyRef:
name: adguard-config
key: AdGuardHome.yaml
ports:
- containerPort: 53 #dns
name: dns
protocol: UDP
- containerPort: 3000 #initial setup
name: http-initial
- containerPort: 80 #web gui
name: http
protocol: TCP
volumeMounts:
- name: adguard-data
mountPath: /opt/adguardhome/work
volumes:
- name: adguard-data
persistentVolumeClaim:
claimName: adguard-pvc
Now when we look at the deployment we can see we will need a few more files, a persistent volume and claim, a configmap, and a service.
Here is the persistent volume and claim:
adguard-pv-pvc.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: adguard-pv
namespace: adguard
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: "/mnt/data/adguard"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: adguard-pvc
namespace: adguard
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: "" # your storage class name
volumeName: adguard-pv
And lastly, we have the service:
adguard-service.yml
apiVersion: v1
kind: Service
metadata:
name: adguard-service
namespace: adguard
spec:
selector:
app: adguard
ports:
- protocol: TCP
port: 3000
targetPort: 3000
name: http-initial
- protocol: TCP
port: 80
targetPort: 80
name: http
- protocol: UDP
port: 53
targetPort: 53
name: dns
type: LoadBalancer
And that should be that. Instead of using “kubectl apply” (cringe bruh), I used Argo CD to deploy. You can hit the LB IP to set up AdGuard home.
Three things to note here:
I used the LB service type. For LB provisioning I use MetalLB. If you were to deploy this to a cloud, you would use their LB provisioner. In this case, I use 10.0.0.212 as my DNS resolver and as you can see, it works well.
Latency appears to be minimal. This can depend on your upstream DNS provider. I need to do more testing to see if there are any use-specific latency issues.
The client is the internal IP of the Kubernetes pod. I am not sure how to fix that but I will look into it.
Great! That was really easy! Make sure to let me know if you have any questions or comments!
Cheers,
Joe