Updating server components of YTsaurus
Important
This describes how to perform an update using the operator version 0.32.0 or later. For differences with older versions, see the section Migrating from enableFullUpdate to updatePlan.
This article describes the process of fully updating the server components of a YTsaurus cluster via the Kubernetes operator: how to prepare for the update, update the operator, modify the Ytsaurus specification, monitor the update progress, and verify the result.
What you need to know before updating
- Update only to the next major version.
- Update the cluster sequentially by major versions, without skipping intermediate ones: first
25.1 → 25.2, then25.2 → 25.3. Skipping a version may disrupt cluster operation. Within the target major version, you can select the latest minor version to get the most recent updates — for example,25.2.0 → 25.3.2. See available versions in the release list. - The update cannot be undone.
- Once the master servers exit
read-onlymode and apply irreversible changes, rolling back to the previous version is not supported. - Update the operator first, then the cluster.
- Before updating the cluster, update the operator. Its version must be compatible with the target cluster version. Check compatibility in the compatibility table.
- The cluster may be unavailable during the update.
- By default, the cluster is fully unavailable during the update — all operations and requests are interrupted. Schedule the update during a period of minimal load. If the cluster must remain available, choose a different strategy — see Update strategies.
Updating the cluster without downtime
If you need to update the cluster without downtime, configure the RollingUpdate strategy via the updatePlan field. See an example in the section Updating the cluster without downtime via RollingUpdate.
Cluster update
The update process consists of four steps:
1. Prepare the cluster for the update
Before changing the Ytsaurus specification, check the current state of the cluster and make sure the operator is ready to start a new update cycle.
-
Find out the current cluster version:
$ kubectl get YTsaurus <cluster_name> -n <namespace> -o jsonpath='{.spec.coreImage}' ghcr.io/ytsaurus/ytsaurus:stable-25.1.0-relwithdebinfo -
Check the cluster state:
$ kubectl get YTsaurus <cluster_name> -n <namespace> NAME CLUSTERSTATE UPDATESTATE UPDATINGCOMPONENTS BLOCKEDCOMPONENTS YTsaurus RunningBefore the update, the cluster must be in the
Runningstate. If the cluster is in another state, fix the issues first — see the Troubleshooting section. -
Make sure the operator is ready for the update. To do this, check its logs:
kubectl logs -n <namespace> deployment/ytsaurus-ytop-chart-controller-manager --tail=100 # If the deployment name is different, get the list kubectl get deployments -n <namespace>This is an important step: the operator must not be busy with pending actions. Proceed to the next step only when the logs contain the message
INFO YTsaurus is running and happy. This means the operator considers the cluster consistent and is not performing any pending actions.Important
If the operator does not report
running and happy, do not start the update. This may lead to unpredictable cluster behavior. -
Save a backup copy of the specification:
The file is required to enable rollback before passing the point of no return:
kubectl get YTsaurus <cluster_name> -n <namespace> -o yaml > ytsaurus-spec-backup.yamlAfter the master servers exit the
read‑onlymode and apply irreversible changes, rollback to the previous version is not supported.
If all checks are passed, you can proceed with updating the operator.
2. Update the operator
Update the operator first. New versions of server components may not work correctly with an older version of the operator.
Warning
The new version of the operator may trigger a cluster update immediately — without you changing coreImage. This happens if the new operator version generates static configs differently from the old one: the operator detects a discrepancy and starts reconciliation. For more details on the reasons and how to stop an unwanted update, see the section Automatic update after operator update.
Check the current operator version:
helm list -n <namespace>
See the list of releases and compatible versions on the releases page and in the compatibility table.
Update the operator:
helm upgrade YTsaurus --install oci://ghcr.io/ytsaurus/ytop-chart --version <new_version>
Verify that the operator has been updated:
kubectl get pods -n <namespace>
Right after the update, you may see both the old and new pods at the same time:
NAME READY STATUS RESTARTS AGE
ytsaurus-ytop-chart-controller-manager-6f67fd5d5c-6bbws 2/2 Running 0 21s
ytsaurus-ytop-chart-controller-manager-7478f9b6cb-qr8wd 2/2 Terminating 0 23h
After some time, the old pod will be removed:
NAME READY STATUS RESTARTS AGE
ytsaurus-ytop-chart-controller-manager-6f67fd5d5c-6bbws 2/2 Running 0 25s
3. Start the update
When you change the coreImage field in the Ytsaurus specification, the operator recreates pods for all server components from this specification, even if the image of a specific component hasn’t changed. This ensures version compatibility across all server components.
Components with their own release cycle — Query Tracker, YQL agent, and others — are not updated in this process. To learn how to update them, see the section Updating individual components. Before updating, check the compatibility of these components with the target cluster version in the compatibility table.
Save the current specification to a file for editing:
kubectl get YTsaurus <cluster_name> -n <namespace> -o yaml > ytsaurus-spec-new.yaml
Warning
Only save the specification from your running cluster using the kubectl get ytsaurus command. Do not use a specification from GitHub or another template: it won’t include your current settings — such as marked disks, encryption parameters, and custom settings. Applying a clean specification may break the cluster.
Make the following changes to the ytsaurus-spec-new.yaml file:
-
Set the
updatePlanfield with a list of components to update. For a full update, specify theEverythingclass — all server components will be updated. -
Change
coreImageto the next version. -
Select the target version on the releases page. Open the required release and copy the image tag
ghcr.io/ytsaurus/ytsaurus.
spec:
coreImage: ghcr.io/ytsaurus/ytsaurus:stable-25.2.0-relwithdebinfo # Next version
updatePlan:
- class: Everything # Full update of all server components
Important
Only update to the stable version following your current one. Do not use dev images from the main branch. After a successful update, rolling back to the previous version is not supported.
By default, the operator uses the BulkUpdate strategy — the cluster will be completely unavailable during the update. If the cluster must stay available, configure the RollingUpdate strategy via the updatePlan field in the ytsaurus-spec-new.yaml file before applying the changes. See an example in the section Updating without cluster downtime using RollingUpdate.
Apply the modified specification:
kubectl apply -f ytsaurus-spec-new.yaml
Expected output:
ytsaurus.cluster.ytsaurus.tech/<cluster_name> configured
Monitor the status in the UPDATESTATE field of the Ytsaurus resource:
kubectl get YTsaurus <cluster_name> -n <namespace>
During the update, the output may look like this:
NAME CLUSTERSTATE UPDATESTATE UPDATINGCOMPONENTS
ytsaurus Updating WaitingForPodsCreation {ms hp ds dnd rp end tnd sch ca}
For a description of update stages and pod states, see the status reference below.
Check the pod statuses:
kubectl get pods -n <namespace>
Note
The update may take some time, as the operator first downloads the new Docker image and then starts the updated components. To have images ready in advance and speed up the update, configure image pre‑loading.
If the update takes too long, check the events for the problematic pod:
kubectl describe pod <pod_name> -n <namespace> | grep -A 10 "Events:"
If the events show an image pull error ImagePullBackOff, verify that the image tag is correct and that this version exists in the registry. If the pod is in the Pending state, the issue is related to resources — check their availability in the cluster.
4. Verify the result
The update is complete when the following conditions are met:
- The cluster is in the
Runningstate. - All main pods are in the
Runningstate. - There are no pods in the cluster in the
Init,Pending,ImagePullBackOff, andCrashLoopBackOffstates.
Check the final cluster state:
kubectl get YTsaurus <cluster_name> -n <namespace>
Expected output:
NAME CLUSTERSTATE UPDATESTATE UPDATINGCOMPONENTS BLOCKEDCOMPONENTS
ytsaurus Running
Check pod statuses:
kubectl get pods -n <namespace>
Example of expected output:
NAME READY STATUS RESTARTS AGE
ca-0 1/1 Running 0 5m
dnd-0 1/1 Running 0 5m
dnd-1 1/1 Running 0 5m
dnd-2 1/1 Running 0 5m
ds-0 1/1 Running 0 10m
end-0 2/2 Running 0 5m
hp-0 1/1 Running 0 5m
ms-0 1/1 Running 0 10m
qt-0 1/1 Running 15 75d
rp-0 1/1 Running 0 5m
sch-0 1/1 Running 0 5m
tnd-0 1/1 Running 0 10m
Verify that the new version is specified in the specification:
kubectl get YTsaurus <cluster_name> -n <namespace> -o jsonpath='{.spec.coreImage}'
Expected output:
ghcr.io/ytsaurus/ytsaurus:stable-25.2.0-relwithdebinfo
Make sure the operator is again logging Ytsaurus is running and happy:
kubectl logs -n <namespace> deployment/ytsaurus-ytop-chart-controller-manager --tail=100
After a successful update, clear the updatePlan field in the ytsaurus-spec-new.yaml file — leave it empty:
spec:
updatePlan: []
You can achieve the same result with an explicit rule using the Nothing class — the operator won’t update any component:
spec:
updatePlan:
- class: Nothing
Apply the change:
kubectl apply -f ytsaurus-spec-new.yaml
The operator doesn’t clear updatePlan automatically — reset it yourself. An empty updatePlan means “don’t update anything” and protects against accidental component restarts during further specification changes. If you leave - class: Everything, the next change to coreImage will trigger a full update of all components again.
Updating to the next version: if you need to update to another version, repeat all steps starting from the Preparing for update section. Each time, save the specification anew via kubectl get ytsaurus — the operator might have changed it during the update, and the local file from last time is no longer up to date.
Troubleshooting updates
Use this section if the update doesn’t start, takes too long, fails, or behaves unpredictably.
Version conflict when applying the specification
You get a version conflict error when trying to apply the specification:
Error from server (Conflict): error when applying patch: the object has been modified; please apply your changes to the latest version and try again
This means another process has modified the specification. Save the current version of the specification and retry the change:
kubectl get YTsaurus <cluster_name> -n <namespace> -o yaml > ytsaurus-spec-new.yaml
Image not found
Image pull error:
Failed to pull image "ghcr.io/ytsaurus/ytsaurus:stable-X.X.X-relwithdebinfo": not found
Check that:
- The image tag is specified correctly.
- This version exists in the registry.
Pod stuck in Init state for a long time
This behavior is possible when Kubernetes is still downloading the new image.
kubectl describe pod <pod_name> -n <namespace> | grep -A 10 "Events:"
Example of normal process:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 3m10s default-scheduler Successfully assigned ytsaurus/ms-0 to docker-desktop
Normal Pulling 3m9s kubelet Pulling image "ghcr.io/ytsaurus/ytsaurus:stable-25.2.0-relwithdebinfo"
If the pod remains in the Init state longer than expected, check the pod logs and events to identify the issue.
Job is in CrashLoopBackOff state
For example, you might see yt-scheduler-init-job-op-archive in the CrashLoopBackOff state.
During an update, this may be a temporary state. The job might start before the cluster fully prepares tablet cells. Because of this, the job enters a restart loop but usually converges later — this is normal.
First, check the overall cluster status:
kubectl get YTsaurus <cluster_name> -n <namespace>
If the cluster is still updating, wait for the process to complete and check the job status again. If the cluster isn’t updating or the job doesn’t converge after a long time, check the job logs to identify the cause of the problem.
Operator doesn’t start the update
Check that:
- The
updatePlanfield lists the components to update — for example,- class: Everything. IfupdatePlanis empty and you changedcoreImage, the cluster will enter theUpdateBlockedstate and the update won’t start. - The operator has completed previous actions and the logs show
running and happy. - The cluster was in the
Runningstate before the update started. - Check the operator logs:
kubectl logs -n <namespace> deployment/ytsaurus-ytop-chart-controller-manager --tail=100
Update entered the ImpossibleToStart state
The Kubernetes operator may stop the update if it considers it unsafe. For example, if some tablet cell bundles are in poor condition — tablet cells aren’t working or have errors. In this case, the update won’t start until you fix the issue.
Check the resource status:
kubectl get YTsaurus -n <namespace>
Example output:
NAME CLUSTERSTATE UPDATESTATE UPDATINGCOMPONENTS
minisaurus Updating ImpossibleToStart
To find the reason, run the command:
kubectl describe YTsaurus -n <namespace>
And check the Conditions block in UpdateStatus.
Example of why an update can’t start
kubectl describe YTsaurus -n <namespace>
...
Update Status:
Conditions:
Last Transition Time: 2023-09-26T09:18:11Z
Message: Tablet cell bundles ([sys default]) aren't in 'good' health
Reason: Update
Status: True
Type: NoPossibility
State: ImpossibleToStart
If you can’t start the update, revert the specification to its previous value. After that, the operator will cancel the update and return the cluster to the Running state.
Unrecognized master options after update
After updating the cluster, master server configs may still contain unrecognized options that are no longer used in the new version of YTsaurus. This often happens during major updates. In this case, you’ll see a warning:
Found unrecognized options in dynamic cluster config
You can remove unrecognized master options in two ways:
- Using the CLI command — yt admin remove-master-unrecognized-options. This method supports the
--dryflag for previewing changes. - Using a standalone script — remove_master_unrecognized_options from the GitHub repository.
Advanced scenarios
Updating individual components
Warning
Use partial updates only in rare cases, such as fixing an error. We recommend discussing this decision with the YTsaurus team first.
A newer version of one component may require a specific version of master servers. If dependencies aren’t met, the cluster may fail to start. To update the cluster, we recommend using the update via the coreImage field. This guarantees version compatibility across all server components.
In the Ytsaurus specification, you can manage component images individually. How the operator handles such changes depends on the component type:
-
Components with their own release cycle — Query Tracker, YQL agent, Strawberry, and others. For more information, see the section Components with their own release cycle.
To update these components, change the
imagefield in theYtsaurusspecification. This is the only way to update these components. When you change their image, the operator updates only their pods without stopping cluster operation.When fully updating the cluster via the
coreImagefield, these components’ pods will restart, but their image will remain the same — the one set in theimagefield.Example: updating Query Tracker to version
0.0.7:spec: queryTrackers: image: ghcr.io/ytsaurus/query-tracker:0.0.7kubectl apply -f y