Skip to content

Commit

Permalink
Add support for customising deployment strategy (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
amir-bio authored Jun 2, 2021
1 parent f45df6d commit db95ee5
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 0 deletions.
8 changes: 8 additions & 0 deletions charts/k8s-service/templates/_deployment_spec.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ metadata:
{{- end }}
spec:
replicas: {{ if .isCanary }}{{ .Values.canary.replicaCount | default 1 }}{{ else }}{{ .Values.replicaCount }}{{ end }}
{{- if .Values.deploymentStrategy.enabled }}
strategy:
type: {{ .Values.deploymentStrategy.type }}
{{- if and (eq .Values.deploymentStrategy.type "RollingUpdate") .Values.deploymentStrategy.rollingUpdate }}
rollingUpdate:
{{ toYaml .Values.deploymentStrategy.rollingUpdate | indent 6 }}
{{- end }}
{{- end }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "k8s-service.name" . }}
Expand Down
31 changes: 31 additions & 0 deletions charts/k8s-service/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,37 @@ canary: {}
# point in time. For example, setting to 3 will signal Kubernetes (via the Deployment contoller) to maintain 3 pods.
replicaCount: 1

# deploymentStrategy specifies the strategy used to replace old Pods by new ones. Type can be "RollingUpdate" or
# "Recreate". "RollingUpdate" is the default value.
# RollingUpdate: The Deployment updates Pods in a rolling update fashion.
# Recreate: All existing Pods are killed before new ones are created.
#
# RollingUpdate can be further refined by providing custom rollingUpdate options.
# The rollingUpdate variable is a map that is directly injected into the deployment spec and it has the following keys:
# - maxUnavailable (Optional) : Field that specifies the maximum number of Pods that can be unavailable
# during the update process. The value can be an absolute number
# (for example, 5) or a percentage of desired Pods (for example, 10%).
# The value cannot be 0 if rollingUpdate.maxSurge is 0.
# This option defaults to 25%.
# - maxSurge (Optional) : Field that specifies the maximum number of Pods that can be created over
# the desired number of Pods. The value can be an absolute number (for example, 5)
# or a percentage of desired Pods (for example, 10%). The value cannot be 0 if
# MaxUnavailable is 0.
# This option defaults to 25%.
#
# EXAMPLE:
#
# deploymentStrategy:
# enabled: false
# type: RollingUpdate
# rollingUpdate:
# maxSurge: 30%
# maxUnavailable: 30%
deploymentStrategy:
enabled: false
type: RollingUpdate
rollingUpdate: {}

# deploymentAnnotations will add the provided map to the annotations for the Deployment resource created by this chart.
# The keys and values are free form, but subject to the limitations of Kubernetes resource annotations.
# NOTE: This variable is injected directly into the deployment spec.
Expand Down
80 changes: 80 additions & 0 deletions test/k8s_service_template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -700,3 +700,83 @@ func TestK8SServicePodAddingAdditionalLabels(t *testing.T) {
assert.Equal(t, deployment.Spec.Template.Labels["first-label"], first_custom_pod_label_value)
assert.Equal(t, deployment.Spec.Template.Labels["second-label"], second_custom_pod_label_value)
}

func TestK8SServiceDeploymentStrategyOnlySetIfEnabled(t *testing.T) {
t.Parallel()

deployment := renderK8SServiceDeploymentWithSetValues(
t,
map[string]string{
"deploymentStrategy.enabled": "false",
},
)

// Strategy shouldn't be set
assert.Equal(t, "", string(deployment.Spec.Strategy.Type))
assert.Nil(t, deployment.Spec.Strategy.RollingUpdate)
}

func TestK8SServiceDeploymentRollingUpdateStrategy(t *testing.T) {
t.Parallel()

deployment := renderK8SServiceDeploymentWithSetValues(
t,
map[string]string{
"deploymentStrategy.enabled": "true",
"deploymentStrategy.type": "RollingUpdate",
},
)

assert.EqualValues(t, "RollingUpdate", string(deployment.Spec.Strategy.Type))
require.Nil(t, deployment.Spec.Strategy.RollingUpdate)
}

func TestK8SServiceDeploymentRollingUpdateStrategyWithCustomOptions(t *testing.T) {
t.Parallel()

deployment := renderK8SServiceDeploymentWithSetValues(
t,
map[string]string{
"deploymentStrategy.enabled": "true",
"deploymentStrategy.type": "RollingUpdate",
"deploymentStrategy.rollingUpdate.maxSurge": "30%",
"deploymentStrategy.rollingUpdate.maxUnavailable": "20%",
},
)

assert.EqualValues(t, "RollingUpdate", string(deployment.Spec.Strategy.Type))

rollingUpdateOptions := deployment.Spec.Strategy.RollingUpdate
require.NotNil(t, rollingUpdateOptions)
assert.Equal(t, rollingUpdateOptions.MaxSurge.String(), "30%")
assert.Equal(t, rollingUpdateOptions.MaxUnavailable.String(), "20%")
}

func TestK8SServiceDeploymentRecreateStrategy(t *testing.T) {
t.Parallel()

deployment := renderK8SServiceDeploymentWithSetValues(
t,
map[string]string{
"deploymentStrategy.enabled": "true",
"deploymentStrategy.type": "Recreate",
},
)

assert.Equal(t, "Recreate", string(deployment.Spec.Strategy.Type))
assert.Nil(t, deployment.Spec.Strategy.RollingUpdate)

// Test that custom rolling update options are ignore if the strategy is set to recreate
deployment = renderK8SServiceDeploymentWithSetValues(
t,
map[string]string{
"deploymentStrategy.enabled": "true",
"deploymentStrategy.type": "Recreate",
"deploymentStrategy.rollingUpdate.maxSurge": "30%",
"deploymentStrategy.rollingUpdate.maxUnavailable": "20%",
},
)

assert.Equal(t, "Recreate", string(deployment.Spec.Strategy.Type))
assert.Nil(t, deployment.Spec.Strategy.RollingUpdate)
}

0 comments on commit db95ee5

Please sign in to comment.