Upgrade planning and rollout
The operator supports rolling and blue-green upgrades, but both paths depend on cluster health, backup posture, and explicit authentication for the executor Jobs. Use this page to choose the strategy, stage the right config, and verify the rollout cleanly.
Decision matrix
Choose the upgrade strategy
| Strategy | Use it when | Operator behavior | Watch for |
|---|---|---|---|
| RollingUpdate | You want the default production path with the lowest resource overhead. | The operator upgrades pods one by one, handles leader step-down when needed, and waits for each ordinal to converge before finishing. | Failures hold the rollout until you fix the cause and send an explicit retry request. |
| BlueGreen | You need staged validation, manual promotion, or stronger cutover boundaries for a risky change. | The operator creates a parallel Green revision, validates it, promotes it, and then cleans up the old Blue revision. | This path uses more cluster resources and introduces additional in-flight phases to watch. |
The operator supports RollingUpdate to BlueGreen and BlueGreen to RollingUpdate without renaming or replacing the active StatefulSet. Admission allows the change only after initialization, while every voter is Ready, status.currentVersion equals spec.version, and no upgrade, backup, restore, resize, restart, Green workload, pending request, failure, or safe-mode recovery is active.
Change only spec.upgrade.strategy, then wait until status.acceptedUpgradeStrategy reports the new value. Change spec.version or other workload settings only after that acknowledgment. A strategy change that does not meet these conditions is rejected with recovery guidance.
OpenBao 2.6.0 changed its internal request-forwarding gRPC service name. During a pre-2.6 to 2.6.0 BlueGreen upgrade, Green peers cannot report Raft Autopilot health to the Blue leader and therefore cannot be promoted safely. The operator rejects pre-2.6 to 2.6-or-newer transitions before creating Green resources until a compatible target is explicitly qualified.
Fresh 2.6.0 clusters and the RollingUpdate path remain supported. If a pre-2.6 cluster is configured for BlueGreen, first let the cluster return to a healthy Idle state, switch only the strategy to RollingUpdate, wait for status.acceptedUpgradeStrategy=RollingUpdate, and then request the 2.6.0 version change.
Diagram
Upgrade control flow
Every upgrade starts with validation. After that, the controller either executes a partitioned rolling rollout or creates a parallel Green revision for promotion and cleanup.
Prepare the rollout
- Confirm the cluster is initialized, healthy, and already safe to change. An upgrade is not the time to discover a broken backup path or an unstable seal configuration.
- Set
spec.versionto the target semantic version. The operator blocks downgrades and validates semver format. - If you override
spec.image, keep it aligned withspec.version. Semantic-version tags must match, and digest-pinned images still requirespec.versionas the authoritative intent. - Make sure the upgrade executor Job can authenticate:
- with the default JWT role created from
selfInit.oidc, or - with an explicit
spec.upgrade.jwtAuthRole
- with the default JWT role created from
- If you want pre-upgrade snapshots, configure
spec.backupfirst and make sure the backup auth path is already working. - In the
Hardenedprofile, explicitly allow egress to object storage or other external dependencies the upgrade path needs.
Change the strategy of an existing cluster
Use this sequence in either direction. It deliberately separates the control-plane strategy transition from the next workload change.
- Finish or recover every active upgrade, backup, restore, resize, restart, promotion, rollback, or safe-mode workflow.
- Verify
status.phase=Running,status.currentVersion=spec.version, all voter and configured read replicas are Ready,Available=True, and BlueGreen is absent orIdlewith no Green revision. - Ensure the BlueGreen executor prerequisites are configured before switching to
BlueGreen: an explicitspec.upgrade.jwtAuthRoleor the default role created by enabledselfInit.oidc, plus a resolvable upgrade executor image. The referenced role must already grant the BlueGreen raft join, configuration, remove-peer, promote, and demote capabilities. Self-init policies are created during initial bootstrap and are not rewritten by a later strategy change, so update the role policy first when a rolling-origin cluster was initialized with rolling-only permissions. - Patch only
spec.upgrade.strategy. - Wait for
status.acceptedUpgradeStrategyto equal the requested strategy. - Patch
spec.version,spec.image, replicas, storage, or restart controls in a later request.
Switch an idle cluster from BlueGreen to RollingUpdate
kubectl patch openbaocluster <name> -n <namespace> --type merge -p '{
"spec": {
"upgrade": {
"strategy": "RollingUpdate"
}
}
}'
kubectl get openbaocluster <name> -n <namespace> -o jsonpath='{.status.acceptedUpgradeStrategy}{"\n"}'
Switch an idle cluster from RollingUpdate to BlueGreen
kubectl patch openbaocluster <name> -n <namespace> --type merge -p '{
"spec": {
"upgrade": {
"strategy": "BlueGreen"
}
}
}'
kubectl get openbaocluster <name> -n <namespace> -o jsonpath='{.status.acceptedUpgradeStrategy}{"\n"}'
The active StatefulSet and its PVCs remain the stable workload after either transition. A later rolling rollout continues against a revisioned StatefulSet when switching from BlueGreen; a later blue-green rollout treats the original unrevisioned StatefulSet as Blue when switching from RollingUpdate.
The upgrade executor Job uses JWT auth to talk to OpenBao. Pre-upgrade snapshots use the backup configuration and backup identity path. Do not assume one automatically covers the other.
Setting spec.upgrade.image or a blue-green prePromotionHook selects custom executables for the upgrade path. The identity applying that OpenBaoCluster needs usecustomexecutables on the cluster; existing usehelperimages bindings remain accepted for compatibility.
Use the default rolling path
Use RollingUpdate when you want the lowest operational complexity and you do not need a second revision running in parallel.
- JWT via self-init OIDC
- Explicit upgrade role
- Private registry image
Configure
Use the default rolling path with OIDC bootstrap
spec:
version: "2.5.0"
selfInit:
enabled: true
oidc:
enabled: true
upgrade:
strategy: RollingUpdate
Configure
Use a dedicated JWT role for upgrade Jobs
spec:
version: "2.5.0"
upgrade:
strategy: RollingUpdate
jwtAuthRole: platform-upgrade
Configure
Keep the image and semantic version aligned
spec:
version: "2.5.0"
image: "registry.example.com/openbao/openbao:2.5.0"
upgrade:
strategy: RollingUpdate
jwtAuthRole: platform-upgrade
Apply
Patch the cluster to the target version
kubectl patch openbaocluster <name> -n <namespace> --type merge -p '{
"spec": {
"version": "2.5.0",
"upgrade": {
"strategy": "RollingUpdate"
}
}
}'
If leadership moves while the rollout is in progress, you may see multiple step-down Jobs across the same upgrade. That is expected and does not mean the controller restarted the entire workflow.
When steady read replicas are configured, the operator upgrades the read pool first and only then starts the voter partition rollout. For blue-green, the operator stages the steady read pool down before cutover, restores it afterward, and only then returns the workflow to Idle.
Use blue-green when you need a controlled cutover
Choose BlueGreen when you need parallel validation, a manual promotion point, or stronger rollback boundaries before the new revision takes over production traffic.
Configure
Configure a blue-green upgrade with automatic rollback
spec:
version: "2.5.0"
upgrade:
strategy: BlueGreen
preUpgradeSnapshot: true
blueGreen:
autoPromote: true
autoRollback:
enabled: true
onJobFailure: true
onValidationFailure: true
Configure
Add a pre-promotion verification hook
spec:
upgrade:
strategy: BlueGreen
blueGreen:
verification:
prePromotionHook:
image: curlimages/curl
command: ["curl", "-f", "https://green-cluster:8200/v1/sys/health"]
Use the hook to prove the Green revision is really healthy before promotion. If the hook fails, the operator either holds or rolls back depending on the autoRollback settings.
Reference table
Control in-flight upgrades
| Control | What it does | Use it when |
|---|---|---|
| spec.upgrade.requests.retry | Restarts a failed rolling upgrade after you fix the underlying cause. | The operator preserved status.upgrade.failure.reason (and the deprecated lastError* compatibility fields) and is waiting for an explicit retry. |
| spec.upgrade.requests.promote | Approves promotion when blueGreen.autoPromote=false and the Green revision is already healthy. | You want a manual checkpoint before switching traffic. |
| blueGreen.autoRollback | Aborts or rolls back automatically when validation or execution fails in supported phases. | You want the operator to recover from bad Green revisions without waiting for a human to react. |
Verify the rollout outcome
Verify
Inspect the upgrade result
kubectl get openbaocluster <name> -n <namespace> -o yaml
kubectl get pods -n <namespace>
kubectl get jobs -n <namespace>
Look for an idle cluster rather than just a patched spec. The right end state is healthy pods, no unresolved upgrade failure state, and a condition surface that matches the cluster features you enabled.
Reference table
Expected signals after the upgrade
| Surface | Healthy signal | Why it matters |
|---|---|---|
| Cluster phase | Phase returns to Running. | The lifecycle is no longer in an in-flight upgrade state. |
| Availability | Available=True and the workload Pods are Ready. | The new revision is actually serving instead of only existing on paper. |
| Upgrade status | No unresolved status.upgrade.failure.reason (or deprecated lastErrorReason) and no stalled blue-green phase. | The controller does not think operator action is still required. |
| Protection path | Backup status and external dependency conditions remain healthy. | A successful version change keeps the next restore or backup window intact. |
Keep the change safe
You are reading the unreleased main docs. Use the version menu for the newest published release, or check the release notes for what is already out.
Was this page helpful?
Use Needs work to open a structured GitHub issue for this page. The Yes button only acknowledges the signal locally.