Commit Graph

867 Commits

Author SHA1 Message Date
Adam Kasztenny
ea7a7e7cf9 Reduce log level for optimistic lease update fallback
The "Failed to update lease optimistically, falling back to slow path"
message was logged at Error level, but this is expected behavior during
normal leader election when the optimistic update encounters a conflict.
The system gracefully falls back to the slow path (Get + Update), so
this is not a real error. Downgrade to V(2) Info to reduce log noise.

Kubernetes-commit: 04977a0ea4592bfaa70d5095a4cfe99dd4b847e1
2026-03-14 16:51:49 -04:00
Monis Khan
f5fc1e5f67 Add GC to client-go TLS cache
Signed-off-by: Monis Khan <mok@microsoft.com>

Kubernetes-commit: fa9a1fe5f7084c0a1371d87e880c1a9e58f935a4
2026-01-16 14:58:52 -05:00
Davanum Srinivas
9926c67348 staging: extract CRI streaming modules with client-go compatibility
Extract streaming code into dedicated staging modules while keeping stable
compatibility APIs for external client-go consumers.

This commit:
- adds `k8s.io/cri-streaming` for CRI exec/attach/portforward server code
- adds `k8s.io/streaming` as the canonical home for shared transport
  primitives (`httpstream`, `spdy`, `wsstream`, runtime helpers)
- switches in-tree transport consumers to `k8s.io/streaming`
- removes in-tree kubelet CRI streaming package
- preserves NO_PROXY/no_proxy CIDR handling in extracted SPDY proxier logic
- adds deprecated `k8s.io/apimachinery/pkg/util/httpstream` compatibility
  wrappers (`httpstream`, `spdy`, `wsstream`) backed by `k8s.io/streaming`
- restores exported client-go SPDY/portforward API signatures to
  apimachinery `httpstream` types for downstream compatibility
- adds streaming-native client-go adapters/constructors so in-tree callers
  can use `k8s.io/streaming` without changing external compatibility APIs
- deduplicates SPDY-over-websocket dial negotiation shared by compat and
  streaming tunneling dialers
- logs dropped unknown stream types in `RemoveStreams` adapter fallbacks to
  improve compatibility-path debuggability
- adds integration coverage for the streaming-upgrader-to-client-go-compat
  adapter path against a real cri-streaming exec endpoint
- clarifies kubectl streaming import aliasing to avoid `httpstream` package
  ambiguity
- updates tests, import restrictions, publishing metadata, and vendor/module
  metadata for the new staging modules

Signed-off-by: Davanum Srinivas <davanum@gmail.com>

Kubernetes-commit: 1ee1ff97fb7f9755a44d29bee0c80d2ccbed68dc
2026-02-28 19:40:07 -05:00
Rajneesh180
187c42c884 client-go: guard ResultChan() close in StartEventWatcher
When watch.Broadcaster.Shutdown() is called it drains all queued events
then calls closeAll(), which closes every watcher's result channel.
eventBroadcasterImpl.Shutdown() calls Broadcaster.Shutdown() first,
then calls the cancellation context's cancel() function.  Between those
two steps there is a window in which the result channel is closed while
the cancellation context is still live.

Without the two-value channel receive the goroutine in StartEventWatcher
would spin on the already-closed channel: each select iteration
immediately receives the zero-value watch.Event, the type assertion
fails (nil interface, ok == false), and the loop continues burning CPU
until the select scheduler eventually picks the cancelationCtx.Done()
case.

Guard against this by reading the ok boolean from the channel receive:

  case watchEvent, ok := <-watcher.ResultChan():
    if !ok {
      return
    }

This is the correct and idiomatic Go pattern for a channel that may be
closed by its producer.  Note that when this return path is taken the
broadcaster has already delivered every queued event (Broadcaster.Shutdown
blocks until the distribute loop exits before closeAll runs), so no
events are silently dropped.

