Skip to content

Matt Adam

Tech Blog

Menu
  • Home
  • Home Lab
    • Home Lab
    • Home Lab with NSX-T
  • 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, 2023January 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

  • 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))

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • Setting up the Kubernetes Dashboard
  • Running a DNS server in K3s
  • Raspberry Pi Kubernetes Cluster
  • Pod Routing: NodePort, ClusterIP, NodePortLocal
  • Configure Bootstrap VM for OpenShift and Install OpenShift with vSphere

About

My name is Matt Adam and I’m a Product Line Manager at VMware.

I support the NSX Advanced Load Balancer (Avi Networks) with a focus on containers and Kubernetes. I have a background in load balancing, automation, development, and public cloud.

© 2023 Matt Adam | Powered by Minimalist Blog WordPress Theme