Ctrl K
ComunidadGuías…

MONITORING_FIX.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Monitoring Stack Fix

## Issues Identified

1. **Memory Quota Exceeded**: Alloy and Grafana pods cannot start due to `monitoring-quota` having only 512Mi memory limit
2. **Quota Ownership Conflict**: The quota is owned by `ai-alloy` app but should be owned by `mimir` app
3. **Loki Template Error**: Missing `bucketNames` at the correct level in storage config
4. **Incorrect Sync Wave Order**: Alloy (collector) was deploying before Mimir/Loki (storage backends)

## Current State

```bash
# Current quota (WRONG - too low)
requests.memory: 512Mi
used: 370Mi (alloy 256Mi + tempo 64Mi + overhead)

# Desired quota (from mimir config)
requests.memory: 8Gi
```

## Root Cause Analysis

### Sync Wave Anti-Pattern (FIXED)
**Before:**
- Wave -2: Alloy (collector) ❌
- Wave -1: Mimir, Loki, Tempo (storage) ❌

**Problem:** Alloy deployed first and created the namespace with a 512Mi quota, preventing Mimir's correct 8Gi quota from being applied.

**After (CORRECT):**
- Wave -2: Mimir, Loki, Tempo (storage backends with quota) ✅
- Wave -1: Alloy (collector) ✅
- Wave 0: Grafana (visualization) ✅

### Why This Order Matters

1. **Storage backends must exist before collectors** - Alloy needs Mimir and Loki endpoints to send data to
2. **Namespace infrastructure (quotas) should deploy with the first app** - Mimir now creates the namespace with correct quota
3. **Collectors depend on storage** - Alloy config references `mimir-nginx` and `loki-gateway` services

This follows the standard monitoring architecture pattern:
```
Infrastructure (quotas/limits) → Storage (Mimir/Loki/Tempo) → Collection (Alloy) → Visualization (Grafana)
```

## Fixes Applied

### 1. ✅ Loki Storage Configuration Fixed
Moved `bucketNames` from under `s3` to the `storage` level to match Loki chart expectations.

### 2. ✅ Sync Wave Order Corrected
- Mimir: -1 → -2 (storage backend, creates namespace with correct quota)
- Loki: -1 → -2 (storage backend)
- Tempo: -1 → -2 (storage backend)
- Alloy: -2 → -1 (collector, now deploys after storage)
- Grafana: 0 (unchanged, visualization layer)

### 3. ⚠️ Quota Ownership Transfer Required (Manual Step)

The monitoring quota is currently tracked by ArgoCD as belonging to the `alloy` application:
```
argocd.argoproj.io/tracking-id: ai-alloy:/ResourceQuota:monitoring/monitoring-quota
```

But it's defined in the `mimir` application's `extraObjects` with the correct 8Gi limit.

## Manual Steps Required

### Recommended Approach: Clean Slate Deployment

Since the sync wave order has been corrected, the cleanest approach is to delete and redeploy in the correct order:

```bash
# 1. Delete the old quota (owned by alloy)
kubectl delete resourcequota monitoring-quota -n monitoring

# 2. Sync in the correct order (storage backends first)
argocd app sync mimir    # Wave -2: Creates namespace with correct 8Gi quota
argocd app sync loki     # Wave -2: Storage backend
argocd app sync tempo    # Wave -2: Storage backend

# 3. Wait for storage backends to be healthy
argocd app wait mimir --health
argocd app wait loki --health
argocd app wait tempo --health

# 4. Now sync the collector (depends on storage)
argocd app sync alloy    # Wave -1: Collector

# 5. Finally sync visualization
argocd app sync grafana  # Wave 0: Visualization

# 6. Verify the new quota
kubectl get resourcequota monitoring-quota -n monitoring -o yaml | grep -A 10 "spec:"
# Should show: requests.memory: 8Gi
```

### Alternative: Patch Existing Quota (If You Can't Redeploy)

### Alternative: Patch Existing Quota (If You Can't Redeploy)

```bash
# 1. Patch the quota to increase memory limit
kubectl patch resourcequota monitoring-quota -n monitoring --type=merge -p '
{
  "spec": {
    "hard": {
      "requests.cpu": "4",
      "requests.memory": "8Gi",
      "limits.cpu": "16",
      "limits.memory": "24Gi",
      "count/pods": "40"
    }
  }
}'

# 2. Update the tracking annotation to point to mimir
kubectl annotate resourcequota monitoring-quota -n monitoring \
  argocd.argoproj.io/tracking-id=mimir:/ResourceQuota:monitoring/monitoring-quota \
  --overwrite

# 3. Sync applications (they will now respect the new sync wave order)
argocd app sync mimir loki tempo alloy grafana
```

## Verification

After applying the fix, verify all pods are running:

```bash
# Check quota usage
kubectl get resourcequota monitoring-quota -n monitoring

# Expected output should show:
# requests.memory: 370Mi/8Gi (plenty of headroom)

# Check all monitoring pods
kubectl get pods -n monitoring

# All pods should be Running:
# - alloy-* (DaemonSet - one per node)
# - grafana-*
# - loki-*
# - mimir-*
# - tempo-*
```

## Root Cause

The issue occurred because of an **anti-pattern in sync wave ordering**:

1. **Alloy deployed first** (sync-wave -2) before storage backends
2. **Alloy created the namespace** and somehow a 512Mi quota was applied (possibly from an old config or default)
3. **Mimir deployed second** (sync-wave -1) but couldn't update the existing quota
4. **Mimir's correct 8Gi quota definition was ignored** because the resource already existed

### Why the Original Order Was Wrong

```
❌ WRONG: Collector → Storage
- Alloy (collector) at wave -2
- Mimir/Loki/Tempo (storage) at wave -1
- Problem: Collector has nowhere to send data, creates namespace prematurely
```

```
✅ CORRECT: Storage → Collector
- Mimir/Loki/Tempo (storage) at wave -2
- Alloy (collector) at wave -1
- Benefit: Storage backends exist with correct quota, collector can immediately send data
```

This follows the fundamental monitoring architecture principle:
**Infrastructure → Storage → Collection → Visualization**

## Prevention

1. ✅ **Sync wave order corrected** - Storage backends now deploy before collectors
2. ✅ **Quota ownership clarified** - Only Mimir defines the monitoring-quota
3. ✅ **Loki storage config fixed** - Template will now render correctly
4. 📝 **Document the pattern** - Storage must always precede collection in monitoring stacks