Skip to content

Commit da2eec0

Browse files
authored
Add support for UpdateStrategy when collector mode is Deployment (#320)
1 parent 40a407d commit da2eec0

File tree

10 files changed

+232
-0
lines changed

10 files changed

+232
-0
lines changed

apis/v1alpha1/amazoncloudwatchagent_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,11 @@ type AmazonCloudWatchAgentSpec struct {
280280
// This is only applicable to Daemonset mode.
281281
// +optional
282282
UpdateStrategy appsv1.DaemonSetUpdateStrategy `json:"updateStrategy,omitempty"`
283+
// UpdateStrategy represents the strategy the operator will take replacing existing Deployment pods with new pods
284+
// https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/deployment-v1/#DeploymentSpec
285+
// This is only applicable to Deployment mode.
286+
// +optional
287+
DeploymentUpdateStrategy appsv1.DeploymentStrategy `json:"deploymentUpdateStrategy,omitempty"`
283288
}
284289

285290
// AmazonCloudWatchAgentTargetAllocator defines the configurations for the Prometheus target allocator.

apis/v1alpha1/collector_webhook.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,11 @@ func (c CollectorWebhook) validate(r *AmazonCloudWatchAgent) (admission.Warnings
295295
return warnings, fmt.Errorf("the OpenTelemetry Collector mode is set to %s, which does not support the attribute 'updateStrategy'", r.Spec.Mode)
296296
}
297297

298+
// validate updateStrategy for Deployment
299+
if r.Spec.Mode != ModeDeployment && len(r.Spec.DeploymentUpdateStrategy.Type) > 0 {
300+
return warnings, fmt.Errorf("the OpenTelemetry Collector mode is set to %s, which does not support the attribute 'deploymentUpdateStrategy'", r.Spec.Mode)
301+
}
302+
298303
return warnings, nil
299304
}
300305

apis/v1alpha1/collector_webhook_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,22 @@ func TestOTELColValidatingWebhook(t *testing.T) {
759759
},
760760
expectedErr: "the OpenTelemetry Collector mode is set to deployment, which does not support the attribute 'updateStrategy'",
761761
},
762+
{
763+
name: "invalid updateStrategy for Statefulset mode",
764+
otelcol: AmazonCloudWatchAgent{
765+
Spec: AmazonCloudWatchAgentSpec{
766+
Mode: ModeStatefulSet,
767+
DeploymentUpdateStrategy: appsv1.DeploymentStrategy{
768+
Type: "RollingUpdate",
769+
RollingUpdate: &appsv1.RollingUpdateDeployment{
770+
MaxSurge: &intstr.IntOrString{Type: intstr.Int, IntVal: int32(1)},
771+
MaxUnavailable: &intstr.IntOrString{Type: intstr.Int, IntVal: int32(1)},
772+
},
773+
},
774+
},
775+
},
776+
expectedErr: "the OpenTelemetry Collector mode is set to statefulset, which does not support the attribute 'deploymentUpdateStrategy'",
777+
},
762778
}
763779

764780
for _, test := range tests {

apis/v1alpha1/zz_generated.deepcopy.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apis/v1alpha2/amazoncloudwatchagent_types.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package v1alpha2
77

88
import (
9+
appsv1 "k8s.io/api/apps/v1"
910
v1 "k8s.io/api/core/v1"
1011
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1112

@@ -200,6 +201,16 @@ type AmazonCloudWatchAgentSpec struct {
200201
// object, which shall be mounted into the Collector Pods.
201202
// Each ConfigMap will be added to the Collector's Deployments as a volume named `configmap-<configmap-name>`.
202203
ConfigMaps []v1alpha1.ConfigMapsSpec `json:"configmaps,omitempty"`
204+
// UpdateStrategy represents the strategy the operator will take replacing existing DaemonSet pods with new pods
205+
// https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/daemon-set-v1/#DaemonSetSpec
206+
// This is only applicable to Daemonset mode.
207+
// +optional
208+
UpdateStrategy appsv1.DaemonSetUpdateStrategy `json:"updateStrategy,omitempty"`
209+
// UpdateStrategy represents the strategy the operator will take replacing existing Deployment pods with new pods
210+
// https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/deployment-v1/#DeploymentSpec
211+
// This is only applicable to Deployment mode.
212+
// +optional
213+
DeploymentUpdateStrategy appsv1.DeploymentStrategy `json:"deploymentUpdateStrategy,omitempty"`
203214
}
204215

205216
// AmazonCloudWatchAgentStatus defines the observed state of AmazonCloudWatchAgent.

apis/v1alpha2/zz_generated.deepcopy.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/cloudwatch.aws.amazon.com_amazoncloudwatchagents.yaml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2595,6 +2595,59 @@ spec:
25952595
- name
25962596
type: object
25972597
type: array
2598+
deploymentUpdateStrategy:
2599+
description: |-
2600+
UpdateStrategy represents the strategy the operator will take replacing existing Deployment pods with new pods
2601+
https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/deployment-v1/#DeploymentSpec
2602+
This is only applicable to Deployment mode.
2603+
properties:
2604+
rollingUpdate:
2605+
description: |-
2606+
Rolling update config params. Present only if DeploymentStrategyType =
2607+
RollingUpdate.
2608+
---
2609+
TODO: Update this to follow our convention for oneOf, whatever we decide it
2610+
to be.
2611+
properties:
2612+
maxSurge:
2613+
anyOf:
2614+
- type: integer
2615+
- type: string
2616+
description: |-
2617+
The maximum number of pods that can be scheduled above the desired number of
2618+
pods.
2619+
Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).
2620+
This can not be 0 if MaxUnavailable is 0.
2621+
Absolute number is calculated from percentage by rounding up.
2622+
Defaults to 25%.
2623+
Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when
2624+
the rolling update starts, such that the total number of old and new pods do not exceed
2625+
130% of desired pods. Once old pods have been killed,
2626+
new ReplicaSet can be scaled up further, ensuring that total number of pods running
2627+
at any time during the update is at most 130% of desired pods.
2628+
x-kubernetes-int-or-string: true
2629+
maxUnavailable:
2630+
anyOf:
2631+
- type: integer
2632+
- type: string
2633+
description: |-
2634+
The maximum number of pods that can be unavailable during the update.
2635+
Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).
2636+
Absolute number is calculated from percentage by rounding down.
2637+
This can not be 0 if MaxSurge is 0.
2638+
Defaults to 25%.
2639+
Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods
2640+
immediately when the rolling update starts. Once new pods are ready, old ReplicaSet
2641+
can be scaled down further, followed by scaling up the new ReplicaSet, ensuring
2642+
that the total number of pods available at all times during the update is at
2643+
least 70% of desired pods.
2644+
x-kubernetes-int-or-string: true
2645+
type: object
2646+
type:
2647+
description: Type of deployment. Can be "Recreate" or "RollingUpdate".
2648+
Default is RollingUpdate.
2649+
type: string
2650+
type: object
25982651
env:
25992652
description: |-
26002653
ENV vars to set on the OpenTelemetry Collector's Pods. These can then in certain cases be

docs/api.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,15 @@ object, which shall be mounted into the Collector Pods.
147147
Each ConfigMap will be added to the Collector's Deployments as a volume named `configmap-<configmap-name>`.<br/>
148148
</td>
149149
<td>false</td>
150+
</tr><tr>
151+
<td><b><a href="#amazoncloudwatchagentspecdeploymentupdatestrategy">deploymentUpdateStrategy</a></b></td>
152+
<td>object</td>
153+
<td>
154+
UpdateStrategy represents the strategy the operator will take replacing existing Deployment pods with new pods
155+
https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/deployment-v1/#DeploymentSpec
156+
This is only applicable to Deployment mode.<br/>
157+
</td>
158+
<td>false</td>
150159
</tr><tr>
151160
<td><b><a href="#amazoncloudwatchagentspecenvindex">env</a></b></td>
152161
<td>[]object</td>
@@ -5483,6 +5492,103 @@ metric across all relevant pods (as a quantity)<br/>
54835492
</table>
54845493

54855494

