Skip to content

Configuring Sources

Daniel Lamando edited this page Feb 19, 2022 · 2 revisions

Sources are how kubernetes-dns-sync discovers the DNS records that your Kubernetes cluster wants to create and manage. Sources operate in a read-only role and use a watcher pattern by default to react quickly to any changes made in your cluster.

The most common source, ingress, is designed to cooperate with your cluster's Ingress Controller[s] such as ingress-nginx. Several other sources use Custom Resources to integrate more closely with specific tools.

All sources can be configured with their own annotation_filter. This is a simple dictionary-match filter; for every key present in the filter, only resources with an exact value match will be considered.

Resource Support Table

Source type Kubernetes Kind Target APIVersion Primary usage
ingress Ingress networking.k8s.io/v1 Serving HTTP traffic
crd DNSEndpoint externaldns.k8s.io/v1alpha1 Managing arbitrary DNS records
acme-crd Challenge acme.cert-manager.io/v1 Solving DNS01 challenges
node Node v1 'Dynamic DNS' for your Nodes

See below sections for more info on each source.

All Available Sources

ingress

The original. Furnishes DNS records for your Ingress resources. You'll probably want to set a filter for your ingress class, especially if you have a split-horizon DNS configuration.

Note that if both ingress_class_names and annotation_filter are set, each Ingress will need to match both filters to be considered. If you have a mix of ingress class styles, you could perhaps add two ingress sources, but it would be easier to make your resources consistent to one of the styles.

[[source]]
type = "ingress"

### optional: Set a list of `ingressClassName` values to filter Ingresses by
# ingress_class_names = [ "nginx" ]

### optional: Filter which resources we will manage records for
# annotation_filter = { "kubernetes.io/ingress.class" = "nginx" }

This project uses the Ingress kind from networking.k8s.io/v1, which was introduced in Kubernetes v1.19. If your cluster is older, consider upgrading it.

crd

Allows specifying highly custom records via the CRD from the external-dns project.

To specify complex records such as MX or SRV, use the "rrdata" layout for that record type. For example, a SRV target in a CRD could be: 10 5 5223 server.example.com. See Google Cloud DNS docs for more examples.

The CRD's manifest can be found upstream. Create this CRD in your cluster before enabling the crd source in your configuration.

[[source]]
type = "crd"

# annotation_filter = { "kubernetes.io/ingress.class" = "nginx" }

acme-crd

This source specifically targets cert-manager's v1 Challenge CRD. It presents ACME DNS01 Challenges without cert-manager having DNS provider details.

The configuration includes several optional fields:

[[source]]
type = "acme-crd"

### Set a optional TTL on challenges.
# challenge_ttl = 120

### Whether to allow wildcard certificates.
### Default `true`; set `false` to disallow
# allow_wildcards = false

### Note that this is matched to the annotations from the `Challenge` resource.
# annotation_filter = { ... }

To use, create a cert-manager Issuer or ClusterIssuer with this dummy webhook solver:

    solvers:
    - dns01:
        webhook:
          groupName: kubernetes-dns-sync
          solverName: kubernetes-dns-sync

cert-manager won't like it but as long as kubernetes-dns-sync has correct permissions, the Challenge should get presented anyway and allow the Order to succeed.

node

This source requires a fqdn_template and uses it to compute DNS records for the different Nodes in the Kubernetes cluster.

This is effectively a Kubernetes-based Dynamic DNS arrangement with address_type = ExternalIP. It's also possible to use address_type = InternalIP to build an internal DNS zone. If a node has multiple addresses of the desired type (e.g. dualstack IPv4/IPv6) then each address will be extracted into a DNS target.

In theory you can also use this for hosting round-robin endpoints, but if you're serving HTTP, the ingress source is probably what you want instead.

[[source]]
type = "node"

### required: A FQDN pattern for each node
### If an "index" interpolation doesn't match, that node is skipped
fqdn_template = "{{index .Labels \"kubernetes.io/hostname\"}}.pet.devmode.cloud"

# address_type = "ExternalIP" # default. Or "InternalIP"
# annotation_filter = { "kubernetes.io/node.class" = "workload" }

NOTE: The only interpolation currently allowed in fqdn_template is {{ index .Labels "..." }}