Add a regression test (TestStartEventWatcherExitsOnDirectShutdown) that
creates a broadcaster without an external context so Shutdown() is
fully synchronous, starts a watcher, and verifies the goroutine exits
cleanly via goleak.VerifyNone.

Signed-off-by: Rajneesh180 <rajneeshrehsaan48@gmail.com>

Kubernetes-commit: 95c15b54069922b0a66c198a064577ea0a160694
2026-03-04 16:05:26 +05:30
Michael Aspinwall
aae801378e Add metric tracking the latest cached rv of informers
Kubernetes-commit: 9fb9e933b2ebae2d94edd29b7dec2c1df9e625a6
2026-03-04 22:13:54 +00:00
Jefftree
d6503fcc3e Update leasecandidate client to read from cache
Kubernetes-commit: 5a306036a53754ce26938cedd89b2ddf3b105aa2
2026-01-22 16:55:50 +00:00
tinatingyu
8776b282cc client-go CA rotation
Kubernetes-commit: b806a3207beb1afabc3d3d93fbadba38ffb8a110
2026-03-02 20:40:00 +00:00
Mads Jensen
d91024383a Lint: Activate modernize/forvar rule in golangci-lint.
Kubernetes-commit: dd32d7c324b97d259b99c1464802d9e3ca706a94
2026-03-05 00:11:40 +01:00
xigang
f6c2d7ca65 client-go/cache: add slow-handler tracing in processorListener
Signed-off-by: xigang <wangxigang2014@gmail.com>

Kubernetes-commit: ac1eb12281bdc7fb7e0269fb4bb914369b92bb64
2026-03-03 13:07:08 +08:00
Jordan Liggitt
97646e5606 Fix vet error
Kubernetes-commit: 45900a1debee388738f299c0a001ed01e8b25208
2026-02-17 16:42:55 -05:00
Copilot
78fb6ed2e1 client-go/cache: Remove reflector context cancellation logging
The error returned from Until() is solely from context cancellation
which is expected behavior when the reflector is stopped. Logging
this as an error (or even at V(4)) creates unnecessary noise.

Kubernetes-commit: cc483208aa306b8c4078d4118cf78a10e58481ec
2026-02-16 22:04:52 -05:00
Michael Aspinwall
54ee8fecae Fix deadlock when listeners get added before processing starts
Kubernetes-commit: 0ce498ff21296f44dfa980d8679c0b7697e2d6b8
2026-02-27 18:55:39 +00:00
Peter Engelbert
b840391f92 Rename AllowlistEntry clientcmd.Name to Command
Signed-off-by: Peter Engelbert <pmengelbert@gmail.com>

Kubernetes-commit: 505b937babc9ab0061ed346ec0278a3a605664ac
2026-02-26 13:27:46 -05:00
Ondra Kupka
8a32b4087c client-go/leaderelection: Check context canceled
The change introduced in 59cd1d0b3bb378f40a639e21b615f4df1d4a5a14
causes PollUntilContextTimeout to call the condition function even when
the context is canceled already. This is unnecessary in our case and
only leads to one extra loop of processing and extra error messages.
This change makes the renew loop behave like it did before the change.

