ExternalDNS

ExternalDNS configures your existing DNS provider to make Kubernetes resources discoverable via public DNS servers by getting resources from the Kubernetes API to create a list of DNS records.

Getting started

Prerequisites

Start by checking the ExternalDNS repo’s deployment instructions to get information about the supported DNS providers and steps to setup ExternalDNS for your provider. Each DNS provider will have its own required steps as well as annotations, arguments, and permissions needed for the following configuration.

Installation

Configuration for a ServiceAccount, ClusterRole, and ClusterRoleBinding are necessary for the ExternalDNS deployment to support compatability with Emissary and allow ExternalDNS to get hostnames from Emissary’s Hosts.

The following configuration is an example configuring Emissary - ExternalDNS integration with AWS Route53 as the DNS provider. Refer to the ExternalDNS documentation above for annotations and arguments for your DNS Provider.

  1. Create a YAML file named externaldns-config.yaml, and copy the following configuration into it.
Ensure that the apiGroups include "getambassador.io" following "networking.k8s.io" and the resources include "hosts" after "ingresses".
```yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: external-dns
  annotations:
    eks.amazonaws.com/role-arn: {ARN} # AWS ARN role
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: external-dns
rules:
  - apiGroups: [""]
    resources: ["services","endpoints","pods"]
    verbs: ["get","watch","list"]
  - apiGroups: ["extensions","networking.k8s.io", "getambassador.io"]
    resources: ["ingresses", "hosts"]
    verbs: ["get","watch","list"]
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["list","watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: external-dns-viewer
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: external-dns
subjects:
  - kind: ServiceAccount
    name: external-dns
    namespace: default
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-dns
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: external-dns
  template:
    metadata:
      labels:
        app: external-dns
      annotations:
        iam.amazonaws.com/role: {ARN} # AWS ARN role
    spec:
      serviceAccountName: external-dns
      containers:
      - name: external-dns
        image: registry.opensource.zalan.do/teapot/external-dns:latest
        args:
        - --source=ambassador-host
        - --domain-filter=example.net # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
        - --provider=aws
        - --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization
        - --aws-zone-type=public # only look at public hosted zones (valid values are public, private or no value for both)
        - --registry=txt
        - --txt-owner-id= {Hosted Zone ID} # Insert Route53 Hosted Zone ID here
```
  1. Review the arguments section from the ExternalDNS deployment

Configure or remove arguments to fit your needs. Additional arguments required for your DNS provider can be found by checking the ExternalDNS repo’s deployment instructions.

  • --source=ambassador-host - required across all DNS providers to tell ExternalDNS to look for hostnames in the Emissary Host configurations.
  1. Apply the above config with the following command to deploy ExternalDNS to your cluster and configure support for Emissary
kubectl apply -f externaldns-ambassador.yaml
For the above example, ensure that you are using an EKS cluster, or register your cluster with AWS so that ExternalDNS can view and edit your AWS Hosted Zones. If you are using a cluster outside EKS and not registered with AWS you will see permissions errors from the ExternalDNS pod when attempting to list the Hosted Zones.

Usage

After applying the above configuration, ExternalDNS is ready to use. Configure a Host with the following annotation to allow ExternalDNS to get the IP address of your Emissary’s LoadBalancer and register it with your DNS provider.

apiVersion: getambassador.io/v3alpha1
kind: Host
metadata:
  name: your-hostname
  annotations:
    external-dns.ambassador-service: $productDeploymentName$.$productNamespace$
spec:
  acmeProvider:
    authority: none
  hostname: your-hostname.example.com

Victory! ExternalDNS is now running and configured to report Emissary’s IP and hostname with your DNS provider.