Skip to content

Commit 0779cd7

Browse files
committed
native sidecar support
1 parent 48a5974 commit 0779cd7

22 files changed

+440
-359
lines changed

vertical-pod-autoscaler/pkg/admission-controller/resource/pod/patch/resource_updates.go

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
resource_admission "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/admission-controller/resource"
2626
"k8s.io/autoscaler/vertical-pod-autoscaler/pkg/admission-controller/resource/pod/recommendation"
2727
vpa_types "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1"
28+
"k8s.io/autoscaler/vertical-pod-autoscaler/pkg/recommender/model"
2829
resourcehelpers "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/utils/resources"
2930
vpa_api_util "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/utils/vpa"
3031
)
@@ -54,7 +55,7 @@ func (*resourcesUpdatesPatchCalculator) PatchResourceTarget() PatchResourceTarge
5455
func (c *resourcesUpdatesPatchCalculator) CalculatePatches(pod *core.Pod, vpa *vpa_types.VerticalPodAutoscaler) ([]resource_admission.PatchRecord, error) {
5556
result := []resource_admission.PatchRecord{}
5657

57-
containersResources, annotationsPerContainer, err := c.recommendationProvider.GetContainersResourcesForPod(pod, vpa)
58+
initContainersResources, containersResources, annotationsPerContainer, err := c.recommendationProvider.GetContainersResourcesForPod(pod, vpa)
5859
if err != nil {
5960
return []resource_admission.PatchRecord{}, fmt.Errorf("failed to calculate resource patch for pod %s/%s: %v", pod.Namespace, pod.Name, err)
6061
}
@@ -64,8 +65,14 @@ func (c *resourcesUpdatesPatchCalculator) CalculatePatches(pod *core.Pod, vpa *v
6465
}
6566

6667
updatesAnnotation := []string{}
68+
for i, containerResources := range initContainersResources {
69+
newPatches, newUpdatesAnnotation := getContainerPatch(pod, i, annotationsPerContainer, containerResources, model.ContainerTypeInitSidecar)
70+
result = append(result, newPatches...)
71+
updatesAnnotation = append(updatesAnnotation, newUpdatesAnnotation)
72+
}
73+
6774
for i, containerResources := range containersResources {
68-
newPatches, newUpdatesAnnotation := getContainerPatch(pod, i, annotationsPerContainer, containerResources)
75+
newPatches, newUpdatesAnnotation := getContainerPatch(pod, i, annotationsPerContainer, containerResources, model.ContainerTypeStandard)
6976
result = append(result, newPatches...)
7077
updatesAnnotation = append(updatesAnnotation, newUpdatesAnnotation)
7178
}
@@ -77,33 +84,40 @@ func (c *resourcesUpdatesPatchCalculator) CalculatePatches(pod *core.Pod, vpa *v
7784
return result, nil
7885
}
7986

80-
func getContainerPatch(pod *core.Pod, i int, annotationsPerContainer vpa_api_util.ContainerToAnnotationsMap, containerResources vpa_api_util.ContainerResources) ([]resource_admission.PatchRecord, string) {
87+
func getContainerPatch(pod *core.Pod, i int, annotationsPerContainer vpa_api_util.ContainerToAnnotationsMap, containerResources vpa_api_util.ContainerResources, containerType model.ContainerType) ([]resource_admission.PatchRecord, string) {
8188
var patches []resource_admission.PatchRecord
8289
// Add empty resources object if missing.
83-
requests, limits := resourcehelpers.ContainerRequestsAndLimits(pod.Spec.Containers[i].Name, pod)
90+
var container *core.Container
91+
if containerType == model.ContainerTypeStandard {
92+
container = &pod.Spec.Containers[i]
93+
} else {
94+
container = &pod.Spec.InitContainers[i]
95+
}
96+
97+
requests, limits := resourcehelpers.ContainerRequestsAndLimits(container.Name, pod)
8498
if limits == nil && requests == nil {
85-
patches = append(patches, GetPatchInitializingEmptyResources(i))
99+
patches = append(patches, GetPatchInitializingEmptyResources(i, containerType))
86100
}
87101

88-
annotations, found := annotationsPerContainer[pod.Spec.Containers[i].Name]
102+
annotations, found := annotationsPerContainer[container.Name]
89103
if !found {
90104
annotations = make([]string, 0)
91105
}
92106

93-
patches, annotations = appendPatchesAndAnnotations(patches, annotations, requests, i, containerResources.Requests, "requests", "request")
94-
patches, annotations = appendPatchesAndAnnotations(patches, annotations, limits, i, containerResources.Limits, "limits", "limit")
107+
patches, annotations = appendPatchesAndAnnotations(patches, annotations, requests, i, containerResources.Requests, "requests", "request", containerType)
108+
patches, annotations = appendPatchesAndAnnotations(patches, annotations, limits, i, containerResources.Limits, "limits", "limit", containerType)
95109

96-
updatesAnnotation := fmt.Sprintf("container %d: ", i) + strings.Join(annotations, ", ")
110+
updatesAnnotation := fmt.Sprintf("%s %d: ", containerType, i) + strings.Join(annotations, ", ")
97111
return patches, updatesAnnotation
98112
}
99113

100-
func appendPatchesAndAnnotations(patches []resource_admission.PatchRecord, annotations []string, current core.ResourceList, containerIndex int, resources core.ResourceList, fieldName, resourceName string) ([]resource_admission.PatchRecord, []string) {
114+
func appendPatchesAndAnnotations(patches []resource_admission.PatchRecord, annotations []string, current core.ResourceList, containerIndex int, resources core.ResourceList, fieldName, resourceName string, containerType model.ContainerType) ([]resource_admission.PatchRecord, []string) {
101115
// Add empty object if it's missing and we're about to fill it.
102116
if current == nil && len(resources) > 0 {
103-
patches = append(patches, GetPatchInitializingEmptyResourcesSubfield(containerIndex, fieldName))
117+
patches = append(patches, GetPatchInitializingEmptyResourcesSubfield(containerIndex, fieldName, containerType))
104118
}
105119
for resource, request := range resources {
106-
patches = append(patches, GetAddResourceRequirementValuePatch(containerIndex, fieldName, resource, request))
120+
patches = append(patches, GetAddResourceRequirementValuePatch(containerIndex, fieldName, resource, request, containerType))
107121
annotations = append(annotations, fmt.Sprintf("%s %s", resource, resourceName))
108122
}
109123
return patches, annotations

vertical-pod-autoscaler/pkg/admission-controller/resource/pod/patch/resource_updates_test.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,14 @@ const (
3939
)
4040

4141
type fakeRecommendationProvider struct {
42+
initResources []vpa_api_util.ContainerResources
4243
resources []vpa_api_util.ContainerResources
4344
containerToAnnotations vpa_api_util.ContainerToAnnotationsMap
4445
e error
4546
}
4647

47-
func (frp *fakeRecommendationProvider) GetContainersResourcesForPod(pod *core.Pod, vpa *vpa_types.VerticalPodAutoscaler) ([]vpa_api_util.ContainerResources, vpa_api_util.ContainerToAnnotationsMap, error) {
48-
return frp.resources, frp.containerToAnnotations, frp.e
48+
func (frp *fakeRecommendationProvider) GetContainersResourcesForPod(pod *core.Pod, vpa *vpa_types.VerticalPodAutoscaler) ([]vpa_api_util.ContainerResources, []vpa_api_util.ContainerResources, vpa_api_util.ContainerToAnnotationsMap, error) {
49+
return frp.initResources, frp.resources, frp.containerToAnnotations, frp.e
4950
}
5051

5152
func addResourcesPatch(idx int) resource_admission.PatchRecord {
@@ -107,6 +108,7 @@ func TestCalculatePatches_ResourceUpdates(t *testing.T) {
107108
name string
108109
pod *core.Pod
109110
namespace string
111+
initResources []vpa_api_util.ContainerResources
110112
recommendResources []vpa_api_util.ContainerResources
111113
recommendAnnotations vpa_api_util.ContainerToAnnotationsMap
112114
recommendError error
@@ -292,7 +294,8 @@ func TestCalculatePatches_ResourceUpdates(t *testing.T) {
292294
}
293295
for _, tc := range tests {
294296
t.Run(tc.name, func(t *testing.T) {
295-
frp := fakeRecommendationProvider{tc.recommendResources, tc.recommendAnnotations, tc.recommendError}
297+
// TODO @jklaw tests
298+
frp := fakeRecommendationProvider{tc.initResources, tc.recommendResources, tc.recommendAnnotations, tc.recommendError}
296299
c := NewResourceUpdatesCalculator(&frp)
297300
patches, err := c.CalculatePatches(tc.pod, test.VerticalPodAutoscaler().WithContainer("test").WithName("name").Get())
298301
if tc.expectError == nil {
@@ -334,7 +337,8 @@ func TestGetPatches_TwoReplacementResources(t *testing.T) {
334337
},
335338
}
336339
recommendAnnotations := vpa_api_util.ContainerToAnnotationsMap{}
337-
frp := fakeRecommendationProvider{recommendResources, recommendAnnotations, nil}
340+
// TODO @jklaw tests
341+
frp := fakeRecommendationProvider{nil, recommendResources, recommendAnnotations, nil}
338342
c := NewResourceUpdatesCalculator(&frp)
339343
patches, err := c.CalculatePatches(pod, test.VerticalPodAutoscaler().WithName("name").WithContainer("test").Get())
340344
assert.NoError(t, err)

vertical-pod-autoscaler/pkg/admission-controller/resource/pod/patch/util.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"k8s.io/apimachinery/pkg/api/resource"
2424

2525
resource_admission "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/admission-controller/resource"
26+
"k8s.io/autoscaler/vertical-pod-autoscaler/pkg/recommender/model"
2627
)
2728

2829
// GetAddEmptyAnnotationsPatch returns a patch initializing empty annotations.
@@ -44,28 +45,28 @@ func GetAddAnnotationPatch(annotationName, annotationValue string) resource_admi
4445
}
4546

4647
// GetAddResourceRequirementValuePatch returns a patch record to add resource requirements to a container.
47-
func GetAddResourceRequirementValuePatch(i int, kind string, resource core.ResourceName, quantity resource.Quantity) resource_admission.PatchRecord {
48+
func GetAddResourceRequirementValuePatch(i int, kind string, resource core.ResourceName, quantity resource.Quantity, containerType model.ContainerType) resource_admission.PatchRecord {
4849
return resource_admission.PatchRecord{
4950
Op: "add",
50-
Path: fmt.Sprintf("/spec/containers/%d/resources/%s/%s", i, kind, resource),
51+
Path: fmt.Sprintf("%s/%d/resources/%s/%s", containerType.GetPatchPath(), i, kind, resource),
5152
Value: quantity.String()}
5253
}
5354

5455
// GetPatchInitializingEmptyResources returns a patch record to initialize an empty resources object for a container.
55-
func GetPatchInitializingEmptyResources(i int) resource_admission.PatchRecord {
56+
func GetPatchInitializingEmptyResources(i int, containerType model.ContainerType) resource_admission.PatchRecord {
5657
return resource_admission.PatchRecord{
5758
Op: "add",
58-
Path: fmt.Sprintf("/spec/containers/%d/resources", i),
59+
Path: fmt.Sprintf("%s/%d/resources", containerType.GetPatchPath(), i),
5960
Value: core.ResourceRequirements{},
6061
}
6162
}
6263

6364
// GetPatchInitializingEmptyResourcesSubfield returns a patch record to initialize an empty subfield
6465
// (e.g., "requests" or "limits") within a container's resources object.
65-
func GetPatchInitializingEmptyResourcesSubfield(i int, kind string) resource_admission.PatchRecord {
66+
func GetPatchInitializingEmptyResourcesSubfield(i int, kind string, containerType model.ContainerType) resource_admission.PatchRecord {
6667
return resource_admission.PatchRecord{
6768
Op: "add",
68-
Path: fmt.Sprintf("/spec/containers/%d/resources/%s", i, kind),
69+
Path: fmt.Sprintf("%s/%d/resources/%s", containerType.GetPatchPath(), i, kind),
6970
Value: core.ResourceList{},
7071
}
7172
}

0 commit comments

Comments
 (0)