Skip to content

Commit 257b30d

Browse files
committed
updater: fetch pods matching VPA selectors
Signed-off-by: Omer Aplatony <[email protected]>
1 parent 51b6969 commit 257b30d

File tree

3 files changed

+28
-13
lines changed

3 files changed

+28
-13
lines changed

vertical-pod-autoscaler/pkg/updater/logic/updater.go

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
apiv1 "k8s.io/api/core/v1"
2727
"k8s.io/apimachinery/pkg/fields"
2828
"k8s.io/apimachinery/pkg/labels"
29+
"k8s.io/apimachinery/pkg/util/sets"
2930
kube_client "k8s.io/client-go/kubernetes"
3031
"k8s.io/client-go/kubernetes/fake"
3132
corescheme "k8s.io/client-go/kubernetes/scheme"
@@ -166,6 +167,8 @@ func (u *updater) RunOnce(ctx context.Context) {
166167

167168
inPlaceFeatureEnable := features.Enabled(features.InPlaceOrRecreate)
168169

170+
seenPods := sets.New[*apiv1.Pod]()
171+
169172
for _, vpa := range vpaList {
170173
if slices.Contains(u.ignoredNamespaces, vpa.Namespace) {
171174
klog.V(3).InfoS("Skipping VPA object in ignored namespace", "vpa", klog.KObj(vpa), "namespace", vpa.Namespace)
@@ -185,6 +188,16 @@ func (u *updater) RunOnce(ctx context.Context) {
185188
klog.V(3).InfoS("Skipping VPA object because we cannot fetch selector", "vpa", klog.KObj(vpa))
186189
continue
187190
}
191+
podsWithSelector, err := u.podLister.List(selector)
192+
if err != nil {
193+
klog.ErrorS(err, "Failed to get pods", "selector", selector)
194+
continue
195+
}
196+
197+
// handle the case of overlapping VPA selectors
198+
for _, pod := range podsWithSelector {
199+
seenPods.Insert(pod)
200+
}
188201

189202
vpas = append(vpas, &vpa_api_util.VpaWithSelector{
190203
Vpa: vpa,
@@ -200,13 +213,8 @@ func (u *updater) RunOnce(ctx context.Context) {
200213
return
201214
}
202215

203-
podsList, err := u.podLister.List(labels.Everything())
204-
if err != nil {
205-
klog.ErrorS(err, "Failed to get pods list")
206-
return
207-
}
208216
timer.ObserveStep("ListPods")
209-
allLivePods := filterDeletedPods(podsList)
217+
allLivePods := filterDeletedPodsFromSet(seenPods)
210218

211219
controlledPods := make(map[*vpa_types.VerticalPodAutoscaler][]*apiv1.Pod)
212220
for _, pod := range allLivePods {
@@ -391,10 +399,14 @@ func filterNonEvictablePods(pods []*apiv1.Pod, evictionRestriction restriction.P
391399
return filterPods(pods, evictionRestriction.CanEvict)
392400
}
393401

394-
func filterDeletedPods(pods []*apiv1.Pod) []*apiv1.Pod {
395-
return filterPods(pods, func(pod *apiv1.Pod) bool {
396-
return pod.DeletionTimestamp == nil
397-
})
402+
func filterDeletedPodsFromSet(pods sets.Set[*apiv1.Pod]) []*apiv1.Pod {
403+
result := make([]*apiv1.Pod, 0)
404+
for p := range pods {
405+
if p.DeletionTimestamp == nil {
406+
result = append(result, p)
407+
}
408+
}
409+
return result
398410
}
399411

400412
func newPodLister(kubeClient kube_client.Interface, namespace string) v1lister.PodLister {

vertical-pod-autoscaler/pkg/updater/logic/updater_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3333
"k8s.io/apimachinery/pkg/labels"
3434
"k8s.io/apimachinery/pkg/runtime"
35+
"k8s.io/apimachinery/pkg/types"
3536
"k8s.io/client-go/kubernetes/fake"
3637
featuregatetesting "k8s.io/component-base/featuregate/testing"
3738

@@ -232,6 +233,7 @@ func testRunOnceBase(
232233
Get()
233234

234235
pods[i].Labels = labels
236+
pods[i].UID = types.UID(fmt.Sprintf("pod-uid-%d", i))
235237

236238
inplace.On("CanInPlaceUpdate", pods[i]).Return(canInPlaceUpdate)
237239
if shouldInPlaceFail {
@@ -251,7 +253,7 @@ func testRunOnceBase(
251253
vpaLister := &test.VerticalPodAutoscalerListerMock{}
252254

253255
podLister := &test.PodListerMock{}
254-
podLister.On("List").Return(pods, nil)
256+
podLister.On("List", selector).Return(pods, nil)
255257
targetRef := &v1.CrossVersionObjectReference{
256258
Kind: rc.Kind,
257259
Name: rc.Name,
@@ -381,6 +383,7 @@ func TestRunOnceIgnoreNamespaceMatchingPods(t *testing.T) {
381383
Get()
382384

383385
pods[i].Labels = labels
386+
pods[i].UID = types.UID(fmt.Sprintf("pod-uid-%d", i))
384387
eviction.On("CanEvict", pods[i]).Return(true)
385388
eviction.On("Evict", pods[i], nil).Return(nil)
386389
}
@@ -392,7 +395,7 @@ func TestRunOnceIgnoreNamespaceMatchingPods(t *testing.T) {
392395
vpaLister := &test.VerticalPodAutoscalerListerMock{}
393396

394397
podLister := &test.PodListerMock{}
395-
podLister.On("List").Return(pods, nil)
398+
podLister.On("List", selector).Return(pods, nil)
396399
targetRef := &v1.CrossVersionObjectReference{
397400
Kind: rc.Kind,
398401
Name: rc.Name,

vertical-pod-autoscaler/pkg/utils/test/test_utils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ func (m *PodListerMock) Pods(namespace string) v1.PodNamespaceLister {
156156

157157
// List is a mock implementation of PodLister.List
158158
func (m *PodListerMock) List(selector labels.Selector) (ret []*apiv1.Pod, err error) {
159-
args := m.Called()
159+
args := m.Called(selector)
160160
var returnArg []*apiv1.Pod
161161
if args.Get(0) != nil {
162162
returnArg = args.Get(0).([]*apiv1.Pod)

0 commit comments

Comments
 (0)