Currently volume and dynamic-resource plugin shares an AssumeCache
implementation. However, they features significantly different use case. DRA
call Assume() on objects returned by APIServer, but volume call Assume() on
objects yet to be sent to the APIServer.
VolumeBinding plugin only makes one update request, while DynamicResource makes
2 requests (add finalizer then update allocation status). Taking advantage of
this, currently the volume cache is simpler:
1. Reserve: assume PV/PVC will be updated
2. PreBind: really send the update request
3. AssumeCache receives an update from informer and overwrite the assumed state.
a. if Prebind succeeded, this will surely include the update from step 2.
b. if PreBind is not finished yet, and this is an irrelevant update, it is safe to
overwrite the assumed state, because our update in PreBind will surely fail with Conflict.
While for DynamicResource:
1. Reserve: add devices to inFlightAllocations
2. PreBind:
a. send the 2 update requests
b. add the returned object into AssumeCache
c. AssumeCache dispatch events synchronously to update allocatedDevices
d. remove devices from inFlightAllocations
DynamicResource needs some features from AssumeCache that is not necessary for VolumeBinding:
1. DynamicResource needs strictly ordered update events to update allocatedDevices,
including those from Assume() and Restore()
2. DynamicResource needs to compare ResourceVersion to prevent the assumed state from being
overwritten by older version from informer. While this works, the doc[1] says:
"you must not compare resource versions for greater-than or less-than relationships".
Given so much difference, it can be beneficial to fork another simpler
AssumeCache for VolumeBinding plugin. Because of no need to send events, the
lite AssumeCache is a passive component. It only record the assumed version
without copying all objects from informer into its local cache. When reading,
we read from both informer and local cache. So it will always be up-to-date
with informer, no need to wait for event handler.
This resolves a race condition where AssumeCache and scheduler queue both
receive events from informer. When a pod is scheduling due to PV update event,
the PVCache may be not updated yet because it has not processed the relevant
event.
The passive version still listens events from informer, but only for cleaning up
its local cache to save memory.
[1]: https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions
DRA also calls Register at pkg/kubelet/cm/container_manager_linux.go NewContainerManager(), causing volume stats collector being ignored.
Fix this by moving it out of `sync.Once()`, allowing multiple calls to `Register()` func.
* Add stress test for pod cleanup when rejected due to VolumeAttachmentLimitExceeded
Signed-off-by: Eddie Torres <torredil@amazon.com>
* Move newTestPodsWithResources below TestVolumeAttachLimitExceededCleanup
Signed-off-by: Eddie Torres <torredil@amazon.com>
---------
Signed-off-by: Eddie Torres <torredil@amazon.com>
Listing all keys from etcd turned out to be too expensive, negativly
impacting events POST latency. Events resource is the only resource that
by default has watch cache disabled and which includes very
large number of small objects making it very costly to list keys.
Expected impact:
* No apiserver_resource_size_estimate_bytes metric for events.
* APF overestimating LIST request cost to events. Fallback assumes
object size of 1.5MB, meaning LIST events will always get maxSeats
Most of the time the managed fields were returned in the order as expected,
but not always. Semantically the order is irrelevant, so the comparison gets
relaxed to ignore it by normalizing first.
A mutex lock around decrementing runningPods was missing, leading to a data
race report in ci-kubernetes-integration-race-master:
WARNING: DATA RACE
Read at 0x00c001bd20a8 by goroutine 95696:
k8s.io/kubernetes/test/integration/scheduler_perf.createPodsSteadily.func7()
/home/prow/go/src/k8s.io/kubernetes/test/integration/scheduler_perf/scheduler_perf.go:2133 +0x238
...
Previous write at 0x00c001bd20a8 by goroutine 101407:
k8s.io/kubernetes/test/integration/scheduler_perf.createPodsSteadily.func5()
/home/prow/go/src/k8s.io/kubernetes/test/integration/scheduler_perf/scheduler_perf.go:2064 +0x1a4
...
This doubles the termination timeout for the eviction test from 5min to
10min. Reason for that is that the eviction manager relies on pod stats
metrics, which may not be acceessible during a period of time because of
the kubelet API unreachable. This could be reasoned in hardware or
network pressure when multiple tests run in parallel.
Signed-off-by: Sascha Grunert <sgrunert@redhat.com>