Skip to content

Matt Adam

Tech Blog

Menu
  • Home
  • Home Lab
    • Home Lab – Gen 1
    • Home Lab – Gen 2
    • Home Lab – Gen 3
  • VMware
    • VMware Cloud Foundation (VCF)
    • Avi Networks
  • Kubernetes
    • Openshift
    • K3s
    • Tanzu
      • Tanzu – TKGs (WCP)
      • Tanzu – TKG (TKGm)
    • Avi Kubernetes Operator (AKO)
  • About
  • Privacy Policy
Menu

Running a DNS server in K3s

Posted on January 24, 2023 by Matt Adam

I’ve decided to move my DNS server from a VM in the physical ESXi, to some pods in my Raspberry Pi K3s cluster. If you have some Raspberry Pis laying around and want to setup a simple K8s cluster, checkout my guide: K3s on the Raspberry Pi
The below guide will assume that you’ve setup a kubernetes cluster and have some external Load Balancer configured. In my case, I’m using MetalLB.

Table of Contents

Toggle
  • Configure the Deployment and Service yaml
  • Apply the DNS yaml
  • Testing
  • Extra

Configure the Deployment and Service yaml

The below file will include our deployment using the cytopia/bind image, and an L4 service type LoadBalancer. See additional details on cytopia
It will create 2 services, 1 for UDP 53 and another for TCP 53.
Specify all the A records and the PTR (reverse dns) records that you want added.

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dns
spec:
  selector:
    matchLabels:
      app: dns
  replicas: 3
  template:
    metadata:
      labels:
        app: dns
    spec:
      containers:
      - name: dns
        image: cytopia/bind
        ports:
        - containerPort: 53
        env:
        - name: DNS_PTR
          value: 192.168.3.4=esxi2.home.lab, 192.168.3.5=esxi1.home.lab
        - name: DNS_A
          value: esxi2=192.168.3.4, esxi1=192.168.3.5
        - name: ALLOW_QUERY
          value: any
        - name: DOCKER_LOGS
          value: '1'

---
apiVersion: v1
kind: Service
metadata:
  name: dns-service-udp
  annotations:
    metallb.universe.tf/address-pool: dnspool
    metallb.universe.tf/allow-shared-ip: "dnskey"
spec:
  selector:
    app: dns
  ports:
    - protocol: UDP
      port: 53
      targetPort: 53
  type: LoadBalancer
  loadBalancerIP: 192.168.3.199

---
apiVersion: v1
kind: Service
metadata:
  name: dns-service-tcp
  annotations:
    metallb.universe.tf/address-pool: dnspool
    metallb.universe.tf/allow-shared-ip: "dnskey"
spec:
  selector:
    app: dns
  ports:
    - protocol: TCP
      port: 53
      targetPort: 53
  type: LoadBalancer
  loadBalancerIP: 192.168.3.199

Apply the DNS yaml

# Apply the yaml
kubectl apply -f dns.yaml

Testing

# Kubernetes Objects
kubectl get pods
kubectl get service

# Test DNS
# +short just returns the response
# +vc tests TCP, the default is UDP
dig @192.168.3.199 esxi1.home.lab +short
dig @192.168.3.199 esxi1.home.lab +short +vc
dig @192.168.3.199 -x 192.168.3.5 +short
dig @192.168.3.199 -x 192.168.3.5 +short +vc

Extra

It’s rather annoying to have to add each DNS entry into that list, especially to duplicate it again with the PTR records. Having to do that manually might take minutes..
So I have a simple python script that will take a list of fqdn and IP addresses, and convert them into the appropriate yaml format

#!/usr/bin/python3

import yaml

dns_list = {
  "esxi2.home.lab": "192.168.3.4",
  "esxi1.home.lab": "192.168.3.5",
  "ns1.home.lab": "192.168.3.6"
}

def Arecords(dnslist):
	DNS_A = []
	for dns in dnslist:
		DNS_A.append(dns + "=" + dnslist[dns])
	return (', '.join(DNS_A))

def PTRrecords(dnslist):
	DNS_PTR = []
	for dns in dnslist:
		DNS_PTR.append(dnslist[dns] + "=" + dns)
	return (', '.join(DNS_PTR))

if __name__ == '__main__':
	json = []
	json.append({"name": "DNS_PTR", "value": PTRrecords(dns_list)})
	json.append({"name": "DNS_A", "value": Arecords(dns_list)})
	json.append({"name": "ALLOW_QUERY", "value": "any"})
	json.append({"name": "DOCKER_LOGS", "value": "1"})
	print (yaml.dump(json,sort_keys=False))

Social Media

  • LinkedIn
  • X
  • Bluesky
  • Mastodon

Recent Posts

  • Financial Solutions for ETF share classes
  • Power Consumption Tips for Efficient Home Labs: Save Energy, Save Money
  • Automating Deployments with Terraform in a Home Lab: A Simple Guide for Tech Tinkerers
  • Backup Strategies for Home Lab Data: A Beginner’s Guide to Keeping Your Files Safe
  • Home Lab Monitoring with Grafana and Prometheus: How to Track Your Systems Like a Pro
© 2026 Matt Adam | Powered by Minimalist Blog WordPress Theme