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:
Installation: Install External DNS on a workload cluster in one of the following ways, based on its deployment option:
TKG on Supervisor:
Standalone management cluster: Install External DNS in Workload Clusters Deployed by a Standalone Management Cluster
NoteAs 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.
The following sections describe External DNS components and show how you can configure the External DNS package.
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.
Container | Resource Type | Replicas | Description |
---|---|---|---|
ExternalDNS | DaemonSet | 6 | Expose Kubernetes services for DNS lookup |
ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS providers.
The example provided in the installation topic can be used for Azure DNS. See Install ExternalDNS Using Kubectl.
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: 0.13.4+vmware.2-tkg.2
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: 0.13.4+vmware.2-tkg.2
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: 0.13.4+vmware.2-tkg.2
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
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.
Parameter | Description | Type | Default |
---|---|---|---|
externalDns.namespace | Namespace where external-dns will be deployed | string | tanzu-system-service-discovery |
externalDns.image.repository | Repository containing external-dns image | string | projects.registry.vmware.com/tkg |
externalDns.image.name | Name of external-dns | string | external-dns |
externalDns.image.tag | ExternalDNS image tag | string | v0.7.4_vmware.1 |
externalDns.image.pullPolicy | ExternalDNS image pull policy | string | IfNotPresent |
externalDns.deployment.annotations | Annotations on the external-dns deployment | map<string,string> | {} |
externalDns.deployment.args | Arguments passed via command-line to external-dns | list<string> | [] (Mandatory parameter) |
externalDns.deployment.env | Environment variables to pass to external-dns | list<string> | [] |
externalDns.deployment.securityContext | Security context of the external-dns container | SecurityContext | {} |
externalDns.deployment.volumeMounts | Volume mounts of the external-dns container | list<VolumeMount> | [] |
externalDns.deployment.volumes | Volumes of the external-dns pod | list<Volume> | [] |
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