sigs.k8s.io/external-dns@v0.14.1/docs/tutorials/istio.md (about) 1 # Configuring ExternalDNS to use the Istio Gateway and/or Istio Virtual Service Source 2 This tutorial describes how to configure ExternalDNS to use the Istio Gateway source. 3 It is meant to supplement the other provider-specific setup tutorials. 4 5 **Note:** Using the Istio Gateway source requires Istio >=1.0.0. 6 7 * Manifest (for clusters without RBAC enabled) 8 * Manifest (for clusters with RBAC enabled) 9 * Update existing ExternalDNS Deployment 10 11 ### Manifest (for clusters without RBAC enabled) 12 13 ```yaml 14 apiVersion: apps/v1 15 kind: Deployment 16 metadata: 17 name: external-dns 18 spec: 19 strategy: 20 type: Recreate 21 selector: 22 matchLabels: 23 app: external-dns 24 template: 25 metadata: 26 labels: 27 app: external-dns 28 spec: 29 containers: 30 - name: external-dns 31 image: registry.k8s.io/external-dns/external-dns:v0.14.0 32 args: 33 - --source=service 34 - --source=ingress 35 - --source=istio-gateway # choose one 36 - --source=istio-virtualservice # or both 37 - --domain-filter=external-dns-test.my-org.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones 38 - --provider=aws 39 - --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization 40 - --aws-zone-type=public # only look at public hosted zones (valid values are public, private or no value for both) 41 - --registry=txt 42 - --txt-owner-id=my-identifier 43 ``` 44 45 ### Manifest (for clusters with RBAC enabled) 46 ```yaml 47 apiVersion: v1 48 kind: ServiceAccount 49 metadata: 50 name: external-dns 51 --- 52 apiVersion: rbac.authorization.k8s.io/v1 53 kind: ClusterRole 54 metadata: 55 name: external-dns 56 rules: 57 - apiGroups: [""] 58 resources: ["services","endpoints","pods"] 59 verbs: ["get","watch","list"] 60 - apiGroups: ["extensions","networking.k8s.io"] 61 resources: ["ingresses"] 62 verbs: ["get","watch","list"] 63 - apiGroups: [""] 64 resources: ["nodes"] 65 verbs: ["list"] 66 - apiGroups: ["networking.istio.io"] 67 resources: ["gateways", "virtualservices"] 68 verbs: ["get","watch","list"] 69 --- 70 apiVersion: rbac.authorization.k8s.io/v1 71 kind: ClusterRoleBinding 72 metadata: 73 name: external-dns-viewer 74 roleRef: 75 apiGroup: rbac.authorization.k8s.io 76 kind: ClusterRole 77 name: external-dns 78 subjects: 79 - kind: ServiceAccount 80 name: external-dns 81 namespace: default 82 --- 83 apiVersion: apps/v1 84 kind: Deployment 85 metadata: 86 name: external-dns 87 spec: 88 strategy: 89 type: Recreate 90 selector: 91 matchLabels: 92 app: external-dns 93 template: 94 metadata: 95 labels: 96 app: external-dns 97 spec: 98 serviceAccountName: external-dns 99 containers: 100 - name: external-dns 101 image: registry.k8s.io/external-dns/external-dns:v0.14.0 102 args: 103 - --source=service 104 - --source=ingress 105 - --source=istio-gateway 106 - --source=istio-virtualservice 107 - --domain-filter=external-dns-test.my-org.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones 108 - --provider=aws 109 - --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization 110 - --aws-zone-type=public # only look at public hosted zones (valid values are public, private or no value for both) 111 - --registry=txt 112 - --txt-owner-id=my-identifier 113 ``` 114 115 ### Update existing ExternalDNS Deployment 116 117 * For clusters with running `external-dns`, you can just update the deployment. 118 * With access to the `kube-system` namespace, update the existing `external-dns` deployment. 119 * Add a parameter to the arguments of the container to create dns entries with `--source=istio-gateway`. 120 121 Execute the following command or update the argument. 122 123 ```console 124 kubectl patch deployment external-dns --type='json' \ 125 -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/2", "value": "--source=istio-gateway" }]' 126 ``` 127 128 In case the setup uses a `clusterrole`, just append a new value to the enable the istio group. 129 130 ```console 131 kubectl patch clusterrole external-dns --type='json' \ 132 -p='[{"op": "add", "path": "/rules/4", "value": { "apiGroups": [ "networking.istio.io"], "resources": ["gateways"],"verbs": ["get", "watch", "list" ]} }]' 133 ``` 134 135 ### Verify that Istio Gateway/VirtualService Source works 136 137 Follow the [Istio ingress traffic tutorial](https://istio.io/docs/tasks/traffic-management/ingress/) 138 to deploy a sample service that will be exposed outside of the service mesh. 139 The following are relevant snippets from that tutorial. 140 141 #### Install a sample service 142 With automatic sidecar injection: 143 ```bash 144 $ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.6/samples/httpbin/httpbin.yaml 145 ``` 146 147 Otherwise: 148 ```bash 149 $ kubectl apply -f <(istioctl kube-inject -f https://raw.githubusercontent.com/istio/istio/release-1.6/samples/httpbin/httpbin.yaml) 150 ``` 151 152 #### Using a Gateway as a source 153 ##### Create an Istio Gateway: 154 ```bash 155 $ cat <<EOF | kubectl apply -f - 156 apiVersion: networking.istio.io/v1alpha3 157 kind: Gateway 158 metadata: 159 name: httpbin-gateway 160 namespace: istio-system 161 spec: 162 selector: 163 istio: ingressgateway # use Istio default gateway implementation 164 servers: 165 - port: 166 number: 80 167 name: http 168 protocol: HTTP 169 hosts: 170 - "httpbin.example.com" # this is used by external-dns to extract DNS names 171 EOF 172 ``` 173 174 ##### Configure routes for traffic entering via the Gateway: 175 ```bash 176 $ cat <<EOF | kubectl apply -f - 177 apiVersion: networking.istio.io/v1alpha3 178 kind: VirtualService 179 metadata: 180 name: httpbin 181 spec: 182 hosts: 183 - "httpbin.example.com" 184 gateways: 185 - istio-system/httpbin-gateway 186 http: 187 - match: 188 - uri: 189 prefix: /status 190 - uri: 191 prefix: /delay 192 route: 193 - destination: 194 port: 195 number: 8000 196 host: httpbin 197 EOF 198 ``` 199 200 #### Using a VirtualService as a source 201 202 ##### Create an Istio Gateway: 203 ```bash 204 $ cat <<EOF | kubectl apply -f - 205 apiVersion: networking.istio.io/v1alpha3 206 kind: Gateway 207 metadata: 208 name: httpbin-gateway 209 namespace: istio-system 210 spec: 211 selector: 212 istio: ingressgateway # use Istio default gateway implementation 213 servers: 214 - port: 215 number: 80 216 name: http 217 protocol: HTTP 218 hosts: 219 - "*" 220 EOF 221 ``` 222 223 ##### Configure routes for traffic entering via the Gateway: 224 ```bash 225 $ cat <<EOF | kubectl apply -f - 226 apiVersion: networking.istio.io/v1alpha3 227 kind: VirtualService 228 metadata: 229 name: httpbin 230 spec: 231 hosts: 232 - "httpbin.example.com" # this is used by external-dns to extract DNS names 233 gateways: 234 - istio-system/httpbin-gateway 235 http: 236 - match: 237 - uri: 238 prefix: /status 239 - uri: 240 prefix: /delay 241 route: 242 - destination: 243 port: 244 number: 8000 245 host: httpbin 246 EOF 247 ``` 248 249 To get the targets to the extracted DNS names, external-dns is able to gather information from the kubernetes service of the Istio Ingress Gateway. 250 Please take a look at the [source service documentation](../sources/service.md) for more information on this. 251 252 It is also possible to set the targets manually by using the `external-dns.alpha.kubernetes.io/target` annotation on the Istio Ingress Gateway resource or the Istio VirtualService. 253 254 #### Access the sample service using `curl` 255 ```bash 256 $ curl -I http://httpbin.example.com/status/200 257 HTTP/1.1 200 OK 258 server: envoy 259 date: Tue, 28 Aug 2018 15:26:47 GMT 260 content-type: text/html; charset=utf-8 261 access-control-allow-origin: * 262 access-control-allow-credentials: true 263 content-length: 0 264 x-envoy-upstream-service-time: 5 265 ``` 266 267 Accessing any other URL that has not been explicitly exposed should return an HTTP 404 error: 268 ```bash 269 $ curl -I http://httpbin.example.com/headers 270 HTTP/1.1 404 Not Found 271 date: Tue, 28 Aug 2018 15:27:48 GMT 272 server: envoy 273 transfer-encoding: chunked 274 ``` 275 276 **Note:** The `-H` flag in the original Istio tutorial is no longer necessary in the `curl` commands. 277 278 ### Optional Gateway Annotation 279 280 To support setups where an Ingress resource is used provision an external LB you can add the following annotation to your Gateway 281 282 **Note:** The Ingress namespace can be omitted if its in the same namespace as the gateway 283 284 ```bash 285 $ cat <<EOF | kubectl apply -f - 286 apiVersion: networking.istio.io/v1alpha3 287 kind: Gateway 288 metadata: 289 name: httpbin-gateway 290 namespace: istio-system 291 annotations: 292 "external-dns.alpha.kubernetes.io/ingress": "$ingressNamespace/$ingressName" 293 spec: 294 selector: 295 istio: ingressgateway # use Istio default gateway implementation 296 servers: 297 - port: 298 number: 80 299 name: http 300 protocol: HTTP 301 hosts: 302 - "*" 303 EOF 304 ``` 305 306 ### Debug ExternalDNS 307 308 * Look for the deployment pod to see the status 309 310 ```console$ kubectl get pods | grep external-dns 311 external-dns-6b84999479-4knv9 1/1 Running 0 3h29m 312 ``` 313 314 * Watch for the logs as follows 315 316 ```console 317 $ kubectl logs -f external-dns-6b84999479-4knv9 318 ``` 319 320 At this point, you can `create` or `update` any `Istio Gateway` object with `hosts` entries array. 321 322 > **ATTENTION**: Make sure to specify those whose account is related to the DNS record. 323 324 * Successful executions will print the following 325 326 ```console 327 time="2020-01-17T06:08:08Z" level=info msg="Desired change: CREATE httpbin.example.com A" 328 time="2020-01-17T06:08:08Z" level=info msg="Desired change: CREATE httpbin.example.com TXT" 329 time="2020-01-17T06:08:08Z" level=info msg="2 record(s) in zone example.com. were successfully updated" 330 time="2020-01-17T06:09:08Z" level=info msg="All records are already up to date, there are no changes for the matching hosted zones" 331 ``` 332 333 * If there's any problem around `clusterrole`, you would see the errors showing wrong permissions: 334 335 ```console 336 source \"gateways\" in API group \"networking.istio.io\" at the cluster scope" 337 time="2020-01-17T06:07:08Z" level=error msg="gateways.networking.istio.io is forbidden: User \"system:serviceaccount:kube-system:external-dns\" cannot list resource \"gateways\" in API group \"networking.istio.io\" at the cluster scope" 338 ```