Managed CoreDNS handles DNS resolution for pods in your cluster. By default, it resolves internal cluster services and forwards all other queries to Alibaba Cloud DNS PrivateZone. To route external domain queries to a specific upstream DNS server, or to map domain names to static IP addresses, define a CustomDNSConfig custom resource (CR).
Prerequisites
Before you begin, ensure that you have:
-
Managed CoreDNS plug-in installed, version 1.9.3.20 or later. For installation instructions, see Manage components.
-
A kubectl client connected to your cluster. For connection instructions, see Obtain the kubeconfig file of a cluster and use kubectl to connect to the cluster.
How it works
CustomDNSConfig is a Kubernetes custom resource definition (CRD) that lets you configure DNS behavior per zone without editing the CoreDNS Corefile directly. When you apply a CustomDNSConfig CR, the managed CoreDNS controller reads it, generates the corresponding Corefile configuration, and reloads CoreDNS automatically.
The CR supports two configuration options per zone:
-
`forward` — Route DNS queries for a zone to one or more upstream DNS servers.
-
`hosts` — Map domain names to static IP addresses within a zone.
The following example shows the full CR structure:
apiVersion: networking.alibabacloud.com/v1beta1
kind: CustomDNSConfig
metadata:
name: default
namespace: default
spec:
zones:
- name: example.com
forward:
protocolStrategy: ""
transportConfig: {}
upstreams:
- xxx.xxx.xxx.xxx # IP address
- xxx.xxx.xxx.xxx:53 # IP:port
hosts:
- hostName: "a.example.com"
ipAddress: xxx.xxx.xxx.xxx
Key constraints
| Field | Default | Constraints |
|---|---|---|
spec.zones[].name |
"." (the default zone) |
Must be a fully qualified domain name (FQDN) |
spec.zones[].forward.protocolStrategy |
"" (UDP) |
Set to tcp to use TCP instead |
spec.zones[].forward.transportConfig |
{} |
Read-only; cannot be modified |
spec.zones[].forward.upstreams |
Falls back to Alibaba Cloud DNS PrivateZone | IP or IP:port, IPv4 only, up to 15 addresses per zone |
spec.zones[].hosts[].hostName |
— | Must comply with DNS naming specifications |
spec.zones[].hosts[].ipAddress |
— | Must be a valid IPv4 address |
One CR per cluster: CustomDNSConfig is not namespace-scoped. Only one CR is supported per cluster, and it must be named default. This is a design constraint of the managed CoreDNS controller — CRs with any other name are rejected with a NotSupported status. See Troubleshooting for details.
Add custom DNS zones
Use this approach to route queries for specific domains to dedicated upstream DNS servers, or to add static host entries.
-
Create a file named
default.yamlwith the following content:apiVersion: networking.alibabacloud.com/v1beta1 kind: CustomDNSConfig metadata: name: default spec: zones: - name: example.com forward: upstreams: - 100.100.2.136 # Upstream DNS servers for example.com - 100.100.2.138 - name: foo.com hosts: - hostName: "a.foo.com" # Static IP mappings for foo.com ipAddress: 192.168.0.251 - hostName: "b.foo.com" ipAddress: 192.168.0.252This configuration defines two zones:
-
`example.com` — Queries are forwarded to
100.100.2.136and100.100.2.138.Note:
100.100.2.136and100.100.2.138are the default internal DNS resolution service addresses. For more information, see Endpoints. -
`foo.com` —
a.foo.comresolves to192.168.0.251andb.foo.comresolves to192.168.0.252.
-
-
Apply the CR:
kubectl apply -f default.yaml -
Verify the Corefile was generated:
kubectl get customdnsconfig default -o yaml | grep corefile -A 35 -B 1The output should look similar to:
status: corefile: | example.com:53 { prometheus :9153 forward . 100.100.2.136 100.100.2.138 { policy random prefer_udp } ... } foo.com:53 { prometheus :9153 hosts { 192.168.0.251 a.foo.com 192.168.0.252 b.foo.com fallthrough } forward . /etc/resolv.conf { policy random prefer_udp } ... } ... -- corefileHash: 41f7be21cf3022c305091665ed33b1e5 lastTransitionTime: "2024-09-13T09:07:37Z" phase: GenerateSuccessA
phase: GenerateSuccessstatus confirms the CR was processed and the Corefile was updated.
Modify the default zone
To override the upstream DNS servers used for all cluster queries (the "." zone), configure a zone named ".".
-
Create a file named
default.yamlwith the following content:apiVersion: networking.alibabacloud.com/v1beta1 kind: CustomDNSConfig metadata: name: default spec: zones: - name: . forward: upstreams: - 100.100.2.136 # Custom upstream DNS servers for the default zone - 100.100.2.138 -
Apply the CR:
kubectl apply -f default.yaml -
Verify the Corefile was generated:
kubectl get customdnsconfig default -o yaml | grep corefile -A 35 -B 1The output should look similar to:
status: corefile: | .:53 { errors health { lameduck 20s } ready kubeapi { kubeconfig /etc/kubernetes/config/managed-coredns.conf } k8s_event { level error warning } ... prometheus :9153 forward . 100.100.2.136 100.100.2.138 { policy random prefer_udp } ... } corefileHash: 847bf69cc4c97cee965945f45d17c661 lastTransitionTime: "2024-09-13T09:54:22Z" phase: GenerateSuccessAfter you create or update a
CustomDNSConfigCR, CoreDNS performs a configuration reload. This takes approximately 20 seconds by default (controlled by thelameduckparameter in the Corefile).
Map a domain to multiple IP addresses
A single hostName entry can map to multiple IP addresses. CoreDNS returns all addresses and the client selects one:
hosts:
- hostName: "a.example.com"
ipAddress: 10.0.0.123
- hostName: "a.example.com"
ipAddress: 10.0.0.124
Troubleshooting
CR status shows NotSupported
Only one CustomDNSConfig CR named default is supported per cluster. If you create a CR with any other name, the controller sets its status to NotSupported and ignores it.
To reproduce the error, create a CR named test:
apiVersion: networking.alibabacloud.com/v1beta1
kind: CustomDNSConfig
metadata:
name: test
spec:
zones:
- name: example.com
forward:
upstreams:
- 100.100.2.138
- name: foo.com
hosts:
- hostName: "ah.foo.com"
ipAddress: 1.1.xx.251
- hostName: "aha.foo.com"
ipAddress: 1.1.xx.252
After running kubectl apply -f test.yaml, check the status:
kubectl get customdnsconfig
Expected output:
NAME PHASE VERSION AGE
default GenerateSuccess 847bf69cc4c97cee96xxxxxxxxxxx 89m
test NotSupported 9s
To resolve this, delete the misnamed CR and apply your configuration using a CR named default instead.
View sync events
The managed CoreDNS controller syncs events to the default namespace. To view recent events:
kubectl get events
A successful sync produces output similar to:
LAST SEEN TYPE REASON OBJECT MESSAGE
45m Normal CustomDNSConfigSyncOk customdnsconfig/default custom dns config sync to coredns configmap success