Migrate to zone-aware replication
Table of contents
Overview
This migration guide shows how to migrate to zone-aware replication without downtime or data loss. With zone-aware replication, each replica of incoming samples is distributed across ingesters in different zones. This means that loss of a full zone is possible without downtime.
The general migration process is the following: New stateful sets are created, the write traffic is routed to them, the read traffic is routed to them, the old stateful set is disabled. During the migration, it is ensured that at most one ingester is unavailable at the time, and that an ingester’s data is always written to persistent storage before it is shut down.
The chart makes use of the rollout-operator to coordinate rollouts of the stateful sets. This will automatically set the stateful set’s update strategy to OnDelete.
Prerequisites
Make sure to set the following settings before starting the migration:
- Ingesters are deployed as a stateful set (deployment is currently not supported)
- Autoscaling is disabled (autoscaling is not supported for zone-aware ingesters)
podManagementPolicyis “OrderedReady” (default), not “Parallel” (OrderedReady creates pods consecutively when scaling up or down)frontend_addressis set in the ruler config (make the ruler read from the queriers, not directly from the ingesters. Otherwise, recording and alerting rules may not be evaluated correctly during migration)- The replication factor and the number of zones are at least 3 and the replication factor is not larger than the number of zones
Migration steps
Important: Always continue the next step only when all pods are in the ready state.
-
Before starting the migration, you should ensure that the querier uses all ingesters during the migration. This means that shuffle sharding should be disabled and sharding by all labels should be enabled. It is sufficient to set these settings on the querier using
querier.extraArgs. Setdistributor.sharding-strategytodefaultanddistributor.shard-by-all-labelsto"true"there. Warning: This may increase resource usage of the queriers. - Set
ingester.zoneAwareReplication.enabled=true,ingester.zoneAwareReplication.migration.enabled=true,ingester.zoneAwareReplication.zonesto the desired zones but withreplicas=0. Setrollout_operator.enabled=true. Upgrade the chart.ingester: zoneAwareReplication: enabled: true migration: enabled: true zones: - name: zone-a replicas: 0 nodeSelector: topology.kubernetes.io/zone: zone-a - name: zone-b replicas: 0 nodeSelector: topology.kubernetes.io/zone: zone-b - name: zone-c replicas: 0 nodeSelector: topology.kubernetes.io/zone: zone-cThe stateful sets will be scaled up in the next steps and not created at once to ensure that at most one ingester is unavailable at a time.
-
In
ingester.zoneAwareReplication.zones, setreplicasto the desired replicas for the first zone, the install the Helm chart. -
Repeat the process for the other zones.
-
Enable zone-awareness on the write path by setting
ingester.zoneAwareReplication.migration.writePath=trueand install the Helm chart. This makes the distributors ship data to the new ingesters while the queriers still use all ingesters. Wait forquerier.query_store_afterso that the data that is still on the old ingesters can be queried from the object storage. Ifquery_store_afteris unset, wait at least3 x bucket_store.sync_interval(default 3x15m). This also disables the distributors from writing to the old ingesters. -
Enable zone-awareness on the read path by setting
ingester.zoneAwareReplication.migration.readPath=trueand install the Helm chart. This makes the queriers use the new ingesters. This also disables the queriers from reading from the old ingesters. -
Set
ingester.replicasto 0. This will scale down the stateful set, one replica at a time, so that the ring remains healthy. -
Remove all values below
ingester.zoneAwareReplication.migration. This will delete the old stateful set. - If you have set any querier arguments in the first step, wait
-querier.shuffle-sharding-ingesters-lookback-periodbefore removingquerier.extraArgs.
Faster rollouts
With zone-awareness enabled, it is possible to roll all ingesters in a zone simultaneously. If you want to benefit from these faster rollouts, set ingester.zoneAwareReplication.maxUnavailable to the number of replicas per zone and set ingester.statefulSet.podManagementPolicy to “Parallel”. This will require recreating the stateful sets. Use kubectl delete sts <...> --cascade=orphan to delete only the stateful set, not the pods.