pdns.md 4.02 KB
Newer Older
Anhad Jai Singh's avatar
Anhad Jai Singh committed
1 2 3 4 5 6 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 40 41 42
# Setting up ExternalDNS for PowerDNS

## Prerequisites

The provider has been written for and tested against [PowerDNS](https://github.com/PowerDNS/pdns) v4.1.x and thus requires **PowerDNS Auth Server >= 4.1.x**

PowerDNS provider support was added via [this PR](https://github.com/kubernetes-incubator/external-dns/pull/373), thus you need to use external-dns version >= v0.5

The PDNS provider expects that your PowerDNS instance is already setup and
functional. It expects that zones, you wish to add records to, already exist
and are configured correctly. It does not add, remove or configure new zones in
anyway.

## Feature Support

The PDNS provider currently does not support:

1. Dry running a configuration is not supported.
2. The `--domain-filter` flag is not supported.

## Deployment

Deploying external DNS for PowerDNS is actually nearly identical to deploying
it for other providers. This is what a sample `deployment.yaml` looks like:

```yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: deploy-external-dns
spec:
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: external-dns
    spec:
      # Only use if you're also using RBAC
      # serviceAccountName: external-dns
      containers:
      - name: external-dns
Nick Jüttner's avatar
Nick Jüttner committed
43
        image: registry.opensource.zalan.do/teapot/external-dns:v0.5.3
Anhad Jai Singh's avatar
Anhad Jai Singh committed
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
        args:
        - --source=service # or ingress or both
        - --provider=pdns
        - --pdns-server={{ pdns-api-url }}
        - --pdns-api-key={{ pdns-http-api-key }}
        - --txt-owner-id={{ owner-id-for-this-external-dns }}
        - --log-level=debug
        - --interval=30s
```

## RBAC

If your cluster is RBAC enabled, you also need to setup the following, before you can run external-dns:
```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: external-dns
rules:
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get","watch","list"]
- apiGroups: ["extensions"]
  resources: ["ingresses"]
  verbs: ["get","watch","list"]
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get","watch","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
```

## Testing and Verification

**Important!**: Remember to change `example.com` with your own domain throughout the following text.

Spin up a simple "Hello World" HTTP server with the following spec (`kubectl apply -f`):

```yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: echo
spec:
  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
      - image: hashicorp/http-echo
        name: echo
        ports:
        - containerPort: 5678
        args:
          - -text="Hello World"
---
apiVersion: v1
kind: Service
metadata:
  name: echo
  annotations:
    external-dns.alpha.kubernetes.io/hostname: echo.example.com
spec:
  selector:
    app: echo
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5678
```
**Important!**: Don't run dig, nslookup or similar immediately (until you've
confirmed the record exists). You'll get hit by [negative DNS caching](https://tools.ietf.org/html/rfc2308), which is hard to flush.

Run the following to make sure everything is in order:

```bash
$ kubectl get services echo
$ kubectl get endpoints echo
```

Make sure everything looks correct, i.e the service is defined and recieves a
public IP, and that the endpoint also has a pod IP.

Once that's done, wait about 30s-1m (interval for external-dns to kick in), then do:
```bash
$ curl -H "X-API-Key: ${PDNS_API_KEY}" ${PDNS_API_URL}/api/v1/servers/localhost/zones/example.com. | jq '.rrsets[] | select(.name | contains("echo"))'
```

Once the API shows the record correctly, you can double check your record using:
```bash
$ dig @${PDNS_FQDN} echo.example.com.
```