Workloads often need to resolve private hostnames—such as on-premises databases or VPC resources—without exposing internal records on the public internet. Because Syself Autopilot manages and reconciles CoreDNS automatically, you configure private name resolution by pointing the cluster's upstream resolver (`dnsServers`) to your internal name servers and leveraging cluster-internal Services. This guide explains how upstream forwarding works, how to configure private zones, and critical constraints around control-plane DNS. ## Resolve private names through the cluster's upstream CoreDNS resolves cluster-internal queries (`.cluster.local`) directly and forwards all non-cluster traffic to the node's upstream resolver. You configure this upstream resolver cluster-wide using the `dnsServers` topology variable on the `Cluster` object: ```yaml vars title="cluster.yaml" spec: topology: variables: - name: dnsServers value: ["10.100.0.53"] ``` Because CoreDNS is platform-managed, custom per-zone stub domains (such as a conditional `forward` block for a single internal zone) cannot be configured directly in the Corefile. Instead, all non-cluster DNS traffic routes through the servers configured in `dnsServers`. Point `dnsServers` at a DNS resolver that can serve both internal and external zones such as an on-premises nameserver reached over your [VPN](/docs/hetzner/apalla/network/egress/connect-to-on-prem-or-vpc). This resolver must answer queries for your private domains directly and recursively forward all other requests to the public internet. ## Internal-only Services In-cluster communication remains private by default. Standard `ClusterIP` Services allocate a virtual IP reachable exclusively within the cluster network, while headless Services (`clusterIP: None`) resolve directly to ready pod IPs for predictable per-pod DNS identities. Neither type provisions an external load balancer or publishes public DNS records—making them ideal for internal databases, caches, and inter-service APIs. ## The API endpoint must resolve publicly The cluster's API endpoint name is where split DNS matters most. That name must resolve to the control-plane load balancer from **Syself's side**, not only from your own machine, because the controllers that manage your cluster connect through the same name. > [!WARNING] > Never give the API endpoint a name that only you can resolve, an `/etc/hosts` entry, or a split-horizon view that answers differently inside your own network. If the name does not resolve to the load balancer from the management side, the cluster never finishes provisioning and the control plane remains unavailable. Publish a real, public `A` record for the endpoint name. See [Serve IPv6 clients](/docs/hetzner/apalla/network/load-balancing/serve-ipv6) for the endpoint DNS setup. Restricting who may reach the API is a separate concern from resolving its name; that is the allowlist's responsibility, not DNS's. See [KubeGate: restrict API server access](/docs/hetzner/apalla/security/restrict-api-server-access). ## Where to go next - [Understand in-cluster DNS (CoreDNS)](/docs/hetzner/apalla/network/dns-certs/coredns-behavior-and-tuning) - [Automate DNS records with external-dns](/docs/hetzner/apalla/network/dns-certs/automatic-dns-with-external-dns) - [Diagnose pod DNS resolution](/docs/hetzner/apalla/network/debug/diagnose-pod-dns-resolution)