Skip to content

External DNS with FreeIPA (RFC2136)

Sadly the External DNS Operator do not support RFC2136. Let's use the upstream one.

Thanks to astrid for the starting point.

Prepare IPA DNS Zone

Generate a TSIG key and register it

dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST openshift-external-dns
1
2
3
4
5
6
7
8
$ cat Kopenshift-external-dns.+165+16478.private
Private-key-format: v1.3
Algorithm: 165 (HMAC_SHA512)
Key: c3LyD11u....xX6WA==
Bits: AAA=
Created: 20240205134832
Publish: 20240205134832
Activate: 20240205134832

Configure the key at ipa server and all replicas

1
2
3
4
5
6
$ cat /etc/named/ipa-ext.conf
...
key "openshift-external-dns" {
       algorithm hmac-sha512;
       secret "c3LyD11u....xX6WA==";
};

Allow DNS updates and zone transfer for the key

Select the zone you want to manage, in my example .disco.local:

  • Enable Dynamic update
  • Add grant openshift-external-dns subdomain disco.local ANY ; to BIND update policy Details about the policy configuration you can here

Screenshot

  • Configure Allow transfer is not possible via WebUI. Because

    ldap search example

    At the ipa server

    # kinit admin
    Password for admin@DISCO.LOCAL:
    # ldapsearch idnsname=disco.local.  dn idnsAllowTransfer
    SASL/GSSAPI authentication started
    SASL username: admin@disco.local
    SASL SSF: 256
    SASL data security layer installed.
    # extended LDIF
    #
    # LDAPv3
    # base <cn=dns,dc=disco,dc=local> (default) with scope subtree
    # filter: idnsname=disco.local.
    # requesting: dn idnsAllowTransfer
    #
    
    # disco.local., dns, disco.local
    dn: idnsname=disco.local.,cn=dns,dc=disco,dc=local
    idnsAllowTransfer: none;
    
    # search result
    search: 4
    result: 0 Success
    
    # numResponses: 2
    # numEntries: 1
    #
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    kinit admin
    
    ldapmodify -Y GSSAPI << EOF
    dn: idnsname=coe.muc.redhat.com.,cn=dns,dc=disco,dc=local
    changetype: modify
    replace: idnsAllowTransfer
    idnsAllowTransfer: key openshift-external-dns;
    -
    EOF
    

Deploy External DNS

based on Configuring RFC2136 provider

Deployment

Create a secret with the tsig key c3LyD11u....xX6WA==

 oc create secret generic external-dns-rfc2136-tsig-secret \
    --from-literal=EXTERNAL_DNS_RFC2136_TSIG_SECRET="c3LyD11u....xX6WA=="
---
apiVersion: v1
kind: Namespace
metadata:
  name: external-dns
  labels:
    name: external-dns
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: external-dns
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - pods
      - nodes
    verbs:
      - get
      - watch
      - list
  - apiGroups:
      - extensions
      - networking.k8s.io
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - "route.openshift.io"
    resources:
      - routes
    verbs:
      - get
      - list
      - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: external-dns-viewer
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: external-dns
subjects:
  - kind: ServiceAccount
    name: external-dns
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-dns
spec:
  selector:
    matchLabels:
      app: external-dns
  template:
    metadata:
      labels:
        app: external-dns
    spec:
      serviceAccountName: external-dns
      nodeSelector:
        node-role.kubernetes.io/master: ""
      tolerations:
        - effect: NoSchedule
          key: node-role.kubernetes.io/master
          operator: Exists
      containers:
        - name: external-dns
          env:
            - name: EXTERNAL_DNS_RFC2136_TSIG_SECRET
              valueFrom:
                secretKeyRef:
                  name: external-dns-rfc2136-tsig-secret
                  key: EXTERNAL_DNS_RFC2136_TSIG_SECRET
          image: registry.k8s.io/external-dns/external-dns:v0.14.0
          args:
            - --registry=txt
            - --txt-suffix=-%{record_type}-external-dns
            - --txt-owner-id=cluster.disco.local
            - --provider=rfc2136
            - --rfc2136-host=dns01.disco.local
            - --rfc2136-port=53
            - --rfc2136-zone=disco.local
            - --rfc2136-tsig-secret-alg=hmac-sha512
            - --rfc2136-tsig-keyname=openshift-external-dns
            - --rfc2136-tsig-axfr
            - --source=service
            - --domain-filter=disco.local
oc apply -k https://github.com/openshift-examples/web/tree/main/content/cluster-configuration/external-dns/deployment/

Check the logs of the external-dns pod

oc logs -n infra-external-dns deployment/external-dns

Example deployment

  • Required MetalLB or support of service type LoadBalancer.
1
2
3
4
5
6
7
8
oc new-project external-dns-demo

oc apply -f https://examples.openshift.pub/cluster-configuration/external-dns/../../deploy/deployment-simple-nginx.yaml

oc patch service/simple-nginx --type merge -p '{"spec":{"type":"LoadBalancer"}}'

oc annotate service/simple-nginx external-dns.alpha.kubernetes.io/hostname='external-dns-demo.disco.local'
oc annotate service/simple-nginx external-dns.alpha.kubernetes.io/ttl='60'

2024-02-06 2024-02-05 Contributors: Robert Bohne