kube/certs: use Let's Encrypt's recommended retry schedule (#20292)
Replace the doubling backoff (1m, 2m, 4m, ...) with LE's recommended 1m, 10m, 100m, daily. The old schedule burned retry attempts inside the rate-limit window without speeding recovery. Updates #20288 Updates #19895 Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
This commit is contained in:
+15
-14
@@ -94,6 +94,16 @@ func (cm *CertManager) EnsureCertLoops(ctx context.Context, sc *ipn.ServeConfig)
|
||||
return nil
|
||||
}
|
||||
|
||||
// retrySchedule is the wait between successive failed issuance attempts,
|
||||
// following LE's recommended schedule.
|
||||
// https://letsencrypt.org/docs/integration-guide/#retrying-failures
|
||||
var retrySchedule = []time.Duration{
|
||||
1 * time.Minute,
|
||||
10 * time.Minute,
|
||||
100 * time.Minute,
|
||||
24 * time.Hour,
|
||||
}
|
||||
|
||||
// runCertLoop:
|
||||
// - calls localAPI certificate endpoint to ensure that certs are issued for the
|
||||
// given domain name
|
||||
@@ -103,13 +113,8 @@ func (cm *CertManager) EnsureCertLoops(ctx context.Context, sc *ipn.ServeConfig)
|
||||
// Note that renewal check also happens when the node receives an HTTPS request and it is possible that certs get
|
||||
// renewed at that point. Renewal here is needed to prevent the shared certs from expiry in edge cases where the 'write'
|
||||
// replica does not get any HTTPS requests.
|
||||
// https://letsencrypt.org/docs/integration-guide/#retrying-failures
|
||||
func (cm *CertManager) runCertLoop(ctx context.Context, domain string) {
|
||||
const (
|
||||
normalInterval = 24 * time.Hour // regular renewal check
|
||||
initialRetry = 1 * time.Minute // initial backoff after a failure
|
||||
maxRetryInterval = 24 * time.Hour // max backoff period
|
||||
)
|
||||
const normalInterval = 24 * time.Hour // regular renewal check
|
||||
|
||||
if err := cm.waitForCertDomain(ctx, domain); err != nil {
|
||||
// Best-effort, log and continue with the issuing loop.
|
||||
@@ -153,15 +158,11 @@ func (cm *CertManager) runCertLoop(ctx context.Context, domain string) {
|
||||
nextInterval = normalInterval
|
||||
} else {
|
||||
retryCount++
|
||||
// Calculate backoff: initialRetry * 2^(retryCount-1)
|
||||
// For retryCount=1: 1min * 2^0 = 1min
|
||||
// For retryCount=2: 1min * 2^1 = 2min
|
||||
// For retryCount=3: 1min * 2^2 = 4min
|
||||
backoff := initialRetry * time.Duration(1<<(retryCount-1))
|
||||
if backoff > maxRetryInterval {
|
||||
backoff = maxRetryInterval
|
||||
idx := retryCount - 1
|
||||
if idx >= len(retrySchedule) {
|
||||
idx = len(retrySchedule) - 1
|
||||
}
|
||||
nextInterval = backoff
|
||||
nextInterval = retrySchedule[idx]
|
||||
cm.logf("Error refreshing certificate for %s (retry %d): %v. Will retry in %v\n",
|
||||
domain, retryCount, err, nextInterval)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user