Skip to content

Commit

Permalink
Add PodDisruptionBudget to Atlassian DC Helm Charts (#636)
Browse files Browse the repository at this point in the history
* Add PodDisruptionBudget

* Rename pdb property

* Update docs

---------

Co-authored-by: Yevhen Ivantsov <[email protected]>
  • Loading branch information
bianchi2 and Yevhen Ivantsov authored Aug 7, 2023
1 parent 29ca016 commit 599979e
Show file tree
Hide file tree
Showing 17 changed files with 264 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/main/charts/bamboo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ Kubernetes: `>=1.21.x-0`
| monitoring.serviceMonitor.scrapeIntervalSeconds | int | `30` | Scrape interval for the JMX service. |
| nodeSelector | object | `{}` | Standard K8s node-selectors that will be applied to all Bamboo pods |
| podAnnotations | object | `{}` | Custom annotations that will be applied to all Bamboo pods |
| podDisruptionBudget | object | `{"annotations":{},"enabled":false,"labels":{},"maxUnavailable":null,"minAvailable":null}` | PodDisruptionBudget: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ You can specify only one of maxUnavailable and minAvailable in a single PodDisruptionBudget. When both minAvailable and maxUnavailable are set, maxUnavailable takes precedence. |
| podLabels | object | `{}` | Custom labels that will be applied to all Bamboo pods |
| priorityClassName | string | `nil` | Priority class for the application pods. The PriorityClass with this name needs to be available in the cluster. For details see https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass |
| replicaCount | int | `1` | The initial number of Bamboo pods that should be started at deployment time. Note that Bamboo requires manual configuration via the browser post deployment after the first pod is deployed. At present Bamboo Data Center utilizes an `active-passive` clustering model. This architecture is not ideal where K8s deployments are concerned. As such a Bamboo server cluster comprising only `1` pod is the recommended topology for now. For more detail see: https://atlassian.github.io/data-center-helm-charts/troubleshooting/LIMITATIONS#cluster-size |
Expand Down
26 changes: 26 additions & 0 deletions src/main/charts/bamboo/templates/pdb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{- if .Values.podDisruptionBudget.enabled }}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ include "common.names.fullname" . }}
labels:
{{- include "common.labels.commonLabels" . | nindent 4 }}
{{- with .Values.podDisruptionBudget.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.podDisruptionBudget.annotations }}
annotations:
{{- range $key, $value := . }}
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- end }}
spec:
{{- with .Values.podDisruptionBudget.maxUnavailable }}
maxUnavailable: {{ . }}
{{- else }}
minAvailable: {{ .Values.podDisruptionBudget.minAvailable | default 0 }}
{{- end }}
selector:
matchLabels:
{{- include "common.labels.selectorLabels" . | nindent 6 }}
{{- end }}
12 changes: 11 additions & 1 deletion src/main/charts/bamboo/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1045,6 +1045,16 @@ additionalFiles: []
# key: keystore.jks
# mountPath: /var/ssl

# -- PodDisruptionBudget: https://kubernetes.io/docs/tasks/run-application/configure-pdb/
# You can specify only one of maxUnavailable and minAvailable in a single PodDisruptionBudget. When both minAvailable and maxUnavailable are set, maxUnavailable takes precedence.
#
podDisruptionBudget:
enabled: false
labels: {}
annotations: {}
minAvailable:
maxUnavailable:

# -- Create additional ConfigMaps with given names, keys and content. Ther Helm release name will be used as a prefix
# for a ConfigMap name, fileName is used as subPath
#
Expand All @@ -1060,4 +1070,4 @@ additionalConfigMaps: []
# mountPath: /opt/atlassian/jira/atlassian-jira/WEB-INF/classes
# content: |
# <xml>
# </xml>
# </xml>
1 change: 1 addition & 0 deletions src/main/charts/bitbucket/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ Kubernetes: `>=1.21.x-0`
| monitoring.serviceMonitor.scrapeIntervalSeconds | int | `30` | Scrape interval for the JMX service. |
| nodeSelector | object | `{}` | Standard K8s node-selectors that will be applied to all Bitbucket pods |
| podAnnotations | object | `{}` | Custom annotations that will be applied to all Bitbucket pods |
| podDisruptionBudget | object | `{"annotations":{},"enabled":false,"labels":{},"maxUnavailable":null,"minAvailable":null}` | PodDisruptionBudget: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ You can specify only one of maxUnavailable and minAvailable in a single PodDisruptionBudget. When both minAvailable and maxUnavailable are set, maxUnavailable takes precedence. |
| podLabels | object | `{}` | Custom labels that will be applied to all Bitbucket pods |
| priorityClassName | string | `nil` | Priority class for the application pods. The PriorityClass with this name needs to be available in the cluster. For details see https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass |
| replicaCount | int | `1` | The initial number of Bitbucket pods that should be started at deployment time. Note that if Bitbucket is fully configured (see above) during initial deployment a 'replicaCount' greater than 1 can be supplied. |
Expand Down
26 changes: 26 additions & 0 deletions src/main/charts/bitbucket/templates/pdb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{- if .Values.podDisruptionBudget.enabled }}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ include "common.names.fullname" . }}
labels:
{{- include "common.labels.commonLabels" . | nindent 4 }}
{{- with .Values.podDisruptionBudget.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.podDisruptionBudget.annotations }}
annotations:
{{- range $key, $value := . }}
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- end }}
spec:
{{- with .Values.podDisruptionBudget.maxUnavailable }}
maxUnavailable: {{ . }}
{{- else }}
minAvailable: {{ .Values.podDisruptionBudget.minAvailable | default 0 }}
{{- end }}
selector:
matchLabels:
{{- include "common.labels.selectorLabels" . | nindent 6 }}
{{- end }}
10 changes: 10 additions & 0 deletions src/main/charts/bitbucket/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1334,6 +1334,16 @@ additionalHosts: []
# - "foo.local"
# - "bar.local"

