Skip to content

feat(wrappers): resolve load balancer hostnames to A/AAAA records#6289

Closed
Apoorva64 wants to merge 19 commits into
kubernetes-sigs:masterfrom
Orange-OpenSource:feat/add---resolve-load-balancer-hostname-with-post-processor-wrapper
Closed

feat(wrappers): resolve load balancer hostnames to A/AAAA records#6289
Apoorva64 wants to merge 19 commits into
kubernetes-sigs:masterfrom
Orange-OpenSource:feat/add---resolve-load-balancer-hostname-with-post-processor-wrapper

Conversation

@Apoorva64

@Apoorva64 Apoorva64 commented Mar 17, 2026

Copy link
Copy Markdown

What does this PR do?

This Pr adds per-resource annotation: external-dns.alpha.kubernetes.io/resolve-target. Setting this annotation to true causes ExternalDNS to resolve any CNAME target (i.e. a hostname returned by a cloud load balancer) to its A and AAAA records at sync time, and emit those IP addresses as A/AAAA endpoints instead. DNS resolution uses net.LookupIP and honours the system resolver.
Implementation
Resolution is implemented as a Source Wrapper in resolvesource.go, wrapping any source. Each source propagates the annotation value as an endpoint label using provider_specific.go; the resolvesource wrapper reads the label and resolves the hostname

If resolution fails for a target (e.g. the hostname is temporarily unresolvable), that target is silently skipped and a debug log entry is emitted.

Motivation

Some DNS providers or configurations do not support CNAME records (e.g., internal Dns), requiring IP-based records.

More

  • Yes, this PR title follows Conventional Commits
  • Yes, I added unit tests
  • Yes, I updated end user documentation accordingly

@k8s-ci-robot k8s-ci-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Mar 17, 2026
@k8s-ci-robot k8s-ci-robot added apis Issues or PRs related to API change cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. controller Issues or PRs related to the controller docs needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. source labels Mar 17, 2026
@k8s-ci-robot

Copy link
Copy Markdown
Contributor

Hi @Apoorva64. Thanks for your PR.

I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot k8s-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Mar 17, 2026
@ivankatliarchuk

Copy link
Copy Markdown
Member

#6286 (comment)

@Apoorva64 Apoorva64 changed the title feat(warppers): add --resolve-load-balancer-hostname flag to convert CNAME to AAAA feat(warppers): resolve load balancer hostnames to A/AAAA records using wrappers Mar 17, 2026
@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Mar 17, 2026
@Apoorva64

Copy link
Copy Markdown
Author

@ivankatliarchuk i've looked more into it and i've implemented the annotation for the Ingress and Gateway Resources.
Is this the right way to propogate the annotation to the wrapper?

Comment thread tests/integration/scenarios/tests.yaml Outdated
- hostname: example.com
expected:
- dnsName: svc.example.com
targets: ["104.18.26.120", "104.18.27.120"]

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Theses ips may change

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If they may change we have a problem. The IP should be fairly static, otherwise we end-up with fragile tests

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to checking if the Record types A and AAAA are present instead of checking the direct ips. The example domain is owned by iana so it should be stable https://www.iana.org/help/example-domains

Comment thread docs/annotations/annotations.md Outdated

### Use Cases for `external-dns.alpha.kubernetes.io/resolve-target` annotation

