sigs.k8s.io/external-dns@v0.14.1/docs/tutorials/rfc2136.md (about)

     1  # Configuring RFC2136 provider
     2  This tutorial describes how to use the RFC2136 with either BIND or Windows DNS.
     3  
     4  ## Using with BIND
     5  To use external-dns with BIND: generate/procure a key, configure DNS and add a
     6  deployment of external-dns.
     7  
     8  ### Server credentials:
     9  - RFC2136 was developed for and tested with
    10  [BIND](https://www.isc.org/downloads/bind/) DNS server. This documentation
    11  assumes that you already have a configured and working server. If you don't,
    12  please check BIND documents or tutorials.
    13  - If your DNS is provided for you, ask for a TSIG key authorized to update and
    14  transfer the zone you wish to update. The key will look something like below.
    15  Skip the next steps wrt BIND setup.
    16  ```text
    17  key "externaldns-key" {
    18  	algorithm hmac-sha256;
    19  	secret "96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8=";
    20  };
    21  ```
    22  - If you are your own DNS administrator create a TSIG key. Use
    23  `tsig-keygen -a hmac-sha256 externaldns` or on older distributions
    24  `dnssec-keygen -a HMAC-SHA256 -b 256 -n HOST externaldns`. You will end up with
    25  a key printed to standard out like above (or in the case of dnssec-keygen in a
    26  file called `Kexternaldns......key`).
    27  
    28  ### BIND Configuration:
    29  If you do not administer your own DNS, skip to RFC provider configuration
    30  
    31  - Edit your named.conf file (or appropriate included file) and add/change the
    32  following.
    33    - Make sure You are listening on the right interfaces. At least whatever
    34    interface external-dns will be communicating over and the interface that
    35    faces the internet.
    36    - Add the key that you generated/was given to you above. Copy paste the four
    37    lines that you got (not the same as the example key) into your file.
    38    - Create a zone for kubernetes. If you already have a zone, skip to the next
    39    step. (I put the zone in it's own subdirectory because named,
    40    which shouldn't be running as root, needs to create a journal file and the
    41    default zone directory isn't writeable by named).
    42    ```text
    43    zone "k8s.example.org" {
    44        type master;
    45        file "/etc/bind/pri/k8s/k8s.zone";
    46    };
    47    ```
    48    - Add your key to both transfer and update. For instance with our previous
    49    zone.
    50    ```text
    51    zone "k8s.example.org" {
    52        type master;
    53        file "/etc/bind/pri/k8s/k8s.zone";
    54        allow-transfer {
    55            key "externaldns-key";
    56        };
    57        update-policy {
    58            grant externaldns-key zonesub ANY;
    59        };
    60    };
    61    ```
    62    - Create a zone file (k8s.zone):
    63    ```text
    64    $TTL 60 ; 1 minute
    65    k8s.example.org         IN SOA  k8s.example.org. root.k8s.example.org. (
    66                                    16         ; serial
    67                                    60         ; refresh (1 minute)
    68                                    60         ; retry (1 minute)
    69                                    60         ; expire (1 minute)
    70                                    60         ; minimum (1 minute)
    71                                    )
    72                            NS      ns.k8s.example.org.
    73    ns                      A       123.456.789.012
    74    ```
    75    - Reload (or restart) named
    76  
    77  
    78  ### Using external-dns
    79  To use external-dns add an ingress or a LoadBalancer service with a host that
    80  is part of the domain-filter. For example both of the following would produce
    81  A records.
    82  ```text
    83  apiVersion: v1
    84  kind: Service
    85  metadata:
    86    name: nginx
    87    annotations:
    88      external-dns.alpha.kubernetes.io/hostname: svc.example.org
    89  spec:
    90    type: LoadBalancer
    91    ports:
    92    - port: 80
    93      targetPort: 80
    94    selector:
    95      app: nginx
    96  ---
    97  apiVersion: networking.k8s.io/v1
    98  kind: Ingress
    99  metadata:
   100      name: my-ingress
   101  spec:
   102      rules:
   103      - host: ingress.example.org
   104        http:
   105            paths:
   106            - path: /
   107              backend:
   108                  serviceName: my-service
   109                  servicePort: 8000
   110  ```
   111  
   112  ### Custom TTL
   113  
   114  The default DNS record TTL (Time-To-Live) is 0 seconds. You can customize this value by setting the annotation `external-dns.alpha.kubernetes.io/ttl`. e.g., modify the service manifest YAML file above:
   115  
   116  ```
   117  apiVersion: v1
   118  kind: Service
   119  metadata:
   120    name: nginx
   121    annotations:
   122      external-dns.alpha.kubernetes.io/hostname: nginx.external-dns-test.my-org.com
   123      external-dns.alpha.kubernetes.io/ttl: 60
   124  spec:
   125      ...
   126  ```
   127  
   128  This will set the DNS record's TTL to 60 seconds.
   129  
   130  A default TTL for all records can be set using the the flag with a time in seconds, minutes or hours, such as `--rfc2136-min-ttl=60s`
   131  
   132  There are other annotation that can affect the generation of DNS records, but these are beyond the scope of this
   133  tutorial and are covered in the main documentation.
   134  
   135  ### Test with external-dns installed on local machine (optional)
   136  You may install external-dns and test on a local machine by running:
   137  ```external-dns --txt-owner-id k8s --provider rfc2136 --rfc2136-host=192.168.0.1 --rfc2136-port=53 --rfc2136-zone=k8s.example.org --rfc2136-tsig-secret=96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8= --rfc2136-tsig-secret-alg=hmac-sha256 --rfc2136-tsig-keyname=externaldns-key --rfc2136-tsig-axfr --source ingress --once --domain-filter=k8s.example.org --dry-run```
   138  - host should be the IP of your master DNS server.
   139  - tsig-secret should be changed to match your secret.
   140  - tsig-keyname needs to match the keyname you used (if you changed it).
   141  - domain-filter can be used as shown to filter the domains you wish to update.
   142  
   143  ### RFC2136 provider configuration:
   144  In order to use external-dns with your cluster you need to add a deployment
   145  with access to your ingress and service resources. The following are two
   146  example manifests with and without RBAC respectively.
   147  
   148  - With RBAC:
   149  ```text
   150  apiVersion: v1
   151  kind: Namespace
   152  metadata:
   153    name: external-dns
   154    labels:
   155      name: external-dns
   156  ---
   157  apiVersion: rbac.authorization.k8s.io/v1
   158  kind: ClusterRole
   159  metadata:
   160    name: external-dns
   161    namespace: external-dns
   162  rules:
   163  - apiGroups:
   164    - ""
   165    resources:
   166    - services
   167    - endpoints
   168    - pods
   169    - nodes
   170    verbs:
   171    - get
   172    - watch
   173    - list
   174  - apiGroups:
   175    - extensions
   176    - networking.k8s.io
   177    resources:
   178    - ingresses
   179    verbs:
   180    - get
   181    - list
   182    - watch
   183  ---
   184  apiVersion: v1
   185  kind: ServiceAccount
   186  metadata:
   187    name: external-dns
   188    namespace: external-dns
   189  ---
   190  apiVersion: rbac.authorization.k8s.io/v1
   191  kind: ClusterRoleBinding
   192  metadata:
   193    name: external-dns-viewer
   194    namespace: external-dns
   195  roleRef:
   196    apiGroup: rbac.authorization.k8s.io
   197    kind: ClusterRole
   198    name: external-dns
   199  subjects:
   200  - kind: ServiceAccount
   201    name: external-dns
   202    namespace: external-dns
   203  ---
   204  apiVersion: apps/v1
   205  kind: Deployment
   206  metadata:
   207    name: external-dns
   208    namespace: external-dns
   209  spec:
   210    selector:
   211      matchLabels:
   212        app: external-dns
   213    template:
   214      metadata:
   215        labels:
   216          app: external-dns
   217      spec:
   218        serviceAccountName: external-dns
   219        containers:
   220        - name: external-dns
   221          image: registry.k8s.io/external-dns/external-dns:v0.14.0
   222          args:
   223          - --registry=txt
   224          - --txt-prefix=external-dns-
   225          - --txt-owner-id=k8s
   226          - --provider=rfc2136
   227          - --rfc2136-host=192.168.0.1
   228          - --rfc2136-port=53
   229          - --rfc2136-zone=k8s.example.org
   230          - --rfc2136-zone=k8s.your-zone.org
   231          - --rfc2136-tsig-secret=96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8=
   232          - --rfc2136-tsig-secret-alg=hmac-sha256
   233          - --rfc2136-tsig-keyname=externaldns-key
   234          - --rfc2136-tsig-axfr
   235          - --source=ingress
   236          - --domain-filter=k8s.example.org
   237  ```
   238  
   239  - Without RBAC:
   240  ```text
   241  apiVersion: v1
   242  kind: Namespace
   243  metadata:
   244    name: external-dns
   245    labels:
   246      name: external-dns
   247  ---
   248  apiVersion: apps/v1
   249  kind: Deployment
   250  metadata:
   251    name: external-dns
   252    namespace: external-dns
   253  spec:
   254    selector:
   255      matchLabels:
   256        app: external-dns
   257    template:
   258      metadata:
   259        labels:
   260          app: external-dns
   261      spec:
   262        containers:
   263        - name: external-dns
   264          image: registry.k8s.io/external-dns/external-dns:v0.14.0
   265          args:
   266          - --registry=txt
   267          - --txt-prefix=external-dns-
   268          - --txt-owner-id=k8s
   269          - --provider=rfc2136
   270          - --rfc2136-host=192.168.0.1
   271          - --rfc2136-port=53
   272          - --rfc2136-zone=k8s.example.org
   273          - --rfc2136-zone=k8s.your-zone.org
   274          - --rfc2136-tsig-secret=96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8=
   275          - --rfc2136-tsig-secret-alg=hmac-sha256
   276          - --rfc2136-tsig-keyname=externaldns-key
   277          - --rfc2136-tsig-axfr
   278          - --source=ingress
   279          - --domain-filter=k8s.example.org
   280  ```
   281  
   282  ## Microsoft DNS (Insecure Updates)
   283  
   284  While `external-dns` was not developed or tested against Microsoft DNS, it can be configured to work against it. YMMV.
   285  
   286  ### Insecure Updates
   287  
   288  #### DNS-side configuration
   289  
   290  1. Create a DNS zone
   291  2. Enable insecure dynamic updates for the zone
   292  3. Enable Zone Transfers to all servers
   293  
   294  #### `external-dns` configuration
   295  
   296  You'll want to configure `external-dns` similarly to the following:
   297  
   298  ```text
   299  ...
   300          - --provider=rfc2136
   301          - --rfc2136-host=192.168.0.1
   302          - --rfc2136-port=53
   303          - --rfc2136-zone=k8s.example.org
   304          - --rfc2136-zone=k8s.your-zone.org
   305          - --rfc2136-insecure
   306          - --rfc2136-tsig-axfr # needed to enable zone transfers, which is required for deletion of records.
   307  ...
   308  ```
   309  
   310  ### Secure Updates Using RFC3645 (GSS-TSIG)
   311  
   312  ### DNS-side configuration
   313  
   314  1. Create a DNS zone
   315  2. Enable secure dynamic updates for the zone
   316  3. Enable Zone Transfers to all servers
   317  
   318  If you see any error messages which indicate that `external-dns` was somehow not able to fetch
   319  existing DNS records from your DNS server, this could mean that you forgot about step 3.
   320  
   321  #### Kerberos Configuration
   322  
   323  DNS with secure updates relies upon a valid Kerberos configuration running within the `external-dns` container.  At this time, you will need to create a ConfigMap for the `external-dns` container to use and mount it in your deployment.  Below is an example of a working Kerberos configuration inside a ConfigMap definition.  This may be different depending on many factors in your environment:
   324  
   325  ```yaml
   326  apiVersion: v1
   327  kind: ConfigMap
   328  metadata:
   329    creationTimestamp: null
   330    name: krb5.conf
   331  data:
   332    krb5.conf: |
   333      [logging]
   334      default = FILE:/var/log/krb5libs.log
   335      kdc = FILE:/var/log/krb5kdc.log
   336      admin_server = FILE:/var/log/kadmind.log
   337  
   338      [libdefaults]
   339      dns_lookup_realm = false
   340      ticket_lifetime = 24h
   341      renew_lifetime = 7d
   342      forwardable = true
   343      rdns = false
   344      pkinit_anchors = /etc/pki/tls/certs/ca-bundle.crt
   345      default_ccache_name = KEYRING:persistent:%{uid}
   346  
   347      default_realm = YOUR-REALM.COM
   348  
   349      [realms]
   350      YOUR-REALM.COM = {
   351        kdc = dc1.yourdomain.com
   352        admin_server = dc1.yourdomain.com
   353      }
   354  
   355      [domain_realm]
   356      yourdomain.com = YOUR-REALM.COM
   357      .yourdomain.com = YOUR-REALM.COM
   358  ```
   359  In most cases, the realm name will probably be the same as the domain name, so you can simply replace
   360  `YOUR-REALM.COM` with something like `YOURDOMAIN.COM`.
   361  
   362  Once the ConfigMap is created, the container `external-dns` container needs to be told to mount that ConfigMap as a volume at the default Kerberos configuration location.  The pod spec should include a similar configuration to the following:
   363  
   364  ```yaml
   365  ...
   366      volumeMounts:
   367      - mountPath: /etc/krb5.conf
   368        name: kerberos-config-volume
   369        subPath: krb5.conf
   370  ...
   371    volumes:
   372    - configMap:
   373        defaultMode: 420
   374        name: krb5.conf
   375      name: kerberos-config-volume
   376  ...
   377  ```
   378  
   379  #### `external-dns` configuration
   380  
   381  You'll want to configure `external-dns` similarly to the following:
   382  
   383  ```text
   384  ...
   385          - --provider=rfc2136
   386  	 - --rfc2136-gss-tsig
   387          - --rfc2136-host=dns-host.yourdomain.com
   388          - --rfc2136-port=53
   389          - --rfc2136-zone=your-zone.com
   390          - --rfc2136-zone=your-secondary-zone.com
   391          - --rfc2136-kerberos-username=your-domain-account
   392          - --rfc2136-kerberos-password=your-domain-password
   393          - --rfc2136-kerberos-realm=your-domain.com
   394          - --rfc2136-tsig-axfr # needed to enable zone transfers, which is required for deletion of records.
   395  ...
   396  ```
   397  
   398  As noted above, the `--rfc2136-kerberos-realm` flag is completely optional and won't be necessary in many cases.
   399  Most likely, you will only need it if you see errors similar to this: `KRB Error: (68) KDC_ERR_WRONG_REALM Reserved for future use`.
   400  
   401  The flag `--rfc2136-host` can be set to the host's domain name or IP address.
   402  However, it also determines the name of the Kerberos principal which is used during authentication.
   403  This means that Active Directory might only work if this is set to a specific domain name, possibly leading to errors like this:
   404  `KDC_ERR_S_PRINCIPAL_UNKNOWN Server not found in Kerberos database`.
   405  To fix this, try setting `--rfc2136-host` to the "actual" hostname of your DNS server.
   406  
   407  ## DNS Over TLS (RFCs 7858 and 9103)
   408  
   409  If your DNS server does zone transfers over TLS, you can instruct `external-dns` to connect over TLS with the following flags:
   410  
   411   * `--rfc2136-use-tls` Will enable TLS for both zone transfers and for updates.
   412   * `--tls-ca=<cert-file>` Is the path to a file containing certificate(s) that can be used to verify the DNS server
   413   * `--tls-client-cert=<client-cert-file>` and
   414   * `--tls-client-cert-key=<client-key-file>` Set the client certificate and key for mutual verification
   415   * `--rfc2136-skip-tls-verify` Disables verification of the certificate supplied by the DNS server.
   416  
   417  It is currently not supported to do only zone transfers over TLS, but not the updates. They are enabled and disabled together.