Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Background processing for address lookups of CNAME replacements #377

Merged
merged 7 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ To install the <b>DNS controller manager</b> in your Kubernetes cluster, follow
```

For more examples about the custom resources and the annotations for services and ingresses
see the `examples` directory.
see the [examples](examples/) directory and [translation of `DNSEntries` examples](docs/usage/dnsentry_translation.md)

### Automatic creation of DNS entries for services and ingresses

Expand Down
14 changes: 13 additions & 1 deletion charts/external-dns-management/templates/crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ spec:
properties:
cnameLookupInterval:
description: lookup interval for CNAMEs that must be resolved to IP
addresses
addresses. Only used if `resolveTargetsToAddresses` is set to true
or targets consists of multiple domain names.
format: int64
type: integer
dnsName:
Expand All @@ -122,6 +123,12 @@ spec:
required:
- name
type: object
resolveTargetsToAddresses:
description: enables translation of a target domain name in the resolved
IPv4 and IPv6 addresses. If enabled, `A` and/or `AAAA` records are
created instead of a `CNAME` record. If the target list contains
multiple targets, it is enabled implicitly.
type: boolean
routingPolicy:
description: optional routing policy
properties:
Expand Down Expand Up @@ -162,6 +169,11 @@ spec:
type: object
status:
properties:
cnameLookupInterval:
description: effective lookup interval for CNAMEs that must be resolved
to IP addresses
format: int64
type: integer
lastUpdateTime:
description: lastUpdateTime contains the timestamp of the last status
update
Expand Down
19 changes: 10 additions & 9 deletions docs/usage/dnsentry_status.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ This document provides an overview of the status section of a DNSEntry resource.

### Fields

| Field name | Description |
| -------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `state` | Indicates the state of the DNSEntry. Details see below. |
| `lastUpdateTime` | Timestamp for when the status was updated. Usually changes when any relevant status field like `state`, `message`, `provider`, or `targets` is updated. |
| `message` | Human-readable message indicating details about the last status transition. |
| `provider` | Shows the DNS provider assigned to this entry. |
| `providerType` | Shows the DNS provider type assigned to this entry. |
| `targets` | Shows the stored targets or text of the DNS record in the backend service. |
| `ttl` | Shows the stored TTL value of the DNS record in the backend service. |
| Field name | Description |
|------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
| `state` | Indicates the state of the DNSEntry. Details see below. |
| `cnameLookupInterval` | Shows effective lookup interval for targets domain names to be resolved to IP addresses. Only provided if lookups are active for this entry. |
| `lastUpdateTime` | Timestamp for when the status was updated. Usually changes when any relevant status field like `state`, `message`, `provider`, or `targets` is updated. |
| `message` | Human-readable message indicating details about the last status transition. |
| `provider` | Shows the DNS provider assigned to this entry. |
| `providerType` | Shows the DNS provider type assigned to this entry. |
| `targets` | Shows the stored targets or text of the DNS record in the backend service. |
| `ttl` | Shows the stored TTL value of the DNS record in the backend service. |

Currently the available states are:

Expand Down
185 changes: 185 additions & 0 deletions docs/usage/dnsentry_translation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
# DNSEntry Translation into DNS records

## Creating `A` and/or `AAAA` records

To create an `A` and/or `AAAA` DNS records, the spec of the `DNSEntry` must contains a list of IP addresses as targets.

Example:
```yaml
apiVersion: dns.gardener.cloud/v1alpha1
kind: DNSEntry
metadata:
name: myentry-a
namespace: default
spec:
dnsName: "myentry-a.my-own-domain.com"
targets:
- 1.2.3.4
- 1.2.3.5
- 2abc:1234:5678::42
ttl: 600 # optional to set TTL
```

Two DNS records are created, as can be checked with nslookup:
```bash
$ nslookup -type=A myentry-a.my-own-domain.com
...
Non-authoritative answer:
Name: myentry-a.my-own-domain.com
Address: 1.2.3.4
Name: myentry-a.my-own-domain.com
Address: 1.2.3.5

