sigs.k8s.io/external-dns@v0.14.1/docs/tutorials/designate.md (about) 1 # Setting up ExternalDNS for Services on OpenStack Designate 2 3 This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using OpenStack Designate DNS. 4 5 ## Authenticating with OpenStack 6 7 We are going to use OpenStack CLI - `openstack` utility, which is an umbrella application for most of OpenStack clients including `designate`. 8 9 All OpenStack CLIs require authentication parameters to be provided. These parameters include: 10 * URL of the OpenStack identity service (`keystone`) which is responsible for user authentication and also served as a registry for other 11 OpenStack services. Designate endpoints must be registered in `keystone` in order to ExternalDNS and OpenStack CLI be able to find them. 12 * OpenStack region name 13 * User login name. 14 * User project (tenant) name. 15 * User domain (only when using keystone API v3) 16 17 Although these parameters can be passed explicitly through the CLI flags, traditionally it is done by sourcing `openrc` file (`source ~/openrc`) that is a 18 shell snippet that sets environment variables that all OpenStack CLI understand by convention. 19 20 Recent versions of OpenStack Dashboard have a nice UI to download `openrc` file for both v2 and v3 auth protocols. Both protocols can be used with ExternalDNS. 21 v3 is generally preferred over v2, but might not be available in some OpenStack installations. 22 23 ## Installing OpenStack Designate 24 25 Please refer to the Designate deployment [tutorial](https://docs.openstack.org/project-install-guide/dns/ocata/install.html) for instructions on how 26 to install and test Designate with BIND backend. You will be required to have admin rights in existing OpenStack installation to do this. One convenient 27 way to get yourself an OpenStack installation to play with is to use [DevStack](https://docs.openstack.org/devstack/latest/). 28 29 ## Creating DNS zones 30 31 All domain names that are ExternalDNS is going to create must belong to one of DNS zones created in advance. Here is an example of how to create `example.com` DNS zone: 32 ```console 33 $ openstack zone create --email dnsmaster@example.com example.com. 34 ``` 35 36 It is important to manually create all the zones that are going to be used for kubernetes entities (ExternalDNS sources) before starting ExternalDNS. 37 38 ## Deploy ExternalDNS 39 40 Create a deployment file called `externaldns.yaml` with the following contents: 41 42 ### Manifest (for clusters without RBAC enabled) 43 44 ```yaml 45 apiVersion: apps/v1 46 kind: Deployment 47 metadata: 48 name: external-dns 49 spec: 50 strategy: 51 type: Recreate 52 selector: 53 matchLabels: 54 app: external-dns 55 template: 56 metadata: 57 labels: 58 app: external-dns 59 spec: 60 containers: 61 - name: external-dns 62 image: registry.k8s.io/external-dns/external-dns:v0.14.0 63 args: 64 - --source=service # ingress is also possible 65 - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. 66 - --provider=designate 67 env: # values from openrc file 68 - name: OS_AUTH_URL 69 value: https://controller/identity/v3 70 - name: OS_REGION_NAME 71 value: RegionOne 72 - name: OS_USERNAME 73 value: admin 74 - name: OS_PASSWORD 75 value: p@ssw0rd 76 - name: OS_PROJECT_NAME 77 value: demo 78 - name: OS_USER_DOMAIN_NAME 79 value: Default 80 ``` 81 82 ### Manifest (for clusters with RBAC enabled) 83 84 ```yaml 85 apiVersion: v1 86 kind: ServiceAccount 87 metadata: 88 name: external-dns 89 --- 90 apiVersion: rbac.authorization.k8s.io/v1 91 kind: ClusterRole 92 metadata: 93 name: external-dns 94 rules: 95 - apiGroups: [""] 96 resources: ["services","endpoints","pods"] 97 verbs: ["get","watch","list"] 98 - apiGroups: [""] 99 resources: ["pods"] 100 verbs: ["get","watch","list"] 101 - apiGroups: ["extensions","networking.k8s.io"] 102 resources: ["ingresses"] 103 verbs: ["get","watch","list"] 104 - apiGroups: [""] 105 resources: ["nodes"] 106 verbs: ["watch","list"] 107 --- 108 apiVersion: rbac.authorization.k8s.io/v1 109 kind: ClusterRoleBinding 110 metadata: 111 name: external-dns-viewer 112 roleRef: 113 apiGroup: rbac.authorization.k8s.io 114 kind: ClusterRole 115 name: external-dns 116 subjects: 117 - kind: ServiceAccount 118 name: external-dns 119 namespace: default 120 --- 121 apiVersion: apps/v1 122 kind: Deployment 123 metadata: 124 name: external-dns 125 spec: 126 selector: 127 matchLabels: 128 app: external-dns 129 strategy: 130 type: Recreate 131 template: 132 metadata: 133 labels: 134 app: external-dns 135 spec: 136 serviceAccountName: external-dns 137 containers: 138 - name: external-dns 139 image: registry.k8s.io/external-dns/external-dns:v0.14.0 140 args: 141 - --source=service # ingress is also possible 142 - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. 143 - --provider=designate 144 env: # values from openrc file 145 - name: OS_AUTH_URL 146 value: https://controller/identity/v3 147 - name: OS_REGION_NAME 148 value: RegionOne 149 - name: OS_USERNAME 150 value: admin 151 - name: OS_PASSWORD 152 value: p@ssw0rd 153 - name: OS_PROJECT_NAME 154 value: demo 155 - name: OS_USER_DOMAIN_NAME 156 value: Default 157 ``` 158 159 Create the deployment for ExternalDNS: 160 161 ```console 162 $ kubectl create -f externaldns.yaml 163 ``` 164 165 ### Optional: Trust self-sign certificates 166 If your OpenStack-Installation is configured with a self-sign certificate, you could extend the `pod.spec` with following secret-mount: 167 ```yaml 168 volumeMounts: 169 - mountPath: /etc/ssl/certs/ 170 name: cacerts 171 volumes: 172 - name: cacerts 173 secret: 174 defaultMode: 420 175 secretName: self-sign-certs 176 ``` 177 178 content of the secret `self-sign-certs` must be the certificate/chain in PEM format. 179 180 181 ## Deploying an Nginx Service 182 183 Create a service file called 'nginx.yaml' with the following contents: 184 185 ```yaml 186 apiVersion: apps/v1 187 kind: Deployment 188 metadata: 189 name: nginx 190 spec: 191 selector: 192 matchLabels: 193 app: nginx 194 template: 195 metadata: 196 labels: 197 app: nginx 198 spec: 199 containers: 200 - image: nginx 201 name: nginx 202 ports: 203 - containerPort: 80 204 --- 205 apiVersion: v1 206 kind: Service 207 metadata: 208 name: nginx 209 annotations: 210 external-dns.alpha.kubernetes.io/hostname: my-app.example.com 211 spec: 212 selector: 213 app: nginx 214 type: LoadBalancer 215 ports: 216 - protocol: TCP 217 port: 80 218 targetPort: 80 219 ``` 220 221 Note the annotation on the service; use the same hostname as the DNS zone created above. 222 223 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. 224 225 Create the deployment and service: 226 227 ```console 228 $ kubectl create -f nginx.yaml 229 ``` 230 231 232 Once the service has an external IP assigned, ExternalDNS will notice the new service IP address and notify Designate, 233 which in turn synchronize DNS records with underlying DNS server backend. 234 235 ## Verifying DNS records 236 237 To verify that DNS record was indeed created, you can use the following command: 238 239 ```console 240 $ openstack recordset list example.com. 241 ``` 242 243 There should be a record for my-app.example.com having `ACTIVE` status. And of course, the ultimate method to verify is to issue a DNS query: 244 245 ```console 246 $ dig my-app.example.com @controller 247 ``` 248 249 ## Cleanup 250 251 Now that we have verified that ExternalDNS created all DNS records, we can delete the tutorial's example: 252 253 ```console 254 $ kubectl delete service -f nginx.yaml 255 $ kubectl delete service -f externaldns.yaml 256 ```