Automating DNS with Kubernetes and Synology DSM

After following an internal CKA training, I needed teaching material and flying hours to familiarize myself with Kubernetes to pass the CKA exam (which I did). For that reason, I bought an Intel NUC and installed Ubuntu, and got started with K3S. In this blog, I will share how to set up external DNS at home.

What was the challenge? The DNS world for Kubernetes

During my journey in the world of Kubernetes, I became a bit lost on the DNS side. For applications to be reachable from the outside, running on your k3s cluster, DNS is very useful. Whatever happens, my clients (my wife and kids) should always have a 100% uptime ;-)

So, resolving domain names for clients should still work, no matter if my cluster or my Synology NAS is down. A fallback must be in place pointing to some DNS provider on the internet.

DNS requests are a bit strange. If one of your DNS servers replies but with an incorrect answer, your client will never go to the second DNS server in your list. A good working DNS server is key.

The solution should be able to handle the three following scenarios:

  1. Resolve DNS queries for the internal domain (
  2. Resolve DNS queries for internet domain names. 
  3. Filter ads from web pages

One of the most important components within Kubernetes is DNS. While the internal DNS service is mission-critical, the external isn’t.

However, running DNS on a local network is not as easy as it seems. I could, for instance, run a DNS server on Kubernetes for my local network. But if the K3s cluster is down, I’ll have an angry wife and children complaining about the internet being down (which it isn’t, of course).

The concept

Step 1: Setting up the external DNS server for Kubernetes

I wasn't sure if I should run the DNS server besides my K3s cluster or on a separate virtual machine (VM). After a while, the penny dropped, and I realized that I still had a Synology NAS running. Since the Netflix era, I don't use it as much anymore, so this could come in handy.

And yes, I was lucky. By default, Synology offers a DNS server within DSM (DiskStation Manager OS). I won't bore you with setting it up, as that is a "next, next, finish" installation.

Step 2: Register a domain name within the DSM DNS server

In this instance, I'm using The idea was simple. A master zone on within DSM with forwarding records pointing to the new applications running on my K3s cluster and a wildcard that points to the internet. In case the subdomain isn't running within the cluster but on the internet somewhere. Like my externally hosted website.

external-dns: the beginning

Step 3: Installing an ad-filter application onto my K3s cluster

Luckily, there are several applications to be found on the internet. I chose Adguard since I previously had good experiences with this app.

To manage the settings (WebUI) of Adguard I added an A-record on my DSM pointing to my K3s cluster. “ “ The setup looked like this.

Note: Adguard is used to forward records to the internet resolvers and filter the ads when returning them to the client.

external-dns: Adguard on top of Kubernetes

Everything seemed fine, and after going from one kubectl apply -f to another, I quickly had some applications running.

Though every time I had a new application running, I had to manually add an A-record to the DSM DNS to connect to the WebUI of that application. It is 2022; let’s automate it!

Step 4: Automating the A-record

After some googling, I found out about External-DNS. External-DNS is a service that is used to orchestrate DNS records living on another service, within or outside your network, allowing Kubernetes to sync IP addresses (from services and ingress) with DNS records. It all started with cloud-based API DNS providers. Though there is also a rfc2136 version. The latter is controlled via TSIG secrets.

TSIG (transaction signature) is a computer-networking protocol defined in RFC 2845. Primarily it enables the Domain Name System (DNS) to authenticate updates to a DNS database. It is most commonly used to update Dynamic DNS or a secondary/slave DNS server. TSIG uses shared secret keys and one-way hashing to provide a cryptographically secure means of authenticating each endpoint of a connection as being allowed to make or respond to a DNS update.

Source: Wikipedia

So, the first step is to generate a new TSIG secret within the DSM DNS server. Download this key as this is needed later within your deployment.

All files needed to add External-DNS to your cluster will be linked below.
The deployment example will look like this. 

apiVersion: apps/v1
kind: Deployment
  name: external-dns
  namespace: external-dns
      app: external-dns
        app: external-dns
      serviceAccountName: external-dns
      - name: external-dns
        - --registry=txt
        - --txt-prefix=external-dns-
        - --txt-owner-id=k8s
        - --provider=rfc2136
        - --rfc2136-host= ## your DNS server
        - --rfc2136-port=53
        - ## your domain name
        - --rfc2136-tsig-secret= 2cOPVWlG1eAg3BfVtIfsH4jKH8UOcte
        - --rfc2136-tsig-secret-alg=hmac-sha512
        - --rfc2136-tsig-keyname=externaldns-key
        - --rfc2136-tsig-axfr
        - --source=ingress
        - --source=service
        - ## your domain name
        - --rfc2136-min-ttl=400s ## optional TTL in seconds

For your own purposes, please change the marked items below:

  • ## your DNS server
  • ## your domain name
  • 2cOPVWlG1eAg3BfVtIfsH4jKH8UOcte
  • ## your domain name
  • 400s ## optional TTL in seconds

Applying the above deployment file including the
serviceAccount, clusterRole, ClusterRoleBinding adds the External-DNS to your Kubernetes cluster. Which you can find on the GitHub of external-DNS, links are provided below.

Step 5: The final step

Make sure that you add the generated key to your “Create zone update rule” within DSM – DNS server.

 external-dns: Zone creation


Whenever you add a service or ingress with annotation to your cluster an a-record is added/updated, or deleted on your DNS server.

external-dns: registering dns records


I learned a lot through this journey about DNS and Kubernetes, have an ad-free network, and most importantly, my internet wasn't down at any moment, so I still have a waf of 100%, wink wink ;-)

In my next blog post, I'll explain how to use Let's Encrypt certificates on a private network with my own personal subdomain. Yes, you read this right; private network and Let's Encrypt certificates. But also will tell you the downside of this construction, and why you maybe want to use your own privately signed certificates.

That's it, see you next time. I hope this helped you as much as it helped me. 
Would love to hear from you in the comments!

Wrap up

kind: Ingress
    name: my-ingress
    - host:
          - path: /
                name: my-service
                  number: 8000
            path: /
            pathType: Prefix

Pascal equals passion, passion for food, and passion for automation. As a former chef, he still loves to prepare a beautiful meal. As an engineer, his motto is: “Automate Everything if possible”.
May 07, 2024 | BLOG | 6 MINUTES

8 questions you were afraid to ask about Talos answerd

Talos is a minimal Kubernetes OS that's quickly gaining popularity because of its ease of use and strong focus on security by default. It has already been …

April 30, 2024 | BLOG | 9 MINUTES

12 Factor: 13 years later

How can we make applications easy to operate? The 12-factor methodology is about 13 years old. How did it age in the cloud-native era? Do we need a 13th …

April 25, 2024 | BLOG | 5 MINUTES

Build your own Python Kubernetes Operator

Yes, you read it right – build a K8s operator in Python! I often get reactions like, "But doesn't it have to be in Golang?" Fortunately, that's not …