$ nslookup -type=AAAA myentry-a.my-own-domain.com
...
Non-authoritative answer:
myentry-a.dnstest.my-own-domain.com has AAAA address 2abc:1234:5678::42
```

## Creating a `CNAME` record

To create a `CNAME` DNS record, the target list of the `DNSEntry` must contain exactly one domain name.

Example:
```yaml
apiVersion: dns.gardener.cloud/v1alpha1
kind: DNSEntry
metadata:
name: myentry-cname
namespace: default
spec:
dnsName: "myentry-cname.my-own-domain.com"
targets:
- mytarget.my-own-domain.com
ttl: 600 # optional to set TTL
```

A `CNAME` DNS record is created as expected:
```bash
$ nslookup -type=CNAME myentry-cname.my-own-domain.com
...
Non-authoritative answer:
myentry-cname.my-own-domain.com canonical name = mytarget.my-own-domain.com.
```

## Creating `TXT` record

To create a `TXT` DNS record, the texts list of the `DNSEntry` contains the text values.

Example:
```yaml
apiVersion: dns.gardener.cloud/v1alpha1
kind: DNSEntry
metadata:
name: myentry-txt
namespace: default
spec:
dnsName: "myentry-txt.my-own-domain.com"
text:
- "first value"
- "second value"
ttl: 600 # optional to set TTL
```

`TXT` DNS records are created as expected:
```bash
$ nslookup -type=TXT myentry-txt.my-own-domain.com
...
Non-authoritative answer:
myentry-txt.my-own-domain.com text = "first value"
myentry-txt.my-own-domain.com text = "second value"
```

## Creating `A`/`AAAA` records for multiple domain names

This is a feature to provide a `CNAME` like behaviour for multiple domain names.
The `.spec.targets` list of the `DNSEntry` contains multiple DNS names in this case.
These names are looked up periodically and resolved into their IPv6 an IPv4 addresses.

Example:
```yaml
apiVersion: dns.gardener.cloud/v1alpha1
kind: DNSEntry
metadata:
name: myentry-multi-cname
namespace: default
spec:
dnsName: "myentry-multi-cname.my-own-domain.com"
targets:
- wikipedia.org
- wikipedia.de
ttl: 600 # optional to set TTL
cnameLookupInterval: 200 # optional to specify lookup internal to resolve the DNS names
```

As `wikipedia.org` resolves to `185.15.59.224` and `2a02:ec80:300:ed1a::1` and
`wikipedia.de` to `49.13.55.174` and `2a01:4f8:c012:3f0a::1` (at time of running this example),
you will get these `A` and `AAAA` DNS records:
```bash
$ nslookup -type=A myentry-multi-cname.my-own-domain.com
...
Non-authoritative answer:
Name: myentry-multi-cname.my-own-domain.com
Address: 185.15.59.224
Name: myentry-multi-cname.my-own-domain.com
Address: 49.13.55.174

$ nslookup -type=AAAA myentry-multi-cname.my-own-domain.com
...
Non-authoritative answer:
myentry-multi-cname.my-own-domain.com has AAAA address 2a02:ec80:300:ed1a::1
myentry-multi-cname.my-own-domain.com has AAAA address 2a01:4f8:c012:3f0a::1
```

> [!NOTE]
> Using this feature creates reoccuring work load on the dns-controller-manager as the target domain names
> need to be looked up periodically. If the target addressed have changed, the addresses in the created `A`/`AAAA` records
> will be updated automatically. As two more steps are involved, some additional time is needed until your DNS clients will
> see such changes in comparison with setting the addresses directly as targets.
> The scheduled DNS lookups happen roughly at the set intervals, but timing depends on cluster load and upstream DNS responsiveness.
> Also be aware that this feature can only be used for domain names visible to the dns-controller-manager.

## Creating `A`/`AAAA` records for single domain name

This is a special feature to avoid a `CNAME` record and resolving the domain name into addresses.
The `.spec.targets` list of the `DNSEntry` contains a single DNS name in this case.
These name is looked up periodically and resolved into its current IPv6 an IPv4 addresses.

Example:
```yaml
apiVersion: dns.gardener.cloud/v1alpha1
kind: DNSEntry
metadata:
name: myentry-no-cname
namespace: default
spec:
dnsName: "myentry-no-cname.my-own-domain.com"
targets:
- wikipedia.org
resolveTargetsToAddresses: true # this field is needed to distinguish from CNAME record creation
ttl: 600 # optional to set TTL
cnameLookupInterval: 200 # optional to specify lookup internal to resolve the DNS names
```

As `wikipedia.org` resolves to `185.15.59.224` and `2a02:ec80:300:ed1a::1` (at time of running this example),
you will get these `A` and `AAAA` DNS records:
```bash
$ nslookup -type=A myentry-no-cname.my-own-domain.com
...
Non-authoritative answer:
Name: myentry-no-cname.my-own-domain.com
Address: 185.15.59.224

