As you start your journey with K8s, you will quickly realize that communication between different components in the cluster is extremely important. Pods need to talk to Pods, Pods need to call Services. Just like we need a phone book to find someone else’s number, applications in K8s need a mechanism to find each other’s IP addresses. That mechanism is DNS (Domain Name System) .
In this article, we will learn together:
This article is designed for beginners and those who have some experience with Kubernetes. We will try to explain the concepts in the simplest and most understandable way to understand how DNS works, which is an important foundation before we dive into how Kubernetes uses and manages DNS for applications inside the cluster.
Part 1: DNS - "The Internet's Phonebook" and How It Works
1.1. What is DNS?
Simply put, DNS is like the "Phone Book of the Internet" . It maps domain names that are easy for humans to remember, such as www.google.com, to IP addresses, such as 142.250.199.14. IP addresses are the actual locations of servers that host websites or services on the network.
Thanks to DNS, we don’t need to remember long and complicated IP numbers to access websites. We just type the domain name into our browser, and DNS takes care of the rest – finding the corresponding IP address so our computer can connect to it. This process is called domain name resolution .
1.2. How does DNS work?
But how does DNS know the IP address for a particular domain name? The answer is: a DNS server doesn’t know everything by itself. It relies on a hierarchy of different types of DNS servers working together to find the answer. These intermediate servers are often referred to collectively as DNS resolvers .
DNS Resolver: A server that stores DNS records (or knows how to find them) and responds to DNS queries.
When you type a domain name into your browser, a series of steps takes place to find the IP address:
Let's go into step by step details with the example you want to access www.example.com:
Step 1: Check Local Caches
Your computer checks its own cache first, which is a temporary storage of domain name-IP address pairs that your computer has recently accessed. If the domain name you are looking for is in the cache, your computer will use that IP address and skip the next steps.
Local cache types that can contain this information:
Step 2: Ask Recursive DNS Servers
If it is not found in the local cache, the computer will send the query to the DNS server configured in its network settings (usually your ISP's, or you can configure it to use Google DNS 8.8.8.8, Cloudflare 1.1.1.1). This server is called a Recursive DNS Server (or Recursive Resolver).
This recursive server will also check its own cache. If it has an answer, it will send it back to your computer. If not, it will start the process of "questioning" other DNS servers, starting from the top level.
Step 3: Ask the Root DNS Servers
The Recursive Resolver will ask one of the Root DNS Servers . There are 13 root server clusters around the world, managed by different organizations. They don't know the IP address of www.example.com, but they do know who manages the .com top-level domain (TLD). The Root Server will return the address of the TLD DNS server for .com.
You can see a list of servers that manage TLDs using the dig command (more on that later):
dig +short NS com dig +short NS org # ... và các TLD khác
Step 4: Ask the Top Level Domain DNS Servers (TLD DNS Servers)
The Recursive Resolver then asks the TLD DNS server for .com (the address just received from the Root Server). This TLD server does not know the IP of www.example.com, but it knows who the Authoritative DNS Server is for the entire example.com domain. The TLD Server returns the address of that Authoritative DNS Server.
You can view the authoritative nameservers for a particular domain:
dig +short NS example.com dig +short NS google.com
Step 5: Ask Authoritative DNS Servers
Finally, the Recursive Resolver asks the Authoritative DNS Server for example.com. This is where the actual DNS records for this domain are stored. The Recursive Resolver will ask for the A record (or AAAA record for IPv6) for www.example.com.
A Record is a DNS record that maps a domain name (or subdomain name) to an IPv4 address.
The Authoritative DNS Server will look up the A record for www in the example.com zone and return the corresponding IP address (e.g. 93.184.216.34) to the Recursive Resolver.
The Recursive Resolver receives this IP address, stores it in its cache (for future queries), and sends the final response back to your computer. Your browser now has an IP address and can initiate a connection to the web server www.example.com.
1.3. See DNS in action with dig
We can use the dig (Domain Information Groper) command line tool to perform DNS queries and see how this process works. dig is available on most Linux and macOS systems. On Windows, you can install it via Chocolatey :
choco install bind-tools # Cung cấp dig và các công cụ DNS khác
To find the IP address for www.example.com, we use the command:
dig +short www.example.com
The +short option tells dig to only display the answer part (IP address). The result will be similar to this:
93.184.216.34
But how does dig find this IP? It also performs the same steps as the browser: checking the cache, asking the recursive resolver... To see the details of the "questioning" process through the DNS server levels, we use the +trace option:
dig +trace www.example.com
The output of this command will be quite lengthy, showing each step of the query from your computer to the recursive resolver, then to the root server, the TLD server, and finally the authoritative server to get the answer. Try running this command to see for yourself!
1.4. Using dig to Debug Basic DNS Issues
If you're having trouble accessing a website, dig is a useful tool to check if the problem is with DNS. For example:
Part 2: Why is DNS important in Kubernetes?
In Kubernetes, everything is dynamic :
The problem is: How can a Pod (e.g. frontend) find the IP address of a Service (e.g. backend) using only the name of that Service?
This is where Kubernetes DNS comes in. It provides an internal name resolution mechanism for the cluster, allowing Pods and Services to discover each other using DNS names instead of dynamic IP addresses.
Imagine you have a web application with 2 parts: frontend (running in Pods) and backend (running in other Pods). You create a Service called backend-service that points to the backend Pods. Now, from the frontend Pod, you just need to call the backend-service address and K8s DNS will automatically resolve it to the ClusterIP address of the backend-service, and Kube-proxy will route the traffic to one of the healthy backend Pods.
Without DNS, the frontend Pod would have to somehow keep track of the ever-changing IP addresses of the backend Pods or the Service's ClusterIP address - which is extremely complex and inefficient.
Part 3: How Kubernetes DNS Works
Kubernetes defines a standard DNS specification for naming and resolving resources in the cluster. When a Service or Pod is created, the K8s DNS server (usually CoreDNS) automatically creates the corresponding DNS records.
3.1. DNS records for Services:
This is the most commonly used record type. A Service named <service-name> in the namespace <namespace-name> will have a DNS A record (or AAAA record for IPv6) with the format:
<service-name>.<namespace-name>.svc.<cluster-domain>
For example: A Service named my-nginx in the default namespace will have a fully qualified DNS name of my-nginx.default.svc.cluster.local. This name will resolve to the Service's ClusterIP address.
Important:
3.2. DNS records for Pods:
Kubernetes can also create DNS records for each Pod, although these are less directly used for service-to-service communication. The format is typically:
<pod-ip-address-dashed>.<namespace-name>.pod.<cluster-domain>
For example: A Pod with IP 10.244.1.10 in the dev namespace will have a DNS name of 10-244-1-10.dev.pod.cluster.local. This name resolves directly to the IP of that Pod.
3.3. Headless Services and SRV Records:
When you create a Headless Service (by setting clusterIP: None), K8s DNS will not create an A record for that Service itself. Instead:
3.4. How do Pods get DNS configuration?
When a Pod is created, the kubelet on the Node will configure the /etc/resolv.conf file inside that Pod's container. This file typically looks like this:
nameserver <coredns-cluster-ip> search <namespace>.svc.<cluster-domain> svc.<cluster-domain> <cluster-domain> [custom-search-paths] options ndots:5
Part 4: CoreDNS - Kubernetes' Default DNS Server
From Kubernetes v1.13 onwards, CoreDNS has become the default DNS server, replacing the previous kube-dns.
What is CoreDNS?
CoreDNS is a flexible, highly extensible DNS server written in Go. CoreDNS's biggest strength is its plugin- based architecture. All of CoreDNS' functionality is implemented by plugins, and you can easily add, remove, or reconfigure these plugins to customize the DNS server's behavior.
Why choose CoreDNS over kube-dns?
CoreDNS in Kubernetes:
In K8s, CoreDNS is typically deployed as a Deployment in the kube-system namespace. It has a corresponding Service (usually named kube-dns, for backwards compatibility reasons) with a fixed ClusterIP. This is the IP address written to the Pods' /etc/resolv.conf file.
CoreDNS continuously watches the Kubernetes API Server for information about newly created, updated, or deleted Services and Endpoints. Based on this information, it answers DNS queries for the cluster's internal domain names.
Part 5: Inside CoreDNS - Configuration (Corefile)
CoreDNS behavior is controlled by a main configuration file called the Corefile . In Kubernetes, this Corefile is typically stored in a ConfigMap named coredns in the kube-system namespace.
Corefile has a fairly simple structure:
.:53 { # Các plugin và cấu hình của chúng plugin1 [args...] plugin2 [args...] ... } another.zone:5353 { # Cấu hình cho zone khác plugin3 }
An example default (simplified) Corefile in K8s:
.:53 { # Ghi log lỗi ra stdout errors # Cung cấp endpoint health check tại http://localhost:8080/health # Sẵn sàng khi tất cả plugin đều sẵn sàng health { lameduck 5s } # Báo cáo trạng thái sẵn sàng cho K8s (sử dụng cùng port với health) ready # Plugin chính xử lý các truy vấn DNS cho K8s cluster # Nó sẽ theo dõi các Service và Pods # pods insecure: Cho phép phân giải Pod A records (IP dạng gạch ngang) # upstream: Sử dụng /etc/resolv.conf của node để phân giải tên bên ngoài nếu plugin `forward` không được dùng # fallthrough: Nếu không tìm thấy bản ghi trong K8s, chuyển tiếp truy vấn cho plugin tiếp theo kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure upstream fallthrough in-addr.arpa ip6.arpa } # Cung cấp metrics theo chuẩn Prometheus tại http://localhost:9153/metrics prometheus :9153 # Chuyển tiếp các truy vấn không thuộc cluster.local (và các zone đặc biệt khác) # đến các máy chủ DNS upstream được định nghĩa trong /etc/resolv.conf của Node. # policy sequential: Thử từng upstream theo thứ tự forward . /etc/resolv.conf { max_concurrent 1000 } # Bật bộ nhớ đệm DNS để tăng tốc độ và giảm tải # 30: Kích thước cache (mặc định là 10000 bản ghi) # success 9984, denial 30: Cache các câu trả lời thành công/thất bại cache 30 # Phát hiện vòng lặp DNS loop # Tải lại cấu hình Corefile nếu file thay đổi (mặc định 5s) reload 5s # Cân bằng tải giữa các kết nối đến upstream (khi dùng forward) loadbalance }
Explanation of important Plugins:
DNS query processing flow in CoreDNS:
Part 6: Troubleshooting - Check and fix basic DNS issues in K8s
DNS is one of the common causes of connectivity issues in Kubernetes. Here are the basic steps to check:
Check CoreDNS Pods status:
kubectl get pods -n kube-system -l k8s-app=kube-dns # hoặc kubectl get pods -n kube-system -l app.kubernetes.io/name=CoreDNS (tùy label)
Make sure the CoreDNS Pods are in Running state. If not, check their logs:
kubectl logs -n kube-system <coredns-pod-name>
Check Service kube-dns:
kubectl get service kube-dns -n kube-system
Make sure the Service exists and has a ClusterIP.
Check /etc/resolv.conf inside the Pod that is having trouble connecting: Run a shell inside the Pod that is having trouble connecting:
kubectl exec -it <your-pod-name> -n <your-namespace> -- sh # hoặc bash
Then, view the file contents:
cat /etc/resolv.conf
Check internal Service resolution (same namespace):
nslookup <service-name> # Ví dụ: nslookup kubernetes # (Service mặc định trong namespace default)
Check internal Service resolution (different namespace):
nslookup <service-name>.<namespace-name> # Ví dụ: nslookup kube-dns.kube-system
Check internal Service resolution (full name):
nslookup <service-name>.<namespace-name>.svc.cluster.local # Ví dụ: nslookup kube-dns.kube-system.svc.cluster.local
Check external domain name resolution:
nslookup google.com
Query CoreDNS directly (bypassing local cache):
nslookup google.com <coredns-service-ip> # Hoặc dùng dig: dig @<coredns-service-ip> google.com
Part 7: Customizing CoreDNS (For Intermediate)
One of the great advantages of CoreDNS is its customization. You can edit the coredns ConfigMap to:
Changing Upstream Forwarders: Instead of using Node's /etc/resolv.conf, you can specify specific DNS servers (like 8.8.8.8, 1.1.1.1, or your company's internal DNS) in the forward plugin.
forward . 8.8.8.8 1.1.1.1
Add Stub Domains: Forward queries for a specific domain (e.g. *.mycompany.local) to another internal DNS server.
mycompany.local:53 { errors cache 30 forward . 192.168.1.50 # DNS server của công ty } .:53 { # ... cấu hình còn lại ... # Đảm bảo plugin kubernetes đứng trước forward hoặc dùng fallthrough kubernetes cluster.local ... { fallthrough } forward . /etc/resolv.conf # Forward các tên miền khác nếu không khớp mycompany.local hoặc cluster.local # ... }
Important Note: Be careful when editing the CoreDNS ConfigMap. Incorrect configuration can break DNS functionality of the entire cluster. Always test thoroughly after making changes. The reload plugin will automatically apply the changes after a few seconds without restarting the Pod.
Conclude
DNS is an essential, often hidden, yet critically important component of any Kubernetes cluster. Understanding how DNS works, from the basics to specific implementations in K8s with CoreDNS, is key to building and operating robust applications. It provides a flexible service discovery mechanism that allows applications to reliably communicate with each other in the dynamic environment of K8s.