All Products
Search
Document Center

Container Compute Service:Configure custom parameters for managed CoreDNS

Last Updated:Mar 26, 2026

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:

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.

  1. Create a file named default.yaml with 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.252

    This configuration defines two zones:

    • `example.com` — Queries are forwarded to 100.100.2.136 and 100.100.2.138.

      Note: 100.100.2.136 and 100.100.2.138 are the default internal DNS resolution service addresses. For more information, see Endpoints.
    • `foo.com`a.foo.com resolves to 192.168.0.251 and b.foo.com resolves to 192.168.0.252.

  2. Apply the CR:

    kubectl apply -f default.yaml
  3. Verify the Corefile was generated:

    kubectl get customdnsconfig default -o yaml | grep corefile -A 35 -B 1

    The 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: GenerateSuccess

    A phase: GenerateSuccess status 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 ".".

  1. Create a file named default.yaml with 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
  2. Apply the CR:

    kubectl apply -f default.yaml
  3. Verify the Corefile was generated:

    kubectl get customdnsconfig default -o yaml | grep corefile -A 35 -B 1

    The 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: GenerateSuccess
    After you create or update a CustomDNSConfig CR, CoreDNS performs a configuration reload. This takes approximately 20 seconds by default (controlled by the lameduck parameter 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