Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
E

external-dns

> 云原生
Open source

Configure external DNS servers dynamically from Kubernetes resources

9.0K stars0 likes6 views
WebsiteGitHub

About

Configure external DNS servers dynamically from Kubernetes resources


hide:

  • toc
  • navigation

ExternalDNS

ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS providers.

Documentation

This README is a part of the complete documentation, available here and DeepWiki.

What It Does

Inspired by Kubernetes DNS, Kubernetes' cluster-internal DNS server, ExternalDNS makes Kubernetes resources discoverable via public DNS servers. Like KubeDNS, it retrieves a list of resources (Services, Ingresses, etc.) from the Kubernetes API to determine a desired list of DNS records. Unlike KubeDNS, however, it's not a DNS server itself, but merely configures other DNS providers accordingly—e.g. AWS Route 53 or Google Cloud DNS.

In a broader sense, ExternalDNS allows you to control DNS records dynamically via Kubernetes resources in a DNS provider-agnostic way.

The FAQ contains additional information and addresses several questions about key concepts of ExternalDNS.

To see ExternalDNS in action, have a look at this video or read this blogpost.

Running ExternalDNS

ExternalDNS allows you to keep selected zones (via --domain-filter) synchronized with Ingresses and Services of type=LoadBalancer and nodes in many DNS providers. See In-tree providers for the built-in list, and New providers for webhook-based ones.

ExternalDNS is, by default, aware of the records it is managing, therefore it can safely manage non-empty hosted zones. We strongly encourage you to set --txt-owner-id to a unique value that doesn't change for the lifetime of your cluster. You might also want to run ExternalDNS in a dry run mode (--dry-run flag) to see the changes to be submitted to your DNS Provider API.

Note that all flags can be replaced with environment variables; for instance, --dry-run could be replaced with EXTERNAL_DNS_DRY_RUN=1.

ExternalDNS runs as a controller in your cluster, and can also be run locally to test a configuration. For provider-specific setup, see the In-tree providers table (each row links its tutorial) or the webhook providers. More tutorials — ingress controllers, sources, and provider extras — are in the full documentation.

Running Locally

See the contributor guide for details on compiling from source.

Setup Steps

Next, run an application and expose it via a Kubernetes Service:

bash
kubectl run nginx --image=nginx --port=80
kubectl expose pod nginx --port=80 --target-port=80 --type=LoadBalancer

Annotate the Service with your desired external DNS name. Make sure to change example.org to your domain.

bash
kubectl annotate service nginx "external-dns.kubernetes.io/hostname=nginx.example.org."

Optionally, you can customize the TTL value of the resulting DNS record by using the external-dns.kubernetes.io/ttl annotation:

bash
kubectl annotate service nginx "external-dns.kubernetes.io/ttl=10"

For more details on configuring TTL, see advanced ttl.

Use the internal-hostname annotation to create DNS records with ClusterIP as the target.

bash
kubectl annotate service nginx "external-dns.kubernetes.io/internal-hostname=nginx.internal.example.org."

If the service is not of type Loadbalancer you need the --publish-internal-services flag.

Locally run a single sync loop of ExternalDNS.

bash
external-dns --txt-owner-id my-cluster-id --provider google --google-project example-project --source service --once --dry-run

This should output the DNS records it will modify to match the managed zone with the DNS records you desire. It also assumes you are running in the default namespace. See the FAQ for more information regarding namespaces.

Note: TXT records will have the my-cluster-id value embedded. Those are used to ensure that ExternalDNS is aware of the records it manages.

Once you're satisfied with the result, you can run ExternalDNS like you would run it in your cluster: as a control loop, and not in dry-run mode:

bash
external-dns --txt-owner-id my-cluster-id --provider google --google-project example-project --source service

Check that ExternalDNS has created the desired DNS record for your Service and that it points to its load balancer's IP. Then try to resolve it:

bash
dig +short nginx.example.org.
104.155.60.49

Now you can experiment and watch how ExternalDNS makes sure that your DNS records are configured as desired. Here are a couple of things you can try out:

  • Change the desired hostname by modifying the Service's annotation.
  • Recreate the Service and see that the DNS record will be updated to point to the new load balancer IP.
  • Add another Service to create more DNS records.
  • Remove Services to clean up your managed zone (record deletion requires --policy=sync; with --policy=upsert-only records are never deleted).

Note

If using a txt registry and attempting to use a CNAME the --txt-prefix must be set to avoid conflicts. Changing --txt-prefix will result in lost ownership over previously created records.

If externalIPs list is defined for a LoadBalancer service, this list will be used instead of an assigned load balancer IP to create a DNS record. It's useful when you run bare metal Kubernetes clusters behind NAT or in a similar setup, where a load balancer IP differs from a public IP (e.g. with MetalLB).

New providers

No new provider will be added to ExternalDNS in-tree.

ExternalDNS has introduced a webhook system, which can be used to add a new provider. See PR #3063 for all the discussions about it.

Some known providers using webhooks are the ones in the table below.

NOTE: The maintainers of ExternalDNS have not reviewed those providers, use them at your own risk and following the license and usage recommendations provided by the respective projects. The maintainers of ExternalDNS take no responsibility for any issue or damage from the usage of any externally developed webhook.

Provider Repo
Abion https://github.com/abiondevelopment/external-dns-webhook-abion
Adguard Home Provider https://github.com/muhlba91/external-dns-provider-adguard
Akamai Edge DNS https://github.com/PixiBixi/external-dns-akamai-webhook
Anexia https://github.com/anexia/k8s-external-dns-webhook
Bizfly Cloud https://github.com/bizflycloud/external-dns-bizflycloud-webhook
ClouDNS https://github.com/rwunderer/external-dns-cloudns-webhook
deSEC https://github.com/michelangelomo/external-dns-desec-provider
DigitalOcean https://github.com/amoniacou/external-dns-digitalocean-webhook
Dreamhost https://github.com/asymingt/external-dns-dreamhost-webhook
Efficient IP https://github.com/EfficientIP-Labs/external-dns-efficientip-webhook
Gcore https://github.com/G-Core/external-dns-gcore-webhook
GleSYS https://github.com/glesys/external-dns-glesys
Hetzner https://github.com/mconfalonieri/external-dns-hetzner-webhook
Huawei Cloud https://github.com/setoru/external-dns-huaweicloud-webhook
IONOS https://github.com/ionos-cloud/external-dns-ionos-webhook
Infoblox https://github.com/AbsaOSS/external-dns-infoblox-webhook
Infomaniak https://github.com/M0NsTeRRR/external-dns-webhook-infomaniak
Mikrotik https://github.com/mirceanton/external-dns-provider-mikrotik
Myra Security https://github.com/Myra-Security-GmbH/external-dns-myrasec-webhook
Namecheap https://github.com/evandeaubl/external-dns-namecheap-webhook
NAVER Cloud Platform https://github.com/NaverCloudPlatform/external-dns-navercloud-webhook
Netbird https://codeberg.org/ccbash-oss/external-dns-netbird-webhook
Netcup https://github.com/mrueg/external-dns-netcup-webhook
Netic https://github.com/neticdk/external-dns-tidydns-webhook
OpenStack Designate https://github.com/inovex/external-dns-designate-webhook
OpenWRT https://github.com/renanqts/external-dns-openwrt-webhook
Porkbun https://github.com/mattgmoser/external-dns-porkbun-webhook
PS Cloud Services https://github.com/supervillain3000/external-dns-pscloud-webhook
SAKURA Cloud https://github.com/sacloud/external-dns-sacloud-webhook
Simply https://github.com/uozalp/external-dns-simply-webhook
STACKIT https://github.com/stackitcloud/external-dns-stackit-webhook
Tencent Cloud https://github.com/tkestack/external-dns-tencentcloud-webhook
Unbound https://github.com/guillomep/external-dns-unbound-webhook
Unifi https://github.com/home-operations/external-dns-unifi-webhook
UniFi https://github.com/lexfrei/external-dns-unifios-webhook
Volcengine Cloud https://github.com/volcengine/external-dns-volcengine-webhook
Vultr https://github.com/vultr/external-dns-vultr-webhook
Yandex Cloud https://github.com/ismailbaskin/external-dns-yandex-webhook/

In-tree providers

ExternalDNS supports the DNS providers below, implemented by the ExternalDNS contributors. Maintaining all of these in a central repository introduces lots of toil and potential risks, so external-dns has begun moving providers out of tree (see #4347). No new in-tree providers are accepted; use the webhook system instead.

Those interested can create a webhook provider based on an in-tree provider and submit a PR to reference it in the table above. Providers without a maintainer listed are in need of assistance.

Provider Maintainers Tutorials
Alibaba Cloud DNS guide
AWS Cloud Map guide

Issues· 187 open

View all issuesOpen on GitHub
  • #6769

    feat(source): support NodePort and ClusterIP service targets

    Updated Sep 29, 2026
  • #6741

    Update Helm chart to v0.23.0

    area/releaseUpdated Sep 28, 2026
  • #6754

    rfc2136 provider can write MX records but cannot read them back (AXFR handler has no MX case)

    Updated Sep 24, 2026
  • #6125

    no txt records created for root domains because of the recordtype prefix

    kind/buglifecycle/staleUpdated Sep 24, 2026
  • #6753

    Update multiple Piholes on change

    kind/featureUpdated Sep 24, 2026
  • #6535

    Support automatic ACME DNS-01 delegation CNAME generation

    kind/featureUpdated Sep 23, 2026
  • #4062

    AWS Route 53 entries with wildcard "*" are created by external-dns the first time, but every time after that it says "Failed submitting change"

    kind/buglifecycle/staleUpdated Sep 19, 2026
  • #6712

    Semantic releases to prevent breaking changes causing issues

    kind/featureUpdated Sep 18, 2026
  • #6733

    RFC2136 Provider Fails to Update DNS When First Nameserver is Down

    kind/bugUpdated Sep 17, 2026
  • #6732

    RFC2136: AXFR error: dns: no signature found on multi-message AXFR despite successful transfer on server side

    kind/bugUpdated Sep 16, 2026

> Tags

Goawsclouddnsdnsdns-controller

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 29, 2026
Category云原生
PricingOpen source

> Related tools

K
Kubernetes
容器编排事实标准
H
Helm
Kubernetes 包管理器
S
seaweedfs
SeaweedFS is a distributed storage system for object storage (S3), file systems, and Iceberg tables,