Ops / Security / Observability Audit — SoccerPredictAI¶
Date: 2026-04-24
Auditor: GitHub Copilot (Claude Sonnet 4.6)
Scope: K8s deployment, secrets, CORS, HA, Prometheus, Grafana, drift monitoring
Method: анализ k8s/helm/ns_soccer-api/, src/app/main.py, src/app/metrics.py, src/monitoring/, src/app/config/security.py
1. Deployment и High Availability¶
1.1 Replicas¶
| Компонент | Replicas | SPOF |
|---|---|---|
| FastAPI | 1 | ✅ SPOF |
| Celery worker-api | 1 | ✅ SPOF |
| Celery worker-ml | 1 | ✅ SPOF |
| RabbitMQ | 1 | ✅ SPOF |
| Redis | 1 | ✅ SPOF |
| PostgreSQL | не в этом Helm chart | ? |
| MinIO | не в этом Helm chart | ? |
⚠️ P1: Все компоненты replicas=1. Любой pod failure → сервис недоступен. Нет настроенного кластеринга для RabbitMQ или Redis.
1.2 Autoscaling¶
HPA템플릿 существует (hpa.yaml: CPU 70%, Memory 80%), но отключён в values.yaml.
⚠️ P2: Autoscaling определён в шаблонах, но не включён.
1.3 Resource limits¶
| Компонент | Requests | Limits |
|---|---|---|
| FastAPI | 256Mi / 100m | 1Gi / 500m |
| Celery-ML | 256Mi / 100m | 2Gi / 500m |
| Celery-API | 256Mi / 100m | 1Gi / 500m |
| RabbitMQ | — | 1Gi storage |
| Redis | — | 1Gi storage |
✅ Limits определены. ML worker получает 2Gi — достаточно для sklearn модели.
1.4 Probes¶
# FastAPI:
livenessProbe:
httpGet: /healthcheck/
initialDelaySeconds: 45
periodSeconds: 10
readinessProbe:
httpGet: /healthcheck/
initialDelaySeconds: 10
periodSeconds: 5
✅ liveness и readiness probes настроены для FastAPI.
⚠️ P2: Celery workers используют тот же же deployment.yaml — нужно проверить, используют ли они celery inspect ping или аналог как liveness probe (типичная проблема).
1.5 Storage¶
PVC для RabbitMQ и Redis: storageClassName: manual — предполагает наличие HostPath persistent volume. На single-node окружении это приемлемо, но неустойчиво при миграции.
2. Security Audit¶
2.1 API Authentication¶
| Endpoint group | Аутентификация | Метод |
|---|---|---|
/sources/* (scraping, export) |
✅ X-Token header | FASTAPI_HEADER_TOKEN |
/predict/* |
❌ нет | — |
/monitoring/* |
❌ нет | — |
/livescores/ |
❌ нет | — |
/healthcheck/ |
❌ нет | Открытый по замыслу |
/metrics (Prometheus) |
❌ нет | Открытый по замыслу |
⚠️ P1: Prediction endpoints не защищены аутентификацией.
⚠️ P1: Monitoring endpoints (/monitoring/celery/*) открыты — раскрывают внутреннюю топологию Celery.
2.2 CORS¶
⚠️ P1: CORS allow_origins=["*"] — принимает запросы с любого домена. Уместно только для публичного read-only API.
2.3 Secrets Management¶
| Аспект | Статус |
|---|---|
| SOPS + age шифрование | ✅ values-dev.enc.yaml |
| Секреты не в открытом git | ✅ |
values.yaml — только заглушки (пустые строки) |
✅ |
| Токены через env vars / pydantic-settings | ✅ |
.env файлы — через pydantic BaseSettings |
✅ |
✅ Secrets management корректен — SOPS для K8s, pydantic-settings для приложения.
2.4 Token передача в UI¶
⚠️ P2: Token как query param попадает в access logs, browser history, server-side request logs.
3. Observability¶
3.1 Prometheus Metrics¶
| Метрика | Тип | Реализована |
|---|---|---|
request_count |
Counter | ✅ |
request_latency_seconds |
Histogram | ✅ |
prediction_count |
Counter | ✅ |
prediction_timeouts_total |
Counter | ✅ |
prediction_latency_seconds |
Histogram | ✅ |
inference_latency_seconds |
Histogram | ✅ |
prediction_confidence |
Histogram (per outcome) | ✅ |
model_info |
Gauge | ✅ |
✅ Хорошее покрытие метриками. Inference latency измеряется отдельно от prediction latency.
3.2 Prometheus scrape endpoints¶
| Endpoint | Port | Notes |
|---|---|---|
/metrics |
8000 | FastAPI (PrometheusMiddleware) |
:9091/metrics |
9091 | Celery ML worker (отдельный HTTP server) |
✅ Prometheus scrape настроен для обоих компонентов.
3.3 Grafana¶
⚠️ P1 (Planned, Not Implemented): Grafana не задеплоена. Прометей метрики собираются, но нет дашбордов.
3.4 Drift Monitoring¶
| Аспект | Статус |
|---|---|
src/monitoring/ директория |
Пустая |
| Evidently интеграция | ❌ Не реализовано |
| Feature drift detection | ❌ Не реализовано |
| Prediction confidence tracking | ✅ Метрика есть, но нет alerting |
⚠️ P1 (Planned, Not Implemented): src/monitoring/ пуст. Drift detection не реализован.
3.5 Logging¶
✅ logging (не print) во всех production модулях — соответствует стандартам.
4. Findings¶
| ID | Severity | Описание |
|---|---|---|
| OPS-01 | P1 | Все компоненты replicas=1 — нет HA, любой pod failure ведёт к downtime |
| OPS-02 | P1 | /predict/* и /monitoring/* endpoints не защищены аутентификацией |
| OPS-03 | P1 | CORS allow_origins=["*"] — принимает запросы с любого домена |
| OPS-04 | P1 | Grafana не задеплоена — Prometheus метрики собираются, но нет дашбордов |
| OPS-05 | P1 | src/monitoring/ пуст — drift detection не реализован |
| OPS-06 | P2 | FastAPI autoscaling HPA определён, но отключён (enabled: false) |
| OPS-07 | P2 | Celery worker liveness probe — нужно проверить, есть ли celery inspect ping probe |
| OPS-08 | P2 | storageClassName: manual (HostPath) для RabbitMQ/Redis PVC — непереносимо |