Aller au contenu

Runbook : PolarisAPIExceptions

Alerte : PolarisAPIExceptions (PrometheusRule, severity critical)

Symptôme :

Apache Polaris (catalog Iceberg) retourne des exceptions sur > 2 % des requêtes. Les queries Trino, Spark et dbt qui écrivent/lisent des tables Iceberg échouent.

Severity : 🔴 critical — impact sur tout le data lakehouse


Diagnostic

1. État des pods Polaris

export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
kubectl get pod -n akko -l app.kubernetes.io/name=polaris
kubectl describe pod -n akko -l app.kubernetes.io/name=polaris | tail -30

2. Logs serveur

kubectl logs -n akko -l app.kubernetes.io/name=polaris --tail=200 | \
  grep -iE "error|exception|stack" | head -30

3. Endpoint de santé

kubectl port-forward -n akko svc/akko-polaris 8181:8181 &
curl -f http://localhost:8181/q/health
# Attendu : {"status": "UP"}

4. Backend PostgreSQL

kubectl exec -n akko akko-postgresql-0 -- \
  psql -U postgres -d polaris -c "SELECT count(*) FROM public.tables;"

5. Backend object storage

kubectl exec -n akko akko-minio-0 -- \
  mc ls local/akko-warehouse/ | head -10

Causes fréquentes + correctif

Cause Symptôme Correctif
Pool Postgres épuisé unable to acquire JDBC connection Bump quarkus.datasource.jdbc.max-size (défaut 20)
Credentials object storage expirés AccessDenied, InvalidAccessKeyId Régénérer les creds + kubectl rollout restart Polaris
Bucket object storage introuvable NoSuchBucket Recréer : mc mb local/akko-warehouse
Policy OPA bloquante 403 Forbidden, user not authorized Vérifier le bundle OPA : kubectl logs -n akko opa --tail=50
Namespace PII supprimé en plein query namespace not found Vérifier qu'un DROP NAMESPACE n'est pas en cours
Migration DB manquée column X does not exist Relancer le job polaris-init
JWT Keycloak mal validé 401 Unauthorized Vérifier quarkus.oidc.auth-server-url correct (L04)

Correctif d'urgence (< 5 min)

Rolling restart

kubectl rollout restart deploy/akko-polaris -n akko
kubectl rollout status deploy/akko-polaris -n akko --timeout=180s

Test Trino → Polaris end-to-end

kubectl exec -n akko deploy/akko-trino -- \
  trino --execute="SHOW SCHEMAS FROM iceberg"
# Doit retourner au moins : default, banking

Vérifier que object storage est writable

kubectl exec -n akko akko-minio-0 -- \
  mc cp /etc/hostname local/akko-warehouse/healthcheck.txt && \
  mc cat local/akko-warehouse/healthcheck.txt

Correctif pérenne (R02)

Augmenter le pool DB

# helm/akko/charts/akko-polaris/values.yaml
env:
  - name: QUARKUS_DATASOURCE_JDBC_MAX_SIZE
    value: "50"          # était 20
  - name: QUARKUS_DATASOURCE_JDBC_INITIAL_SIZE
    value: "5"

HA multi-replicas

Polaris est stateless (état en DB + object storage), donc scalable horizontalement :

replicaCount: 2
podDisruptionBudget:
  enabled: true
  minAvailable: 1

Monitoring de la cohabitation avec OPA

OPA peut bloquer silencieusement. Vérifier dans Dashboards le dashboard « OPA decisions » (ratio allow/deny par principal).


Prévention

  • PrometheusRule granulaire :
    - alert: PolarisDBPoolExhausted
      expr: hikaricp_pending_connections{pool="polaris"} > 5
      for: 2m
      severity: warning
    - alert: PolarisMinIOSlow
      expr: histogram_quantile(0.95, rate(polaris_minio_latency_seconds_bucket[5m])) > 1
      severity: warning
    
  • Smoke test hebdomadaire : CREATE TABLE → INSERT → SELECT → DROP depuis Trino
  • Backup DB polaris + object storage warehouse via le CronJob S8-D
  • Versioning du bundle OPA pour rollback rapide si une policy bloque

Lessons learned

  • Polaris + Keycloak backchannel-dynamic (L04) est critique en k3d ou lorsque le DNS pod-to-pod est différent du DNS utilisateur.
  • polaris-init doit être idempotent — voir l'architecture sidecar (R06).

Liens utiles