# -- PodDisruptionBudget: https://kubernetes.io/docs/tasks/run-application/configure-pdb/
# You can specify only one of maxUnavailable and minAvailable in a single PodDisruptionBudget. When both minAvailable and maxUnavailable are set, maxUnavailable takes precedence.
#
podDisruptionBudget:
enabled: false
labels: {}
annotations: {}
minAvailable:
maxUnavailable:

# -- Create additional ConfigMaps with given names, keys and content. Ther Helm release name will be used as a prefix
# for a ConfigMap name, fileName is used as subPath
#
Expand Down
1 change: 1 addition & 0 deletions src/main/charts/confluence/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ Kubernetes: `>=1.21.x-0`
| monitoring.serviceMonitor.scrapeIntervalSeconds | int | `30` | Scrape interval for the JMX service. |
| nodeSelector | object | `{}` | Standard K8s node-selectors that will be applied to all Confluence pods |
| podAnnotations | object | `{}` | Custom annotations that will be applied to all Confluence pods |
| podDisruptionBudget | object | `{"annotations":{},"enabled":false,"labels":{},"maxUnavailable":null,"minAvailable":null}` | PodDisruptionBudget: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ You can specify only one of maxUnavailable and minAvailable in a single PodDisruptionBudget. When both minAvailable and maxUnavailable are set, maxUnavailable takes precedence. |
| podLabels | object | `{}` | Custom labels that will be applied to all Confluence pods |
| priorityClassName | string | `nil` | Priority class for the application pods. The PriorityClass with this name needs to be available in the cluster. For details see https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass |
| replicaCount | int | `1` | The initial number of Confluence pods that should be started at deployment time. Note that Confluence requires manual configuration via the browser post deployment after the first pod is deployed. This configuration must be completed before scaling up additional pods. As such this value should always be kept as 1, but can be altered once manual configuration is complete. |
Expand Down
26 changes: 26 additions & 0 deletions src/main/charts/confluence/templates/pdb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{- if .Values.podDisruptionBudget.enabled }}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ include "common.names.fullname" . }}
labels:
{{- include "common.labels.commonLabels" . | nindent 4 }}
{{- with .Values.podDisruptionBudget.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.podDisruptionBudget.annotations }}
annotations:
{{- range $key, $value := . }}
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- end }}
spec:
{{- with .Values.podDisruptionBudget.maxUnavailable }}
maxUnavailable: {{ . }}
{{- else }}
minAvailable: {{ .Values.podDisruptionBudget.minAvailable | default 0 }}
{{- end }}
selector:
matchLabels:
{{- include "common.labels.selectorLabels" . | nindent 6 }}
{{- end }}
11 changes: 11 additions & 0 deletions src/main/charts/confluence/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,16 @@ additionalHosts: []
# - "foo.local"
# - "bar.local"

# -- PodDisruptionBudget: https://kubernetes.io/docs/tasks/run-application/configure-pdb/
# You can specify only one of maxUnavailable and minAvailable in a single PodDisruptionBudget. When both minAvailable and maxUnavailable are set, maxUnavailable takes precedence.
#
podDisruptionBudget:
enabled: false
labels: {}
annotations: {}
minAvailable:
maxUnavailable:

# -- Create additional ConfigMaps with given names, keys and content. Ther Helm release name will be used as a prefix
# for a ConfigMap name, fileName is used as subPath
#
Expand All @@ -1362,3 +1372,4 @@ additionalConfigMaps: []
# content: |
# <xml>
# </xml>

