Skip to content

Commit b8427b4

Browse files
committed
feat: expand VPA to all GMP components
1 parent 584732e commit b8427b4

File tree

6 files changed

+217
-16
lines changed

6 files changed

+217
-16
lines changed

charts/operator/crds/monitoring.googleapis.com_operatorconfigs.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ spec:
480480
properties:
481481
enabled:
482482
description: |-
483-
Enabled configures whether the operator configures Vertical Pod Autoscaling for the collector pods.
483+
Enabled configures whether the operator configures Vertical Pod Autoscaling for GMP workloads.
484484
In GKE, installing Vertical Pod Autoscaling requires a cluster restart, and therefore it also results in an operator restart.
485485
In other environments, the operator may need to be restarted to enable VPA to run the following check again and watch for the objects.
486486
type: boolean

doc/api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3479,7 +3479,7 @@ bool
34793479
</em>
34803480
</td>
34813481
<td>
3482-
<p>Enabled configures whether the operator configures Vertical Pod Autoscaling for the collector pods.
3482+
<p>Enabled configures whether the operator configures Vertical Pod Autoscaling for GMP workloads.
34833483
In GKE, installing Vertical Pod Autoscaling requires a cluster restart, and therefore it also results in an operator restart.
34843484
In other environments, the operator may need to be restarted to enable VPA to run the following check again and watch for the objects.</p>
34853485
</td>

manifests/setup.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2154,7 +2154,7 @@ spec:
21542154
properties:
21552155
enabled:
21562156
description: |-
2157-
Enabled configures whether the operator configures Vertical Pod Autoscaling for the collector pods.
2157+
Enabled configures whether the operator configures Vertical Pod Autoscaling for GMP workloads.
21582158
In GKE, installing Vertical Pod Autoscaling requires a cluster restart, and therefore it also results in an operator restart.
21592159
In other environments, the operator may need to be restarted to enable VPA to run the following check again and watch for the objects.
21602160
type: boolean

