bcfb07f547
Чёткое разделение audiences:
- docs/ — consumer-facing only, Diplodoc-built. Public contract для
интеграторов (Альтум, BI, third-party).
- docs-internal/ — operator runbooks, status snapshots, legacy tech pages.
НЕ в Diplodoc build, НЕ публикуются.
Изменения:
- Move docs/{ops,status,tech} → docs-internal/{ops,status,tech}
- docs/toc.yaml: убраны секции Operations, Архитектура (legacy), Status
- docs/index.md: убран tab "оператор / on-call", focus на integrators
- docs/README.md: rewritten — scope только integrator guide, editorial
guidelines (no leak internal architecture, stable API contract)
- .yfm: убран явный ignore status/* (теперь не нужно — папка переехала)
- docs-internal/README.md: index для внутренней документации с rationale
разделения
Scrubbing implementation details из Diplodoc страниц:
- events.md: убраны Strimzi/cluster.142 references, OutboxPoller детали,
internal alert names (OrdinisOutboxLagHigh, OrdinisOutboxDLQNonEmpty),
metric names (nsi_outbox_*). Заменены на consumer-observable contract.
- webhooks.md: убраны metric names (nsi_webhook_ssrf_rejected_total),
alert table (OrdinisWebhookHighFailureRate и т.д.). Retry policy
переписана на user-side perspective.
- errors.md: убран alert name OrdinisReadApiErrorBudgetBurnFast, Tempo
endpoint URL, internal connection details.
- x-references.md: OrphanReferenceScanner → general "Ordinis периодически
детектирует". Убраны metric/alert names. Cascade roadmap без link на
internal design doc.
- auth.md: убран file path ScopeContext.java.
- bundle-cuod.md: убран Maven module path.
- caching.md: cascade design link заменён на text reference.
CI:
- .gitlab-ci.yml: новый job build-docs (stage: build) — Node 20 alpine,
pnpm install --frozen-lockfile + pnpm build, artifact docs/_dist на
неделю. Triggers: auto на docs/**, либо manual web. Готов к follow-up
pages-deploy job когда host решён.
- Новый pattern .docs-changes для rules.
Build verified clean: 13 HTML pages, 6.9M, no broken links/refs.
99 lines
4.9 KiB
Markdown
99 lines
4.9 KiB
Markdown
# Ordinis НСИ ЦУОД — Operator Runbook
|
||
|
||
Карточки процедур для on-call инженера. Каждая карточка self-contained: можно
|
||
открыть в момент инцидента и пройти по шагам без необходимости понимать всю
|
||
архитектуру.
|
||
|
||
## Indexed by symptom
|
||
|
||
| Симптом | Карточка |
|
||
|---------------------------------------------------------------|----------|
|
||
| Spring Boot pod'ы залипли в `Init:0/1` после reboot | [vault-unseal.md](vault-unseal.md) |
|
||
| Kafka pod не Running, либо `vault-agent` не достукивается | [kafka-restart.md](kafka-restart.md) |
|
||
| Метрика `ordinis_outbox_dlq_size > 0` | [outbox-dlq.md](outbox-dlq.md) |
|
||
| Pod в `CrashLoopBackOff` с liquibase ошибкой в логах | [db-migrations.md](db-migrations.md) |
|
||
| API возвращает 401 на любые запросы | См. §1 ниже |
|
||
| API возвращает 500 на конкретный endpoint | См. §2 ниже |
|
||
| Admin UI не загружается (502/503) | См. §3 ниже |
|
||
|
||
## 1. 401 Unauthorized
|
||
|
||
Сейчас на staging `ORDINIS_AUTH_REQUIRED=true`. Anonymous = 401. Проверить:
|
||
|
||
```bash
|
||
# 1. Header передан?
|
||
curl -v -H "Authorization: Bearer $TOKEN" ... | grep -i authorization
|
||
|
||
# 2. JWT валиден?
|
||
echo $TOKEN | cut -d. -f2 | base64 -d 2>/dev/null | jq
|
||
# проверить exp, iss, realm_access.roles
|
||
|
||
# 3. Issuer правильный?
|
||
# должен быть https://auth.nstart.space/realms/nstart
|
||
```
|
||
|
||
Если JWT прошёл проверку, но 401 — backend логи:
|
||
```bash
|
||
kubectl logs -n ordinis-staging deploy/ordinis-app -c app --tail=50 \
|
||
| grep -iE "jwt|invalid_token|expired"
|
||
```
|
||
|
||
Типичные причины:
|
||
- `Invalid signature` — Keycloak ротировал ключи, но бэкенд кэширует старый. Restart pod.
|
||
- `Token expired` — refresh token не сработал, юзер должен перелогиниться.
|
||
- `Issuer mismatch` — JWT issued другим Keycloak realm'ом.
|
||
|
||
## 2. 500 Internal Server Error на endpoint
|
||
|
||
```bash
|
||
# Найти trace_id из ответа
|
||
curl -i ... | grep -i traceid
|
||
# либо UI показывает traceId в alert
|
||
|
||
# Найти полный stack trace
|
||
kubectl logs -n ordinis-staging deploy/ordinis-app -c app --tail=200 \
|
||
| grep "<traceId>"
|
||
```
|
||
|
||
Типичные причины (в наших коммитах):
|
||
- `could not determine data type of parameter $N` — Hibernate JPQL с `IS NULL`
|
||
на nullable timestamp. Решение — sentinel value (см. fix audit search).
|
||
- `DataIntegrityViolationException dictionary_records_no_overlap` — bitemporal
|
||
exclusion constraint, период пересекается. Friendly 409 уже маппится — если
|
||
500 значит код-путь неуспел поймать.
|
||
- `JsonMappingException` — payload поломан (фронт передал stale schema).
|
||
|
||
## 3. Admin UI не загружается / 502 / 503
|
||
|
||
```bash
|
||
kubectl get pods -n ordinis-staging | grep admin-ui
|
||
```
|
||
|
||
| Status | Причина |
|
||
|-----------------------|---------|
|
||
| `ImagePullBackOff` | Тег image не существует в registry. Проверь `kubectl describe`. Восстановить: `kubectl set image deployment/ordinis-admin-ui ui=<registry>/ordinis-admin-ui:main -n ordinis-staging` |
|
||
| `CrashLoopBackOff` | nginx config invalid либо resolver недоступен. См. logs. |
|
||
| `Running 1/1`, но 502 | Upstream (writer/read-api) сам в дауне. Проверь те pod'ы. |
|
||
|
||
## 4. Что-то ещё — где смотреть
|
||
|
||
- **Pod state:** `kubectl get pods -n ordinis-staging`
|
||
- **Recent events:** `kubectl get events -n ordinis-staging --sort-by='.lastTimestamp' | tail -20`
|
||
- **Resource usage:** `kubectl top pod -n ordinis-staging`
|
||
- **Logs:** `kubectl logs -n ordinis-staging deploy/<name> -c app --tail=100`
|
||
- **Liveness/readiness probes:** `kubectl describe pod -n ordinis-staging <pod>`
|
||
- **Ingress:** `kubectl get ingress -n ordinis-staging`
|
||
- **Helm release:** `helm history ordinis -n ordinis-staging`
|
||
|
||
## 5. Эскалация
|
||
|
||
>30 мин downtime, не понятно куда копать → tech lead (zimin.an@nstart.space).
|
||
|
||
## 6. Связанные ресурсы
|
||
|
||
- API integration guide: [../integration/api/index.md](../integration/api/index.md) (Diplodoc, latest)
|
||
- Альтум integration: [../integration/altum-imaging-order.md](../integration/altum-imaging-order.md)
|
||
- Project state snapshots: см. `docs/status/*-state.md` в repo (исключены из Diplodoc build)
|
||
- Helm chart: `ordinis-infra/charts/ordinis/`
|
||
- Vault setup: `ordinis-infra/k8s/vault/setup.sh`
|