#### Opt in to resolution for a single Ingress

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still struggling a bit. Could you share actually WHY we need resolve IP for a CNAME? Opt in to resolution for a single Ingress or Opt out of resolution for a single Gateway Route -> a not a use cases` in normal sense.

@Apoorva64 Apoorva64 Mar 18, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep,
In a public cloud provider, when we create a Gateway and an Http Route or an Ingress we usually end up with something like this:
When we create a Gateway we end up with a hostname in the status which points to the loadbalancer's ips.
Diagramme sans nom drawio(1)

The loadbalancer IPs are then routed in an infrastructure where we can't resolve external Records like example-gateway.region.mycloud.com.

If we create a CNAME my-app.internal to example-gateway.region.mycloud.com it won't work as the app my-second-app won't be able to resolve the example-gateway.region.mycloud.com Record

We must then create an A Record in the air-gapped infrastructure instead of a CNAME.
image

But :

  • not all apps are equal and some will be able to resolve the CNAME of example-gateway.region.mycloud.com
    which is why it would be useful to have the control over the annotations.
  • Most of the apps won't be able to resolve the CNAME Record and this is why we may need a global flag

Comment thread source/ingress.go Outdated

// Propagate the per-resource annotation as a label so the PostProcessor can
// apply or suppress hostname resolution on a per-Ingress basis.
if v, ok := ing.Annotations[annotations.ResolveTargetKey]; ok {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A good idea, need to re-think our approach long-term. At the moment just bootstrap it as provider-specific https://github.com/kubernetes-sigs/external-dns/blob/master/source/annotations/provider_specific.go and it should be available at wrapper layer without any code changes at source layer.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to the provider_specific in 6e5cbb0

cfg PostProcessorConfig
}

type PostProcessorConfig struct {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use dedupwrapper. This is already to late, as dedup-wrapper may drop endpoints

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of modifying the dedupwrapper i wrote a new 'resolveSource' wrapper that handles the hostname resolving.

I've put the wrapper before the dedupwrapper

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should i still use the dedupwrapper? i think i saw i message yesterday about it

@ivankatliarchuk ivankatliarchuk Mar 20, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. I deleted the message. Not yet sure. One one side it make sense to have dedicaetd wrapper, on the other side too many wrappers, not too clear yet

Comment thread docs/flags.md Outdated
| `--kubeconfig=""` | Retrieve target cluster configuration from a Kubernetes configuration file (default: auto-detect) |
| `--request-timeout=30s` | Request timeout when calling Kubernetes APIs. 0s means no timeout |
| `--[no-]resolve-service-load-balancer-hostname` | Resolve the hostname of LoadBalancer-type Service object to IP addresses in order to create DNS A/AAAA records instead of CNAMEs |
| `--[no-]resolve-load-balancer-hostname` | Resolve the hostname of LoadBalancer addresses in source status to IP addresses in order to create DNS A/AAAA records instead of CNAMEs |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too-sure about flag at this stage. Probably worth to plan it as follow-up if this PR will get merged

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the description of the use-case in #6289 (comment). Should i remove the flag ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the better option is to add/remove/modify flags in follow up PR.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ivankatliarchuk i removed the flag

Comment thread tests/integration/scenarios/tests.yaml Outdated
- hostname: example.com
expected:
- dnsName: svc.example.com
targets: ["104.18.26.120", "104.18.27.120"]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If they may change we have a problem. The IP should be fairly static, otherwise we end-up with fragile tests

@k8s-ci-robot

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from ivankatliarchuk. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ivankatliarchuk

Copy link
Copy Markdown
Member

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Mar 18, 2026
@coveralls

coveralls commented Mar 18, 2026

Copy link
Copy Markdown

Pull Request Test Coverage Report for Build 23438696528

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • 20 unchanged lines in 2 files lost coverage.
  • Overall coverage increased (+0.003%) to 78.07%

Files with Coverage Reduction New Missed Lines %
annotations/provider_specific.go 5 93.67%
testutils/endpoint.go 15 62.31%
Totals Coverage Status
Change from base Build 23401388822: 0.003%
Covered Lines: 16451
Relevant Lines: 21072

💛 - Coveralls

@mloiseleur mloiseleur changed the title feat(wrappers): resolve load balancer hostnames to A/AAAA records using wrappers feat(wrappers): resolve load balancer hostnames to A/AAAA records Mar 20, 2026
@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 22, 2026
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 23, 2026
@k8s-ci-robot k8s-ci-robot added the internal Issues or PRs related to internal code label Mar 23, 2026
@Apoorva64 Apoorva64 marked this pull request as ready for review March 25, 2026 08:15
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Mar 25, 2026
@ivankatliarchuk

Copy link
Copy Markdown
Member

/ok-to-test

@Apoorva64

Copy link
Copy Markdown
Author

@ivankatliarchuk, is there something to change that I missed or another requirement?

@ivankatliarchuk

Copy link
Copy Markdown
Member

Yeah something strange with this PR. Our tests not triggered.

/ok-to-test

@ivankatliarchuk

Copy link
Copy Markdown
Member

/close

@k8s-ci-robot

Copy link
Copy Markdown
Contributor

@ivankatliarchuk: Closed this PR.

Details

In response to this:

/close

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@ivankatliarchuk

Copy link
Copy Markdown
Member

/reopen

@k8s-ci-robot k8s-ci-robot reopened this Mar 30, 2026
@k8s-ci-robot

Copy link
Copy Markdown
Contributor

@ivankatliarchuk: Reopened this PR.

Details

In response to this:

/reopen

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@ivankatliarchuk

Copy link
Copy Markdown
Member

/ok-to-test

@ivankatliarchuk

Copy link
Copy Markdown
Member

I think this PR is screwed

@Apoorva64

Copy link
Copy Markdown
Author

Should i close and reopen with a new branch name ?

PS: Does External Dns have community meetings ? I've been looking around for it but i can't find it xD

@ivankatliarchuk

Copy link
Copy Markdown
Member

We don't hold any community meetings. There is slack channel, but we not too active there as well.

Try to open a new PR. I seriously do not get what is going on here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

apis Issues or PRs related to API change cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. controller Issues or PRs related to the controller docs internal Issues or PRs related to internal code ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. source

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants