Chapter 2. Scale LokiStack deployments
Scale your LokiStack deployment to handle increased log volume by resizing the deployment or scaling individual components, and configure zone-aware replication for high availability.
2.1. Advanced deployment and scalability for Loki Copy linkLink copied to clipboard!
Configure high availability, scalability, and error handling for Loki to support large-scale deployments across multiple availability zones. These features enable Loki to tolerate zone failures, manage rate limit errors, and scale horizontally to handle increased log ingestion rates.
2.1.1. LokiStack sizing versus component scaling Copy linkLink copied to clipboard!
You can adjust LokiStack capacity by changing the overall t-shirt size or by scaling individual component replicas. Understanding when to use each approach helps optimize resources and maintain performance.
2.1.1.1. Changing the LokiStack size Copy linkLink copied to clipboard!
Changing the t-shirt size (1x.pico, 1x.extra-small, 1x.small, 1x.medium) adjusts CPU, memory, and replica counts for all components proportionally. This is the recommended approach for most sizing adjustments.
When to change the t-shirt size:
-
Log ingestion rate has increased beyond the current size capacity (for example, 100 GB/day
500 GB/day) - Query performance degrades due to insufficient resources across multiple components
- You are scaling the entire logging infrastructure up or down
How to change the size:
apiVersion: loki.grafana.com/v1
kind: LokiStack
metadata:
name: logging-loki
namespace: openshift-logging
spec:
size: 1x.small # Change from 1x.extra-small
Changing the size initiates a rolling restart of all Loki components. Plan sizing changes during maintenance windows.
2.1.1.2. Scaling individual components Copy linkLink copied to clipboard!
You can override the default replica count for specific components by using spec.template.<component>.replicas. This provides fine-grained control for workload-specific optimizations.
When to scale individual components:
- Read-heavy workload (many queries, low ingestion)
-
Increase
querierandqueryFrontendreplicas to handle query load without changing the overall size. - Write-heavy workload (high ingestion, few queries)
-
Increase
distributorandingesterreplicas to handle write throughput. - High-availability requirements
- Increase gateway replica count for redundancy at the query entry point.
- Cost optimization
-
Scale down non-critical components (for example,
rulerif not using alerting rules) while maintaining ingestion capacity.
Example: Scaling queriers for read-heavy workload:
apiVersion: loki.grafana.com/v1
kind: LokiStack
metadata:
name: logging-loki
namespace: openshift-logging
spec:
size: 1x.small
template:
querier:
replicas: 4 # Override default for 1x.small (normally 2)
queryFrontend:
replicas: 3 # Override default for 1x.small (normally 2)
Example: Scaling distributors and ingesters for write-heavy workload:
apiVersion: loki.grafana.com/v1
kind: LokiStack
metadata:
name: logging-loki
namespace: openshift-logging
spec:
size: 1x.small
template:
distributor:
replicas: 4 # Override default for 1x.small (normally 2)
ingester:
replicas: 4 # Override default for 1x.small (normally 2)
Component replica overrides remain unchanged when you change the size. If you change from 1x.small to 1x.medium, the querier and queryFrontend overrides remain at 4 and 3 replicas instead of adopting the 1x.medium defaults. Remove explicit replica settings to return to size-based defaults.
2.1.1.3. Decision guide Copy linkLink copied to clipboard!
Use the following decision guide to choose between changing the size and scaling components:
| Scenario | Recommended Action | Reason |
|---|---|---|
| Log ingestion rate exceeds size capacity | Change t-shirt size | All components need proportional scaling |
| High query latency but ingestion is fine |
Scale | Targeted fix avoids over-provisioning ingesters/distributors |
| High ingestion latency but queries are fine |
Scale | Targeted fix avoids over-provisioning query components |
| Adding alerting rules (ruler enabled) | No action needed initially; monitor ruler CPU | Ruler resources scale with the t-shirt size |
| Want to optimize costs |
Scale down unused components (for example, | Fine-grained control reduces waste |
| Unsure what component is bottleneck | Change t-shirt size | Safer default that scales everything proportionally |
2.1.2. Zone aware data replication Copy linkLink copied to clipboard!
Enable zone-aware data replication to protect against log loss during zone failures.
The Loki Operator offers support for zone-aware data replication through pod topology spread constraints. Enabling this feature enhances reliability and safeguards against log loss if a single zone failure occurs. When configuring the deployment size as 1x.extra-small, 1x.small, or 1x.medium, the replication.factor field is automatically set to 2.
To ensure proper replication, you need to have at least as many availability zones as the replication factor specifies. While it is possible to have more availability zones than the replication factor, having fewer zones can lead to write failures. Each zone should host an equal number of instances for optimal operation.
Example LokiStack CR with zone replication enabled
apiVersion: loki.grafana.com/v1
kind: LokiStack
metadata:
name: logging-loki
namespace: openshift-logging
spec:
replicationFactor: 2
replication:
factor: 2
zones:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
- spec.replicationFactor
-
Deprecated field, values entered are overwritten by
replication.factor. - spec.replication.factor
- This value is automatically set when deployment size is selected at setup.
- spec.replication.zones.maxSkew
- The maximum difference in number of pods between any two topology domains. The default is 1, and you cannot specify a value of 0.
- spec.replication.zones.topologyKey
- Defines zones in the form of a topology key that corresponds to a node label.
2.1.3. Recovering Loki pods from failed zones Copy linkLink copied to clipboard!
Manually delete Loki persistent volumes in failed zones to allow automatic rescheduling.
In OpenShift Container Platform a zone failure happens when specific availability zone resources become inaccessible. Availability zones are isolated areas within a cloud provider’s data center, aimed at enhancing redundancy and fault tolerance. If your OpenShift Container Platform cluster is not configured to handle this, a zone failure can lead to service or data loss.
Loki pods are part of a StatefulSet, and they come with Persistent Volume Claims (PVCs) provisioned by a StorageClass object. Each Loki pod and its PVCs reside in the same zone. When a zone failure occurs in a cluster, the StatefulSet controller automatically attempts to recover the affected pods in the failed zone.
The following procedure deletes the PVCs in the failed zone, and all data contained therein. To avoid complete data loss, the replication factor field of the LokiStack CR should always be set to a value greater than 1 to ensure that Loki is replicating.
Prerequisites
-
Verify your
LokiStackCR has a replication factor greater than 1. - Zone failure detected by the control plane, and nodes in the failed zone are marked by cloud provider integration.
The StatefulSet controller automatically attempts to reschedule pods in a failed zone. Because the associated PVCs are also in the failed zone, automatic rescheduling to a different zone does not work. You must manually delete the PVCs in the failed zone to allow successful re-creation of the stateful Loki Pod and its provisioned PVC in the new zone.
Procedure
List the pods in
Pendingstatus by running the following command:$ oc get pods --field-selector status.phase==Pending -n openshift-loggingExample
oc get podsoutputNAME READY STATUS RESTARTS AGE logging-loki-index-gateway-1 0/1 Pending 0 17m logging-loki-ingester-1 0/1 Pending 0 16m logging-loki-ruler-1 0/1 Pending 0 16m- STATUS
-
These pods are in
Pendingstatus because their corresponding PVCs are in the failed zone.
List the PVCs in
Pendingstatus by running the following command:$ oc get pvc -o=json -n openshift-logging | jq '.items[] | select(.status.phase == "Pending") | .metadata.name' -rExample
oc get pvcoutputstorage-logging-loki-index-gateway-1 storage-logging-loki-ingester-1 wal-logging-loki-ingester-1 storage-logging-loki-ruler-1 wal-logging-loki-ruler-1Delete the PVC(s) for a pod by running the following command:
$ oc delete pvc <pvc_name> -n openshift-loggingDelete the pod(s) by running the following command:
$ oc delete pod <pod_name> -n openshift-loggingOnce these objects have been successfully deleted, they should automatically be rescheduled in an available zone.
Troubleshooting
If PVCs hang in the terminating state without being deleted, PVC metadata finalizers might be set to kubernetes.io/pv-protection. Remove the finalizer for each PVC by running the following command, then retry deletion:
$ oc patch pvc <pvc_name> -p '{"metadata":{"finalizers":null}}' -n openshift-logging