You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Vladimir Smagin ca5bd7ca4f bump lib version 4 months ago
.github Update pull requests template 4 months ago
controller dependencies: Upgrade all k8s client-go dependent sources to v1.18.X 6 months ago
docs Merge pull request #1704 from DataDog/aws-cache-zones-list 4 months ago
endpoint *: fix goreportcard golint warnings 8 months ago
img Add Logo for ExternalDNS (#313) 3 years ago
internal add license header check to the CI 4 months ago
kustomize chore(kustomize): move image tag to kustomization.yaml 4 months ago
pkg Merge pull request #1704 from DataDog/aws-cache-zones-list 4 months ago
plan Remove unnecessary import 7 months ago
provider fix hetzner records update 4 months ago
registry Fix index out of range when hostname has no dots 4 months ago
scripts adding kubernetes adder 2 years ago
source Merge pull request #1628 from josephglanville/jpg/contour-httpproxy 4 months ago
.gitignore Using dep in travis to ensure all dependencies are installed (#471) 2 years ago
.golangci.yml fix goimports local import order and update golangci-lint 5 months ago
.zappr.yaml chore: add zappr file in order to push to pierone (#279) 3 years ago aws: cache zones list 4 months ago Update Contributing Documentation 4 months ago
Dockerfile use latest Alpine version in ExternalDNS dockerfile 6 months ago Update go versions to 1.14.x that were missed in commit 99cebfcf from PR #1476 8 months ago
LICENSE Initial commit 3 years ago
Makefile Moved coverprofile creation into Makefile 4 months ago
OWNERS Move Inactive Maintainers To Emeritus Approvers 4 months ago Remove test automation section from contributing docs 4 months ago
SECURITY_CONTACTS Remove occurrences of "master" from the project (#1636) 6 months ago
cloudbuild.yaml fix: add version to binary for --version flag 1 year ago Update (#426) 3 years ago
go.mod bump lib version 4 months ago
go.sum bump kubernetes dependencies and run go mod tidy 5 months ago
main.go aws: cache zones list 4 months ago



Build Status Coverage Status GitHub release go-doc Go Report Card

ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS providers.

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.

The Latest Release: v0.7

ExternalDNS' current release is v0.7. This version allows you to keep selected zones (via --domain-filter) synchronized with Ingresses and Services of type=LoadBalancer in various cloud providers:

From this release, ExternalDNS can become aware of the records it is managing (enabled via --registry=txt), therefore ExternalDNS can safely manage non-empty hosted zones. We strongly encourage you to use v0.5 (or greater) with --registry=txt enabled and --txt-owner-id set 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, or --registry txt could be replaced with EXTERNAL_DNS_REGISTRY=txt.

Status of providers

ExternalDNS supports multiple DNS providers which have been implemented by the ExternalDNS contributors. Maintaining all of those in a central repository is a challenge and we have limited resources to test changes. This means that it is very hard to test all providers for possible regressions and, as written in the Contributing section, we encourage contributors to step in as maintainers for the individual providers and help by testing the integrations.

End-to-end testing of ExternalDNS is currently performed in the separate kubernetes-on-aws repository.

We define the following stability levels for providers:

  • Stable: Used for smoke tests before a release, used in production and maintainers are active.
  • Beta: Community supported, well tested, but maintainers have no access to resources to execute integration tests on the real platform and/or are not using it in production.
  • Alpha: Community provided with no support from the maintainers apart from reviewing PRs.

The following table clarifies the current status of the providers according to the aforementioned stability levels:

Provider Status Maintainers
Google Cloud DNS Stable
AWS Route 53 Stable
AWS Cloud Map Beta
AzureDNS Beta
CloudFlare Beta
RcodeZero Alpha
DigitalOcean Alpha
Hetzner Alpha @21h
DNSimple Alpha
Infoblox Alpha @saileshgiri
Dyn Alpha
OpenStack Designate Alpha
PowerDNS Alpha
CoreDNS Alpha
Exoscale Alpha
Oracle Cloud Infrastructure DNS Alpha
Linode DNS Alpha
RFC2136 Alpha
NS1 Alpha
TransIP Alpha
VinylDNS Alpha
RancherDNS Alpha
Akamai FastDNS Alpha
OVH Alpha
Scaleway DNS Alpha @Sh4d1
Vultr Alpha
UltraDNS Alpha

Running ExternalDNS:

The are two ways of running ExternalDNS:

  • Deploying to a Cluster
  • Running Locally

Deploying to a Cluster

The following tutorials are provided:

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:

$ kubectl run nginx --image=nginx --replicas=1 --port=80
$ kubectl expose deployment nginx --port=80 --target-port=80 --type=LoadBalancer

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

$ kubectl annotate service nginx ""

Optionally, you can customize the TTL value of the resulting DNS record by using the annotation:

$ kubectl annotate service nginx ""

For more details on configuring TTL, see here.

Locally run a single sync loop of ExternalDNS.

$ external-dns --registry txt --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 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:

$ external-dns --registry txt --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:

$ dig +short

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.

The tutorials section contains examples, including Ingress resources, and shows you how to set up ExternalDNS in different environments such as other cloud providers and alternative Ingress controllers.


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.


ExternalDNS was built with extensibility in mind. Adding and experimenting with new DNS providers and sources of desired DNS records should be as easy as possible. It should also be possible to modify how ExternalDNS behaves—e.g. whether it should add records but never delete them.

Here's a rough outline on what is to come (subject to change):








Yet to be defined

  • Support for CoreDNS
  • Support for record weights
  • Support for different behavioral policies
  • Support for Services with type=NodePort
  • Support for CRDs
  • Support for more advanced DNS record configurations

Have a look at the milestones to get an idea of where we currently stand.


Are you interested in contributing to external-dns? We, the maintainers and community, would love your suggestions, contributions, and help! Also, the maintainers can be contacted at any time to learn more about how to get involved.

We also encourage ALL active community participants to act as if they are maintainers, even if you don't have "official" write permissions. This is a community effort, we are here to serve the Kubernetes community. If you have an active interest and you want to get involved, you have real power! Don't assume that the only people who can get things done around here are the "maintainers". We also would love to add more "official" maintainers, so show us what you can do!

The external-dns project is currently in need of maintainers for specific DNS providers. Ideally each provider would have at least two maintainers. It would be nice if the maintainers run the provider in production, but it is not strictly required. Provider listed here that do not have a maintainer listed are in need of assistance.

Read the contributing guidelines and have a look at the contributing docs to learn about building the project, the project structure, and the purpose of each package.

For an overview on how to write new Sources and Providers check out Sources and Providers.


ExternalDNS is an effort to unify the following similar projects in order to bring the Kubernetes community an easy and predictable way of managing DNS records across cloud providers based on their Kubernetes resources:

User Demo How-To Blogs and Examples