Kubernetes-commit: aa494f8174d745c3d9842f3d48272a3c2d6dcbcc
2026-02-26 12:04:01 +01:00
Lukasz Szaszkiewicz
7b594c4c71 reflector: reject Table format resources in List and Watch paths
Kubernetes-commit: a46b1903a5426ede16d021b49c96d3f4ba7aea4d
2026-02-10 21:42:42 +01:00
Richa Banker
59f55827e6 Add processing latency metric for RealFIFO
Kubernetes-commit: d049bd123391f4c1a86e493888560d8549a52dc2
2026-02-16 15:15:47 -08:00
Christian Nuss
b5668cea26 client-go: Replace deprecated BackoffManager with DelayFunc in Reflector
Move backoff documentation comments to var block for better discoverability.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Kubernetes-commit: 33ebd41b2c1abdc03beabd9ccff3428a8fd46473
2026-02-07 12:04:08 -05:00
Michael Aspinwall
139a95c065 Plumb bookmark RVs to controller for observation
Kubernetes-commit: 428b903cd990762a2588fa471791d9c8c747c196
2026-01-28 22:30:06 +00:00
Michael Aspinwall
d883e606da Add rv query to store
Kubernetes-commit: 9c6ac550efa6e721c85b0f1074f26f734286fba9
2026-01-28 22:29:39 +00:00
Davanum Srinivas
decb8c0791 Move dump package from apimachinery to k8s.io/utils
Replace all imports of k8s.io/apimachinery/pkg/util/dump with
k8s.io/utils/dump across the repo. The apimachinery dump package
now contains deprecated wrapper functions that delegate to
k8s.io/utils/dump for backwards compatibility.

Signed-off-by: Davanum Srinivas <davanum@gmail.com>

Kubernetes-commit: 550cc8645bedcc8b187e0ebeb52ead29d5631a32
2026-02-10 15:20:41 -05:00
Michael Aspinwall
b8c6b3c159 Pipe feature gates
Kubernetes-commit: 718ebb6dfc7a5a64ee17821a0de177e3a1eb11f0
2026-02-10 22:39:18 +00:00
Patrick Ohly
ff8083eb1d client-go informers: context-aware Start + WaitForCacheSync
Passing a context to StartWithContext enables context-aware reflector
logging. This is the main remaining source of log spam (output to stderr
instead of per-test logger) in controller unit tests.

WaitForCacheSynceWithContext takes advantage of the new cache.WaitFor +
NamedHasSynced functionality to finish "immediately" (= no virtual time
passed) in a synctest bubble. While at it, the return type gets improved so
that a failure is easier to handle.

Kubernetes-commit: 5ff323de791df88880f6e065f5de4b445e5c90ed
2025-11-21 16:23:44 +01:00
Patrick Ohly
e70bc766e0 client-go cache: wait for cache sync via channels, better logging
The main advantage is that waiting on channels creates a causal relationship
between goroutines which is visible to synctest. When a controller in a
synctest bubble does a WaitFor in a test's background goroutine for the
controller, the test can use synctest.Wait to wait for completion of cache
sync, without requiring any test specific "has controller synced" API. Without
this, the test had to poll or otherwise wait for the controller.

The polling in WaitForCacheSync moved the virtual clock forward by a random
amount, depending on how often it had to check in wait.Poll. Now tests can be
written such that all events during a test happen at a predictable time. This
will be demonstrated in a separate commit for the
pkg/controller/devicetainteviction unit test.

The benefit for normal production is immediate continuation when the last
informer is synced (not really a problem, but still...) and more important,
nicer logging thanks to the names associated with the thing that is being
waited for. The caller decides whether logging is enabled or disabled and
describes what is being waited for (typically informer caches, but maybe also
event handlers or even something else entirely as long as it implements the
DoneChecker interface).

Before:

    Waiting for caches to sync
    Caches are synced

After:

    Waiting for="cache and event handler sync"
    Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1.Pod"
    Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1.ResourceClaim"
    Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1.ResourceSlice"
    Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1.DeviceClass"
    Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1alpha3.DeviceTaintRule"
    Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1.ResourceClaim + event handler k8s.io/kubernetes/pkg/controller/devicetainteviction.(*Controller).Run"
    Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1.Pod + event handler k8s.io/kubernetes/pkg/controller/devicetainteviction.(*Controller).Run"
    Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1alpha3.DeviceTaintRule + event handler k8s.io/kubernetes/pkg/controller/devicetainteviction.(*Controller).Run"
    Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1.ResourceSlice + event handler k8s.io/kubernetes/pkg/controller/devicetainteviction.(*Controller).Run"

The "SharedIndexInformer *v1.Pod" is also how this appears in metrics.

Kubernetes-commit: fdcbb6cba9a04c028b158bf66d505df7431f63fe
2025-11-18 12:39:11 +01:00
Patrick Ohly
b37e79caad client-go cache: allow passing name+logger to DeltaFIFO, RealFIFO and Reflector
This improves logging and enables more informative waiting for cache sync in a
following commit. It addresses one klog.TODO in the Reflector.

The RealFIFOOptions and InformerOptions structs get extended the same way as
DeltaFIFOOptions before: a logger may be set, but it's not required. This is
not an API break.

That the name has to be passed separately is a bit annoying at first glance
because it could also be set directly on the logger through WithName, but
keeping it separate is better:
- name can be set without providing a logger
- name can be defaulted
- less code in the caller when passing through a logger and adding
  the name only in the field
- last but not least, extracting the name is not supported in a portable
  manner by logr

All in-tree references in production code get updated.

While at it, logging in the fifos gets updated to follow best practices: if
some code encounters an abnormal situation and then continues, it should use
utilruntime.HandleErrorWithLogger instead of normal error logging.

Existing "logger" fields get moved to the top because that is a more common
place for such a read-only field.

Kubernetes-commit: 45251e5f654e6c052659d110cd721f9fbe185191
2025-11-18 18:09:46 +01:00
Richa Banker
12b64ed22e Wire InformerName through SharedIndexInformer
Kubernetes-commit: 96386809339faee1169d163749cb4b7d354bec1e
2026-02-05 11:45:38 -08:00
Richa Banker
117e93e87c Add FIFO queue depth metrics
Kubernetes-commit: 864357774f24ee17b2bc7bde84eb5b87cc7ab95b
2026-02-05 11:42:20 -08:00
Richa Banker
50ef81ad18 Add identity tracking for queue items
Kubernetes-commit: db27f4c1234a50e3157373c060ac8ba71c513500
2026-01-28 19:01:51 -08:00
Patrick Ohly
3590eb7f48 client-go informers: replace time.Sleep with callback
While time.Sleep is what the test needs, maybe an arbitrary hook invocation is
more acceptable in the production code because it is more general.

Kubernetes-commit: 2ec0305d728bf5ce8f8df314a18e71aa120a00cf
2026-01-27 14:47:37 +01:00
Patrick Ohly
889b95a769 client-go informers: fix potential deadlock
In the unlikely situation that sharedProcessor.distribute was triggered by a
resync before sharedProcessor.run had a chance to start the listeners, the
sharedProcessor deadlocked: sharedProcessor.distribute held a read/write lock
on listenersLock while being blocked on the write to the listener's
channel. The listeners who would have read from those weren't get started
because sharedProcessor.run was blocked trying to get a read lock for
listenersLock.

This gets fixed by releasing the read/write lock in sharedProcessor.distribute
while waiting for all listeners to be started. Because either all or no
listeners are started, the existing global listenersStarted boolean is
sufficient.