$ nslookup -type=AAAA myentry-no-cname.my-own-domain.com
...
Non-authoritative answer:
myentry-no-cname.my-own-domain.com has AAAA address 2a02:ec80:300:ed1a::1
```

> [!NOTE]
> Using this feature creates reoccuring work load on the dns-controller-manager as the target domain names
> need to be looked up periodically. If the target addressed have changed, the addresses in the created `A`/`AAAA` records
> will be updated automatically. As two more steps are involved, some additional time is needed until your DNS clients will
> see such changes in comparison with setting the addresses directly as targets.
> The scheduled DNS lookups happen roughly at the set intervals, but timing depends on cluster load and upstream DNS responsiveness.
> Also be aware that this feature can only be used for domain names visible to the dns-controller-manager.
15 changes: 15 additions & 0 deletions examples/43-entry-resolve-to-addresses.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: dns.gardener.cloud/v1alpha1
kind: DNSEntry
metadata:
annotations:
# If you are delegating the DNS management to Gardener, uncomment the following line (see https://gardener.cloud/documentation/guides/administer_shoots/dns_names/)
#dns.gardener.cloud/class: garden
name: resolve-to-a
namespace: default
spec:
dnsName: my.domain-name.example.com
ttl: 600
cnameLookupInterval: 30
resolveTargetsToAddresses: true # if this flag is set, the target name will be resolved and A/AAAA records will be created instead of an CNAME.
targets:
- my.domain-name.example.com
1 change: 1 addition & 0 deletions examples/50-ingress-with-dns.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ metadata:
#dns.gardener.cloud/ttl: "500"
#dns.gardener.cloud/owner-id: second
#dns.gardener.cloud/ip-stack: dual-stack # AWS-route 53 only: enable both A and AAAA alias targets
#dns.gardener.cloud/resolve-targets-to-addresses: "true"
name: test-ingress
namespace: default
spec:
Expand Down
1 change: 1 addition & 0 deletions examples/50-service-with-dns.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ metadata:
#dns.gardener.cloud/owner-id: second
#service.beta.kubernetes.io/aws-load-balancer-ip-address-type: dualstack # AWS-route 53 only: enable both A and AAAA alias targets
#dns.gardener.cloud/ip-stack: dual-stack # AWS-route 53 only: alternative way to enable A and AAAA alias targets
#dns.gardener.cloud/resolve-targets-to-addresses: "true"
name: test-service
namespace: default
spec:
Expand Down
14 changes: 13 additions & 1 deletion pkg/apis/dns/crds/dns.gardener.cloud_dnsentries.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ spec:
properties:
cnameLookupInterval:
description: lookup interval for CNAMEs that must be resolved to IP
addresses
addresses. Only used if `resolveTargetsToAddresses` is set to true
or targets consists of multiple domain names.
format: int64
type: integer
dnsName:
Expand All @@ -116,6 +117,12 @@ spec:
required:
- name
type: object
resolveTargetsToAddresses:
description: enables translation of a target domain name in the resolved
IPv4 and IPv6 addresses. If enabled, `A` and/or `AAAA` records are
created instead of a `CNAME` record. If the target list contains
multiple targets, it is enabled implicitly.
type: boolean
routingPolicy:
description: optional routing policy
properties:
Expand Down Expand Up @@ -156,6 +163,11 @@ spec:
type: object
status:
properties:
cnameLookupInterval:
description: effective lookup interval for CNAMEs that must be resolved
to IP addresses
format: int64
type: integer
lastUpdateTime:
description: lastUpdateTime contains the timestamp of the last status
update
Expand Down
14 changes: 13 additions & 1 deletion pkg/apis/dns/crds/zz_generated_crds.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,8 @@ spec:
properties:
cnameLookupInterval:
description: lookup interval for CNAMEs that must be resolved to IP
addresses
addresses. Only used if ` + "`" + `resolveTargetsToAddresses` + "`" + ` is set to true
or targets consists of multiple domain names.
format: int64
type: integer
dnsName:
Expand All @@ -235,6 +236,12 @@ spec:
required:
- name
type: object
resolveTargetsToAddresses:
description: enables translation of a target domain name in the resolved
IPv4 and IPv6 addresses. If enabled, ` + "`" + `A` + "`" + ` and/or ` + "`" + `AAAA` + "`" + ` records are
created instead of a ` + "`" + `CNAME` + "`" + ` record. If the target list contains
multiple targets, it is enabled implicitly.
type: boolean
routingPolicy:
description: optional routing policy
properties:
Expand Down Expand Up @@ -275,6 +282,11 @@ spec:
type: object
status:
properties:
cnameLookupInterval:
description: effective lookup interval for CNAMEs that must be resolved
to IP addresses
format: int64
type: integer
lastUpdateTime:
description: lastUpdateTime contains the timestamp of the last status
update
Expand Down
11 changes: 10 additions & 1 deletion pkg/apis/dns/v1alpha1/dnsentry.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,15 @@ type DNSEntrySpec struct {
// time to live for records in external DNS system
// +optional
TTL *int64 `json:"ttl,omitempty"`
// lookup interval for CNAMEs that must be resolved to IP addresses
// lookup interval for CNAMEs that must be resolved to IP addresses.
// Only used if `resolveTargetsToAddresses` is set to true or targets consists of multiple domain names.
// +optional
CNameLookupInterval *int64 `json:"cnameLookupInterval,omitempty"`
// enables translation of a target domain name in the resolved IPv4 and IPv6 addresses.
// If enabled, `A` and/or `AAAA` records are created instead of a `CNAME` record.
// If the target list contains multiple targets, it is enabled implicitly.
// +optional
ResolveTargetsToAddresses *bool `json:"resolveTargetsToAddresses,omitempty"`
// text records, either text or targets must be specified
// +optional
Text []string `json:"text,omitempty"`
Expand All @@ -80,6 +86,9 @@ type DNSEntryStatus struct {
// effective routing policy
// +optional
RoutingPolicy *RoutingPolicy `json:"routingPolicy,omitempty"`
// effective lookup interval for CNAMEs that must be resolved to IP addresses
// +optional
CNameLookupInterval *int64 `json:"cnameLookupInterval,omitempty"`
}

type DNSBaseStatus struct {
Expand Down
Loading