cloudflare.md 6.3 KB
Newer Older
Nick Jüttner's avatar
Nick Jüttner committed
1 2 3 4
# Setting up ExternalDNS for Services on Cloudflare

This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using Cloudflare DNS.

5
Make sure to use **>=0.4.2** version of ExternalDNS for this tutorial.
Nick Jüttner's avatar
Nick Jüttner committed
6 7 8 9 10 11 12 13 14 15 16 17 18

## Creating a Cloudflare DNS zone

We highly recommend to read this tutorial if you haven't used Cloudflare before:

[Create a Cloudflare account and add a website](https://support.cloudflare.com/hc/en-us/articles/201720164-Step-2-Create-a-Cloudflare-account-and-add-a-website)

## Creating Cloudflare Credentials

Snippet from [Cloudflare - Getting Started](https://api.cloudflare.com/#getting-started-endpoints):

>Cloudflare's API exposes the entire Cloudflare infrastructure via a standardized programmatic interface. Using Cloudflare's API, you can do just about anything you can do on cloudflare.com via the customer dashboard.

Pascal Kutscha's avatar
Pascal Kutscha committed
19
>The Cloudflare API is a RESTful API based on HTTPS requests and JSON responses. If you are registered with Cloudflare, you can obtain your API key from the bottom of the "My Account" page, found here: [Go to My account](https://dash.cloudflare.com/profile).
Nick Jüttner's avatar
Nick Jüttner committed
20 21 22 23 24

The environment vars `CF_API_KEY` and `CF_API_EMAIL` will be needed to run ExternalDNS with Cloudflare.

## Deploy ExternalDNS

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

### Manifest (for clusters without RBAC enabled)
Nick Jüttner's avatar
Nick Jüttner committed
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44

```yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: external-dns
spec:
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: external-dns
    spec:
      containers:
      - name: external-dns
Nick Jüttner's avatar
Nick Jüttner committed
45
        image: registry.opensource.zalan.do/teapot/external-dns:latest
Nick Jüttner's avatar
Nick Jüttner committed
46 47 48 49
        args:
        - --source=service # ingress is also possible
        - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
        - --provider=cloudflare
50
        - --cloudflare-proxied # (optional) enable the proxy feature of Cloudflare (DDOS protection, CDN...)
Nick Jüttner's avatar
Nick Jüttner committed
51 52 53 54 55 56 57
        env:
        - name: CF_API_KEY
          value: "YOUR_CLOUDFLARE_API_KEY"
        - name: CF_API_EMAIL
          value: "YOUR_CLOUDFLARE_EMAIL"
```

58
### Manifest (for clusters with RBAC enabled)
Nick Jüttner's avatar
Nick Jüttner committed
59

60 61 62 63 64 65 66 67 68 69 70 71 72 73
```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"]
74 75 76
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get","watch","list"]
77 78 79
- apiGroups: ["extensions"] 
  resources: ["ingresses"] 
  verbs: ["get","watch","list"]
80 81 82
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["list"]
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
---
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
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: external-dns
spec:
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: external-dns
    spec:
      serviceAccountName: external-dns
      containers:
      - name: external-dns
Nick Jüttner's avatar
Nick Jüttner committed
112
        image: registry.opensource.zalan.do/teapot/external-dns:latest
113 114 115 116 117 118 119 120 121 122
        args:
        - --source=service # ingress is also possible
        - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
        - --provider=cloudflare
        - --cloudflare-proxied # (optional) enable the proxy feature of Cloudflare (DDOS protection, CDN...)
        env:
        - name: CF_API_KEY
          value: "YOUR_CLOUDFLARE_API_KEY"
        - name: CF_API_EMAIL
          value: "YOUR_CLOUDFLARE_EMAIL"
Nick Jüttner's avatar
Nick Jüttner committed
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
```

## Deploying an Nginx Service

Create a service file called 'nginx.yaml' with the following contents:

```yaml
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: example.com
152
    external-dns.alpha.kubernetes.io/ttl: "120" #optional
Nick Jüttner's avatar
Nick Jüttner committed
153 154 155 156 157 158 159 160 161 162 163 164 165
spec:
  selector:
    app: nginx
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
```

Note the annotation on the service; use the same hostname as the Cloudflare DNS zone created above. The annotation may also be a subdomain
of the DNS zone (e.g. 'www.example.com').

166 167
By setting the TTL annotation on the service, you have to pass a valid TTL, which must be 120 or above.
This annotation is optional, if you won't set it, it will be 1 (automatic) which is 300.
168
For Cloudflare proxied entries, set the TTL annotation to 1 (automatic), or do not set it.
169

Nick Jüttner's avatar
Nick Jüttner committed
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
ExternalDNS uses this annotation to determine what services should be registered with DNS.  Removing the annotation
will cause ExternalDNS to remove the corresponding DNS records.

Create the deployment and service:

```
$ kubectl create -f nginx.yaml
```

Depending where you run your service it can take a little while for your cloud provider to create an external IP for the service.

Once the service has an external IP assigned, ExternalDNS will notice the new service IP address and synchronize
the Cloudflare DNS records.

## Verifying Cloudflare DNS records

Derek Perkins's avatar
Derek Perkins committed
186
Check your [Cloudflare dashboard](https://www.cloudflare.com/a/dns/example.com) to view the records for your Cloudflare DNS zone.
Nick Jüttner's avatar
Nick Jüttner committed
187 188 189

Substitute the zone for the one created above if a different domain was used.

190
This should show the external IP address of the service as the A record for your domain.
Nick Jüttner's avatar
Nick Jüttner committed
191

192
## Cleanup
Nick Jüttner's avatar
Nick Jüttner committed
193 194 195 196

Now that we have verified that ExternalDNS will automatically manage Cloudflare DNS records, we can delete the tutorial's example:

```
Adrian Rangel's avatar
Adrian Rangel committed
197 198
$ kubectl delete -f nginx.yaml
$ kubectl delete -f externaldns.yaml
Nick Jüttner's avatar
Nick Jüttner committed
199
```
200 201 202 203

## Setting cloudflare-proxied on a per-ingress basis

Using the `external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"` annotation on your ingress, you can specify if the proxy feature of Cloudflare should be enabled for that record. This setting will override the global `--cloudflare-proxied` setting.