Skip to content

Commit

Permalink
feat(aws): always create AAAA alias records in route53 (#5111)
Browse files Browse the repository at this point in the history
* First pass based on existing PR, what is currently on master and some
extra tests.

* Try to resolve AWS service documentation

* Add documentation on how to opt-out of AAAA record creation

* Address documentation concerns

* Add some IPv6 tests to sources

* Make recommended changes to documentation
  • Loading branch information
rlees85 authored Mar 3, 2025
1 parent d4a66bd commit 7c23e01
Show file tree
Hide file tree
Showing 15 changed files with 448 additions and 305 deletions.
17 changes: 6 additions & 11 deletions docs/sources/gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,18 @@ The targets from each parent Gateway matching the \*Route are then combined and

## Dualstack Routes

Gateway resources may be served from an external-loadbalancer which may support both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces.
External DNS Controller uses the `external-dns.alpha.kubernetes.io/dualstack` annotation to determine this. If this annotation is
set to `true` then ExternalDNS will create two records (one A record
and one AAAA record) for each hostname associated with the Route resource.
Gateway resources may be served from an external-loadbalancer which may support
both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces. When using the AWS
Route53 provider, External DNS Controller will always create both A and AAAA
alias DNS records by default, regardless of whether the load balancer is dual
stack or not.

Example:
## Example

```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
annotations:
external-dns.alpha.kubernetes.io/dualstack: "true"
name: echo
spec:
hostnames:
Expand All @@ -112,7 +111,3 @@ spec:
type: PathPrefix
value: /echo
```
The above HTTPRoute resource is backed by a dualstack Gateway.
ExternalDNS will create both an A `echoserver.example.org` record and
an AAAA record of the same name, that each are aliases for the same LB.
33 changes: 20 additions & 13 deletions docs/tutorials/aws-load-balancer-controller.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,17 @@ spec:
The above should result in the creation of an (ipv4) ALB in AWS which will forward
traffic to the echoserver application.

If the `source=ingress` argument is specified, then ExternalDNS will create DNS
records based on the hosts specified in ingress objects. The above example would
result in two alias records being created, `echoserver.mycluster.example.org` and
`echoserver.example.org`, which both alias the ALB that is associated with the
Ingress object.
If the `--source=ingress` argument is specified, then ExternalDNS will create
DNS records based on the hosts specified in ingress objects. The above example
would result in two alias records (A and AAAA) being created for each of the
domains: `echoserver.mycluster.example.org` and `echoserver.example.org`. All
four records alias the ALB that is associated with the Ingress object. As the
ALB is IPv4 only, the AAAA alias records have no effect.

If you would like ExternalDNS to not create AAAA records at all, you can add the
following command line parameter: `--exclude-record-types=AAAA`. Please be
aware, this will disable AAAA record creation even for dualstack enabled load
balancers.

Note that the above example makes use of the YAML anchor feature to avoid having
to repeat the http section for multiple hosts that use the exact same paths. If
Expand Down Expand Up @@ -138,15 +144,17 @@ In the above example we create a default path that works for any hostname, and
make use of the `external-dns.alpha.kubernetes.io/hostname` annotation to create
multiple aliases for the resulting ALB.

## Dualstack ALBs
## Dualstack Load Balancers

AWS [supports][4] both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces for ALBs.
The AWS Load Balancer Controller uses the `alb.ingress.kubernetes.io/ip-address-type`
annotation (which defaults to `ipv4`) to determine this. If this annotation is
set to `dualstack` then ExternalDNS will create two alias records (one A record
and one AAAA record) for each hostname associated with the Ingress object.
AWS [supports both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces for ALBs][4]
and [NLBs][5]. The AWS Load Balancer Controller uses the `alb.ingress.kubernetes.io/ip-address-type`
annotation (which defaults to `ipv4`) to determine this. ExternalDNS creates
both A and AAAA alias DNS records by default, regardless of this annotation.
It's possible to create only A records with the following command line
parameter: `--exclude-record-types=AAAA`

[4]: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#ip-address-type
[5]: https://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancers.html#ip-address-type

Example:

Expand Down Expand Up @@ -174,5 +182,4 @@ spec:
```

The above Ingress object will result in the creation of an ALB with a dualstack
interface. ExternalDNS will create both an A `echoserver.example.org` record and
an AAAA record of the same name, that each are aliases for the same ALB.
interface.
37 changes: 34 additions & 3 deletions docs/tutorials/aws.md
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ Annotations which are specific to AWS.

### alias

`external-dns.alpha.kubernetes.io/alias` if set to `true` on an ingress, it will create an ALIAS record when the target is an ALIAS as well.
`external-dns.alpha.kubernetes.io/alias` if set to `true` on an ingress, it will create two ALIAS records (one 'A' for IPv4 and one 'AAAA' for IPv6) when the target is an ALIAS as well.
To make the target an alias, the ingress needs to be configured correctly as described in [the docs](./gke-nginx.md#with-a-separate-tcp-load-balancer).
In particular, the argument `--publish-service=default/nginx-ingress-controller` has to be set on the `nginx-ingress-controller` container.
If one uses the `nginx-ingress` Helm chart, this flag can be set with the `controller.publishService.enabled` configuration option.
Expand Down Expand Up @@ -650,6 +650,32 @@ This should show something like:
]
```

Or for IPv6 (AAAA) records:

```bash
aws route53 list-resource-record-sets --output json --hosted-zone-id $ZONE_ID \
--query "ResourceRecordSets[?Name == 'nginx.example.com.']|[?Type == 'AAAA']"
```

This should show something like:

```json
[
{
"Name": "nginx.example.com.",
"Type": "AAAA",
"AliasTarget": {
"HostedZoneId": "ZEWFWZ4R16P7IB",
"DNSName": "ae11c2360188411e7951602725593fd1-1224345803.eu-central-1.elb.amazonaws.com.",
"EvaluateTargetHealth": true
}
}
]
```

IPv6 (AAAA) records are created when ALIAS is enabled even for load balancers that do not have dualstack enabled.
However, Route53 returns empty sets when querying such records, meaning they are harmless and IPv4 will work as normal.

You can also fetch the corresponding text records:

```bash
Expand All @@ -674,9 +700,9 @@ This will show something like:
]
```

Note created TXT record alongside ALIAS record. TXT record signifies that the corresponding ALIAS record is managed by ExternalDNS. This makes ExternalDNS safe for running in environments where there are other records managed via other means.
Note created TXT record alongside ALIAS records. TXT record signifies that the corresponding ALIAS records are managed by ExternalDNS. This makes ExternalDNS safe for running in environments where there are other records managed via other means.

For more information about ALIAS record, see [Choosing between alias and non-alias records](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-choosing-alias-non-alias.html).
For more information about ALIAS records, see [Choosing between alias and non-alias records](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-choosing-alias-non-alias.html).

Let's check that we can resolve this DNS name. We'll ask the nameservers assigned to your zone first.

Expand Down Expand Up @@ -876,6 +902,11 @@ env:

The DynamoDB Registry can be used to store dns records metadata. See the [DynamoDB Registry Tutorial](../registry/dynamodb.md) for more information.

## Disable AAAA Record Creation

If you would like ExternalDNS to not create AAAA records at all, you can add the following command line parameter: `--exclude-record-types=AAAA`.
Please be aware, this will disable AAAA record creation even for dualstack enabled load balancers.

## Clean up

Make sure to delete all Service objects before terminating the cluster so all load balancers get cleaned up correctly.
Expand Down
82 changes: 46 additions & 36 deletions docs/tutorials/kube-ingress-aws.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,17 @@ spec:
The above should result in the creation of an (ipv4) ALB in AWS which will forward
traffic to skipper which will forward to the echoserver application.

If the `--source=ingress` argument is specified, then ExternalDNS will create DNS
records based on the hosts specified in ingress objects. The above example would
result in two alias records being created, `echoserver.mycluster.example.org` and
`echoserver.example.org`, which both alias the ALB that is associated with the
Ingress object.
If the `--source=ingress` argument is specified, then ExternalDNS will create
DNS records based on the hosts specified in ingress objects. The above example
would result in two alias records (A and AAAA) being created for each of the
domains: `echoserver.mycluster.example.org` and `echoserver.example.org`. All
four records alias the ALB that is associated with the Ingress object. As the
ALB is IPv4 only, the AAAA alias records have no effect.

If you would like ExternalDNS to not create AAAA records at all, you can add the
following command line parameter: `--exclude-record-types=AAAA`. Please be
aware, this will disable AAAA record creation even for dualstack enabled load
balancers.

Note that the above example makes use of the YAML anchor feature to avoid having
to repeat the http section for multiple hosts that use the exact same paths. If
Expand Down Expand Up @@ -197,13 +203,14 @@ In the above example we create a default path that works for any hostname, and
make use of the `external-dns.alpha.kubernetes.io/hostname` annotation to create
multiple aliases for the resulting ALB.

## Dualstack ALBs
## NLBs

AWS [supports](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#ip-address-type) both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces for ALBs.
The Kubernetes Ingress AWS controller supports the `alb.ingress.kubernetes.io/ip-address-type`
annotation (which defaults to `ipv4`) to determine this. If this annotation is
set to `dualstack` then ExternalDNS will create two alias records (one A record
and one AAAA record) for each hostname associated with the Ingress object.
AWS has
[NLBs](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/introduction.html)
and [kube-ingress-aws-controller][1] is able to create NLBs instead of ALBs.
The Kubernetes Ingress AWS controller supports the `zalando.org/aws-load-balancer-type`
annotation (which defaults to `alb`) to determine this. If this annotation is
set to `nlb` then ExternalDNS will create an NLB instead of an ALB.

Example:

Expand All @@ -212,7 +219,7 @@ apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/ip-address-type: dualstack
zalando.org/aws-load-balancer-type: nlb
name: echoserver
spec:
ingressClassName: skipper
Expand All @@ -229,18 +236,32 @@ spec:
pathType: Prefix
```

The above Ingress object will result in the creation of an ALB with a dualstack
interface. ExternalDNS will create both an A `echoserver.example.org` record and
an AAAA record of the same name, that each are aliases for the same ALB.
The above Ingress object will result in the creation of an NLB. A
successful create, you can observe in the ingress `status` field, that is
written by [kube-ingress-aws-controller][1]:

## NLBs
```yaml
status:
loadBalancer:
ingress:
- hostname: kube-ing-lb-atedkrlml7iu-1681027139.$region.elb.amazonaws.com
```

AWS has
[NLBs](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/introduction.html)
and [kube-ingress-aws-controller][1] is able to create NLBs instead of ALBs.
The Kubernetes Ingress AWS controller supports the `zalando.org/aws-load-balancer-type`
annotation (which defaults to `alb`) to determine this. If this annotation is
set to `nlb` then ExternalDNS will create an NLB instead of an ALB.
ExternalDNS will create A and AAAA alias records for: `echoserver.example.org`.
ExternalDNS will use these alias records to automatically maintain IP addresses
of the NLB.

## Dualstack Load Balancers

AWS [supports both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces for ALBs][5]
and [NLBs][6]. The Kubernetes Ingress AWS controller supports the `alb.ingress.kubernetes.io/ip-address-type`
annotation (which defaults to `ipv4`) to determine this. ExternalDNS creates
both A and AAAA alias DNS records by default, regardless of this annotation.
It's possible to create only A records with the following command line
parameter: `--exclude-record-types=AAAA`

[5]: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#ip-address-type
[6]: https://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancers.html#ip-address-type

Example:

Expand All @@ -249,7 +270,7 @@ apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
zalando.org/aws-load-balancer-type: nlb
alb.ingress.kubernetes.io/ip-address-type: dualstack
name: echoserver
spec:
ingressClassName: skipper
Expand All @@ -266,19 +287,8 @@ spec:
pathType: Prefix
```

The above Ingress object will result in the creation of an NLB. A
successful create, you can observe in the ingress `status` field, that is
written by [kube-ingress-aws-controller][1]:

```yaml
status:
loadBalancer:
ingress:
- hostname: kube-ing-lb-atedkrlml7iu-1681027139.$region.elb.amazonaws.com
```

ExternalDNS will create a A-records `echoserver.example.org`, that
use AWS ALIAS record to automatically maintain IP addresses of the NLB.
The above Ingress object will result in the creation of an ALB with a dualstack
interface.

## RouteGroup (optional)

Expand Down
3 changes: 0 additions & 3 deletions endpoint/labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,6 @@ const (
// supposed to be inserted by AWS SD Provider, and parsed into OwnerLabelKey and ResourceLabelKey key by AWS SD Registry
AWSSDDescriptionLabel = "aws-sd-description"

// DualstackLabelKey is the name of the label that identifies dualstack endpoints
DualstackLabelKey = "dualstack"

// txtEncryptionNonce label for keep same nonce for same txt records, for prevent different result of encryption for same txt record, it can cause issues for some providers
txtEncryptionNonce = "txt-encryption-nonce"
)
Expand Down
Loading

0 comments on commit 7c23e01

Please sign in to comment.