Tanzu Packages latest

Install External DNS for Service Discovery

Last Updated February 10, 2025

This topic gives an overview of the External DNS package, which you can install in Tanzu Kubernetes Grid (TKG) workload clusters to provide service discovery services for the cluster.

External DNS allows for DNS records to be created automatically for Kubernetes services with an ingress component such as Contour with Envoy. The External DNS package is validated with the following DNS providers: AWS (Route 53), Azure DNS, and RFC2136-compliant DNS servers (such as BIND).

You can use ExternalDNS to expose Kubernetes services for DNS lookup. You need to interface the ExternalDNS component with a supported DNS provider. The ExternalDNS package has been validated with the following providers:

  • AWS (Route 53)
  • Azure DNS
  • RFC2136 (BIND)

See Install External DNS in Workload Clusters Deployed by a Standalone Management Cluster.

As of v2.5, TKG does not support clusters on AWS or Azure. See the End of Support for TKG Management and Workload Clusters on AWS and Azure in the Tanzu Kubernetes Grid v2.5 Release Notes.

External DNS Components, Configuration, Data Values

The following sections describe External DNS components and show how you can configure the External DNS package.

ExternalDNS Components

The ExternalDNS package installs on the cluster the container listed in the table. For more information, see https://github.com/kubernetes-sigs/external-dns. The package pulls the container from the VMware public registry specified in Package Repository.

ContainerResource TypeReplicasDescription
ExternalDNSDaemonSet6Expose Kubernetes services for DNS lookup

ExternalDNS Data Values

ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS providers.

The following example can be use for RFC2136-compliant DNS provider (such as BIND).

apiVersion: v1
kind: ServiceAccount
metadata:
  name: dns-sa
  namespace: tkg-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: dns-role-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: dns-sa
    namespace: tkg-system
---
apiVersion: packaging.carvel.dev/v1alpha1
kind: PackageInstall
metadata:
  name: dns
  namespace: tkg-system
spec:
  serviceAccountName: dns-sa
  packageRef:
    refName: dns.tanzu.vmware.com
    versionSelection:
      constraints: v0.14.2+vmware.1-tkg.1
  values:
  - secretRef:
      name: dns-data-values
---
apiVersion: v1
kind: Secret
metadata:
  name: dns-data-values
  namespace: tkg-system
stringData:
  values.yml: |
    ---
    namespace: service-discovery
    dns:
      pspNames: "vmware-system-restricted"
      deployment:
        args:
        - --txt-owner-id=k8s
        - --provider=rfc2136
        - --rfc2136-host=192.168.0.1 #! IP of RFC2136 compatible dns server
        - --rfc2136-port=53
        - --rfc2136-zone=my-zone.example.org #! zone where services are deployed
        - --rfc2136-tsig-secret=REPLACE_ME_WITH_TSIG_SECRET #! TSIG key authorized to update the DNS server
        - --rfc2136-tsig-secret-alg=hmac-sha256
        - --rfc2136-tsig-keyname=externaldns-key
        - --rfc2136-tsig-axfr
        - --source=service
        - --source=contour-httpproxy #! export contour HTTPProxy objs
        - --domain-filter=my-zone.example.org #! zone where services are deployed

The following example can be used for AWS DNS provider (Route 53).

apiVersion: v1
kind: ServiceAccount
metadata:
  name: dns-sa
  namespace: tkg-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: dns-role-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: dns-sa
    namespace: tkg-system
---
apiVersion: packaging.carvel.dev/v1alpha1
kind: PackageInstall
metadata:
  name: dns
  namespace: tkg-system
spec:
  serviceAccountName: dns-sa
  packageRef:
    refName: dns.tanzu.vmware.com
    versionSelection:
      constraints: v0.14.2+vmware.1-tkg.1
  values:
  - secretRef:
      name: dns-data-values
---
apiVersion: v1
kind: Secret
metadata:
  name: dns-data-values
  namespace: tkg-system
