# Canary a StatefulSet upgrade with a partition

> Upgrade one replica of a Redis StatefulSet first, check it, then roll the rest, using the rolling update partition.

Level: Intermediate · Topic: Workloads · About 10 minutes
Try it in the browser: https://k8wiz.com/playground/canary-a-statefulset-with-a-partition

The playground is a simulated Kubernetes cluster that runs in the browser. kubectl output and errors follow the real ones.

## The situation

`cache` is a 3-replica Redis StatefulSet on `redis:7.4`. You need to move it to `redis:8.0`, but you want one replica on 8.0 for a while before the others follow.

A StatefulSet updates Pods from the highest ordinal down. Its rolling update `partition` holds back every Pod whose ordinal is below it.

## Objectives

1. Only cache-2 runs redis 8.0 (Set the partition before you change the image)
2. See the partitioned rollout finish (`kubectl rollout status sts/cache`)
3. All three run redis 8.0

## Hints

1. First hold back cache-0 and cache-1: `kubectl patch sts cache -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":2}}}}'`.
2. Then `kubectl set image sts/cache redis=redis:8.0` and `kubectl rollout status sts/cache`. Only ordinals 2 and up are updated.
3. `kubectl get pods -L controller-revision-hash` shows which revision each Pod runs. A Pod below the partition that gets deleted comes back on the old revision.
4. When you're happy, set the partition to 0 and the rest follow, highest ordinal first.

## Solution

```bash
kubectl patch sts cache -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":2}}}}'
```
```bash
kubectl set image sts/cache redis=redis:8.0
```
```bash
kubectl rollout status sts/cache
```
```bash
kubectl get pods -L controller-revision-hash
```
```bash
kubectl patch sts cache -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":0}}}}'
```
```bash
kubectl rollout status sts/cache
```

## What it teaches

- With a `partition` of N, only Pods with an ordinal of N or more get the new template. The others stay on the current revision, even if they're recreated.
- Each template change is a ControllerRevision (`kubectl get controllerrevisions`), which is what `kubectl rollout history` and `kubectl rollout undo` use for StatefulSets.
- Set the partition before changing the template. Changing the image first starts the full rollout at once.
- Lowering the partition step by step gives you a staged rollout you control, one ordinal at a time.
