Can I use external-dns and openstack designate for automatic dns?
Yes, to reduce manual effort and automate the configuration of DNS zones, you may want to use external-dns. In summary, external-dns allows you to control DNS records dynamically with Kubernetes resources in a DNS provider-agnostic way. external-dns is not a DNS server by itself, but merely configures other DNS providers (for example, OpenStack Designate, Amazon Route53, Google Cloud DNS, and so on.)
Prerequisites
To successfully complete the following steps, you need the following:
kubectl
latest version- A running Kubernetes cluster on our openstack
- A valid
kubeconfig
for your cluster - Installed OpenStack CLI tools
- OpenStack API access
- A valid domain
Configure Your domain to use designate
Delegate your domains from your DNS provider to the following DNS name servers so that Designate can control the DNS resources of your domain.
dns1.ddns.innovo.cloud
dns2.ddns.innovo.cloud
Create a new DNS Zone
Before you use ExternalDNS, you need to add your DNS zones to your DNS provider, in this case, Designate DNS.
In our example we use the test domain name example.foo.
It is important to create the zones before starting to control the DNS resources with Kubernetes.
Note: You must include the final
.
at the end of the zone/domain to be created.
$ openstack zone create --email webmaster@example.foo example.foo.
Next, make sure that the zone was created successfully and the status is active.
$ openstack zone list
$ openstack zone show example.foo.
Create application credentials for external-dns
Attention: It is imported to login with your service user into your openstack project, because Application Credentials are user specific.
Visit the WebGui and go to Identity -> Application Credentials, then click on the Button + CREATE APPLICATION CREDENTIAL
or create credentials via cli:
$ openstack application credential create <name_of_app_credentials>
Install external-dns into your cluster
Note: Don’t forget to change the openstack application credentials and the command line arguments in the external-dns deployment
--domain-filter=example.foo
and the--txt-owner-id=<owner-id>
. The domain-filter is the dns zone. With the txt-owner-id external-dns can identify the entries managed by itself. You should change the image to a new version if available (and shedule updates) if you want to use it in production.
- Namespace:
apiVersion: v1
kind: Namespace
metadata:
name: external-dns
- RBAC:
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: external-dns
namespace: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: external-dns
rules:
- apiGroups: [""]
resources: ["services", "endpoints", "pods"]
verbs: ["get", "watch", "list"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
- apiGroups: ["extensions", "networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "watch", "list"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["watch", "list"]
---
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: external-dns
- Secret:
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: designate-openstack-credentials
namespace: external-dns
stringData:
OS_AUTH_URL: <auth-url>
OS_REGION_NAME: <region>
OS_AUTH_TYPE: v3applicationcredential
OS_APPLICATION_CREDENTIAL_ID: <appcred_id>
OS_APPLICATION_CREDENTIAL_SECRET: <appcred_secret>
- Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
namespace: external-dns
spec:
selector:
matchLabels:
app: external-dns
strategy:
type: Recreate
template:
metadata:
labels:
app: external-dns
spec:
serviceAccountName: external-dns
containers:
- args:
- --source=service
- --source=ingress
- --registry=txt
- --provider=designate
- --domain-filter=example.foo
- --txt-owner-id=<owner-id>
- --log-level=debug
envFrom:
- secretRef:
name: designate-openstack-credentials
image: registry.k8s.io/external-dns/external-dns:v0.14.2
imagePullPolicy: IfNotPresent
name: external-dns
Annotate the service or ingress
To add the dns entry to designate the service or ingress needs to be annotated with external-dns.alpha.kubernetes.io/hostname: my-app.example.foo
. For example:
apiVersion: v1
kind: Namespace
metadata:
name: my-app
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: my-app
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: my-app
annotations:
external-dns.alpha.kubernetes.io/hostname: my-app.example.foo
spec:
selector:
app: nginx
type: LoadBalancer
ports:
- protocol: TCP
port: 80
targetPort: 80
DNS Lookup
Make the dns record will be looked up correct:
$ openstack recordset list example.foo.
$ dig my-app.example.foo @dns1.ddns.innovo.cloud.
$ dig my-app.example.foo @dns2.ddns.innovo.cloud.
$ dig my-app.example.foo
Further information
For further information, please have a look at: