vinyldns.md 5.44 KB
Newer Older
Dave Grizzanti's avatar
Dave Grizzanti committed
1 2
# Setting up ExternalDNS for VinylDNS

3 4 5 6
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using VinylDNS.

The environment vars `VINYLDNS_ACCESS_KEY`, `VINYLDNS_SECRET_KEY`, and `VINYLDNS_HOST` will be needed to run ExternalDNS with VinylDNS.

Dave Grizzanti's avatar
Dave Grizzanti committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
## Create a sample deployment and service for external-dns to use

Run an application and expose it via a Kubernetes Service:

```console
$ kubectl run nginx --image=nginx --replicas=1 --port=80
$ kubectl expose deployment nginx --port=80 --target-port=80 --type=LoadBalancer
```

Annotate the Service with your desired external DNS name. Make sure to change `example.org` to your domain.

```console
$ kubectl annotate service nginx "external-dns.alpha.kubernetes.io/hostname=nginx.example.org."
```

After the service is up and running, it should get an EXTERNAL-IP. At first this may showing as `<pending>`

```console
$ kubectl get svc
NAME         CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
kubernetes   10.0.0.1     <none>        443/TCP        1h
nginx        10.0.0.115   <pending>     80:30543/TCP   10s
```

Once it's available

```console
% kubectl get svc
NAME         CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
kubernetes   10.0.0.1     <none>        443/TCP        1h
nginx        10.0.0.115   34.x.x.x      80:30543/TCP   2m
```

40 41 42 43 44
## Deploy ExternalDNS to Kubernetes

Connect your `kubectl` client to the cluster you want to test ExternalDNS with.
Then apply one of the following manifests file to deploy ExternalDNS.

David Grizzanti's avatar
David Grizzanti committed
45 46 47 48
**Note for examples below**

When using `registry=txt` option, make sure to also use the `txt-prefix` and `txt-owner-id` options as well. If you try to create a `TXT` record in VinylDNS without a prefix, it will try to create a `TXT` record with the same name as your actual DNS record and fail (creating a stranded record `external-dns` cannot manage).

49 50 51
### Manifest (for clusters without RBAC enabled)

```yaml
52
apiVersion: apps/v1
53 54 55 56 57 58
kind: Deployment
metadata:
  name: external-dns
spec:
  strategy:
    type: Recreate
59 60 61
  selector:
    matchLabels:
      app: external-dns
62 63 64 65 66 67 68 69 70 71 72 73
  template:
    metadata:
      labels:
        app: external-dns
    spec:
      containers:
      - name: external-dns
        image: registry.opensource.zalan.do/teapot/external-dns:latest
        args:
        - --provider=vinyldns
        - --source=service
        - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
David Grizzanti's avatar
David Grizzanti committed
74 75 76
        - --registry=txt
        - --txt-owner-id=grizz
        - --txt-prefix=txt-
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
        env:
        - name: VINYLDNS_HOST
          value: "YOUR_VINYLDNS_HOST"
        - name: VINYLDNS_ACCESS_KEY
          value: "YOUR_VINYLDNS_ACCESS_KEY"
        - name: VINYLDNS_SECRET_KEY
          value: "YOUR_VINYLDNS_SECRET_KEY"
```

### Manifest (for clusters with RBAC enabled)

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: external-dns
rules:
- apiGroups: [""]
Alfred Krohmer's avatar
Alfred Krohmer committed
100
  resources: ["services","endpoints","pods"]
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
  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
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: external-dns
subjects:
- kind: ServiceAccount
  name: external-dns
  namespace: default
---
122
apiVersion: apps/v1
123 124 125 126 127 128
kind: Deployment
metadata:
  name: external-dns
spec:
  strategy:
    type: Recreate
129 130 131
  selector:
    matchLabels:
      app: external-dns
132 133 134 135 136 137 138 139 140 141 142 143 144
  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=vinyldns
        - --source=service
        - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
David Grizzanti's avatar
David Grizzanti committed
145 146 147
        - --registry=txt
        - --txt-owner-id=grizz
        - --txt-prefix=txt-
148 149 150 151 152 153 154 155 156 157
        env:
        env:
        - name: VINYLDNS_HOST
          value: "YOUR_VINYLDNS_HOST"
        - name: VINYLDNS_ACCESS_KEY
          value: "YOUR_VINYLDNS_ACCESS_KEY"
        - name: VINYLDNS_SECRET_KEY
          value: "YOUR_VINYLDNS_SECRET_KEYY
```

Dave Grizzanti's avatar
Dave Grizzanti committed
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
## Running a locally built version pointed to the above nginx service
Make sure your kubectl is configured correctly. Assuming you have the sources, build and run it like below.

The vinyl access details needs to exported to the environment before running.

```bash
make
# output skipped

export VINYLDNS_HOST=<fqdn of vinyl dns api>
export VINYLDNS_ACCESS_KEY=<access key>
export VINYLDNS_SECRET_KEY=<secret key>

./build/external-dns \
    --provider=vinyldns \
    --source=service \
    --domain-filter=elements.capsps.comcast.net. \
    --zone-id-filter=20e8bfd2-3a70-4e1b-8e11-c9c1948528d3 \
    --registry=txt \
David Grizzanti's avatar
David Grizzanti committed
177
    --txt-owner-id=grizz \
Dave Grizzanti's avatar
Dave Grizzanti committed
178 179 180 181 182 183 184 185 186 187 188 189
    --txt-prefix=txt- \
    --namespace=default \
    --once \
    --dry-run \
    --log-level debug

INFO[0000] running in dry-run mode. No changes to DNS records will be made.
INFO[0000] Created Kubernetes client https://some-k8s-cluster.example.com
INFO[0001] Zone: [nginx.example.org.]
# output skipped
```

190
Having `--dry-run=true` and `--log-level=debug` is a great way to see _exactly_ what VinylDNS is doing or is about to do.