// This module is included in the following assemblies:
//
// upgrading/assembly-upgrade.adoc

[id='con-upgrade-cluster-{context}']
= Upgrading Kubernetes with minimal downtime

[role="_abstract"]
If you are upgrading Kubernetes, refer to the Kubernetes upgrade documentation to check the upgrade path and the steps to upgrade your nodes correctly.
Before upgrading Kubernetes, link:{supported-configurations}[check the supported versions for your version of Strimzi^].

When performing your upgrade, you'll want to keep your Kafka clusters available.

You can employ one of the following strategies:

. Configuring pod disruption budgets
. Rolling pods by one of these methods:
.. Using the Strimzi Drain Cleaner
.. Manually by applying an annotation to your pod

When using either of the methods to roll the pods, you must set a pod disruption budget of zero using the `maxUnavailable` property.

NOTE: `StrimziPodSet` custom resources manage Kafka and ZooKeeper pods using a custom controller that cannot use the `maxUnavailable` value directly.
Instead, the `maxUnavailable` value is converted to a `minAvailable` value.
If there are three broker pods and the `maxUnavailable` property is set to `0` (zero), the `minAvailable` setting is `3`, requiring all three broker pods to be available and allowing zero pods to be unavailable.

For Kafka to stay operational, topics must also be replicated for high availability.
This requires topic configuration that specifies a replication factor of at least 3 and a minimum number of in-sync replicas to 1 less than the replication factor.

.Kafka topic replicated for high availability
[source,yaml,subs="attributes+"]
----
apiVersion: {KafkaTopicApiVersion}
kind: KafkaTopic
metadata:
  name: my-topic
  labels:
    strimzi.io/cluster: my-cluster
spec:
  partitions: 1
  replicas: 3
  config:
    # ...
    min.insync.replicas: 2
    # ...
----

In a highly available environment, the Cluster Operator maintains a minimum number of in-sync replicas for topics during the upgrade process so that there is no downtime.

== Rolling pods using the Strimzi Drain Cleaner

You can use the xref:assembly-drain-cleaner-{context}[Strimzi Drain Cleaner] to evict nodes during an upgrade.
The Strimzi Drain Cleaner annotates pods with a rolling update pod annotation.
This informs the Cluster Operator to perform a rolling update of an evicted pod.

A pod disruption budget allows only a specified number of pods to be unavailable at a given time.
During planned maintenance of Kafka broker pods, a pod disruption budget ensures Kafka continues to run in a highly available environment.

You specify a pod disruption budget using a `template` customization for a Kafka component.
By default, pod disruption budgets allow only a single pod to be unavailable at a given time.

In order to use the Drain Cleaner to roll pods, you set `maxUnavailable` to `0` (zero).
Reducing the pod disruption budget to zero prevents voluntary disruptions, so pods must be evicted manually.

.Specifying a pod disruption budget
[source,yaml,subs=attributes+]
----
apiVersion: {KafkaApiVersion}
kind: Kafka
metadata:
  name: my-cluster
  namespace: myproject
spec:
  kafka:
    # ...
    template:
      podDisruptionBudget:
        maxUnavailable: 0
# ...
----

== Rolling pods manually while keeping topics available

During an upgrade, you can trigger a manual rolling update of pods through the Cluster Operator.
Using `Pod` resources, rolling updates restart the pods of resources with new pods.
As with using the Strimzi Drain Cleaner, you'll need to set the `maxUnavailable` value to zero for the pod disruption budget.

You need to watch the pods that need to be drained.
You then add a pod annotation to make the update.

Here, the annotation updates a Kafka broker.

.Performing a manual rolling update on a Kafka broker pod
[source,shell,subs="+quotes,attributes"]
----
kubectl annotate pod _<cluster_name>_-kafka-_<index>_ strimzi.io/manual-rolling-update=true
----

You replace _<cluster_name>_ with the name of the cluster.
Kafka broker pods are named _<cluster-name>_-kafka-_<index>_, where _<index>_ starts at zero and ends at the total number of replicas minus one.
For example, `my-cluster-kafka-0`.

[role="_additional-resources"]
.Additional resources
* xref:assembly-drain-cleaner-str[Draining pods using the Strimzi Drain Cleaner]
* xref:proc-manual-rolling-update-pods-str[Performing a rolling update using a pod annotation]
* link:{BookURLConfiguring}#type-PodDisruptionBudgetTemplate-reference[`PodDisruptionBudgetTemplate` schema reference^]
* {kubernetes-docs}[Kubernetes documentation^]
