wiki(ingest): vds-kzntsv network-stack mismatch RCA + ifupdown anti-pattern
Incident 2026-05-28 ~05:45–13:52 MSK на vds-kzntsv. ~2.5ч активного outage + ~5.5ч на эфемерной статике до окончательного fix хостером. Revised RCA: наш netplan+systemd-networkd конфликтовал с provider's expected ifupdown stack. Их start/ipadd procedure ожидает чистый ifupdown и не может auto-recover когда networkd «держит» eth0. 8 дней работало потому что networkd сам тянул DHCP. Когда что-то на стороне Rusonyx разорвало DHCP-binding — auto-recovery не сработала. Fix: systemctl mask netplan + systemd-networkd* (на running system без stop — IP и SSH сохранились), Rusonyx ребутнул VM и положил чистый /etc/network/interfaces.d/ifcfg-eth0 через свой start/ipadd. Netmask /18, gw 89.253.192.1, чистый ifupdown. Wiki: - NEW concepts/vds-kzntsv-dhcp-outage-2026-05-28 — full RCA + recovery runbook (эфемерная статика + permanent-fix via ifupdown) + diagnostic dot-graph + revised lessons-learned + anti-pattern - NEW sources/vds-kzntsv-incident-2026-05-28 — timeline 05:25 backup OK → 08:43 statics → 13:52 final reset; provider's ifcfg-eth0 content; ticket text reference - UPDATE entities/vds-kzntsv — mask /18, ifupdown stack, kernel cmdline net.ifnames=0 объясняет eth0 naming, hypervisor hw80, pass-store путь, Known issues § - UPDATE concepts/rusonyx-vps-onboarding-quirks — quirk #9 переписан про /18 layout + canonical ifcfg, quirk #10 NEW про ifupdown vs netplan stack choice + bootstrap mask commands - UPDATE index.md + log.md Tasks: - STATUS header: incident RESOLVED summary - NEXT_SESSION: следующая сессия — cleanup netplan-artifacts (optional), registry GC (~20G pending), board-viewer-build unhealthy разбор Memory (out-of-repo): vds-kzntsv-rusonyx-network-recovery переписан с revised RCA — canonical bootstrap step «mask netplan/networkd» для всех Rusonyx Ubuntu VDS. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,58 +1,72 @@
|
||||
---
|
||||
_last_updated_: 2026-05-26T22:00:00+03:00
|
||||
session_id: 2026-05-26-tenant-scheduler-seller-pinning
|
||||
_last_updated_: 2026-05-28T14:15:00+03:00
|
||||
session_id: 2026-05-28-vds-kzntsv-network-stack-mismatch
|
||||
---
|
||||
|
||||
# Next session handoff
|
||||
|
||||
## Recent commits
|
||||
## Контекст сессии
|
||||
|
||||
- `victor/books d1054bd` — wiki(ingest): tenant-scheduler-seller-pinning + task-runner auto-deploy
|
||||
- `victor/books 81e0f29` — ci(deploy): task-runner добавлен в auto-deploy matrix (+ secret PORTAINER_STACK_ID_BOOKVA_TASK_RUNNER=48)
|
||||
- `victor/books 519d8dc` — feat(tenant-split): tasks.json per-tenant defaults + Group C idSeller filter (job-scheduler 1.6.0, task-runner 0.4.0, tasks 0.1.0)
|
||||
- `victor/slovo-overlay f8b7bc5` — scheduler tasks.json template (slovo=2) + mount-path fix /app→/usr/src/app
|
||||
- `victor/bookva-overlay c49afd7` — scheduler tasks.json template (bookva=1)
|
||||
vds-kzntsv (89.253.255.94) был недоступен по сети ~05:45–08:30 MSK 28 мая 2026 (~2.5ч активного outage). С 08:43 жил на эфемерной статике (через VNC) до окончательного fix хостером в **13:52 MSK** — они переписали конфиг через свой `start/ipadd` procedure, мы предварительно masked netplan + systemd-networkd через SSH.
|
||||
|
||||
## Что сделано / LIVE сейчас
|
||||
**Revised RCA** (после resolution): наш сетевой стек был mixed (netplan+networkd поверх provider's expected ifupdown). 8 дней работало потому что networkd сам получал DHCP. Когда что-то на стороне Rusonyx разорвало DHCP-binding (28.05 утром) — их auto-recovery `start/ipadd` не смогла применить static config, потому что networkd «держал» eth0. Fix = mask netplan/networkd, оставить только ifupdown.
|
||||
|
||||
Scheduler seller-pinning **выкачен на оба tenant'а**, verified в живых контейнерах:
|
||||
- 16 джоб запинены: slovo `idSeller=2`/`salesChannels=[2]`, bookva `idSeller=1`/`[1]`. Zero cross-tenant leakage (проверено node-скриптом в обоих job-scheduler контейнерах).
|
||||
- Group C code-патчи (idSeller-фильтр в 4 handler'ах) + удалены 3 latent-бага: hardcoded `idSeller:1` (loadSellersPrices), `salesChannels:[1]` (load-products-to-ozon), cross-seller хардкод (withdrawProductsFromSale). 13/13 тестов green.
|
||||
- Все 4 контейнера (`books-job-scheduler`, `books-task-runner`, `bookva-scheduler`, `bookva-task-runner`) на `master-519d8dc`+, healthy.
|
||||
- task-runner теперь в auto-deploy pipeline — будущие code-changes раскатываются без ручных шагов. Деталь: slovo tr бандлен в job-scheduler стек, bookva tr = отдельный Portainer-стек 48.
|
||||
- Wiki: concept [tenant-scheduler-seller-pinning] + source ingested в books/.wiki.
|
||||
## LIVE сейчас
|
||||
|
||||
bookva volume tasks.json залит (md5-verified), backup на VDS `/tmp/bookva-tasks-live-backup-20260526-212259.json`.
|
||||
- **vds-kzntsv** работает на чистом ifupdown stack: `/etc/network/interfaces.d/ifcfg-eth0` (provider-managed), netmask **/18** (`255.255.192.0`), gw `89.253.192.1`. `netplan` + `systemd-networkd*` masked.
|
||||
- **24 docker контейнера up** включая весь стек (gitea, registry, verdaccio, postgres, mariadb, mongo, redis, owncloud/oCIS, modulair-rag×4, mssql, board-viewer, traefik, portainer, ntfy, vds-ops-mcp, vds-docker-proxy-ro). **1 unhealthy** — `board-viewer-build` (предсуществующий, не связан с инцидентом).
|
||||
- **Диск 79%** (118G/158G) — после quick GC сегодня утром (build cache 10.6G + dangling 0.3G + container logs ~3G truncated). Registry GC ~20G storage **не сделан** — pending.
|
||||
- **Wiki, memory, STATUS** — обновлены с финальным RCA. Commit за сессию pending (см. ниже).
|
||||
|
||||
## Открытые треки
|
||||
## Что делать на следующей сессии (по приоритету)
|
||||
|
||||
| Трек | Готовность | Entry-point |
|
||||
|---|---|---|
|
||||
| **slovo-overlay deploy НЕ активен** ⚪ | slovo сейчас работает на **legacy** bundled compose (`books-job-scheduler` стек = mongo+proxy+task-runner+scheduler в одном, bind-mount только `default.json`). slovo-overlay `deploy/*.compose.yml` (named volumes, mount-path fix) — **подготовлены, но не задеплоены**. Миграция = отдельная таска (parity audit с bookva). | `slovo-overlay/deploy/` |
|
||||
| **docs-commit → лишний redeploy** ⚪ | `.wiki/`-only push триггерит build→skip→deploy.yml workflow_run→полный redeploy (idempotent, но шумно). Можно добавить `.wiki/`+`docs/` в skip-pattern detect-changes в build.yml, либо guard в deploy workflow_run. | `books/.gitea/workflows/build.yml` |
|
||||
| **bookva compose без DEPLOY_AT** ⚪ | bookva-overlay compose используют `${CORE_SHA}` → recreate только при смене digest (не force). slovo использует `__TAG__`+`__DEPLOY_AT__`. Для re-deploy того же тега bookva не пересоздаётся. Норма для нашего flow (новый код = новый digest), но асимметрия. | `bookva-overlay/deploy/*.compose.yml` |
|
||||
| `books-api-shutdown` (из прошлой сессии) | soak с bookva LIVE — проверить всё ещё ли books-api нужен для slovo fallback. | TBD |
|
||||
| `bookva-ozon-credentials-audit` ⚪ (user-deferred) | bookva ozonSeller.clientId = slovo's (cp-a). Финансовый риск. User: «сам подумаю». | TBD |
|
||||
| `bookva-mongo-cleanup` ⚪ (user-deferred) | 2817 agendaJobs из cp-a. User: «не трогай не стирай». | TBD |
|
||||
### 1. Cleanup netplan-artifacts (опционально, низкий приоритет)
|
||||
|
||||
После resolution на сервере остались netplan конфиги (не активны, netplan masked, но лежат):
|
||||
|
||||
- `/etc/netplan/01-eth0.yaml` — мы создали 28.05 утром при попытке fix через netplan
|
||||
- `/etc/netplan/50-cloud-init.yaml` — от cloud-init
|
||||
- `/etc/cloud/cloud.cfg.d/99-disable-network-config.cfg` — мы создали (с опечаткой `disbaled` в одной из попыток, потом исправили)
|
||||
|
||||
Можно удалить или оставить — они не влияют (netplan masked). **Если** соберёмся когда-нибудь снять mask с netplan — следует тогда clean up. Сейчас не трогаем.
|
||||
|
||||
### 2. Registry GC (~20G storage reclaim — pending)
|
||||
|
||||
Из task #2 в TaskList. Окно read-only=true на 5-15 мин. **Делать только в low-traffic окно** — registry push/pull временно недоступен.
|
||||
|
||||
```bash
|
||||
# на VDS
|
||||
sudo docker exec registry registry garbage-collect --delete-untagged=true /etc/docker/registry/config.yml
|
||||
# проверка размера до/после
|
||||
sudo du -sh /opt/stacks/registry
|
||||
```
|
||||
|
||||
### 3. board-viewer-build unhealthy — разбор
|
||||
|
||||
Предсуществующий, не связан с инцидентом. Если беспокоит — `sudo docker logs board-viewer-build | tail -50` + проверить healthcheck в compose. Иначе можно `--no-healthcheck` если он не нужен в running container.
|
||||
|
||||
### 4. SLA / RCA от Rusonyx — follow up (опционально)
|
||||
|
||||
В первом нашем тикете запрашивали технический RCA + SLA-компенсацию. User просил это не муссировать. На усмотрение — можно через несколько дней спросить «приходил ли формальный RCA», но force'ить не нужно.
|
||||
|
||||
## Спроси user'а
|
||||
|
||||
- **slovo→slovo-overlay миграция** — мигрировать slovo на slovo-overlay deploy (named volumes, как bookva) или оставить legacy bundled compose? Сейчас работает, но parity нарушен (mount-path fix в репо не применён к live).
|
||||
- **docs-redeploy guard** — фиксить пайплайн чтобы `.wiki/`-коммиты не триггерили redeploy?
|
||||
- **withdrawProductsFromSale** — была cross-seller логика (snять seller2 если seller1 снял тот же offer_id). Я её удалил (single-seller). Если бизнес-смысл cross-coordination всё ещё нужен между Ozon-аккаунтами — пересмотреть.
|
||||
- **Registry GC** — окно ~5-15 мин в read-only=true, делать ночью или сейчас?
|
||||
- **Cleanup netplan artifacts** — оставить как есть или зачистить `/etc/netplan/*`? (Low-priority)
|
||||
- **Push wiki + memory + tasks** — push'нуть commit'нутые изменения в origin? (Per project-discipline нужен per-session grant, пока не давал)
|
||||
|
||||
## Не делать (preemptive guards)
|
||||
|
||||
- **Не stop** `bookva-*` / `books-*` контейнеры (`db,mongo,es,minio,api,web,scheduler,task-runner,ntfy`) — production на bookseller.kzntsv.site + slovo URL.
|
||||
- **Не push без grant в next session** — auto-push был session-only (этот session был grant'нут).
|
||||
- **task-runner для bookva** — теперь авто-деплоится (стек 48). НЕ нужно руками. Но если меняешь bookva-task-runner стек руками — помни что pipeline его перезапишет.
|
||||
- **bookva-mongo agendaJobs 2817 docs** — user explicit «не трогай не стирай».
|
||||
- **Не trust деплой «успех» без smoke** — bookva compose без DEPLOY_AT может не пересоздать контейнер при том же digest; проверяй APP_VERSION/uptime после деплоя.
|
||||
- **НЕ unmask netplan/systemd-networkd** на vds-kzntsv. Anti-pattern для Rusonyx (см. concept).
|
||||
- **НЕ редактировать `/etc/network/interfaces` или `/etc/network/interfaces.d/ifcfg-eth0`** — provider's start/ipadd procedure перезапишет при любых их manipulations с VM (resize, network reset).
|
||||
- **НЕ reboot VDS без необходимости** — конфиг теперь правильный, но любой их network-action может что-то поменять, и проверить новое состояние придётся через VNC.
|
||||
- **НЕ делать registry GC без `read-only=true` mode** — rogue push может corrupt'ить blobs.
|
||||
|
||||
## Memory updates за сессию
|
||||
|
||||
- **idSeller == idSalesChannel** маппинг (канон): bookva=1, slovo=2. User-fixed, без проверки БД.
|
||||
- Deploy-механика: slovo job-scheduler чит tasks.json из **image built-in** (bind только default.json), bookva — из **named volume** (shadow'ит image).
|
||||
- `deploy.yml` auto-deploy покрывает api/web/task-runner/job-scheduler (task-runner добавлен 2026-05-26). slovo tr бандлен в scheduler-стек, bookva tr отдельный стек 48.
|
||||
- books CI build path-filter: `tasks.json` триггерит web+scheduler ребилд; `packages/tasks` или `packages/task-runner` → task-runner ребилд.
|
||||
- Креды: `pass books-vds/full-env` (SSH key `id_ed25519_books_ops`, Portainer URL+key), `pass gitea/admin-token` (Gitea API).
|
||||
- **UPDATE** `vds-kzntsv-rusonyx-network-recovery.md` — переписан с revised RCA: provider stack = ifupdown, netmask /18, canonical bootstrap-step `mask netplan/networkd`. Anti-pattern: netplan на Rusonyx.
|
||||
- **Уточнение паттерна:** при сетевых проблемах на Rusonyx VDS первым делом проверять что стек = ifupdown (не netplan). `systemctl is-enabled netplan systemd-networkd networking` — должно быть `masked masked enabled`.
|
||||
|
||||
## Recent commits
|
||||
|
||||
- (pending — этот сеанс ещё не commit'ил; wiki + memory + STATUS + NEXT_SESSION готовы к одному commit'у).
|
||||
|
||||
Reference in New Issue
Block a user