// 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 the Kubernertes 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

You have to configure the pod disruption budget before using one of the methods to roll your pods.

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: 1
  config:
    # ...
    default.replication.factor: 3
    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 Strimzi Drain Cleaner tool 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.

To do this, you set `maxUnavailable` to 0 (zero).
Reducing the maximum 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
* {kubernetes-docs}[Kubernetes documentation^]
* link:{BookURLUsing}#replicating_topics_for_high_availability[Replicating topics for high availability^]
* link:{BookURLUsing}#type-PodDisruptionBudgetTemplate-reference[PodDisruptionBudgetTemplate schema reference^]
* link:{BookURLUsing}#proc-manual-rolling-update-pods-str[Performing a rolling update using a pod annotation^]
