Skip to content

Setup External DNS

external-dns provisions DNS records based on the host information. This project will setup and manage records in Route 53 that point to controller deployed ALBs.

Prerequisites

Role Permissions

Adequate roles and policies must be configured in AWS and available to the node(s) running the external-dns. See https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/aws.md#iam-permissions.

Installation

  1. Download sample external-dns manifest

    wget https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/examples/external-dns.yaml
    
  2. Edit the --domain-filter flag to include your hosted zone(s)

    The following example is for a hosted zone test-dns.com:

    args:
    - --source=service
    - --source=ingress
    - --domain-filter=test-dns.com # 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=my-identifier
    
  3. Deploy external-dns

    kubectl apply -f external-dns.yaml
    
  4. Verify it deployed successfully.

    kubectl logs -f $(kubectl get po | egrep -o 'external-dns[A-Za-z0-9-]+')
    

    Should display output similar to the following:

    time="2019-12-11T10:26:05Z" level=info msg="config: {Master: KubeConfig: RequestTimeout:30s IstioIngressGateway:istio-system/istio-ingressgateway Sources:[service ingress] Namespace: AnnotationFilter: FQDNTemplate: CombineFQDNAndAnnotation:false Compatibility: PublishInternal:false PublishHostIP:false ConnectorSourceServer:localhost:8080 Provider:aws GoogleProject: DomainFilter:[test-dns.com] ZoneIDFilter:[] AlibabaCloudConfigFile:/etc/kubernetes/alibaba-cloud.json AlibabaCloudZoneType: AWSZoneType:public AWSAssumeRole: AWSBatchChangeSize:4000 AWSBatchChangeInterval:1s AWSEvaluateTargetHealth:true AzureConfigFile:/etc/kubernetes/azure.json AzureResourceGroup: CloudflareProxied:false InfobloxGridHost: InfobloxWapiPort:443 InfobloxWapiUsername:admin InfobloxWapiPassword: InfobloxWapiVersion:2.3.1 InfobloxSSLVerify:true DynCustomerName: DynUsername: DynPassword: DynMinTTLSeconds:0 OCIConfigFile:/etc/kubernetes/oci.yaml InMemoryZones:[] PDNSServer:http://localhost:8081 PDNSAPIKey: PDNSTLSEnabled:false TLSCA: TLSClientCert: TLSClientCertKey: Policy:upsert-only Registry:txt TXTOwnerID:my-identifier TXTPrefix: Interval:1m0s Once:false DryRun:false LogFormat:text MetricsAddress::7979 LogLevel:info TXTCacheInterval:0s ExoscaleEndpoint:https://api.exoscale.ch/dns ExoscaleAPIKey: ExoscaleAPISecret: CRDSourceAPIVersion:externaldns.k8s.io/v1alpha CRDSourceKind:DNSEndpoint ServiceTypeFilter:[] RFC2136Host: RFC2136Port:0 RFC2136Zone: RFC2136Insecure:false RFC2136TSIGKeyName: RFC2136TSIGSecret: RFC2136TSIGSecretAlg: RFC2136TAXFR:false}"
    time="2019-12-11T10:26:05Z" level=info msg="Created Kubernetes client https://10.100.0.1:443"
    

Usage

  1. To create a record set in the subdomain, from your ingress which has been created by the ingress-controller, add the following annotation in the ingress objectresource:

    annotations:
      kubernetes.io/ingress.class: alb
      alb.ingress.kubernetes.io/scheme: internet-facing
    
      # external-dns specific configuration for creating route53 record-set
      external-dns.alpha.kubernetes.io/hostname: my-app.test-dns.com # give your domain name here
    
  2. A snippet of the external-dns pod log indicating route53 update:

    time="2019-12-11T10:26:08Z" level=info msg="Desired change: CREATE my-app.test-dns.com A"
    time="2019-12-11T10:26:08Z" level=info msg="Desired change: CREATE my-app.test-dns.com TXT"
    time="2019-12-11T10:26:08Z" level=info msg="2 record(s) in zone my-app.test-dns.com. were successfully updated"
    
  3. External DNS configures Simple routing policy for the route53 records. You can configure Weighted policy by specifying the weight and the identifier via annotation. Weighted policy allows you to split the traffic between multiple load balancers. Here is an example to specify weight and identifier:

     annotations:
       # For creating weighted route53 records
       external-dns.alpha.kubernetes.io/hostname: my-app.test-dns.com
       external-dns.alpha.kubernetes.io/aws-weight: "100"
       external-dns.alpha.kubernetes.io/set-identifier: "3"
    
    You can refer to the External DNS documentation for further details [link].