The TestListenerResyncPeriods tests now runs twice, with and without the
artificial delay. It gets converted to a synctest, so it executes quickly
despite the time.Sleep calls and timing is deterministic. The enhanced log
output confirms that with the delay, the initial sync completes later:

    === RUN   TestListenerResyncPeriods
        shared_informer_test.go:236: 0s: listener3: handle: pod1
        shared_informer_test.go:236: 0s: listener3: handle: pod2
        shared_informer_test.go:236: 0s: listener1: handle: pod1
        shared_informer_test.go:236: 0s: listener1: handle: pod2
        shared_informer_test.go:236: 0s: listener2: handle: pod1
        shared_informer_test.go:236: 0s: listener2: handle: pod2
        shared_informer_test.go:236: 2s: listener2: handle: pod1
        shared_informer_test.go:236: 2s: listener2: handle: pod2
        shared_informer_test.go:236: 3s: listener3: handle: pod1
        shared_informer_test.go:236: 3s: listener3: handle: pod2
    --- PASS: TestListenerResyncPeriods (0.00s)
    === RUN   TestListenerResyncPeriodsDelayed
        shared_informer_test.go:236: 1s: listener1: handle: pod1
        shared_informer_test.go:236: 1s: listener1: handle: pod2
        shared_informer_test.go:236: 1s: listener2: handle: pod1
        shared_informer_test.go:236: 1s: listener2: handle: pod2
        shared_informer_test.go:236: 1s: listener3: handle: pod1
        shared_informer_test.go:236: 1s: listener3: handle: pod2
        shared_informer_test.go:236: 2s: listener2: handle: pod1
        shared_informer_test.go:236: 2s: listener2: handle: pod2
        shared_informer_test.go:236: 3s: listener3: handle: pod1
        shared_informer_test.go:236: 3s: listener3: handle: pod2
    --- PASS: TestListenerResyncPeriodsDelayed (0.00s)

Kubernetes-commit: e6ef79b2f6bb05205652e4fe48ffa523d9e3a1ec
2026-01-23 19:38:52 +01:00
Michael Aspinwall
ef73fc0205 Add enforcement for rv update in watchlist to preserve the rv ordering invariant
Kubernetes-commit: 35d29e4772261b283498e04148b89cef64fd6297
2026-01-27 23:09:17 +00:00
Patrick Ohly
d55310b9f9 client-go remotecommand: structured, contextual logging
The API for the package already had a context, so all that was missing was to
extract and use the logger from that.

Kubernetes-commit: 1620b2707623036f5133cf8045da89411d2c4345
2024-12-20 13:50:01 +01:00
Patrick Ohly
24500c1c50 client-go clientcmd: exclude from structured, contextual logging
The only log output is for error messages which should normally not occur. It's
also likely that users expect to see exactly those messages, so it's better to
not touch them.

Kubernetes-commit: 8701f481ff6e24257021f07afcec67df2aef27dc
2024-12-04 15:39:14 +01:00
Patrick Ohly
b0c7207279 Revert "apimachinery: contextual logging in network util code"
Kubernetes-commit: 9d65b9be20e5ee0a4ef34f0ba071d35987da4ab0
2026-01-27 17:21:02 +01:00
Michael Aspinwall
36db2c5c73 Add michaelasp to client-go cache reviewers
Kubernetes-commit: 8418cf16d7d918804db1b040338ffc3c164cff8d
2026-01-21 21:46:59 +00:00
Michael Aspinwall
914300b800 Add benchmarks for adding objects with slow handlers
Kubernetes-commit: 082f38d97bb68e77347b48dd5b29023b1a357373
2026-01-16 00:47:09 +00:00
Michael Aspinwall
f5283a4822 Ensure that processing does not block queue writers
Kubernetes-commit: 40c01b99a7bac05f6de438d67dd20a60333a0ac4
2026-01-16 00:46:52 +00:00
Michael Aspinwall
2f59c18c8b Add atomic resync and remove usage of store in FIFO
Kubernetes-commit: 6fbaebc054fc61f4775bb3a803beba7e924e266b
2026-01-15 20:22:36 +00:00
Michael Aspinwall
aad3a6de89 Add support for ReplacedAll delta handling
Kubernetes-commit: 3d585f1c500be795dfaf24e2c6a7b024986481c1
2026-01-14 13:46:37 -05:00
Michael Aspinwall
0a8284b969 Plumb AtomicFIFO options into controller/store construction
Kubernetes-commit: 022fec7ba8b0e2c71e1f38634a31f296d0090b31
2026-01-14 13:23:12 -05:00
Michael Aspinwall
2cb222485f Guard against unexpected delta types in batch processing
Kubernetes-commit: 64f780c1ecd7e9ec0989cb3ebd584cd9249a4c8c
2026-01-14 12:41:04 -05:00
Michael Aspinwall
14f3889b62 Make PopBatch process a single-item batch identically to Pop
Kubernetes-commit: b8470beda4e4a17ad38e9a58ce86c96f420bb720
2026-01-14 13:18:37 -05:00
Michael Aspinwall
759b00eb22 Expand controller unit test coverage
Kubernetes-commit: 1c29ee7e7b5e039b8df1a5cb75798c0359ca73d9
2026-01-14 13:08:26 -05:00
Michael Aspinwall
4678a135e1 Plumb keyFunc to informer/controller/delta handling
Kubernetes-commit: 4171c8cff8e79d3624f7e3bc83513fbec1671a24
2026-01-14 13:04:31 -05:00
Michael Aspinwall
c38fc0fb1f Refactor RealFIFO#Replace delete/update handling to reconcileReplacement
Kubernetes-commit: b94e610244ea8e37bcade7eec7e77be0ff61e572
2026-01-14 12:56:32 -05:00
Michael Aspinwall
f3701130c2 Fix Replaced delta documentation
Kubernetes-commit: ebd6959b126bad49c305d8088103455ce13241b2
2026-01-14 12:45:13 -05:00
Michael Aspinwall
548663c679 Refactor delta addition/clearing
Kubernetes-commit: 2dad39751d993757b3f218fda93a380a450a2257
2026-01-14 12:44:38 -05:00
Patrick Ohly
ecaf85d034 client-go remotecommand: structured, contextual logging
The API for the package already had a context, so all that was missing was to
extract and use the logger from that.