stringData:
  values.yml: |
    ---
    namespace: service-discovery
    dns:
      pspNames: "vmware-system-restricted"
      deployment:
        args:
        - --source=service
        - --source=ingress
        - --source=contour-httpproxy #! configure external-dns to read Contour HTTPProxy resources
        - --domain-filter=my-zone.example.org #! zone where services are deployed
        - --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)
        - --aws-prefer-cname
        - --registry=txt
        - --txt-owner-id=REPLACE_ME_WITH_ROUTE_53_HOSTED_ZONE_ID #! Route53 hosted zone identifier for my-zone.example.org
        - --txt-prefix=txt #! disambiguates TXT records from CNAME records
        env:
          - name: AWS_ACCESS_KEY_ID
            valueFrom:
              secretKeyRef:
                name: route53-credentials #! Kubernetes secret for route53 credentials
                key: aws_access_key_id
          - name: AWS_SECRET_ACCESS_KEY
            valueFrom:
              secretKeyRef:
                name: route53-credentials #! Kubernetes secret for route53 credentials
                key: aws_secret_access_key

The following example can be used for an Azure DNS provider.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: dns-sa
  namespace: tkg-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: dns-role-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: dns-sa
    namespace: tkg-system
---
apiVersion: packaging.carvel.dev/v1alpha1
kind: PackageInstall
metadata:
  name: dns
  namespace: tkg-system
spec:
  serviceAccountName: dns-sa
  packageRef:
    refName: dns.tanzu.vmware.com
    versionSelection:
      constraints: v0.14.2+vmware.1-tkg.1
  values:
  - secretRef:
      name: dns-data-values
---
apiVersion: v1
kind: Secret
metadata:
  name: dns-data-values
  namespace: tkg-system
stringData:
  values.yml: |
    ---
    namespace: service-discovery
    dns:
      pspNames: "vmware-system-restricted"
      deployment:
        args:
        - --provider=azure
        - --source=service
        - --source=ingress
        - --source=contour-httpproxy #! configure external-dns to read Contour HTTPProxy resources
        - --domain-filter=my-zone.example.org #! zone where services are deployed
        - --azure-resource-group=my-resource-group #! Azure resource group
        volumeMounts:
        - name: azure-config-file
          mountPath: /etc/kubernetes
          readOnly: true
        #@overlay/replace
        volumes:
        - name: azure-config-file
          secret:
            secretName: azure-config-file

ExternalDNS Configuration Parameters

The table lists and describes the available configuration parameters for ExternalDNS. Refer to the site https://github.com/kubernetes-sigs/external-dns#running-externaldns for additional guidance.

ParameterDescriptionTypeDefault
externalDns.namespaceNamespace where external-dns will be deployedstringtanzu-system-service-discovery
externalDns.image.repositoryRepository containing external-dns imagestringprojects.packages.broadcom.com/tkg
externalDns.image.nameName of external-dnsstringexternal-dns
externalDns.image.tagExternalDNS image tagstringv0.7.4_vmware.1
externalDns.image.pullPolicyExternalDNS image pull policystringIfNotPresent
externalDns.deployment.annotationsAnnotations on the external-dns deploymentmap<string,string>{}
externalDns.deployment.argsArguments passed via command-line to external-dnslist<string>[] (Mandatory parameter)
externalDns.deployment.envEnvironment variables to pass to external-dnslist<string>[]
externalDns.deployment.securityContextSecurity context of the external-dns containerSecurityContext{}
externalDns.deployment.volumeMountsVolume mounts of the external-dns containerlist<VolumeMount>[]
externalDns.deployment.volumesVolumes of the external-dns podlist<Volume>[]

Example Configmap

The following example configmap defines a Kerberos configuration that ExternalDNS can interface with. Custom entries include the domain/realm name and the kdc/admin_server addresses.

apiVersion: v1
kind: ConfigMap
metadata:
  name: krb.conf
  namespace: tanzu-system-service-discovery
data:
  krb5.conf: |
    [logging]
    default = FILE:/var/log/krb5libs.log
    kdc = FILE:/var/log/krb5kdc.log
    admin_server = FILE:/var/log/kadmind.log

    [libdefaults]
    dns_lookup_realm = false
    ticket_lifetime = 24h
    renew_lifetime = 7d
    forwardable = true
    rdns = false
    pkinit_anchors = /etc/pki/tls/certs/ca-bundle.crt
    default_ccache_name = KEYRING:persistent:%{uid}

    default_realm = CORP.ACME

    [realms]
    CORP.ACME = {
      kdc = controlcenter.corp.acme
      admin_server = controlcenter.corp.acme
    }

    [domain_realm]
    corp.acme = CORP.ACME
    .corp.acme = CORP.ACME