1 change: 1 addition & 0 deletions src/main/charts/crowd/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ Kubernetes: `>=1.21.x-0`
| monitoring.serviceMonitor.scrapeIntervalSeconds | int | `30` | Scrape interval for the JMX service. |
| nodeSelector | object | `{}` | Standard K8s node-selectors that will be applied to all Crowd pods |
| podAnnotations | object | `{}` | Custom annotations that will be applied to all Crowd pods |
| podDisruptionBudget | object | `{"annotations":{},"enabled":false,"labels":{},"maxUnavailable":null,"minAvailable":null}` | PodDisruptionBudget: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ You can specify only one of maxUnavailable and minAvailable in a single PodDisruptionBudget. When both minAvailable and maxUnavailable are set, maxUnavailable takes precedence. |
| podLabels | object | `{}` | Custom labels that will be applied to all Crowd pods |
| priorityClassName | string | `nil` | Priority class for the application pods. The PriorityClass with this name needs to be available in the cluster. For details see https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass |
| replicaCount | int | `1` | The initial number of Crowd pods that should be started at deployment time. Note that Crowd requires manual configuration via the browser post deployment after the first pod is deployed. This configuration must be completed before scaling up additional pods. As such this value should always be kept as 1, but can be altered once manual configuration is complete. |
Expand Down
26 changes: 26 additions & 0 deletions src/main/charts/crowd/templates/pdb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{- if .Values.podDisruptionBudget.enabled }}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ include "common.names.fullname" . }}
labels:
{{- include "common.labels.commonLabels" . | nindent 4 }}
{{- with .Values.podDisruptionBudget.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.podDisruptionBudget.annotations }}
annotations:
{{- range $key, $value := . }}
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- end }}
spec:
{{- with .Values.podDisruptionBudget.maxUnavailable }}
maxUnavailable: {{ . }}
{{- else }}
minAvailable: {{ .Values.podDisruptionBudget.minAvailable | default 0 }}
{{- end }}
selector:
matchLabels:
{{- include "common.labels.selectorLabels" . | nindent 6 }}
{{- end }}
12 changes: 11 additions & 1 deletion src/main/charts/crowd/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -857,8 +857,18 @@ monitoring:
#
dashboardLabels: {}
# grafana_dashboard: dc_monitoring

# -- Annotations added to Grafana dashboards ConfigMaps. See: https://github.com/kiwigrid/k8s-sidecar#usage
#
dashboardAnnotations: {}
# k8s-sidecar-target-directory: /tmp/dashboards/example-folder

# -- PodDisruptionBudget: https://kubernetes.io/docs/tasks/run-application/configure-pdb/
# You can specify only one of maxUnavailable and minAvailable in a single PodDisruptionBudget. When both minAvailable and maxUnavailable are set, maxUnavailable takes precedence.
#
podDisruptionBudget:
enabled: false
labels: {}
annotations: {}
minAvailable:
maxUnavailable:
1 change: 1 addition & 0 deletions src/main/charts/jira/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ Kubernetes: `>=1.21.x-0`
| monitoring.serviceMonitor.scrapeIntervalSeconds | int | `30` | Scrape interval for the JMX service. |
| nodeSelector | object | `{}` | Standard K8s node-selectors that will be applied to all Jira pods |
| podAnnotations | object | `{}` | Custom annotations that will be applied to all Jira pods |
| podDisruptionBudget | object | `{"annotations":{},"enabled":false,"labels":{},"maxUnavailable":null,"minAvailable":null}` | PodDisruptionBudget: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ You can specify only one of maxUnavailable and minAvailable in a single PodDisruptionBudget. When both minAvailable and maxUnavailable are set, maxUnavailable takes precedence. |
| podLabels | object | `{}` | Custom labels that will be applied to all Jira pods |
| priorityClassName | string | `nil` | Priority class for the application pods. The PriorityClass with this name needs to be available in the cluster. For details see https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass |
| replicaCount | int | `1` | The initial number of Jira pods that should be started at deployment time. Note that Jira requires manual configuration via the browser post deployment after the first pod is deployed. This configuration must be completed before scaling up additional pods. As such this value should always be kept as 1, but can be altered once manual configuration is complete. |
Expand Down
26 changes: 26 additions & 0 deletions src/main/charts/jira/templates/pdb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{- if .Values.podDisruptionBudget.enabled }}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ include "common.names.fullname" . }}
labels:
{{- include "common.labels.commonLabels" . | nindent 4 }}
{{- with .Values.podDisruptionBudget.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.podDisruptionBudget.annotations }}
annotations:
{{- range $key, $value := . }}
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- end }}
spec:
{{- with .Values.podDisruptionBudget.maxUnavailable }}
maxUnavailable: {{ . }}
{{- else }}
minAvailable: {{ .Values.podDisruptionBudget.minAvailable | default 0 }}
{{- end }}
selector:
matchLabels:
{{- include "common.labels.selectorLabels" . | nindent 6 }}
{{- end }}
10 changes: 10 additions & 0 deletions src/main/charts/jira/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,16 @@ additionalHosts: []
# - "foo.local"
# - "bar.local"

