Orca ORCA v0.174.2
Documentation navigation

Loki PVC Near Full

Runbook for a Loki PVC approaching full. For the generic PVC near-full runbook (expansion procedure, StatefulSet volumeClaimTemplate convergence), see 04-storage/04-pvc-near-full.md. This runbook is the Loki-specific overlay: the failure mode (log ingestion halts) and the scoped PVC regex (.+-loki-.*) differ. The Loki PVC name (storage-*-loki-N) does not match the Mimir ingester regex (.**mimir-ingester.*), so without this dedicated rule a filling Loki volume would go unnoticed.

Meaning

Loki (SingleBinary deployment) keeps its chunks + index on its own filesystem PVC, separate from the Mimir blocks storage. A full disk halts log ingestion — Loki cannot write new chunks or index entries. kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytes (scraped from the kubelet by synapse-client) is the PVC utilisation; > 0.8 for 10m is the warning tier; > 0.9 for 5m is the critical tier (imminent ingestion halt).

Retention gotcha: compactor.retention_period alone does not delete data — compactor.retention_enabled must also be true. A cluster with retention_period set but retention_enabled: false fills up forever.

The metrics are already in the synapse-client kubelet allow-list — no chart PR is needed.

What changed from the chart

  • All environments — the chart alert had no environment filter. Kept as-is. The {{ $labels.environment }} is in the summary/description.
  • Two tiers, one runbook — the warning tier (80%) is this runbook's alert. The critical tier (90%) is the same expr with > 0.9 and severity: critical.

Impact

  • Log ingestion halts when the disk fills — no new logs are ingested, so Loki queries return data only up to the fill point.
  • Dashboards and alerts that rely on Loki (LogQL alerts, error-log panels) go blind.
  • If the disk fills completely, Loki may crash or refuse to start on restart (cannot write to the index).

Diagnosis

The alert labels carry k8s_cluster_name, environment, namespace, persistentvolumeclaim. From the alert, note all of them.

1. Confirm the utilisation and identify the Loki pod

export KUBECONFIG=~/.kube/<cluster>.yaml   # e.g. prd-par01.yaml
kubectl -n <namespace> get pvc <persistentvolumeclaim> -o wide
kubectl -n <namespace> get pod -o wide | grep loki

Confirm via Mimir (port-forward synapse-server-mimir-gateway, header X-Scope-OrgID: corti):

QUERY='kubelet_volume_stats_used_bytes{persistentvolumeclaim="<persistentvolumeclaim>"} / kubelet_volume_stats_capacity_bytes{persistentvolumeclaim="<persistentvolumeclaim>"}'
curl -s -G -H "X-Scope-OrgID: corti" "http://localhost:9090/prometheus/api/v1/query" --data-urlencode "query=$QUERY" | jq -r '.data.result[0].value[1]'

2. Check whether retention is enabled

kubectl -n <namespace> get configmap -l app.kubernetes.io/name=loki -o yaml | grep -E 'retention_enabled|retention_period'

If retention_enabled is false or absent, retention is not deleting anything — that is likely why the disk is filling.

Mitigation

Step 1 — Activate PIM

Activate the required Azure Privileged Identity Management roles before touching production (MultiTenantEuOnlyAccessPimRoles / DevOpsPimRoles / Platform Team (privileged)), as in 03-kafka/01-consumer-lag.md.

Step 2 — Enable retention (the durable fix)

If compactor.retention_enabled is false, enable it and set a retention_period in the synapse-server chart / deployments overlay. This is a GitOps change — the Loki config is a ConfigMap rendered from chart values. The compactor starts deleting chunks older than the retention period on its next run.

Step 3 — Expand the PVC

Follow 04-storage/04-pvc-near-full.md Mitigation step 3 for the full procedure — the Loki PVC is a volumeClaimTemplate on the Loki StatefulSet, so the zero-downtime orphan-delete + ArgoCD sync convergence applies:

# 1. Capacity fix (urgent, online)
kubectl -n <namespace> patch pvc <persistentvolumeclaim> --patch '{"spec":{"resources":{"requests":{"storage":"<new-size>Gi"}}}}'

# 2. GitOps convergence — edit the synapse-server chart values to match, merge, then:
kubectl -n <namespace> delete sts <statefulset> --cascade=orphan

Step 4 — Trim retention (reversible)

If expanding is not immediately possible, shorten the retention_period so the compactor deletes more data. This reduces the window of queryable logs but frees space.

Verify

  • The alert clears once used / capacity <= 0.8 sustained for the for: 10m window.
  • kubectl -n <namespace> get pvc <persistentvolumeclaim> shows the updated Capacity.
  • The compactor is running and deleting: loki_compactor_runs_total is increasing.

Notes

  • Metrics already collected — kubelet_volume_stats_* are in the synapse-client kubelet allow-list. No chart PR required.
  • Retention gotcha — retention_period alone does not delete; retention_enabled: true must also be set. This is the most common cause of a filling Loki PVC.
  • Two tiers, one runbook — warning (80%) is this alert; critical (90%) is the same expr with > 0.9.
  • See also — 04-storage/04-pvc-near-full.md (generic PVC expansion), 06-mimir-ingester-pvc-near-full.md (Mimir ingester PVC — separate regex, separate failure mode).