You've probably created many deployments. Typically, you expose your deployment to the Internet by creating a Service with type=LoadBalancer
. Depending on your environment, this usually assigns a random publicly available endpoint to your service that you can access from anywhere in the world. On Google Container Engine, this is a public IP address:
$ kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx 10.3.249.226 35.187.104.85 80:32281/TCP 1m
But dealing with IPs for service discovery isn't nice, so you register this IP with your DNS provider under a better name—most likely, one that corresponds to your service name. If the IP changes, you update the DNS record accordingly.
Those times are over! ExternalDNS takes care of that last step for you by keeping your DNS records synchronized with your external entry points.
ExternalDNS' usefulness also becomes clear when you use Ingresses to allow external traffic into your cluster. Via Ingress, you can tell Kubernetes to route traffic to different services based on certain HTTP request attributes, e.g. the Host header:
$ kubectl get ing
NAME HOSTS ADDRESS PORTS AGE
entrypoint frontend.example.org,backend.example.org 35.186.250.78 80 1m
But there's nothing that actually makes clients resolve those hostnames to the Ingress' IP address. Again, you normally have to register each entry with your DNS provider. Only if you're lucky can you use a wildcard, like in the example above.
EnternalDNS can solve this for you as well.
So far, Google CloudDNS and AWS Route 53 with ALIAS records. There's interest in supporting CoreDNS and Azure DNS. We're open to discussing/adding other providers if the community believes it would be valuable.
Initial support for Google CloudDNS is available since the v0.1
release. Initial support for AWS Route 53 is available in the v0.2
release (CNAME based) and ALIAS is targeted for the v0.3
release.
There are no plans regarding other providers at the moment.
Services exposed via type=LoadBalancer
and for the hostnames defined in Ingress objects. It also seems useful to expose Services with type=NodePort
to point to your cluster's nodes directly, but there's no commitment to doing this yet.
There are three sources of information for ExternalDNS to decide on DNS name. ExternalDNS will pick one in order as listed below:
-
For ingress objects ExternalDNS will create a DNS record based on the host specified for the ingress object. For services ExternalDNS will look for the annotation
external-dns.alpha.kubernetes.io/hostname
on the service and use the corresponding value. -
If compatibility mode is enabled (e.g.
--compatibility={mate,molecule}
flag), External DNS will parse annotations used by Zalando/Mate, wearemolecule/route53-kubernetes. Compatibility mode with Kops DNS Controller is planned to be added in the future. -
If
--fqdn-template
flag is specified, e.g.--fqdn-template={{.Name}}.my-org.com
, ExternalDNS will use service/ingress specifications for the provided template to generate DNS name.
Regarding Services, we'll support the OSI Layer 4 load balancers that Kubernetes creates on AWS and Google Container Engine, and possibly other clusters running on Google Compute Engine.
Regarding Ingress, we'll support:
- Google's Ingress Controller on GKE that integrates with their Layer 7 load balancers (GLBC)
- nginx-ingress-controller v0.9.x with a fronting Service
- Zalando's AWS Ingress controller, based on AWS ALBs and Skipper
ExternalDNS is a joint effort to unify different projects accomplishing the same goals, namely:
- Kops' DNS Controller
- Zalando's Mate
- Molecule Software's route53-kubernetes
We strive to make the migration from these implementations a smooth experience. This means that, for some time, we'll support their annotation semantics in ExternalDNS and allow both implementations to run side-by-side. This enables you to migrate incrementally and slowly phase out the other implementation.
ExternalDNS will allow you to opt into any Services and Ingresses that you want it to consider, by an annotation. This way, it can co-exist with other implementations running in the same cluster if they also support this pattern. However, we'll most likely declare ExternalDNS to be the default implementation. This means that ExternalDNS will consider Services and Ingresses that don't specifically declare which controller they want to be processed by; this is similar to the ingress.class
annotation on GKE.
ExternalDNS since v0.3 implements the concept of owning DNS records. This means that ExternalDNS will keep track of which records it has control over, and will never modify any records over which it doesn't have control. This is a fundamental requirement to operate ExternalDNS safely when there might be other actors creating DNS records in the same target space.
For now ExternalDNS uses TXT records to label owned records, and there might be other alternatives coming in the future releases.
Yes — Zalando replaced Mate with ExternalDNS since its v0.3 release, which now runs in production-level clusters. We are planning to document a step-by-step tutorial on how the switch from Mate to ExternalDNS has occured.
Check out the following decriptive tutorials on how to run ExternalDNS in GKE and AWS.