diff --git a/charts/descheduler/README.md b/charts/descheduler/README.md index f9d6c5b20..6b2a1262c 100644 --- a/charts/descheduler/README.md +++ b/charts/descheduler/README.md @@ -63,6 +63,10 @@ The following table lists the configurable parameters of the _descheduler_ chart | `deschedulingInterval` | If using kind:Deployment, sets time between consecutive descheduler executions. | `5m` | | `replicas` | The replica count for Deployment | `1` | | `leaderElection` | The options for high availability when running replicated components | _see values.yaml_ | +| `podDisruptionBudget.enabled` | If `true` and `kind` is `Deployment`, create a PodDisruptionBudget for the descheduler | `false` | +| `podDisruptionBudget.minAvailable` | Minimum descheduler pods that must stay available (mutually exclusive with `maxUnavailable`) | `1` | +| `podDisruptionBudget.maxUnavailable`| Maximum descheduler pods that can be unavailable (mutually exclusive with `minAvailable`) | `""` | +| `podDisruptionBudget.annotations` | Annotations to add to the PodDisruptionBudget | `{}` | | `cmdOptions` | The options to pass to the _descheduler_ command | _see values.yaml_ | | `priorityClassName` | The name of the priority class to add to pods | `system-cluster-critical` | | `rbac.create` | If `true`, create & use RBAC resources | `true` | diff --git a/charts/descheduler/templates/poddisruptionbudget.yaml b/charts/descheduler/templates/poddisruptionbudget.yaml new file mode 100644 index 000000000..4e1405e73 --- /dev/null +++ b/charts/descheduler/templates/poddisruptionbudget.yaml @@ -0,0 +1,30 @@ +{{- if and (eq .Values.kind "Deployment") (.Values.podDisruptionBudget).enabled }} +{{- if .Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" }} +apiVersion: policy/v1 +{{- else }} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ template "descheduler.fullname" . }} + namespace: {{ include "descheduler.namespace" . }} + labels: + {{- include "descheduler.labels" . | nindent 4 }} + {{- with .Values.podDisruptionBudget.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} + {{- end }} + {{- with .Values.podDisruptionBudget.unhealthyPodEvictionPolicy }} + unhealthyPodEvictionPolicy: {{ . }} + {{- end }} + selector: + matchLabels: + {{- include "descheduler.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/charts/descheduler/tests/poddisruptionbudget_test.yaml b/charts/descheduler/tests/poddisruptionbudget_test.yaml new file mode 100644 index 000000000..addfecbf3 --- /dev/null +++ b/charts/descheduler/tests/poddisruptionbudget_test.yaml @@ -0,0 +1,75 @@ +suite: Test Descheduler PodDisruptionBudget + +templates: + - "*.yaml" + +release: + name: descheduler + +tests: + - it: is not created for the default CronJob kind even when enabled + template: templates/poddisruptionbudget.yaml + set: + podDisruptionBudget: + enabled: true + asserts: + - hasDocuments: + count: 0 + + - it: is not created for Deployment kind unless enabled + template: templates/poddisruptionbudget.yaml + set: + kind: Deployment + asserts: + - hasDocuments: + count: 0 + + - it: creates a PodDisruptionBudget for Deployment kind when enabled + template: templates/poddisruptionbudget.yaml + set: + kind: Deployment + podDisruptionBudget: + enabled: true + asserts: + - isKind: + of: PodDisruptionBudget + - equal: + path: spec.minAvailable + value: 1 + - notExists: + path: spec.maxUnavailable + - equal: + path: spec.selector.matchLabels["app.kubernetes.io/name"] + value: descheduler + + - it: supports maxUnavailable instead of minAvailable + template: templates/poddisruptionbudget.yaml + set: + kind: Deployment + podDisruptionBudget: + enabled: true + minAvailable: "" + maxUnavailable: 1 + asserts: + - equal: + path: spec.maxUnavailable + value: 1 + - notExists: + path: spec.minAvailable + + - it: supports unhealthyPodEvictionPolicy and annotations + template: templates/poddisruptionbudget.yaml + set: + kind: Deployment + podDisruptionBudget: + enabled: true + unhealthyPodEvictionPolicy: IfHealthyBudget + annotations: + example.com/team: platform + asserts: + - equal: + path: spec.unhealthyPodEvictionPolicy + value: IfHealthyBudget + - equal: + path: metadata.annotations["example.com/team"] + value: platform diff --git a/charts/descheduler/values.yaml b/charts/descheduler/values.yaml index e53283181..b0d1bbbfb 100644 --- a/charts/descheduler/values.yaml +++ b/charts/descheduler/values.yaml @@ -80,6 +80,20 @@ leaderElection: {} # resourceName: "descheduler" # resourceNamespace: "kube-system" +# Pod Disruption Budget for the descheduler Deployment. Optional. +# Only rendered when kind is "Deployment". The descheduler runs a single replica +# by default, so this is disabled by default. Enable it for highly available +# setups (replicas > 1 with leaderElection enabled) to keep a descheduler pod +# available during voluntary node disruptions. +podDisruptionBudget: + enabled: false + # minAvailable and maxUnavailable are mutually exclusive; set only one. + minAvailable: 1 + maxUnavailable: "" + # See https://kubernetes.io/docs/tasks/run-application/configure-pdb/ + # unhealthyPodEvictionPolicy: IfHealthyBudget + annotations: {} + command: - "/bin/descheduler"