Skip to content
Open
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
1 change: 1 addition & 0 deletions docs/flags.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ tags:
| `--kubeconfig=""` | Retrieve target cluster configuration from a Kubernetes configuration file (default: auto-detect) |
| `--request-timeout=30s` | [DEPRECATED: use --kube-api-request-timeout] Request timeout when calling Kubernetes APIs. 0s means no timeout |
| `--kube-api-request-timeout=30s` | Request timeout when calling Kubernetes APIs. 0s means no timeout |
| `--kube-api-cache-sync-timeout=1m0s` | Timeout for waiting for Kubernetes informer caches to sync during startup. Values <= 0 use the default (60s). Increase only after ruling out RBAC, network, or API server issues. |
| `--kube-api-qps=5` | Maximum QPS to the Kubernetes API server from this client. |
| `--kube-api-burst=10` | Maximum burst for throttle to the Kubernetes API server from this client. |
| `--provider=provider` | The DNS provider where the DNS records will be created (required, options: akamai, alibabacloud, aws, aws-sd, azure, azure-dns, azure-private-dns, civo, cloudflare, coredns, dnsimple, exoscale, gandi, godaddy, google, inmemory, linode, ns1, oci, ovh, pdns, pihole, plural, rfc2136, scaleway, skydns, transip, webhook) |
Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/externaldns/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type Config struct {
APIServerURL string
KubeConfig string
RequestTimeout time.Duration
CacheSyncTimeout time.Duration
KubeAPIRequestTimeout time.Duration
KubeAPIQPS int
KubeAPIBurst int
Expand Down Expand Up @@ -356,6 +357,7 @@ var defaultConfig = &Config{
RegexDomainFilter: regexp.MustCompile(""),
Registry: RegistryTXT,
RequestTimeout: time.Second * 30,
CacheSyncTimeout: time.Second * 60,
KubeAPIRequestTimeout: time.Second * 30,
KubeAPIQPS: int(rest.DefaultQPS),
KubeAPIBurst: rest.DefaultBurst,
Expand Down Expand Up @@ -744,6 +746,7 @@ func bindFlags(b flags.FlagBinder, cfg *Config) {
b.StringVar("kubeconfig", "Retrieve target cluster configuration from a Kubernetes configuration file (default: auto-detect)", defaultConfig.KubeConfig, &cfg.KubeConfig)
b.DurationVar("request-timeout", "[DEPRECATED: use --kube-api-request-timeout] Request timeout when calling Kubernetes APIs. 0s means no timeout", defaultConfig.RequestTimeout, &cfg.RequestTimeout)
b.DurationVar("kube-api-request-timeout", "Request timeout when calling Kubernetes APIs. 0s means no timeout", defaultConfig.KubeAPIRequestTimeout, &cfg.KubeAPIRequestTimeout)
b.DurationVar("kube-api-cache-sync-timeout", "Timeout for waiting for Kubernetes informer caches to sync during startup. Values <= 0 use the default (60s). Increase only after ruling out RBAC, network, or API server issues.", defaultConfig.CacheSyncTimeout, &cfg.CacheSyncTimeout)
b.IntVar("kube-api-qps", "Maximum QPS to the Kubernetes API server from this client.", defaultConfig.KubeAPIQPS, &cfg.KubeAPIQPS)
b.IntVar("kube-api-burst", "Maximum burst for throttle to the Kubernetes API server from this client.", defaultConfig.KubeAPIBurst, &cfg.KubeAPIBurst)
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/externaldns/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ var (
APIServerURL: "",
KubeConfig: "",
RequestTimeout: time.Second * 30,
CacheSyncTimeout: time.Second * 60,
KubeAPIRequestTimeout: time.Second * 30,
KubeAPIQPS: int(rest.DefaultQPS),
KubeAPIBurst: rest.DefaultBurst,
Expand Down Expand Up @@ -144,6 +145,7 @@ var (
APIServerURL: "http://127.0.0.1:8080",
KubeConfig: "/some/path",
RequestTimeout: time.Second * 77,
CacheSyncTimeout: time.Second * 60,
KubeAPIRequestTimeout: time.Second * 77,
KubeAPIQPS: int(rest.DefaultQPS),
KubeAPIBurst: rest.DefaultBurst,
Expand Down
2 changes: 1 addition & 1 deletion source/ambassador_host.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func NewAmbassadorHostSource(
informerFactory.Start(ctx.Done())

// wait for the local cache to be populated.
if err := informers.WaitForDynamicCacheSync(ctx, informerFactory); err != nil {
if err := informers.WaitForDynamicCacheSync(ctx, informerFactory, cfg.CacheSyncTimeout); err != nil {
return nil, err
}

Expand Down
2 changes: 1 addition & 1 deletion source/contour_httpproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func NewContourHTTPProxySource(
informerFactory.Start(ctx.Done())

// wait for the local cache to be populated.
if err := informers.WaitForDynamicCacheSync(ctx, informerFactory); err != nil {
if err := informers.WaitForDynamicCacheSync(ctx, informerFactory, cfg.CacheSyncTimeout); err != nil {
return nil, err
}

Expand Down
2 changes: 1 addition & 1 deletion source/f5_transportserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func NewF5TransportServerSource(
informerFactory.Start(ctx.Done())

// wait for the local cache to be populated.
if err := informers.WaitForDynamicCacheSync(ctx, informerFactory); err != nil {
if err := informers.WaitForDynamicCacheSync(ctx, informerFactory, cfg.CacheSyncTimeout); err != nil {
return nil, err
}

Expand Down
2 changes: 1 addition & 1 deletion source/f5_virtualserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func NewF5VirtualServerSource(
informerFactory.Start(ctx.Done())

// wait for the local cache to be populated.
if err := informers.WaitForDynamicCacheSync(ctx, informerFactory); err != nil {
if err := informers.WaitForDynamicCacheSync(ctx, informerFactory, cfg.CacheSyncTimeout); err != nil {
return nil, err
}

Expand Down
8 changes: 4 additions & 4 deletions source/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,18 +214,18 @@ func newGatewayRouteSource(
if rtInformerFactory != gwInformerFactory {
rtInformerFactory.Start(ctx.Done())
}
if err := informers.WaitForCacheSync(ctx, gwInformerFactory); err != nil {
if err := informers.WaitForCacheSync(ctx, gwInformerFactory, config.CacheSyncTimeout); err != nil {
return nil, err
}
if lsInformer != nil && lsInformerFactory != gwInformerFactory {
if err := informers.WaitForCacheSync(ctx, lsInformerFactory); err != nil {
if err := informers.WaitForCacheSync(ctx, lsInformerFactory, config.CacheSyncTimeout); err != nil {
return nil, err
}
}
if err := informers.WaitForCacheSync(ctx, rtInformerFactory); err != nil {
if err := informers.WaitForCacheSync(ctx, rtInformerFactory, config.CacheSyncTimeout); err != nil {
return nil, err
}
if err := informers.WaitForCacheSync(ctx, kubeInformerFactory); err != nil {
if err := informers.WaitForCacheSync(ctx, kubeInformerFactory, config.CacheSyncTimeout); err != nil {
return nil, err
}

Expand Down
4 changes: 2 additions & 2 deletions source/gloo_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,10 @@ func NewGlooSource(

informerFactory.Start(ctx.Done())
dynamicInformerFactory.Start(ctx.Done())
if err := informers.WaitForCacheSync(ctx, informerFactory); err != nil {
if err := informers.WaitForCacheSync(ctx, informerFactory, cfg.CacheSyncTimeout); err != nil {
return nil, err
}
if err := informers.WaitForDynamicCacheSync(ctx, dynamicInformerFactory); err != nil {
if err := informers.WaitForDynamicCacheSync(ctx, dynamicInformerFactory, cfg.CacheSyncTimeout); err != nil {
return nil, err
}

Expand Down
28 changes: 14 additions & 14 deletions source/informers/informers.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ import (
)

const (
// defaultTimeout is the maximum time in seconds to wait for informer caches
// to complete initial sync. This is intentionally longer than the per-request
// timeout: a cache sync may require multiple sequential API calls
// DefaultCacheSyncTimeout is the maximum time in seconds to wait for informer
// caches to complete initial sync. This is intentionally longer than the
// per-request timeout: a cache sync may require multiple sequential API calls
// (LIST + Watch handshake), so the total wait needs to exceed a single request duration.
defaultTimeout = 60
DefaultCacheSyncTimeout = 60
)

type informerFactory interface {
Expand All @@ -41,21 +41,21 @@ type dynamicInformerFactory interface {
WaitForCacheSync(stopCh <-chan struct{}) map[schema.GroupVersionResource]bool
}

func WaitForCacheSync(ctx context.Context, factory informerFactory) error {
return waitForCacheSync(ctx, factory.WaitForCacheSync)
func WaitForCacheSync(ctx context.Context, factory informerFactory, timeout time.Duration) error {
return waitForCacheSync(ctx, factory.WaitForCacheSync, timeout)
}

func WaitForDynamicCacheSync(ctx context.Context, factory dynamicInformerFactory) error {
return waitForCacheSync(ctx, factory.WaitForCacheSync)
func WaitForDynamicCacheSync(ctx context.Context, factory dynamicInformerFactory, timeout time.Duration) error {
return waitForCacheSync(ctx, factory.WaitForCacheSync, timeout)
}

// waitForCacheSync waits for informer caches to sync with a default timeout.
// waitForCacheSync waits for informer caches to sync within the given timeout.
// If timeout is <= 0, the default is used.
// Returns an error if any cache fails to sync, wrapping the context error if a timeout occurred.
func waitForCacheSync[K comparable](ctx context.Context, waitFunc func(<-chan struct{}) map[K]bool) error {
// The function receives a ctx but then creates a new timeout,
// effectively overriding whatever deadline the caller may have set.
// If the caller passed a context with a 30s timeout, this function ignores it and waits 60s anyway.
timeout := defaultTimeout * time.Second
func waitForCacheSync[K comparable](ctx context.Context, waitFunc func(<-chan struct{}) map[K]bool, timeout time.Duration) error {
if timeout <= 0 {
timeout = DefaultCacheSyncTimeout * time.Second
}
ctx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()
for typ, done := range waitFunc(ctx.Done()) {
Expand Down
4 changes: 2 additions & 2 deletions source/informers/informers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func TestWaitForCacheSync(t *testing.T) {
ctx := t.Context()

factory := &mockInformerFactory{syncResults: tt.syncResults}
err := WaitForCacheSync(ctx, factory)
err := WaitForCacheSync(ctx, factory, 0)

if tt.expectError {
assert.Error(t, err)
Expand Down Expand Up @@ -112,7 +112,7 @@ func TestWaitForDynamicCacheSync(t *testing.T) {
ctx := t.Context()

factory := &mockDynamicInformerFactory{syncResults: tt.syncResults}
err := WaitForDynamicCacheSync(ctx, factory)
err := WaitForDynamicCacheSync(ctx, factory, 0)

if tt.expectError {
assert.Error(t, err)
Expand Down
2 changes: 1 addition & 1 deletion source/informers/transformers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ func TestTransformerWithOptions_WithFakeClient(t *testing.T) {
require.NoError(t, err)

factory.Start(ctx.Done())
err = WaitForCacheSync(ctx, factory)
err = WaitForCacheSync(ctx, factory, 0)
require.NoError(t, err)

got, err := serviceInformer.Lister().Services(svc.Namespace).Get(svc.Name)
Expand Down
2 changes: 1 addition & 1 deletion source/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func NewIngressSource(
informerFactory.Start(ctx.Done())

// wait for the local cache to be populated.
if err := informers.WaitForCacheSync(ctx, informerFactory); err != nil {
if err := informers.WaitForCacheSync(ctx, informerFactory, cfg.CacheSyncTimeout); err != nil {
return nil, err
}

Expand Down
4 changes: 2 additions & 2 deletions source/istio_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,10 @@ func NewIstioGatewaySource(
istioInformerFactory.Start(ctx.Done())

// wait for the local cache to be populated.
if err := informers.WaitForCacheSync(ctx, informerFactory); err != nil {
if err := informers.WaitForCacheSync(ctx, informerFactory, cfg.CacheSyncTimeout); err != nil {
return nil, err
}
if err := informers.WaitForCacheSync(ctx, istioInformerFactory); err != nil {
if err := informers.WaitForCacheSync(ctx, istioInformerFactory, cfg.CacheSyncTimeout); err != nil {
return nil, err
}

Expand Down
4 changes: 2 additions & 2 deletions source/istio_virtualservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,10 @@ func NewIstioVirtualServiceSource(
istioInformerFactory.Start(ctx.Done())

// wait for the local cache to be populated.
if err := informers.WaitForCacheSync(ctx, informerFactory); err != nil {
if err := informers.WaitForCacheSync(ctx, informerFactory, cfg.CacheSyncTimeout); err != nil {
return nil, err
}
if err := informers.WaitForCacheSync(ctx, istioInformerFactory); err != nil {
if err := informers.WaitForCacheSync(ctx, istioInformerFactory, cfg.CacheSyncTimeout); err != nil {
return nil, err
}

Expand Down
2 changes: 1 addition & 1 deletion source/kong_tcpingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func NewKongTCPIngressSource(
informerFactory.Start(ctx.Done())

// wait for the local cache to be populated.
if err := informers.WaitForDynamicCacheSync(ctx, informerFactory); err != nil {
if err := informers.WaitForDynamicCacheSync(ctx, informerFactory, cfg.CacheSyncTimeout); err != nil {
return nil, err
}

Expand Down
2 changes: 1 addition & 1 deletion source/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func NewNodeSource(
informerFactory.Start(ctx.Done())

// wait for the local cache to be populated.
if err := informers.WaitForCacheSync(ctx, informerFactory); err != nil {
if err := informers.WaitForCacheSync(ctx, informerFactory, cfg.CacheSyncTimeout); err != nil {
return nil, err
}

Expand Down
2 changes: 1 addition & 1 deletion source/openshift_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func NewOcpRouteSource(
informerFactory.Start(ctx.Done())

// wait for the local cache to be populated.
if err := informers.WaitForCacheSync(ctx, informerFactory); err != nil {
if err := informers.WaitForCacheSync(ctx, informerFactory, cfg.CacheSyncTimeout); err != nil {
return nil, err
}

Expand Down
2 changes: 1 addition & 1 deletion source/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func NewPodSource(
informerFactory.Start(ctx.Done())

// wait for the local cache to be populated.
if err := informers.WaitForCacheSync(ctx, informerFactory); err != nil {
if err := informers.WaitForCacheSync(ctx, informerFactory, cfg.CacheSyncTimeout); err != nil {
return nil, err
}

Expand Down
2 changes: 1 addition & 1 deletion source/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func NewServiceSource(
informerFactory.Start(ctx.Done())

// wait for the local cache to be populated.
if err := informers.WaitForCacheSync(ctx, informerFactory); err != nil {
if err := informers.WaitForCacheSync(ctx, informerFactory, config.CacheSyncTimeout); err != nil {
return nil, err
}

Expand Down
2 changes: 2 additions & 0 deletions source/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ type Config struct {
GlooNamespaces []string
SkipperRouteGroupVersion string
KubeAPIRequestTimeout time.Duration
CacheSyncTimeout time.Duration
KubeAPIQPS int
KubeAPIBurst int
DefaultTargets []string
Expand Down Expand Up @@ -161,6 +162,7 @@ func NewSourceConfig(cfg *externaldns.Config, opts ...OverrideConfigOption) (*Co
GlooNamespaces: cfg.GlooNamespaces,
SkipperRouteGroupVersion: cfg.SkipperRouteGroupVersion,
KubeAPIRequestTimeout: cfg.KubeAPIRequestTimeout,
CacheSyncTimeout: cfg.CacheSyncTimeout,
KubeAPIQPS: cfg.KubeAPIQPS,
KubeAPIBurst: cfg.KubeAPIBurst,
DefaultTargets: cfg.DefaultTargets,
Expand Down
2 changes: 1 addition & 1 deletion source/traefik_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func NewTraefikSource(
informerFactory.Start(ctx.Done())

// wait for the local cache to be populated.
if err := informers.WaitForDynamicCacheSync(ctx, informerFactory); err != nil {
if err := informers.WaitForDynamicCacheSync(ctx, informerFactory, cfg.CacheSyncTimeout); err != nil {
return nil, err
}

Expand Down
2 changes: 1 addition & 1 deletion source/unstructured.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func NewUnstructuredFQDNSource(
}

informerFactory.Start(ctx.Done())
if err := informers.WaitForDynamicCacheSync(ctx, informerFactory); err != nil {
if err := informers.WaitForDynamicCacheSync(ctx, informerFactory, cfg.CacheSyncTimeout); err != nil {
return nil, err
}

Expand Down
Loading