How do you use External-DNS in Kubernetes with Linode Domains?

The Kubernetes Incubator project, External-DNS exposes Services and Ingresses through DNS names configured through various DNS providers.

Are Linode DNS Manager services supported in External-DNS?

1 Reply

Using External-DNS in Kubernetes with Linode Domains

The Kubernetes Incubator project, External-DNS exposes Services and Ingresses through DNS names configured through various DNS providers.

Linode DNS Manager services are supported in External-DNS.

Defer to the Linode guide included in the source repository for updated installation and configuration guidance.

This community post will only cover the basics.

If your cluster was created with the linode-cli or the terraform-linode-k8s module then External DNS is already installed.

Configuring External-DNS

You will need a Linode APIv4 Personal Access Token. Follow the Linode Developers: Access-and-Authentication notes.

This token will only need access to Domains.

If you already have a Personal Access Token stored in a Kubernetes Secret, you can reuse that secret name in the external-dns.yaml file below and skip the external-dns-linode-token.yaml instructions.

Manifest

Replacing the ... with the actual token created above and name the following external-dns-linode-token.yaml:

  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: external-dns-linode
    namespace: kube-system
  stringData:
    token: "..."
  ---

Name the following external-dns.yaml:

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: external-dns
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: external-dns
  namespace: kube-system
rules:
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get","watch","list"]
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get","watch","list"]
- apiGroups: ["extensions"]
  resources: ["ingresses"]
  verbs: ["get","watch","list"]
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["list"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: external-dns-viewer
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: external-dns
subjects:
- kind: ServiceAccount
  name: external-dns
  namespace: kube-system
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: external-dns
  namespace: kube-system
spec:
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: external-dns
    spec:
      serviceAccountName: external-dns
      containers:
      - name: external-dns
        image: registry.opensource.zalan.do/teapot/external-dns:latest
        args:
        - --provider=linode
        # - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
        env:
        - name: EXTERNAL_DNS_SOURCE
          value: |-
            service
            ingress
        - name: LINODE_TOKEN
          valueFrom:
            secretKeyRef:
              name: external-dns-linode
              key: token
---

Install these manifests with:

kubectl apply -f external-dns-linode-token.yaml
kubectl apply -f external-dns.yaml

Deploying an Nginx Service

Now, create a service file called 'nginx.yaml' with the following contents:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx
spec:
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  annotations:
    external-dns.alpha.kubernetes.io/hostname: ...
spec:
  selector:
    app: nginx
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

The key piece of this manifest is the external-dns.alpha.kubernetes.io/hostname annotation and its value.

Replace the ... with the DNS name that you want to give the service.

The domain referenced here must be one that is already on the Linode account. The user that generated the token must also have access to update that domain.

Now install the nginx Deployment and Service:

kubectl create -f nginx.yaml

When the Service is assigned an external address, External-DNS will update the A record of the domain name in the Linode DNS Manager.

Linode DNS Manager changes can take up to 30 minutes to fully propagate.

If the annotation or service is removed, External-DNS will remove the associated DNS record. This may also take 30 minutes to take effect.

Depending on the TTL value configured on the domain (and any external-dns annotations to set the ttl) global replication of these changes can vary.

Removal

To remove all of the configured services, including External-DNS, the Linode token, and any DNS names created or updated in this process:

kubectl delete service -f nginx.yaml
kubectl delete service -f external-dns.yaml
kubectl delete service -f external-dns-linode-token.yaml

Posted March 21, 2019

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct