skip to content

What do the Kubernetes pod spec fields dnsPolicy and dnsConfig control, and what are the available dnsPolicy values?

level: middleimportance: should knowfreq 34%

answer

  1. ClusterFirst = default cluster DNS
  2. hostNetwork needs ClusterFirstWithHostNet
  3. 'Default' means node's resolver — not the default
  4. None requires dnsConfig
  5. dnsConfig merges with cluster policies; ndots override

basics

~20 s

dnsPolicy chooses which resolver configuration a pod gets: ClusterFirst (the default, cluster DNS), ClusterFirstWithHostNet (cluster DNS for pods sharing the node network namespace), Default (inherit the node's resolver settings), or None (supply everything yourself). dnsConfig adds or replaces nameservers, search domains and resolver options.

solid answer

~50 s

`dnsPolicy` selects the source of the pod's `/etc/resolv.conf`: - **ClusterFirst** — the default. Cluster DNS is the nameserver, with the cluster search list and `ndots:5`; anything not in the cluster domain is forwarded upstream by CoreDNS. - **ClusterFirstWithHostNet** — required to get cluster DNS in a pod with `hostNetwork: true`. Without it such a pod silently falls back to the node's resolver and cannot resolve Service names. - **Default** — despite the name, *not* the default: the pod inherits the node's resolver configuration, so cluster Service names do not resolve. - **None** — no configuration is generated; `dnsConfig` must supply it. `dnsConfig` tunes the result: `nameservers`, `searches`, and `options` such as `ndots`. With `None` those values are the entire configuration; with the cluster policies they are **merged** with what Kubernetes generated, which is the usual way to lower `ndots` for one workload.

code

yaml · 10 lines
yaml
apiVersion: v1
kind: Pod
metadata:
  name: node-agent
spec:
  hostNetwork: true
  dnsPolicy: ClusterFirstWithHostNet   # without this, cluster names do not resolve
  containers:
    - name: agent
      image: agent:2.1

go deeper

for a junior

Name the four values and know the default is ClusterFirst; the key recall is that 'Default' means the node's settings, not the default choice.

for a middle

Explain merge semantics of dnsConfig and give a real use for each policy, especially the host-network case.

for a senior

Lead with the diagnostic habit of reading the pod's effective /etc/resolv.conf, and discuss lowering ndots for egress-heavy workloads and the short-name breakage it can cause.

for a principal

Treat these fields as governance surface: workloads setting None escape node-local caching and forwarding policy, so decide whether admission control defaults or constrains them per workload class.

## What these fields do Every pod gets an `/etc/resolv.conf` written for it. `dnsPolicy` chooses the template used to generate it; `dnsConfig` adjusts the result. Together they are the only supported way to change name resolution for a workload without editing files at runtime. ## The four dnsPolicy values **`ClusterFirst`** — the default when the field is omitted. The kubelet writes the cluster DNS Service address as `nameserver`, the namespace-scoped search list, and `options ndots:5`. Cluster names are answered by CoreDNS from its live view of Services and endpoints; anything else CoreDNS forwards to its configured upstream resolvers. The name is slightly misleading: it does not mean "try the cluster then try elsewhere" in the resolver — the resolver only ever talks to CoreDNS, and CoreDNS decides what to forward. **`ClusterFirstWithHostNet`** — behaves like `ClusterFirst`, but must be set explicitly on pods with `hostNetwork: true`. This is the single most common trap in this area: a host-network pod with the default policy does **not** get cluster DNS, because the pod shares the node's network namespace and the kubelet applies the node's resolver settings. The symptom is a node agent or exporter that cannot resolve any `*.svc.cluster.local` name while everything else works. The fix is one line. **`Default`** — the pod inherits the node's `/etc/resolv.conf` (whatever the kubelet was configured to treat as the host resolver). Cluster Service names will not resolve unless the node's resolver happens to know them. It is useful for workloads that must resolve exactly as the node does — some node-level tooling, or a debugging container — and its name causes endless confusion, because it is not the default. **`None`** — Kubernetes generates nothing. The pod's resolver configuration comes entirely from `dnsConfig`, which then becomes mandatory. Use it when a workload must talk to a specific resolver, for example a pod that queries an internal corporate DNS directly and must not inherit cluster search paths. ## dnsConfig Three fields: - `nameservers` — a list of resolver addresses. With `None` these are the only servers; otherwise they are appended to the generated one (with a limit on total entries, typically three for the standard resolver). - `searches` — extra search suffixes, appended to the generated list. Useful to give a workload a legacy internal suffix so that historic short names keep resolving. - `options` — resolver options as name/value pairs. The common uses are `ndots` (lowering it for egress-heavy workloads) and options that change how parallel queries are issued, which some teams use to work around a UDP query-collision race that causes multi-second resolution stalls. Merge semantics matter: with `ClusterFirst`, `dnsConfig` **adds to** what Kubernetes generated, and a repeated option overrides the generated one — so setting `ndots: "2"` replaces `ndots:5` while leaving nameserver and search list intact. With `None`, nothing is generated and omissions mean the setting is simply absent. ## Choosing correctly - Ordinary application → leave it alone; `ClusterFirst` is right. - Egress-heavy application making many external calls → `ClusterFirst` plus `dnsConfig` lowering `ndots`, after checking the workload does not depend on short cross-namespace names. - Node agent with `hostNetwork: true` that must reach in-cluster Services → `ClusterFirstWithHostNet`. - Node-level tool that must see exactly what the node sees → `Default`. - Workload that must use a specific external resolver and nothing else → `None` with an explicit `dnsConfig`. ## Operational notes These fields are part of the pod template, so changing them triggers a rollout — they are not runtime tunables. In a platform team, they are also a governance surface: a workload that sets `None` bypasses cluster DNS entirely, escaping any node-local caching, forwarding rules or query visibility the platform relies on. Admission policy is the usual place to constrain that, and to inject a default `ndots` for a workload class rather than asking every team to remember it. When debugging, always read the effective file rather than the manifest: `kubectl exec <pod> -- cat /etc/resolv.conf` shows what the pod actually received, which immediately reveals a host-network pod that never got cluster DNS.

  • A DaemonSet with hostNetwork: true cannot resolve any *.svc.cluster.local name, though it reaches the internet fine. What is wrong?
    Its dnsPolicy is still ClusterFirst, which for a host-network pod means the kubelet gives it the node's resolver configuration rather than cluster DNS. External names resolve because the node's resolver handles them; cluster names do not, because the node's resolver knows nothing about Services. Setting dnsPolicy: ClusterFirstWithHostNet fixes it, and the change requires a rollout since it lives in the pod template.
  • How do dnsConfig values interact with an existing cluster DNS policy?
    They are merged into the generated configuration rather than replacing it: extra nameservers are appended, extra search suffixes are added to the cluster list, and an option specified with the same name overrides the generated value. That is why setting ndots in dnsConfig under ClusterFirst changes only the threshold and leaves cluster resolution intact. Under dnsPolicy: None nothing is generated, so dnsConfig is the complete configuration.

saying these in an interview costs you the question

  • Believing dnsPolicy: Default is the default value
  • Setting hostNetwork: true and expecting cluster Service names to resolve anyway
  • Using dnsPolicy: None without dnsConfig, which the API rejects
  • Thinking dnsConfig replaces the whole configuration under ClusterFirst rather than merging
  • Treating these as runtime settings instead of pod-template fields that require a rollout

context