pkg/operator/apis/monitoring/v1/operator_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ type ScalingSpec struct {
328328

329329
// VPASpec defines configuration options for vertical pod autoscaling.
330330
type VPASpec struct {
331-
// Enabled configures whether the operator configures Vertical Pod Autoscaling for the collector pods.
331+
// Enabled configures whether the operator configures Vertical Pod Autoscaling for GMP workloads.
332332
// In GKE, installing Vertical Pod Autoscaling requires a cluster restart, and therefore it also results in an operator restart.
333333
// In other environments, the operator may need to be restarted to enable VPA to run the following check again and watch for the objects.
334334
Enabled bool `json:"enabled,omitempty"`

pkg/operator/scaling.go

Lines changed: 155 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ import (
3636
)
3737

3838
const (
39-
collectorVPAName = "collector"
39+
alertmanagerVPAName = "alertmanager"
40+
collectorVPAName = "collector"
41+
operatorVPAName = "gmp-operator"
42+
ruleEvaluatorVPAName = "rule-evaluator"
4043
)
4144

4245
type scalingReconciler struct {
@@ -96,14 +99,53 @@ func (r *scalingReconciler) Reconcile(ctx context.Context, req reconcile.Request
9699
}
97100

98101
func applyVPA(ctx context.Context, c client.Client, namespace string) error {
99-
vpa := autoscalingv1.VerticalPodAutoscaler{
102+
alertmanagerVPA := autoscalingv1.VerticalPodAutoscaler{
103+
ObjectMeta: metav1.ObjectMeta{
104+
Namespace: namespace,
105+
Name: alertmanagerVPAName,
106+
},
107+
}
108+
if _, err := controllerutil.CreateOrUpdate(ctx, c, &alertmanagerVPA, func() error {
109+
alertmanagerVPA.Spec = autoscalingv1.VerticalPodAutoscalerSpec{
110+
TargetRef: &autoscaling.CrossVersionObjectReference{
111+
APIVersion: "apps/v1",
112+
Kind: "StatefulSet",
113+
Name: alertmanagerVPAName,
114+
},
115+
UpdatePolicy: &autoscalingv1.PodUpdatePolicy{
116+
MinReplicas: ptr.To(int32(1)),
117+
UpdateMode: ptr.To(autoscalingv1.UpdateModeAuto),
118+
},
119+
ResourcePolicy: &autoscalingv1.PodResourcePolicy{
120+
ContainerPolicies: []autoscalingv1.ContainerResourcePolicy{
121+
{
122+
ContainerName: "alertmanager",
123+
Mode: ptr.To(autoscalingv1.ContainerScalingModeAuto),
124+
MinAllowed: corev1.ResourceList{
125+
corev1.ResourceCPU: resource.MustParse("1m"),
126+
corev1.ResourceMemory: resource.MustParse("16Mi"),
127+
},
128+
},
129+
{
130+
ContainerName: "config-reloader",
131+
Mode: ptr.To(autoscalingv1.ContainerScalingModeOff),
132+
},
133+
},
134+
},
135+
}
136+
return nil
137+
}); err != nil {
138+
return err
139+
}
140+
141+
collectorVPA := autoscalingv1.VerticalPodAutoscaler{
100142
ObjectMeta: metav1.ObjectMeta{
101143
Namespace: namespace,
102144
Name: collectorVPAName,
103145
},
104146
}
105-
if _, err := controllerutil.CreateOrUpdate(ctx, c, &vpa, func() error {
106-
vpa.Spec = autoscalingv1.VerticalPodAutoscalerSpec{
147+
if _, err := controllerutil.CreateOrUpdate(ctx, c, &collectorVPA, func() error {
148+
collectorVPA.Spec = autoscalingv1.VerticalPodAutoscalerSpec{
107149
TargetRef: &autoscaling.CrossVersionObjectReference{
108150
APIVersion: "apps/v1",
109151
Kind: "DaemonSet",
@@ -118,6 +160,7 @@ func applyVPA(ctx context.Context, c client.Client, namespace string) error {
118160
ContainerName: "prometheus",
119161
Mode: ptr.To(autoscalingv1.ContainerScalingModeAuto),
120162
MinAllowed: corev1.ResourceList{
163+
corev1.ResourceCPU: resource.MustParse("4m"),
121164
corev1.ResourceMemory: resource.MustParse("32Mi"),
122165
},
123166
},
@@ -132,18 +175,124 @@ func applyVPA(ctx context.Context, c client.Client, namespace string) error {
132175
}); err != nil {
133176
return err
134177
}
178+
179+
operatorVPA := autoscalingv1.VerticalPodAutoscaler{
180+
ObjectMeta: metav1.ObjectMeta{
181+
Namespace: namespace,
182+
Name: operatorVPAName,
183+
},
184+
}
185+
if _, err := controllerutil.CreateOrUpdate(ctx, c, &operatorVPA, func() error {
186+
collectorVPA.Spec = autoscalingv1.VerticalPodAutoscalerSpec{
187+
TargetRef: &autoscaling.CrossVersionObjectReference{
188+
APIVersion: "apps/v1",
189+
Kind: "Deployment",
190+
Name: operatorVPAName,
191+
},
192+
UpdatePolicy: &autoscalingv1.PodUpdatePolicy{
193+
MinReplicas: ptr.To(int32(1)),
194+
UpdateMode: ptr.To(autoscalingv1.UpdateModeAuto),
195+
},
196+
ResourcePolicy: &autoscalingv1.PodResourcePolicy{
197+
ContainerPolicies: []autoscalingv1.ContainerResourcePolicy{
198+
{
199+
ContainerName: "operator",
200+
Mode: ptr.To(autoscalingv1.ContainerScalingModeAuto),
201+
MinAllowed: corev1.ResourceList{
202+
corev1.ResourceCPU: resource.MustParse("1m"),
203+
corev1.ResourceMemory: resource.MustParse("16Mi"),
204+
},
205+
},
206+
},
207+
},
208+
}
209+
return nil
210+
}); err != nil {
211+
return err
212+
}
213+
214+
ruleEvaluatorVPA := autoscalingv1.VerticalPodAutoscaler{
215+
ObjectMeta: metav1.ObjectMeta{
216+
Namespace: namespace,
217+
Name: ruleEvaluatorVPAName,
218+
},
219+
}
220+
if _, err := controllerutil.CreateOrUpdate(ctx, c, &ruleEvaluatorVPA, func() error {
221+
collectorVPA.Spec = autoscalingv1.VerticalPodAutoscalerSpec{
222+
TargetRef: &autoscaling.CrossVersionObjectReference{
223+
APIVersion: "apps/v1",
224+
Kind: "Deployment",
225+
Name: ruleEvaluatorVPAName,
226+
},
227+
UpdatePolicy: &autoscalingv1.PodUpdatePolicy{
228+
MinReplicas: ptr.To(int32(1)),
229+
UpdateMode: ptr.To(autoscalingv1.UpdateModeAuto),
230+
},
231+
ResourcePolicy: &autoscalingv1.PodResourcePolicy{
232+
ContainerPolicies: []autoscalingv1.ContainerResourcePolicy{
233+
{
234+
ContainerName: "evaluator",
235+
Mode: ptr.To(autoscalingv1.ContainerScalingModeAuto),
236+
MinAllowed: corev1.ResourceList{
237+
corev1.ResourceCPU: resource.MustParse("1m"),
238+
corev1.ResourceMemory: resource.MustParse("16Mi"),
239+
},
240+
},
241+
{
242+
ContainerName: "config-reloader",
243+
Mode: ptr.To(autoscalingv1.ContainerScalingModeOff),
244+
},
245+
},
246+
},
247+
}
248+
return nil
249+
}); err != nil {
250+
return err
251+
}
252+
135253
return nil
136254
}
137255

138256
func deleteVPA(ctx context.Context, c client.Writer, namespace string) error {
139-
vpa := autoscalingv1.VerticalPodAutoscaler{
257+
alertmanagerVPA := autoscalingv1.VerticalPodAutoscaler{
258+
ObjectMeta: metav1.ObjectMeta{
259+
Name: alertmanagerVPAName,
260+
Namespace: namespace,
261+
},
262+
}
263+
if err := c.Delete(ctx, &alertmanagerVPA); client.IgnoreNotFound(err) != nil {
264+
return err
265+
}
266+
267+
collectorVPA := autoscalingv1.VerticalPodAutoscaler{
140268
ObjectMeta: metav1.ObjectMeta{
141269
Name: collectorVPAName,
142270
Namespace: namespace,
143271
},
144272
}
145-
if err := c.Delete(ctx, &vpa); client.IgnoreNotFound(err) != nil {
273+
if err := c.Delete(ctx, &collectorVPA); client.IgnoreNotFound(err) != nil {
146274
return err
147275
}
276+
277+
operatorVPA := autoscalingv1.VerticalPodAutoscaler{
278+
ObjectMeta: metav1.ObjectMeta{
279+
Name: operatorVPAName,
280+
Namespace: namespace,
281+
},
282+
}
283+
if err := c.Delete(ctx, &operatorVPA); client.IgnoreNotFound(err) != nil {
284+
return err
285+
}
286+
287+
ruleEvaluatorVPA := autoscalingv1.VerticalPodAutoscaler{
288+
ObjectMeta: metav1.ObjectMeta{
289+
Name: ruleEvaluatorVPAName,
290+
Namespace: namespace,
291+
},
292+
}
293+
if err := c.Delete(ctx, &ruleEvaluatorVPA); client.IgnoreNotFound(err) != nil {
294+
return err
295+
}
296+
148297
return nil
149298
}

pkg/operator/scaling_test.go

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,26 @@ import (
2828
)
2929

3030
func TestApplyVPA(t *testing.T) {
31-
vpa := autoscalingv1.VerticalPodAutoscaler{
31+
alertmanagerVPA := autoscalingv1.VerticalPodAutoscaler{
32+
ObjectMeta: metav1.ObjectMeta{
33+
Name: alertmanagerVPAName,
34+
},
35+
}
36+
collectorVPA := autoscalingv1.VerticalPodAutoscaler{
3237
ObjectMeta: metav1.ObjectMeta{
3338
Name: collectorVPAName,
3439
},
3540
}
41+
operatorVPA := autoscalingv1.VerticalPodAutoscaler{
42+
ObjectMeta: metav1.ObjectMeta{
43+
Name: operatorVPAName,
44+
},
45+
}
46+
ruleEvaluatorVPA := autoscalingv1.VerticalPodAutoscaler{
47+
ObjectMeta: metav1.ObjectMeta{
48+
Name: ruleEvaluatorVPAName,
49+
},
50+
}
3651

3752
scheme, err := NewScheme()
3853
if err != nil {
@@ -59,7 +74,7 @@ func TestApplyVPA(t *testing.T) {
5974
wantErr: true,
6075
},
6176
"update": {
62-
c: fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(&vpa).Build(),
77+
c: fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(&alertmanagerVPA, &collectorVPA, &operatorVPA, &ruleEvaluatorVPA).Build(),
6378
},
6479
}
6580

@@ -74,18 +89,44 @@ func TestApplyVPA(t *testing.T) {
7489
case err != nil && tc.wantErr:
7590
// Ok
7691
case err == nil && !tc.wantErr:
77-
// Ok
92+
if err := tc.c.Get(context.TODO(), client.ObjectKey{Name: alertmanagerVPAName}, &autoscalingv1.VerticalPodAutoscaler{}); err != nil {
93+
t.Error(err)
94+
}
95+
if err := tc.c.Get(context.TODO(), client.ObjectKey{Name: collectorVPAName}, &autoscalingv1.VerticalPodAutoscaler{}); err != nil {
96+
t.Error(err)
97+
}
98+
if err := tc.c.Get(context.TODO(), client.ObjectKey{Name: operatorVPAName}, &autoscalingv1.VerticalPodAutoscaler{}); err != nil {
99+
t.Error(err)
100+
}
101+
if err := tc.c.Get(context.TODO(), client.ObjectKey{Name: ruleEvaluatorVPAName}, &autoscalingv1.VerticalPodAutoscaler{}); err != nil {
102+
t.Error(err)
103+
}
78104
}
79105
})
80106
}
81107
}
82108

83109
func TestDeleteVPA(t *testing.T) {
84-
vpa := autoscalingv1.VerticalPodAutoscaler{
110+
alertmanagerVPA := autoscalingv1.VerticalPodAutoscaler{
111+
ObjectMeta: metav1.ObjectMeta{
112+
Name: alertmanagerVPAName,
113+
},
114+
}
115+
collectorVPA := autoscalingv1.VerticalPodAutoscaler{
85116
ObjectMeta: metav1.ObjectMeta{
86117
Name: collectorVPAName,
87118
},
88119
}
120+
operatorVPA := autoscalingv1.VerticalPodAutoscaler{
121+
ObjectMeta: metav1.ObjectMeta{
122+
Name: operatorVPAName,
123+
},
124+
}
125+
ruleEvaluatorVPA := autoscalingv1.VerticalPodAutoscaler{
126+
ObjectMeta: metav1.ObjectMeta{
127+
Name: ruleEvaluatorVPAName,
128+
},
129+
}
89130

90131
scheme, err := NewScheme()
91132
if err != nil {
@@ -113,7 +154,7 @@ func TestDeleteVPA(t *testing.T) {
113154
c: fake.NewClientBuilder().WithScheme(scheme).WithInterceptorFuncs(deleteInterceptorWithNotFoundError).Build(),
114155
},
115156
"ok": {
116-
c: fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(&vpa).Build(),
157+
c: fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(&alertmanagerVPA, &collectorVPA, &operatorVPA, &ruleEvaluatorVPA).Build(),
117158
},
118159
"err": {
119160
c: fake.NewClientBuilder().WithScheme(scheme).WithInterceptorFuncs(deleteInterceptorWithError).Build(),
@@ -132,7 +173,18 @@ func TestDeleteVPA(t *testing.T) {
132173
case err != nil && tc.wantErr:
133174
// Ok
134175
case err == nil && !tc.wantErr:
135-
// Ok
176+
if err := tc.c.Get(context.TODO(), client.ObjectKey{Name: alertmanagerVPAName}, &autoscalingv1.VerticalPodAutoscaler{}); !apierrors.IsNotFound(err) {
177+
t.Errorf("expected not found, got %s", err)
178+
}
179+
if err := tc.c.Get(context.TODO(), client.ObjectKey{Name: collectorVPAName}, &autoscalingv1.VerticalPodAutoscaler{}); !apierrors.IsNotFound(err) {
180+
t.Errorf("expected not found, got %s", err)
181+
}
182+
if err := tc.c.Get(context.TODO(), client.ObjectKey{Name: operatorVPAName}, &autoscalingv1.VerticalPodAutoscaler{}); !apierrors.IsNotFound(err) {
183+
t.Errorf("expected not found, got %s", err)
184+
}
185+
if err := tc.c.Get(context.TODO(), client.ObjectKey{Name: ruleEvaluatorVPAName}, &autoscalingv1.VerticalPodAutoscaler{}); !apierrors.IsNotFound(err) {
186+
t.Errorf("expected not found, got %s", err)
187+
}
136188
}
137189
})
138190
}

0 commit comments

Comments
 (0)