Skip to content
Monitoring

Monitoring

Prometheus Metrics

MetricTypeLabelsDescription
drop_images_cached_totalCounterimage, nodeTotal images successfully cached
drop_pull_duration_secondsHistogramimageDuration of pull operations
drop_pull_errors_totalCounterimage, nodeTotal failed pull attempts
drop_discovery_images_foundGaugepolicy, source_typeImages found per discovery source
drop_active_pullsGaugeCurrently active pull Pods
drop_reconcile_totalCountercontroller, resultReconciliation attempts

Enable ServiceMonitor

helm install drop oci://ghcr.io/corewire/charts/drop \
  --set serviceMonitor.enabled=true

Example Queries

# Pull rate by image (success/min)
sum by (image) (rate(drop_images_cached_total[5m])) * 60

# Pull duration percentiles per image
histogram_quantile(0.50, sum by (le, image) (rate(drop_pull_duration_seconds_bucket[30m])))
histogram_quantile(0.90, sum by (le, image) (rate(drop_pull_duration_seconds_bucket[30m])))
histogram_quantile(0.95, sum by (le, image) (rate(drop_pull_duration_seconds_bucket[30m])))

# Images with p90 pull time > 30s (slow images worth caching)
histogram_quantile(0.90, sum by (le, image) (rate(drop_pull_duration_seconds_bucket[1h]))) > 30

# Pull success ratio (0–1)
sum(rate(drop_images_cached_total[5m])) /
  (sum(rate(drop_images_cached_total[5m])) + sum(rate(drop_pull_errors_total[5m])))

# Cache coverage per CachedImage (nodes cached / nodes targeted)
sum by (cachedimage) (drop_nodes_cached)
  / sum by (cachedimage) (drop_nodes_targeted)

# Nodes with incomplete coverage
sum by (cachedimage) (drop_nodes_targeted - drop_nodes_cached) > 0

# Active pulls right now
drop_active_pulls

# Discovery source health
drop_discovery_source_health

Kubernetes Events

ReasonTypeDescription
PullStartedNormalImage pull Pod created on a node
PullSucceededNormalImage successfully cached on a node
PullFailedWarningImage pull failed on a node
kubectl get events --field-selector involvedObject.kind=CachedImage

Loki Queries

eventPullTime signals read Kubernetes pull events from Loki. These LogQL queries let you explore the same raw data the operator uses for discovery.

# All Pulled events (the source for eventPullTime signals)
{job="kubernetes-events"} | json | reason = "Pulled"

# All Pulling events (in-progress pulls)
{job="kubernetes-events"} | json | reason = "Pulling"

# Pull events in a specific namespace
{job="kubernetes-events", namespace="production"} | json | reason = "Pulled"

# Pulls for a specific image
{job="kubernetes-events"} | json | reason = "Pulled"
  | message =~ `"nginx:1.25`

# Slow pulls — duration string has 2+ digits before the decimal (≥10s)
{job="kubernetes-events"} | json | reason = "Pulled"
  | message =~ `in [1-9][0-9]+\.`

# Pull failures and backoffs
{job="kubernetes-events"} | json
  | reason =~ "Failed|BackOff"
  | involvedObject_kind = "Pod"

# Pull event rate by namespace (metric query)
sum by (namespace) (
  rate({job="kubernetes-events"} | json | reason = "Pulled" [5m])
)

Status Conditions

All resources use metav1.Condition with type Ready:

status:
  conditions:
    - type: Ready
      status: "True"
      reason: Cached
      message: "Image cached on all 5 target nodes"

Health Endpoints

EndpointPortDescription
/healthz8081Liveness probe
/readyz8081Readiness probe
Last updated on