5495+
### AmazonCloudWatchAgent.spec.deploymentUpdateStrategy
5496+
<sup><sup>[↩ Parent](#amazoncloudwatchagentspec)</sup></sup>
5497+
5498+
5499+
5500+
UpdateStrategy represents the strategy the operator will take replacing existing Deployment pods with new pods
5501+
https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/deployment-v1/#DeploymentSpec
5502+
This is only applicable to Deployment mode.
5503+
5504+
<table>
5505+
<thead>
5506+
<tr>
5507+
<th>Name</th>
5508+
<th>Type</th>
5509+
<th>Description</th>
5510+
<th>Required</th>
5511+
</tr>
5512+
</thead>
5513+
<tbody><tr>
5514+
<td><b><a href="#amazoncloudwatchagentspecdeploymentupdatestrategyrollingupdate">rollingUpdate</a></b></td>
5515+
<td>object</td>
5516+
<td>
5517+
Rolling update config params. Present only if DeploymentStrategyType =
5518+
RollingUpdate.
5519+
---
5520+
TODO: Update this to follow our convention for oneOf, whatever we decide it
5521+
to be.<br/>
5522+
</td>
5523+
<td>false</td>
5524+
</tr><tr>
5525+
<td><b>type</b></td>
5526+
<td>string</td>
5527+
<td>
5528+
Type of deployment. Can be "Recreate" or "RollingUpdate". Default is RollingUpdate.<br/>
5529+
</td>
5530+
<td>false</td>
5531+
</tr></tbody>
5532+
</table>
5533+
5534+
5535+
### AmazonCloudWatchAgent.spec.deploymentUpdateStrategy.rollingUpdate
5536+
<sup><sup>[↩ Parent](#amazoncloudwatchagentspecdeploymentupdatestrategy)</sup></sup>
5537+
5538+
5539+
5540+
Rolling update config params. Present only if DeploymentStrategyType =
5541+
RollingUpdate.
5542+
---
5543+
TODO: Update this to follow our convention for oneOf, whatever we decide it
5544+
to be.
5545+
5546+
<table>
5547+
<thead>
5548+
<tr>
5549+
<th>Name</th>
5550+
<th>Type</th>
5551+
<th>Description</th>
5552+
<th>Required</th>
5553+
</tr>
5554+
</thead>
5555+
<tbody><tr>
5556+
<td><b>maxSurge</b></td>
5557+
<td>int or string</td>
5558+
<td>
5559+
The maximum number of pods that can be scheduled above the desired number of
5560+
pods.
5561+
Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).
5562+
This can not be 0 if MaxUnavailable is 0.
5563+
Absolute number is calculated from percentage by rounding up.
5564+
Defaults to 25%.
5565+
Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when
5566+
the rolling update starts, such that the total number of old and new pods do not exceed
5567+
130% of desired pods. Once old pods have been killed,
5568+
new ReplicaSet can be scaled up further, ensuring that total number of pods running
5569+
at any time during the update is at most 130% of desired pods.<br/>
5570+
</td>
5571+
<td>false</td>
5572+
</tr><tr>
5573+
<td><b>maxUnavailable</b></td>
5574+
<td>int or string</td>
5575+
<td>
5576+
The maximum number of pods that can be unavailable during the update.
5577+
Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).
5578+
Absolute number is calculated from percentage by rounding down.
5579+
This can not be 0 if MaxSurge is 0.
5580+
Defaults to 25%.
5581+
Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods
5582+
immediately when the rolling update starts. Once new pods are ready, old ReplicaSet
5583+
can be scaled down further, followed by scaling up the new ReplicaSet, ensuring
5584+
that the total number of pods available at all times during the update is at
5585+
least 70% of desired pods.<br/>
5586+
</td>
5587+
<td>false</td>
5588+
</tr></tbody>
5589+
</table>
5590+
5591+
54865592
### AmazonCloudWatchAgent.spec.env[index]
54875593
<sup><sup>[↩ Parent](#amazoncloudwatchagentspec)</sup></sup>
54885594

internal/manifests/collector/deployment.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ func Deployment(params manifests.Params) *appsv1.Deployment {
3333
Selector: &metav1.LabelSelector{
3434
MatchLabels: manifestutils.SelectorLabels(params.OtelCol.ObjectMeta, ComponentAmazonCloudWatchAgent),
3535
},
36+
Strategy: params.OtelCol.Spec.DeploymentUpdateStrategy,
3637
Template: corev1.PodTemplateSpec{
3738
ObjectMeta: metav1.ObjectMeta{
3839
Labels: labels,

internal/manifests/collector/deployment_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/stretchr/testify/assert"
1212
v1 "k8s.io/api/core/v1"
1313
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
14+
"k8s.io/apimachinery/pkg/util/intstr"
1415

1516
"github.com/aws/amazon-cloudwatch-agent-operator/apis/v1alpha1"
1617
"github.com/aws/amazon-cloudwatch-agent-operator/internal/config"
@@ -185,6 +186,37 @@ func TestDeploymenttPodSecurityContext(t *testing.T) {
185186
assert.Equal(t, &runasGroup, d.Spec.Template.Spec.SecurityContext.RunAsGroup)
186187
}
187188

189+
func TestDeploymentUpdateStrategy(t *testing.T) {
190+
otelcol := v1alpha1.AmazonCloudWatchAgent{
191+
ObjectMeta: metav1.ObjectMeta{
192+
Name: "my-instance",
193+
},
194+
Spec: v1alpha1.AmazonCloudWatchAgentSpec{
195+
DeploymentUpdateStrategy: appsv1.DeploymentStrategy{
196+
Type: "RollingUpdate",
197+
RollingUpdate: &appsv1.RollingUpdateDeployment{
198+
MaxSurge: &intstr.IntOrString{Type: intstr.Int, IntVal: int32(1)},
199+
MaxUnavailable: &intstr.IntOrString{Type: intstr.Int, IntVal: int32(1)},
200+
},
201+
},
202+
},
203+
}
204+
205+
cfg := config.New()
206+
207+
params := manifests.Params{
208+
Config: cfg,
209+
OtelCol: otelcol,
210+
Log: logger,
211+
}
212+
213+
d := Deployment(params)
214+
215+
assert.Equal(t, "RollingUpdate", string(d.Spec.Strategy.Type))
216+
assert.Equal(t, 1, d.Spec.Strategy.RollingUpdate.MaxSurge.IntValue())
217+
assert.Equal(t, 1, d.Spec.Strategy.RollingUpdate.MaxUnavailable.IntValue())
218+
}
219+
188220
func TestDeploymentHostNetwork(t *testing.T) {
189221
// Test default
190222
otelcol1 := v1alpha1.AmazonCloudWatchAgent{

0 commit comments

Comments
 (0)