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

Load Balancing Options all for rfc2136 provider #5122

Open
marbon87 opened this issue Feb 24, 2025 · 3 comments
Open

Load Balancing Options all for rfc2136 provider #5122

marbon87 opened this issue Feb 24, 2025 · 3 comments
Labels
kind/feature Categorizes issue or PR as related to a new feature.

Comments

@marbon87
Copy link

We have to update multiple dns-servers with the same records and actually using multiple external-dns applications with the rfc2136 provider (one per destination) to update all dns-servers.

rfc2136 provider allows to configure multiple hosts to be update but only with the load balancing strategy round-robin, random and disabled.
I would be helplful to have a load balancing option "all" that updates all configred hosts.

@marbon87 marbon87 added the kind/feature Categorizes issue or PR as related to a new feature. label Feb 24, 2025
@Jeremy-Boyle
Copy link
Contributor

Jeremy-Boyle commented Feb 24, 2025

Hi @marbon87 what would you be looking to achieve here ?

Sending the records to all the hosts at once, that way if you have segmented hosts which do not update each other such as a dns farm?

I think the issue might be if one of them is down then that might cause a issue with the current code, but thats easily fixable.

@marbon87
Copy link
Author

Exactly, I want to update all hosts simultaneously.

@Jeremy-Boyle
Copy link
Contributor

Jeremy-Boyle commented Feb 24, 2025

Actually, looking at the code, I believe this behavior is already implemented. Load balancing is handled with the flag as you mentioned, and if multiple nameservers are defined, it will cycle through them as expected. The documentation could be clearer, but typically, load balancing is meant for distributing requests across multiple targets. Explicitly adding an "all" option doesn’t align with the conventional definition of load balancing. By default defining more than one host behaves in the manor you are looking for with the existing code in main. Could you please confirm it works as you would expect ?

Please take a look:

for i := 0; i < len(r.nameservers); i++ {
nameserver := r.getNextNameserver()
log.Debugf("Sending message to nameserver: %s", nameserver)
c, err := makeClient(r, nameserver)
if err != nil {
lastErr = fmt.Errorf("error setting up TLS: %w", err)
r.lastErr = lastErr
continue
}
if !r.insecure {
if r.gssTsig {
keyName, handle, err := r.KeyData(nameserver)
if err != nil {
lastErr = err
r.lastErr = lastErr
continue
}
defer handle.Close()
defer handle.DeleteContext(keyName)
c.TsigProvider = handle
msg.SetTsig(keyName, tsig.GSS, clockSkew, time.Now().Unix())
} else {
c.TsigProvider = tsig.HMAC{r.tsigKeyName: r.tsigSecret}
msg.SetTsig(r.tsigKeyName, r.tsigSecretAlg, clockSkew, time.Now().Unix())
}
}

func (r *rfc2136Provider) getNextNameserver() string {
if len(r.nameservers) == 1 {
return r.nameservers[0]
}
r.mu.Lock()
defer r.mu.Unlock()
if r.lastErr != nil {
log.Warnf("Last operation failed for nameserver %s", r.nameservers[r.counter])
log.Warnf("Last operation error message: %v", r.lastErr)
}
var nameserver string
switch r.loadBalancingStrategy {
case "random":
for {
nameserver = r.nameservers[r.randGen.Intn(len(r.nameservers))]
// Ensure that we don't get the same nameserver as the last one
if nameserver != r.nameservers[r.counter] {
break
}
}
case "round-robin":
nameserver = r.nameservers[r.counter]
r.counter = (r.counter + 1) % len(r.nameservers)
default:
if r.lastErr != nil {
r.counter = (r.counter + 1) % len(r.nameservers)
nameserver = r.nameservers[r.counter]
} else {
nameserver = r.nameservers[r.counter]
}
}
// Last error has been logged, reset it for the next operation
r.lastErr = nil
return nameserver
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature Categorizes issue or PR as related to a new feature.
Projects
None yet
Development

No branches or pull requests

2 participants