KubernetesCXIII · Kubernetes DNS Advanced TroubleshootingDNS advanced troubleshooting
Stub domains and upstream resolvers — overriding DNS for specific zones
What you'll learn
- Configure stub domains for specific zones
- Configure upstream resolvers per zone
- Reason about corporate DNS integration
- Apply the operational discipline of testing DNS changes
Prerequisites
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
Stub domains and upstream resolvers allow Kubernetes Pods to query specific DNS servers for specific zones. This lesson walks the configuration, the use cases, and the discipline.
The stub domain concept
flowchart LR
A[Pod] -->|query billing.corp| B[CoreDNS]
B -->|stub .corp| C[Corporate DNS]
C -->|response| B
B -->|response| A
A -->|query api.example.com| B
B -->|forward .| D[Upstream DNS]
D -->|response| B
B -->|response| A
The stub domain concept:
- Stub domains. Queries for specific zones are sent to specific upstream DNS servers.
- Upstream resolvers. Queries for everything else go to the default upstream.
A Pod that queries billing.corp is sent to the
corporate DNS; a Pod that queries api.example.com
goes to the upstream DNS (e.g., cloud DNS).
Pod-level stub domains (legacy)
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
dnsConfig:
stubDomains:
- corp: [10.0.0.10] # queries for .corp go to 10.0.0.10
- internal: [10.0.0.11] # queries for .internal go to 10.0.0.11
nameservers:
- 10.96.0.10 # CoreDNS
containers:
- name: app
image: myapp
The Pod-level stub domains:
.corpis sent to10.0.0.10(corporate DNS)..internalis sent to10.0.0.11(internal DNS).- Everything else goes to CoreDNS (
10.96.0.10).
This is the legacy approach; the recommended approach is to configure CoreDNS directly.
CoreDNS forward plugin (preferred)
.:53 {
errors
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
forward . /etc/resolv.conf
forward .corp 10.0.0.10 {
prefer_health
}
forward .internal 10.0.0.11 {
prefer_health
}
cache 30
prometheus :9153
}
The CoreDNS forward plugin:
forward .corp 10.0.0.10— queries for.corpzones go to 10.0.0.10.forward .internal 10.0.0.11— queries for.internalgo to 10.0.0.11.forward . /etc/resolv.conf— queries for everything else go to the upstream DNS in /etc/resolv.conf.
The CoreDNS approach is preferred because it’s cluster-wide, not per-Pod.
The use cases
flowchart LR
A[Use cases] --> B[Corporate DNS integration]
A --> C[Internal services not in Kubernetes]
A --> D[Conditional forwarding]
A --> E[Compliance requirements]
The use cases:
- Corporate DNS integration. Resolve
.corpzones via the corporate DNS. - Internal services not in Kubernetes. Resolve
.internalzones (legacy systems, databases). - Conditional forwarding. Different upstreams for different zones.
- Compliance. Some regulations require DNS resolution to stay within certain boundaries.
The verification
# Inside a Pod
kubectl exec -it myapp-pod -- nslookup billing.corp
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: billing.corp
Address: 10.0.5.10
The query goes to CoreDNS, which forwards to the
corporate DNS (10.0.0.10), which returns the
address (10.0.5.10).
kubectl exec -it myapp-pod -- nslookup api.example.com
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: api.example.com
Address: 93.184.216.34
The query goes to CoreDNS, which forwards to the upstream DNS, which returns the public address.
The operational trade-offs
flowchart LR
A[Pod stubDomains] --> B[+ Per-Pod control]
A --> C[- Per-Pod config]
A --> D[- Difficult to manage at scale]
E[CoreDNS forward] --> F[+ Cluster-wide]
F --> G[- Affects every Pod]
The trade-offs:
Pod stubDomains:
- Pros: Per-Pod control.
- Cons: Per-Pod config; difficult to manage at scale.
CoreDNS forward:
- Pros: Cluster-wide; one place to configure.
- Cons: Affects every Pod; a misconfiguration affects all.
Quiz
Knowledge check · 4 questions
Q1. How is a stub domain configured in the preferred, modern approach?
Q2. A CoreDNS Corefile change takes effect without restarting the CoreDNS Pods.
Q3. Make an internal corporate zone resolvable from Pods without sending those names to the public upstream.
Applications need to reach ldap.corp.example.com, which exists only in the corporate DNS at 10.0.0.10. From a Pod, `dig ldap.corp.example.com` returns NXDOMAIN with the answer coming from 10.96.0.10. The Corefile contains a single `forward . /etc/resolv.conf` stanza and no zone-specific forwarding. Cluster names and public names both resolve correctly.
Q4. In a Corefile, what is the first argument to the forward plugin, and what happens if two forward stanzas declare the same zone inside one server block?
Passing score: 75%. Answers are checked in this browser.
The operational discipline
Stub domains and upstream resolvers in production rest on five non-negotiable elements:
- Use CoreDNS forward, not Pod stubDomains. Cluster-wide, easier to manage.
- Test the configuration in staging. A misconfiguration can leak internal DNS to public.
- Document the zones. Which zones are stubbed; which upstreams serve them.
- Monitor CoreDNS. Ensure the forward is working; alert on upstream failures.
- Restrict access to the corporate DNS. Use NetworkPolicy to allow only CoreDNS to query the corporate DNS.
Stub domains are production DNS configuration. The discipline is to test, document, and monitor.