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  ```