# -- PodDisruptionBudget: https://kubernetes.io/docs/tasks/run-application/configure-pdb/
# You can specify only one of maxUnavailable and minAvailable in a single PodDisruptionBudget. When both minAvailable and maxUnavailable are set, maxUnavailable takes precedence.
#
podDisruptionBudget:
enabled: false
labels: {}
annotations: {}
minAvailable:
maxUnavailable:

# -- Create additional ConfigMaps with given names, keys and content. Ther Helm release name will be used as a prefix
# for a ConfigMap name, fileName is used as subPath
#
Expand Down
75 changes: 75 additions & 0 deletions src/test/java/test/PodDisruptionBudgetTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package test;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import test.helm.Helm;
import test.model.*;

import java.util.Map;

import static test.jackson.JsonNodeAssert.assertThat;

public class PodDisruptionBudgetTest {

private Helm helm;

@BeforeEach
void initHelm(TestInfo testInfo) {
helm = new Helm(testInfo);
}

@ParameterizedTest
@EnumSource(value = Product.class, names = {"bamboo_agent"}, mode = EnumSource.Mode.EXCLUDE)
void pod_disruption_budget_enabled_min_available(Product product) throws Exception {
final var resources = helm.captureKubeResourcesFromHelmChart(product, Map.of(
"podDisruptionBudget.enabled", "true",
"podDisruptionBudget.minAvailable", "1"
));

KubeResource pdb = resources.get(Kind.PodDisruptionBudget, product.getHelmReleaseName());
assertThat(pdb.getSpec().get("minAvailable")).hasValueEqualTo(1);
}

@ParameterizedTest
@EnumSource(value = Product.class, names = {"bamboo_agent"}, mode = EnumSource.Mode.EXCLUDE)
void pod_disruption_budget_min_available_max_unavailable(Product product) throws Exception {
final var resources = helm.captureKubeResourcesFromHelmChart(product, Map.of(
"podDisruptionBudget.enabled", "true",
"podDisruptionBudget.minAvailable", "1",
"podDisruptionBudget.maxUnavailable", "2"
));

// assert that when both mixAvailable and maxUnavailable are defined, only maxUnavailable is set in pdb
KubeResource pdb = resources.get(Kind.PodDisruptionBudget, product.getHelmReleaseName());
assertThat(pdb.getSpec().get("maxUnavailable")).hasValueEqualTo(2);
assertThat(pdb.getSpec().path("minAvailable")).isEmpty();
}

@ParameterizedTest
@EnumSource(value = Product.class, names = {"bamboo_agent"}, mode = EnumSource.Mode.EXCLUDE)
void pod_disruption_budget_annotations(Product product) throws Exception {
final var resources = helm.captureKubeResourcesFromHelmChart(product, Map.of(
"podDisruptionBudget.enabled", "true",
"podDisruptionBudget.minAvailable", "1",
"podDisruptionBudget.annotations.foo", "bar"
));

KubeResource pdb = resources.get(Kind.PodDisruptionBudget, product.getHelmReleaseName());
assertThat(pdb.getAnnotations().path("foo")).hasTextEqualTo("bar");
}

@ParameterizedTest
@EnumSource(value = Product.class, names = {"bamboo_agent"}, mode = EnumSource.Mode.EXCLUDE)
void pod_disruption_budget_labels(Product product) throws Exception {
final var resources = helm.captureKubeResourcesFromHelmChart(product, Map.of(
"podDisruptionBudget.enabled", "true",
"podDisruptionBudget.minAvailable", "1",
"podDisruptionBudget.labels.foo", "bar"
));

KubeResource pdb = resources.get(Kind.PodDisruptionBudget, product.getHelmReleaseName());
assertThat(pdb.getMetadata().path("labels").path("foo")).hasTextEqualTo("bar");
}
}
2 changes: 1 addition & 1 deletion src/test/java/test/model/Kind.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
* The different types of Kubernetes resource we use.
*/
public enum Kind {
StatefulSet, Deployment, ServiceAccount, ConfigMap, Secret, Service, Pod, Job, ClusterRole, Role, ClusterRoleBinding, RoleBinding, PersistentVolume, PersistentVolumeClaim, Ingress, ServiceMonitor
StatefulSet, Deployment, ServiceAccount, ConfigMap, Secret, Service, Pod, Job, ClusterRole, Role, ClusterRoleBinding, RoleBinding, PersistentVolume, PersistentVolumeClaim, Ingress, ServiceMonitor, PodDisruptionBudget
}

0 comments on commit 599979e

Please sign in to comment.