Skip to content

feat: allow RollingUpdate to be specified for k8s Deployment - #497

Open
otan wants to merge 8 commits into
temporalio:mainfrom
otan:feat/deployment-rolling-update-strategy
Open

feat: allow RollingUpdate to be specified for k8s Deployment#497
otan wants to merge 8 commits into
temporalio:mainfrom
otan:feat/deployment-rolling-update-strategy

Conversation

@otan

@otan otan commented Aug 3, 2026

Copy link
Copy Markdown

What

Adds an optional spec.strategy field on WorkerDeployment that mirrors apps/v1 Deployment.spec.strategy. The controller applies it to owned versioned Deployments on create/update and reconciles drift so settings like maxUnavailable / maxSurge stick.

This is distinct from spec.rollout.strategy, which controls Temporal traffic routing across versions.

Why

Owned Deployments currently inherit the Kubernetes default rolling update (25% / 25%). On large fleets, in-place restarts of a Current version (same build ID) can take too many pollers offline at once and spike schedule_to_start. Users need a conservative strategy such as maxUnavailable: 5%.

Testing

  • make generate manifests
  • go test ./internal/k8s/ ./internal/planner/ -run 'Strategy|ApplyDeploymentStrategyDefaults|ReplicasNilPreserved'

Resolves #496

@otan
otan requested review from a team, eniko-dif and jlegrone as code owners August 3, 2026 19:39
@otan
otan force-pushed the feat/deployment-rolling-update-strategy branch from a728390 to baf447c Compare August 3, 2026 19:42
@CLAassistant

CLAassistant commented Aug 3, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@otan
otan force-pushed the feat/deployment-rolling-update-strategy branch from baf447c to f171c37 Compare August 3, 2026 19:42
Expose maxUnavailable/maxSurge on owned version Deployments for less disruptive in-place restarts.

Co-authored-by: Cursor <cursoragent@cursor.com>
@otan
otan force-pushed the feat/deployment-rolling-update-strategy branch from f171c37 to e880e0e Compare August 3, 2026 19:43
@jaypipes

jaypipes commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

@otan thanks so much for this contribution! I'll review a little later today or tomorrow morning. Been looking into some bug fixes earlier this week.

@jaypipes jaypipes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@otan thanks for this! :) Code looks good to me except for a couple requests (see inline). Address those small issues and I'll aim to get this into the v1.9.0 release (set to be cut on August 18th)

Comment thread api/v1alpha1/deprecated_temporalworkerdeployment_types.go Outdated
Comment thread api/v1alpha1/workerdeployment_types.go Outdated
Comment thread internal/k8s/deployments.go
@otan
otan requested a review from jaypipes August 6, 2026 21:05
@otan

otan commented Aug 6, 2026

Copy link
Copy Markdown
Author

all good!

@jaypipes jaypipes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesomesauce, thank you so much @otan :)

Comment thread internal/planner/planner.go
Comment thread internal/k8s/deployments.go
@otan
otan requested a review from eniko-dif August 7, 2026 20:19
@otan
otan force-pushed the feat/deployment-rolling-update-strategy branch from 9f11f30 to 7b3824e Compare August 7, 2026 20:19
@otan

otan commented Aug 7, 2026

Copy link
Copy Markdown
Author

all done

Deep-copy strategy defaults so comparison does not mutate live Deployments,
and move CR defaulting/validation onto the WorkerDeployment webhook.
@otan
otan force-pushed the feat/deployment-rolling-update-strategy branch from 7b3824e to 8672c08 Compare August 7, 2026 20:19

@jaypipes jaypipes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @otan!

Comment thread api/v1alpha1/workerdeployment_types.go Outdated
Comment on lines +84 to +90
// DeploymentStrategy describes how to replace Pods for each versioned
// Deployment this controller owns. Mirrors apps/v1 Deployment.spec.strategy.
// When omitted, Kubernetes defaults apply (RollingUpdate with
// maxUnavailable/maxSurge 25%). This is distinct from spec.rollout.strategy,
// which controls Temporal traffic routing across worker versions.
// +optional
DeploymentStrategy *appsv1.DeploymentStrategy `json:"deploymentStrategy,omitempty"`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have two concerns with this:

  1. Having both deploymentStrategy and rolloutStrategy may be confusing.
  2. So far we haven't committed to making the underlying deployment resource type part of the public API. Ie. we could switch to statefulsets or replicasets instead in the future. Ideally we should keep the worker spec agnostic to the underlying k8s resource types.

I also think it needs to be clarified in the documentation when deploymentStrategy would apply, since the controller computes a new build ID (and thus creates a fresh k8s deployment object) for each new worker version. For example does this only matter if you manually perform a rolling update via kubectl rollout restart for a specific version?

Do we actually need to support the Recreate deployment strategy? If not, what would it look like if we only exposed maxUnavailable as an option? I think my concerns would be resolved if the new config was named like spec.maxUnavailablePerVersion which doesn't tie us to deployments as the underlying resource type.

@otan otan Aug 10, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having both deploymentStrategy and rolloutStrategy may be confusing.

For example does this only matter if you manually perform a rolling update via kubectl rollout restart for a specific version?

yep. we just have no control over kubectl rollout restart at the moment (and we do a manual HPA patch to get around it). i can amend that - i originally wanted to keep it to just strategy to meet the original k8s Worker definition but was told to change it. i'm happy to rename it to whatever makes you more comfortable.

So far we haven't committed to making the underlying deployment resource type part of the public API. Ie. we could switch to statefulsets or replicasets instead in the future. Ideally we should keep the worker spec agnostic to the underlying k8s resource types.

AFAICT, this deployment.strategy is an option available to both statefulsets or replicasets

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose Deployment rollingUpdate strategy (maxUnavailable/maxSurge) on TemporalWorkerDeployment

5 participants