Kubernetes-commit: 0690af4710a5b322163564d82b95b90417ae3644
2024-12-20 13:50:01 +01:00
Patrick Ohly
e01401eb86 client-go clientcmd: exclude from structured, contextual logging
The only log output is for error messages which should normally not occur. It's
also likely that users expect to see exactly those messages, so it's better to
not touch them.

Kubernetes-commit: 1ec1248a6555be7ca7a0827061cdd3ef162f6c45
2024-12-04 15:39:14 +01:00
Patrick Ohly
e3793792ba client-go portforward + apiserver proxy: structured, contextual logging
When debugging, it helps to keep output from different connections
separate. This can be done with contextual logging and using different loggers
for each connection.

Cancellation is handled separately for requests. Therefore the new APIs only
add support for passing a logger instance.

Kubernetes-commit: dfdf07bb531aa8a397f3c74e5eec851130325971
2024-12-04 15:21:11 +01:00
Patrick Ohly
d7581d0654 client-go watch: implement interface with pointer
I wasn't entirely sure whether this should return a value or a pointer to
satisfy the interface. Both works, so I benchmarked it elsewhere (REST
mapper). Mem allocs are the same (one alloc/call), but returning a value is 10%
slower when calling one method.

What I then benchmarked is whether pointer vs value receiver in the wrapper
makes a difference. Converting from value receiver (what I had before) to
pointer receiver reduced call overhead by 6%. That's because with a value
receiver, Go has to auto-generate a variant with pointer receiver and calls the
value receiver through that.

That can be seen in a debugger (call stack) and when setting breakpoints:

    (dlv) b restMapperWrapper.KindForWithContext
    Command failed: Location "restMapperWrapper.KindForWithContext" ambiguous: k8s.io/apimachinery/pkg/api/meta.restMapperWrapper.KindForWithContext, k8s.io/apimachinery/pkg/api/meta.(*restMapperWrapper).KindForWithContext…

Conventional wisdom is to define types with value receiver because those can be
called also on unmutable instances, making them more flexible.

But for types which will only ever be used via a pointer, I think pointer
receiver is better for the reasons above (small performance difference, easier
to debug).

Kubernetes-commit: b21dcbcaa1ccf4995bf486afc37dc0321c5bdf0b
2025-02-13 11:53:16 +01:00