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'у).
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# Admin Task Board
|
||||
_Updated: 2026-05-28 — **vds-kzntsv network-stack mismatch RESOLVED** в 13:52 MSK. Сначала ~2.5ч активного outage (05:45-08:30) + ~5.5ч на эфемерной статике до окончательного fix хостером. Revised RCA: наш netplan+networkd поверх provider's expected ifupdown stack ломал их auto-recovery когда DHCP-binding разорвался на их стороне. Fix: `systemctl mask netplan systemd-networkd` (на running system, без stop — IP и SSH сохранились), Rusonyx ребутнули + положили чистый `/etc/network/interfaces.d/ifcfg-eth0` с /18 netmask через свой `start/ipadd` procedure. Все 24 docker контейнера up. Disk after GC: 79% (132G→118G/158G). Anti-pattern закреплён: НЕ использовать netplan на Rusonyx VDS. Wiki updated с revised RCA + permanent-fix runbook + 2 quirks (#9 /18 layout, #10 ifupdown vs netplan)._
|
||||
_Updated: 2026-05-27 — `modulair-rag-vds-redeploy` 🟢 **closed** в ту же сессию: 4-контейнерный стек развёрнут на VDS (Portainer stack 15), acceptance 6/6. Образы пересобраны на самом VDS (push 3.36GB через traefik с дома падал 499); env/entrypoint/minio-host скорректированы под VDS-реальность. 3 follow-up'а переданы в modulair-rag handoff._
|
||||
_Updated: 2026-05-27 — заведена `modulair-rag-vds-redeploy` ⚪ (handoff из modulair-rag session). NAS-loss redeploy 4 контейнеров на VDS. Блокер MinIO снят — verified up на VDS 2026-05-27. postgres `proxy`-network reachability подтверждён (`postgres:5432` резолвится из pipeline/mcp). Спека: modulair-rag concept `nas-loss-vds-redeploy-context` + compose.yml as-is._
|
||||
_Updated: 2026-05-27 (ночь, после re-open) — ops-mcp multi-tenant **activated** (stack 26 PUT + BOOKVA_MARIADB_PASSWORD env). Smoke verified: slovo/bookva DB queries возвращают tenant-specific data (АФО2 vs Ира warehouses), bookva agendaJobs count=2818. Один host-level books-ops-mcp видит обе tenant DBs._
|
||||
|
||||
@@ -81,6 +81,84 @@ OpenSSH for Windows **не имеет** `-pw` flag (как `plink`/PuTTY) или
|
||||
|
||||
См. также: support-ticket draft в [`vds-kzntsv-bootstrap-2026-05-20`](../sources/vds-kzntsv-bootstrap-2026-05-20.md) с конкретными suggestions для Rusonyx.
|
||||
|
||||
## 9. Сеть = /18, не /24. Gw в той же subnet
|
||||
|
||||
Rusonyx прописывает VM в **/18** (`netmask 255.255.192.0`), не в /24. Адреса `89.253.192.0 – 89.253.255.255` — это один большой L2 broadcast domain, gateway `89.253.192.1` сидит **внутри** него.
|
||||
|
||||
Каноническая ifupdown-конфигурация (то что прописывает их `start/ipadd` procedure):
|
||||
|
||||
```
|
||||
auto eth0
|
||||
allow-hotplug eth0
|
||||
iface eth0 inet static
|
||||
address 89.253.255.94
|
||||
netmask 255.255.192.0
|
||||
post-up ip ro add 169.254.0.0/16 dev eth0 metric 400
|
||||
post-up ip ro add 89.253.192.1 dev eth0 metric 400
|
||||
post-up ip ro add default via 89.253.192.1 dev eth0 metric 400
|
||||
post-up ip ro add 89.253.192.0/18 via 89.253.192.1 dev eth0 src 89.253.255.94 metric 400
|
||||
post-up ip ro del 89.253.192.0/18 dev eth0 proto kernel scope link src 89.253.255.94
|
||||
```
|
||||
|
||||
Тонкость: их post-up сначала добавляет 89.253.192.0/18 **через gw** (routed), потом удаляет автоматически добавленный kernel-route (directly attached). То есть весь трафик внутри /18 идёт **через gw**, не L2-broadcast — типичный hosting-pattern для изоляции клиентов друг от друга (`proxy-ARP` / routed-on-host).
|
||||
|
||||
Эфемерная статика для recovery (если конфиг утерян):
|
||||
|
||||
```bash
|
||||
sudo ip addr add 89.253.255.94/18 dev eth0 # /18 — gw сам в подсети, link-route не нужен
|
||||
sudo ip route add default via 89.253.192.1 dev eth0
|
||||
```
|
||||
|
||||
Если по какой-то причине /18 не приемлем — fallback с /24 и link-route к gw:
|
||||
|
||||
```bash
|
||||
sudo ip addr add 89.253.255.94/24 dev eth0
|
||||
sudo ip route add 89.253.192.1 dev eth0 # link-scope route к gw
|
||||
sudo ip route add default via 89.253.192.1
|
||||
```
|
||||
|
||||
DNS resolvers: `89.253.252.30`, `89.253.252.31`.
|
||||
|
||||
Как обнаружить gw/netmask для конкретной VM:
|
||||
|
||||
1. **Соседний VPS у того же хостера** — `ip route` + `ip addr` покажут.
|
||||
2. **`/etc/network/interfaces.d/ifcfg-<iface>`** на самой VM (если конфиг present) — provider's canonical setup.
|
||||
3. Cached DHCP lease (если уцелел): `cat /run/systemd/netif/leases/*` → поле `ROUTER=`.
|
||||
4. Активационное письмо при выдаче VPS.
|
||||
5. Support ticket — последний resort.
|
||||
|
||||
Подробный кейс где это пригодилось — [`vds-kzntsv-dhcp-outage-2026-05-28`](vds-kzntsv-dhcp-outage-2026-05-28.md).
|
||||
|
||||
## 10. Network stack: ifupdown (NOT netplan)
|
||||
|
||||
Rusonyx provisioning ожидает **`ifupdown` + `networking` service**, не netplan/systemd-networkd. Их `start/ipadd/ipdel` procedure (вызывается при start VM / IP add-remove / network reset) кладёт `/etc/network/interfaces.d/ifcfg-<iface>` и ребутает networking.
|
||||
|
||||
Header в их `/etc/network/interfaces`:
|
||||
|
||||
```
|
||||
# Autoconfigured by Provider's start/ipadd/ipdel procedure.
|
||||
# !!! DO NOT MANUALLY EDIT OR DELETE THIS FILE !!!
|
||||
```
|
||||
|
||||
**Проблема**: Ubuntu 24.04 base ships netplan + systemd-networkd. cloud-init часто оставляет `/etc/netplan/50-cloud-init.yaml` с `dhcp4: true`. После первого boot оба стека активны параллельно.
|
||||
|
||||
Скорее всего **8 дней работает потому что DHCP сам всё резолвит**. Но если что-то на стороне хостера разорвёт DHCP-binding (rare, но случается — см. инцидент 2026-05-28), **их auto-recovery `start/ipadd` не сможет применить static config**, потому что networkd «держит» eth0. → VM лежит до тикета.
|
||||
|
||||
**Канон setup после bootstrap для Rusonyx Ubuntu VDS:**
|
||||
|
||||
```bash
|
||||
sudo systemctl disable systemd-networkd.service systemd-networkd.socket systemd-networkd-wait-online.service
|
||||
sudo systemctl mask systemd-networkd.service systemd-networkd.socket systemd-networkd-wait-online.service
|
||||
sudo systemctl mask netplan # preventive
|
||||
# leave networking enabled (default)
|
||||
```
|
||||
|
||||
**Безопасно на running system** — `disable`/`mask` без `stop` не убивают текущий процесс. Изменение вступает только при следующем boot.
|
||||
|
||||
**Anti-pattern:** прописывать persistent статику через `/etc/netplan/*.yaml`. Использовать ifupdown (`/etc/network/interfaces.d/*`), а лучше — попросить хостера через тикет «настройте дефолтную конфигурацию» — они через `start/ipadd` пропишут это сами.
|
||||
|
||||
Подробный кейс — [`vds-kzntsv-dhcp-outage-2026-05-28`](vds-kzntsv-dhcp-outage-2026-05-28.md).
|
||||
|
||||
## Когда применять
|
||||
|
||||
- Любой новый Rusonyx VDS (Astra Облако).
|
||||
|
||||
217
.wiki/concepts/vds-kzntsv-dhcp-outage-2026-05-28.md
Normal file
217
.wiki/concepts/vds-kzntsv-dhcp-outage-2026-05-28.md
Normal file
@@ -0,0 +1,217 @@
|
||||
---
|
||||
title: vds-kzntsv network-stack mismatch 2026-05-28 — postmortem + recovery procedure
|
||||
type: concept
|
||||
tags: [vds, rusonyx, network, dhcp, outage, postmortem, recovery, runbook, ifupdown, netplan]
|
||||
sources: [../sources/vds-kzntsv-incident-2026-05-28.md]
|
||||
updated: 2026-05-28
|
||||
---
|
||||
|
||||
# vds-kzntsv network-stack mismatch 2026-05-28
|
||||
|
||||
Постмортем + переиспользуемый runbook. Конкретный инцидент: [[../entities/vds-kzntsv]] (89.253.255.94) был недоступен снаружи примерно с **28 мая 2026, ~05:45–08:30 MSK** (~2.5 часа активного outage), плюс ещё ~5.5 часов работы на эфемерной статике до окончательного fix хостером в ~13:52 MSK. Подробная хроника — в [[../sources/vds-kzntsv-incident-2026-05-28]].
|
||||
|
||||
**Root cause (по итогу resolution хостером):** наш Ubuntu 24.04 VDS с момента активации (2026-05-20) работал на **двух параллельно активных** сетевых стеках — `netplan` + `systemd-networkd` (от cloud-init + наши манипуляции) **поверх** `ifupdown` + `networking` (provider's expected stack). Их provisioning кладёт конфиг в `/etc/network/interfaces.d/ifcfg-eth0` через `start/ipadd/ipdel` procedure, и ожидает что ifupdown подхватит при boot. networkd на eth0 этому мешает. 8 дней «работало», потому что networkd сам получал DHCP lease и обходил проблему. Когда DHCP-binding слетел на их стороне (28.05 ~05:45-08:00 MSK), их `start/ipadd` procedure не могла восстановить IP через ifupdown, потому что eth0 был «захвачен» systemd-networkd → VM осталась без IP. Окончательное решение: mask `netplan` + `systemd-networkd`, переход на чистый `networking` stack.
|
||||
|
||||
## Симптомокартина
|
||||
|
||||
| Симптом | Где видно |
|
||||
|---|---|
|
||||
| SSH с любого хоста — `No route to host` / `Destination Host Unreachable` | workstation, sibling-VPS [[../entities/books-vds]] |
|
||||
| Hoster gateway `89.253.192.40` отвечает `Destination Host Unreachable` на ARP | внешний `traceroute` падает на 3-м hop |
|
||||
| VM **жива** (через VNC), процессы и docker контейнеры работают | Rusonyx panel → Консоль |
|
||||
| `ip -br link` показывает `eth0 UP LOWER_UP` с MAC | физический NIC ОК |
|
||||
| `ip a show eth0` — **только** `inet6 fe80::*/64 scope link`, **нет IPv4** | DHCP lease отсутствует |
|
||||
| `ip route` — только docker-сети, **нет default** | следствие отсутствия IPv4 |
|
||||
| `networkctl status eth0` → `State: degraded (configuring)`, `Online state: online` | networkd ждёт ответ от DHCP |
|
||||
| `journalctl -u systemd-networkd -b` — повторяющийся `eth0: DHCPv6 lease lost`, **никаких** DHCPv4 offer'ов | DHCP-сервер хостера не отвечает |
|
||||
| LLDP-сосед видим: `Connected To: hw80.rusonyx.ru on port fe:54:00:9c:63:01` | L2 со свитчем здоров → проблема выше |
|
||||
|
||||
**Анти-симптомы** (что отметает наши конфиг-ошибки):
|
||||
|
||||
- netplan не менялся днями (см. `git log` если бы был — у нас не versioned, но `stat /etc/netplan/*.yaml`).
|
||||
- Тот же шаблон netplan работает на соседнем VPS [[../entities/books-vds]] (89.253.255.133) у того же хостера.
|
||||
- Reboot VM не помогает (uptime после ребута 1 час, IP так и не получен).
|
||||
- Daily backup завершился успешно за ~3 часа до обнаружения отказа → не «давно сломалось», именно острый отказ.
|
||||
|
||||
## Диагностика — алгоритм
|
||||
|
||||
```dot
|
||||
digraph diag {
|
||||
"Внешний SSH/ping не доходит" [shape=diamond];
|
||||
"Открыть VNC → ip -br link" [shape=box];
|
||||
"Link UP?" [shape=diamond];
|
||||
"Без NIC — driver/hardware issue" [shape=box];
|
||||
"ip a show <iface>" [shape=box];
|
||||
"Есть IPv4?" [shape=diamond];
|
||||
"Сеть работает иначе" [shape=box];
|
||||
"networkctl status <iface>" [shape=box];
|
||||
"LLDP видит свитч?" [shape=diamond];
|
||||
"Cable/L2 issue — тикет в DC" [shape=box];
|
||||
"Соседний VPS у того же хостера работает?" [shape=diamond];
|
||||
"Глобальный outage — ждать или тикет" [shape=box];
|
||||
"DHCP server проблема — статика + тикет" [shape=doublecircle];
|
||||
|
||||
"Внешний SSH/ping не доходит" -> "Открыть VNC → ip -br link";
|
||||
"Открыть VNC → ip -br link" -> "Link UP?";
|
||||
"Link UP?" -> "Без NIC — driver/hardware issue" [label="нет"];
|
||||
"Link UP?" -> "ip a show <iface>" [label="да"];
|
||||
"ip a show <iface>" -> "Есть IPv4?";
|
||||
"Есть IPv4?" -> "Сеть работает иначе" [label="да"];
|
||||
"Есть IPv4?" -> "networkctl status <iface>" [label="нет"];
|
||||
"networkctl status <iface>" -> "LLDP видит свитч?";
|
||||
"LLDP видит свитч?" -> "Cable/L2 issue — тикет в DC" [label="нет"];
|
||||
"LLDP видит свитч?" -> "Соседний VPS у того же хостера работает?" [label="да"];
|
||||
"Соседний VPS у того же хостера работает?" -> "Глобальный outage — ждать или тикет" [label="нет"];
|
||||
"Соседний VPS у того же хостера работает?" -> "DHCP server проблема — статика + тикет" [label="да"];
|
||||
}
|
||||
```
|
||||
|
||||
Ключевые команды для каждого узла:
|
||||
|
||||
```bash
|
||||
ip -br link # NIC + state одной строкой на интерфейс
|
||||
ip a show eth0 # есть ли IPv4
|
||||
sudo networkctl status eth0 # State + LLDP-сосед (Connected To: ...)
|
||||
sudo journalctl -u systemd-networkd -b | grep -iE "dhcp|discover|offer|nack" | tail -20
|
||||
sudo ls /run/systemd/netif/leases/ # есть ли свежий lease (пусто — нет ни одного)
|
||||
```
|
||||
|
||||
## Recovery procedure (эфемерная статика — для немедленного восстановления)
|
||||
|
||||
Используется когда сеть лежит **прямо сейчас** и нужно срочно поднять доступ. Маска **/18** (как прописывает хостер) — это самая чистая форма; gw в той же подсети, дополнительный link-route не требуется:
|
||||
|
||||
```bash
|
||||
sudo ip addr add 89.253.255.94/18 dev eth0
|
||||
sudo ip route add default via 89.253.192.1 dev eth0
|
||||
```
|
||||
|
||||
DNS (если `/etc/resolv.conf` не сохранился):
|
||||
|
||||
```bash
|
||||
sudo bash -c 'echo -e "nameserver 89.253.252.30\nnameserver 89.253.252.31" > /etc/resolv.conf'
|
||||
```
|
||||
|
||||
Альтернативная форма с **/24** (если по какой-то причине /18 не приемлемо — например провайдер изменил routing) — тогда нужны 3 команды с link-route к gw:
|
||||
|
||||
```bash
|
||||
sudo ip addr add 89.253.255.94/24 dev eth0
|
||||
sudo ip route add 89.253.192.1 dev eth0
|
||||
sudo ip route add default via 89.253.192.1 dev eth0
|
||||
```
|
||||
|
||||
Проверка:
|
||||
|
||||
```bash
|
||||
ip a show eth0 # inet 89.253.255.94/...
|
||||
ip route # default via 89.253.192.1 dev eth0
|
||||
curl -s -m 5 https://api.ipify.org # должно вернуть 89.253.255.94
|
||||
```
|
||||
|
||||
**Эфемерность:** прописано через `ip` — на reboot стирается. Для persistence см. ниже § «Permanent fix через ifupdown».
|
||||
|
||||
## Permanent fix — через ifupdown stack (то что прописывает хостер)
|
||||
|
||||
**Это и есть financial state после resolution 2026-05-28**. Это конфигурация **которую хостер ставит/восстанавливает через свой `start/ipadd` procedure** — наш `ifcfg-eth0` это просто слепок того что они кладут.
|
||||
|
||||
### /etc/network/interfaces.d/ifcfg-eth0
|
||||
|
||||
```bash
|
||||
# Autoconfigured by Provider's start/ipadd/ipdel procedure.
|
||||
# !!! DO NOT MANUALLY EDIT OR DELETE THIS FILE !!!
|
||||
|
||||
auto eth0
|
||||
allow-hotplug eth0
|
||||
iface eth0 inet static
|
||||
address 89.253.255.94
|
||||
netmask 255.255.192.0
|
||||
post-up ip ro add 169.254.0.0/16 dev eth0 metric 400
|
||||
post-up ip ro add 89.253.192.1 dev eth0 metric 400
|
||||
post-up ip ro add default via 89.253.192.1 dev eth0 metric 400
|
||||
post-up ip ro add 89.253.192.0/18 via 89.253.192.1 dev eth0 src 89.253.255.94 metric 400
|
||||
post-up ip ro del 89.253.192.0/18 dev eth0 proto kernel scope link src 89.253.255.94
|
||||
```
|
||||
|
||||
**Не редактировать руками** — хостер перезапишет через `start/ipadd` при следующих manipulations с VM (resize, network reset). Если нужны user-specific routes — отдельный файл рядом, **не** редактировать ifcfg-eth0.
|
||||
|
||||
### Прибить netplan + systemd-networkd
|
||||
|
||||
```bash
|
||||
sudo systemctl disable systemd-networkd.service systemd-networkd.socket systemd-networkd-wait-online.service
|
||||
sudo systemctl mask systemd-networkd.service systemd-networkd.socket systemd-networkd-wait-online.service
|
||||
sudo systemctl mask netplan # preventive — netplan.service unit not exist в Ubuntu, но mask не повредит
|
||||
|
||||
# verify
|
||||
systemctl is-enabled netplan systemd-networkd networking
|
||||
# expected: masked, masked, enabled
|
||||
```
|
||||
|
||||
**Безопасно на running system** — `disable`/`mask` блокируют только автозапуск на **следующий boot**. Текущий networkd-процесс продолжает работать до явного `stop` или reboot. SSH-сессии и L3-конфиг (IP/маршруты) переживают.
|
||||
|
||||
### Запросить provider-side reset
|
||||
|
||||
Если IP по DHCP не приходит и `/etc/network/interfaces.d/ifcfg-eth0` отсутствует или пустой — тикет в Rusonyx с запросом «настроить дефолтную конфигурацию сети». Они через свою `start/ipadd` procedure пропишут `ifcfg-eth0` и ребутнут VM. После ребута сеть поднимается на ifupdown.
|
||||
|
||||
## Kernel cmdline (для понимания почему `eth0`, а не `ens3`)
|
||||
|
||||
Rusonyx прописывает в GRUB `net.ifnames=0 biosdevname=0` — это **выключает** systemd predictable interface naming. Поэтому интерфейс всегда `eth0`, не `ens3`/`enp0s3` (хотя udev знает их как altnames для `ip a show`). Менять эти флаги в cmdline нельзя — провайдерский `ifcfg-eth0` рассчитан именно на `eth0`.
|
||||
|
||||
## Где взять gateway если он неизвестен
|
||||
|
||||
У Rusonyx и многих российских VDS-хостингов используется **proxy-ARP / unnumbered routing** — gateway сидит в `/18` или `/19` надсети, а наш `/24` гостирует через неё. **Не угадывать `.1` в своей /24** — это не сработает.
|
||||
|
||||
Источники:
|
||||
|
||||
1. **Соседний VPS у того же хостера** — самый надёжный. `ssh sibling 'ip route'` покажет `default via X.X.X.X dev eth0`. Так мы и сделали в этот раз — взяли gw из [[../entities/books-vds]] (89.253.192.1).
|
||||
2. **Cached lease** на самой VM (если уцелел): `cat /run/systemd/netif/leases/*`, `cat /var/lib/dhcp/dhclient.leases` — поля `ROUTER=`, `DNS=`. В этот раз не уцелело.
|
||||
3. **Тикет в support** — последний resort, тратит часы.
|
||||
4. **Активационное письмо** при выдаче VPS — обычно содержит netmask + gw. Но если VPS активирован годы назад — письмо может быть утеряно.
|
||||
|
||||
## Root cause (по итогам resolution)
|
||||
|
||||
**Корректировка относительно нашей первоначальной гипотезы** (которую мы вынесли в тикет на основе наших observations):
|
||||
|
||||
Первоначально мы атрибутировали отказ полностью инфраструктуре хостера (DHCP server / MAC binding). Это было **частично** верно — что-то в их инфре действительно потеряло binding нашей VM 28.05 в окне ~05:45-08:15 MSK, и их `start/ipadd` procedure пыталась его восстановить. Но **их procedure не смогла справиться** потому что наш сетевой стек был сконфигурирован неправильно:
|
||||
|
||||
- Поверх их ожидаемого `ifupdown + networking` (под который рассчитан их `start/ipadd`) у нас активны параллельно `netplan + systemd-networkd` (от cloud-init).
|
||||
- `systemd-networkd` «захватывал» eth0 на уровне routing и DHCP, не давая ifupdown'у нормально применить provider's static config.
|
||||
- 8 дней с этим conflict'ом всё работало, потому что networkd сам получал DHCP lease (там где их `ipadd` не успевал) и сеть жила.
|
||||
- Когда что-то на стороне хостера разорвало DHCP binding — networkd не смог получить новый lease (потому что binding с их стороны был broken), а ifupdown с готовой статикой не смог взять интерфейс (потому что networkd ещё держал его в configuring state).
|
||||
|
||||
**Окончательное решение** хостера (после нашего тикета): `mask netplan + systemd-networkd`, reboot — после boot ifupdown подхватил `ifcfg-eth0` сразу, конфликта нет, сеть работает.
|
||||
|
||||
**Атрибуция ответственности:**
|
||||
|
||||
- **Их сторона:** что-то в их сетевой инфре спровоцировало DHCP-binding loss 28.05 (точная причина не указана в ответе — отписка через сутки). Это **trigger** инцидента.
|
||||
- **Наша сторона:** мы наколхозили `netplan + systemd-networkd` поверх их `ifupdown`-stack (отчасти от cloud-init, отчасти при попытках восстановить сеть через VNC). Эта конфигурация **усугубила** инцидент: их auto-recovery не смогла сработать. Это **prolonging factor**.
|
||||
|
||||
Без conflict'а — инцидент длился бы минуты до auto-recovery. С conflict'ом — длился до нашего тикета + ручного fix хостером.
|
||||
|
||||
## Lessons learned (revised)
|
||||
|
||||
1. **Уважать provider's expected stack.** Rusonyx — ifupdown. Не накатывать netplan поверх, даже если он «по умолчанию в Ubuntu 24.04». Чистый netplan был бы менее проблемным чем mixed setup, но безопаснее всего — то что хостер использует.
|
||||
2. **Hostprovider auto-recovery — реальная вещь.** У Rusonyx есть `start/ipadd` procedure которая инжектит IP при reboot/start. Если она работает корректно — DHCP lease loss восстанавливается прозрачно для клиента. Не мешать её работе.
|
||||
3. **Соsed (sibling VPS) — главный диагностический инструмент.** [[../entities/books-vds]] подтвердил отсутствие глобального outage и дал референс на сетевые параметры (gw, DNS resolvers).
|
||||
4. **Готовый тикет-шаблон важен.** Хороший initial-ticket с конкретикой (LLDP, journalctl, ping/traceroute) сократил процесс. Хостер увидел что мы не зовём «оно не работает» а уже сделали половину RCA.
|
||||
5. **Когда хостер просит configuration change — оценить trade-off.** Их framing «у вас неправильный стек» был корректен (по последствиям), но мы первоначально подозревали что они переводят разговор от своего RCA. Reality — **и то и другое одновременно**: их инфра glitched, наш стек не дал auto-recovery, оба фактора важны.
|
||||
6. **`disable + mask` без `stop` — безопасно на running system.** Не падает SSH, не падает IP. Изменение вступает только на reboot. Это полезный паттерн для «приготовить состояние к чистому reboot, не трогая текущее».
|
||||
|
||||
## Anti-pattern
|
||||
|
||||
**Не делать**: persistent статику через `netplan` для VDS у Rusonyx. Это противоречит их provisioning. Использовать только ifupdown (`/etc/network/interfaces.d/*`), а лучше — попросить их `start/ipadd` procedure сделать это (тикет).
|
||||
|
||||
## Lessons learned
|
||||
|
||||
1. **DHCP — единая точка отказа на стороне хостера.** Если у них падает DHCP-привязка нашей VM, и lease истёк — мы выпадаем независимо от состояния нашего стека. Mitigation: статика в netplan, **но** это требует договорённости с хостером (они могут autosocket pool — статический IP перестанет работать когда они ребалансируют).
|
||||
2. **Soсед — главный диагностический инструмент.** [[../entities/books-vds]] был ключом: подтвердил что L2/глобальный outage отсутствует, дал точный gw для статики. **Иметь второй VPS у того же хостера** — это **бесплатный** мониторинг сетевой инфры хостера.
|
||||
3. **VNC console — обязательный backup-канал.** Без [[rusonyx-vps-onboarding-quirks]] §1-2 и доступа в VNC мы бы не смогли ни диагностировать, ни поднять статику.
|
||||
4. **Activation-email с netmask+gw — критичный артефакт.** Хранить (в pass-store / pinned email folder).
|
||||
5. **Cached lease file** — мог бы сократить recovery на 2-3 шага. Не уцелел. Можно периодически бэкапить `/run/systemd/netif/leases/` куда-то persistent? — minor follow-up, vs стоимость не оправдан.
|
||||
6. **Daily backup-лог = upper-bound оценки downtime.** Если backup прошёл успешно в 05:45 — VDS был жив. Это поможет хостеру в их RCA найти точное окно.
|
||||
|
||||
## Cross-refs
|
||||
|
||||
- [[../entities/vds-kzntsv]] — host details, обновлено note про gw в /18.
|
||||
- [[../entities/books-vds]] — sibling VPS у того же хостера, использован для gw discovery.
|
||||
- [[rusonyx-vps-onboarding-quirks]] — VNC + sshd quirks; quirk #9 добавлен про proxy-ARP gw layout.
|
||||
- [[../sources/vds-kzntsv-incident-2026-05-28]] — полная хроника сессии.
|
||||
- `.tasks/STATUS.md` § disk-89-followups — follow-up GC после recovery.
|
||||
@@ -26,11 +26,16 @@ Production CMS (MoreThenCms) **остаётся на** [`windows-recovery-host`]
|
||||
## Доступ
|
||||
|
||||
- **Public IP:** `89.253.255.94`
|
||||
- **Subnet / gateway:** **/18** (`netmask 255.255.192.0`), gateway `89.253.192.1`. Эта конфигурация **прописывается провайдером** в `/etc/network/interfaces.d/ifcfg-eth0` через их `start/ipadd` procedure — не редактировать руками. См. quirk #9-10 в [`rusonyx-vps-onboarding-quirks`](../concepts/rusonyx-vps-onboarding-quirks.md).
|
||||
- **Сетевой стек:** **`ifupdown` + `networking`** (provider's expected; `netplan` + `systemd-networkd` masked после resolution 2026-05-28 incident — см. [`vds-kzntsv-dhcp-outage-2026-05-28`](../concepts/vds-kzntsv-dhcp-outage-2026-05-28.md))
|
||||
- **Kernel cmdline:** `net.ifnames=0 biosdevname=0` — отсюда `eth0` (не `ens3`/`enp0s3`, эти как altnames в `ip a`)
|
||||
- **DNS resolvers:** `89.253.252.30`, `89.253.252.31` (Rusonyx)
|
||||
- **Vendor hostname:** `vps-21075162-534388.host4g.ru`
|
||||
- **Hypervisor (LLDP-сосед):** `hw80.rusonyx.ru` (нужно знать для тикетов хостеру)
|
||||
- **DNS:** `vds.kzntsv.site` (A → 89.253.255.94) + wildcard `*.vds.kzntsv.site` + service hostnames `git/registry/verdaccio.kzntsv.site` (REGRU)
|
||||
- **VNC console:** через Rusonyx панель (кнопка «Остановить VNC» в Управление сервером → Консоль может потребоваться при stale attachment — см. [`rusonyx-vps-onboarding-quirks`](../concepts/rusonyx-vps-onboarding-quirks.md))
|
||||
- **SSH:** `ssh -i ~/.ssh/id_ed25519 vitya@89.253.255.94` (root login + password auth disabled пост-bootstrap; sudo NOPASSWD для vitya)
|
||||
- **Креды:** `~/projects/.common/secrets/vds-kzntsv.env` (root initial pass, sudo pass, portainer admin, DB passwords, registry, portainer API key, traefik dashboard basicauth)
|
||||
- **Креды:** `pass show vds-kzntsv/full-env` (root initial pass, sudo pass, portainer admin, DB passwords, registry, portainer API key, traefik dashboard basicauth, ntfy, verdaccio CI). *Историческая заметка: до перехода на pass-store креды лежали в `~/projects/.common/secrets/vds-kzntsv.env` — папка более не существует.*
|
||||
|
||||
## Software stack
|
||||
|
||||
@@ -125,10 +130,15 @@ DB TLS: self-signed certs (CN matches hostname), клиент с `verify-none` /
|
||||
- Заменяет старый CMS-инфра-host [`windows-recovery-host`](windows-recovery-host.md) **только для инфраструктурных сервисов** (gitea/verdaccio/registry/DBs); production CMS остаётся на recovery-host.
|
||||
- Не зависит от [`dead-synology-diskstation`](dead-synology-diskstation.md) (тот мёртв).
|
||||
|
||||
## Known issues
|
||||
|
||||
- **2026-05-28 network-stack mismatch (~2.5 ч outage + ~5.5 ч на статике до resolution):** наш netplan+networkd конфликтовал с provider's expected ifupdown stack, поэтому когда DHCP-binding кратко потерялся на стороне хостера — auto-recovery (их `start/ipadd`) не сработала. Resolution: mask netplan/networkd + reboot + provider reset config. Подробности + runbook + lessons-learned: [`vds-kzntsv-dhcp-outage-2026-05-28`](../concepts/vds-kzntsv-dhcp-outage-2026-05-28.md). **Не использовать netplan на этом VDS** (anti-pattern).
|
||||
|
||||
## Open issues / TODO
|
||||
|
||||
- DB TLS = self-signed → нужен LE-cert sidecar (lego watch acme.json → extract PEM → reload DBs). Сейчас клиенты обходятся `verify-none`. [`db-tls-self-signed-via-traefik-raw-tcp`](../concepts/db-tls-self-signed-via-traefik-raw-tcp.md).
|
||||
- Backup pipeline — TODO ([`vds-backup-rsync-kreknin`](../../.tasks/vds-backup-rsync-kreknin.md)).
|
||||
- GC cron для verdaccio + registry — TODO ([`vds-gc-cron`](../../.tasks/vds-gc-cron.md)).
|
||||
- GC cron для verdaccio + registry — TODO ([`vds-gc-cron`](../../.tasks/vds-gc-cron.md)). **Срочность поднята после 2026-05-28** — дисковая нагрузка дошла до 89%, ручной GC (build cache + image prune + log truncate) дал 79%; registry GC отложен.
|
||||
- ntfy push — TODO ([`vds-ntfy-push`](../../.tasks/vds-ntfy-push.md)).
|
||||
- `iputils-ping` не установлен на host — `apt install iputils-ping` при следующем maintenance, иначе пользоваться `curl` для проверки сети.
|
||||
- Hermes — defer, ждёт уточнения user.
|
||||
|
||||
@@ -42,6 +42,7 @@ Catalog of all wiki pages. One line per page, organized by type. Updated on ever
|
||||
- [traefik-on-windows-docker-desktop](concepts/traefik-on-windows-docker-desktop.md) — Traefik на Windows Docker Desktop — нюансы
|
||||
- [traefik-tcp-passthrough-vs-starttls](concepts/traefik-tcp-passthrough-vs-starttls.md) — Traefik TCP passthrough vs STARTTLS-protocols
|
||||
- [vbox-windows-stability-tuning](concepts/vbox-windows-stability-tuning.md) — VirtualBox + Windows-гость — нюансы стабильности cross-hypervisor миграции
|
||||
- [vds-kzntsv-dhcp-outage-2026-05-28](concepts/vds-kzntsv-dhcp-outage-2026-05-28.md) — DHCP outage 2026-05-28 на vds-kzntsv — диагностика + recovery runbook (link UP но без IPv4 → статика + тикет хостеру)
|
||||
- [verdaccio-prune-semantics](concepts/verdaccio-prune-semantics.md) — Verdaccio prune semantics — proxied vs locally-published
|
||||
- [wd40efax-smr-cascade](concepts/wd40efax-smr-cascade.md) — WD40EFAX SMR Cascade — root cause NAS failure 2026-05-18
|
||||
- [windows-server-2025-core-bootstrap](concepts/windows-server-2025-core-bootstrap.md) — Win Server 2025 Core (RUVDS) — bootstrap для IIS-хоста: default-blockers + transfer-методов матрица
|
||||
@@ -58,3 +59,4 @@ Catalog of all wiki pages. One line per page, organized by type. Updated on ever
|
||||
- [books-vds-backup-daily-kreknin-2026-05-25](sources/books-vds-backup-daily-kreknin-2026-05-25.md) — books VDS daily backup → kreknin pipeline standup 2026-05-25 (ES file-snapshot repo + DB dumps + curl SMTP)
|
||||
- [ruvds-backup-daily-kreknin-2026-05-24](sources/ruvds-backup-daily-kreknin-2026-05-24.md) — RUVDS daily backup → kreknin pipeline standup 2026-05-24 (rclone+SFTP, SYSTEM task)
|
||||
- [vds-kzntsv-bootstrap-2026-05-20](sources/vds-kzntsv-bootstrap-2026-05-20.md) — VDS bootstrap session 2026-05-20 chronology
|
||||
- [vds-kzntsv-incident-2026-05-28](sources/vds-kzntsv-incident-2026-05-28.md) — DHCP outage incident session 2026-05-28 — chronology + ticket text
|
||||
|
||||
@@ -23,3 +23,7 @@ Append-only log of wiki operations (ingests, promotions, lints, migrations).
|
||||
## [2026-05-24] ingest | concepts/books-ssh-access — SSH access audit на shared VDS pre-cutover Фазы 3 tenant-split. Retained keys table (1 key, vitya core dev), removed cosmetic dead root key, sshd hardening verified via `sshd -T` (not raw config), fail2ban active 2670 failed/37 banned, only vitya@94.19.247.14 в access log last 7 days. Source: .tasks/books-ssh-audit-shared-vds.md.
|
||||
|
||||
## [2026-05-24] ingest | RUVDS IIS migration + backup pipeline — entities/ruvds-iis-host (NEW, 80.64.31.36 Win Server 2025 Core, 25 SNI bindings, 2/24 hostnames DNS-flipped) + sources/iis-migration-to-ruvds-2026-05-23 (NEW, SSH/scp pivot после SMB-block by home-ISP) + sources/ruvds-backup-daily-kreknin-2026-05-24 (NEW, rclone+SFTP SYSTEM task daily 04:30) + concepts/traefik-acme-json-to-iis-cert-import (NEW, PFX+SNI recipe) + UPDATE concepts/windows-server-2025-core-bootstrap (SMB deprecate, HTTP middlebox warning, HTTP/2 note, backup-strategy + cert-import закрыты) + UPDATE entities/windows-recovery-host (IIS partial-cutover state, imgproxy SPOF carve-out) + UPDATE overview (RUVDS line). Sources: .tasks/iis-migration-to-ruvds.md, .tasks/ruvds-backup-daily-kreknin.md.
|
||||
|
||||
## [2026-05-28] ingest | vds-kzntsv DHCP outage postmortem — concepts/vds-kzntsv-dhcp-outage-2026-05-28 (NEW, симптомокартина + диагностический алгоритм + recovery runbook + RCA) + sources/vds-kzntsv-incident-2026-05-28 (NEW, timeline 05:25 backup OK → 08:15 detect → 08:43 statics fix → 08:50 disk GC; ticket text) + UPDATE entities/vds-kzntsv (Доступ §+subnet/gw/hypervisor/DNS resolvers; pass-store вместо .common/secrets; Known issues §NEW with 2026-05-28 incident; Open issues bump GC priority + iputils-ping note) + UPDATE concepts/rusonyx-vps-onboarding-quirks (quirk #9 NEW — gw в /18 надсети + recovery commands). Live session, no raw source ingested.
|
||||
|
||||
## [2026-05-28] update | vds-kzntsv DHCP outage post-resolution — после reset хостером в 13:52 MSK выяснилось что root cause — конфликт двух сетевых стеков (netplan+networkd поверх ожидаемого provider's ifupdown). Их `start/ipadd` ожидает чистый ifupdown, не мог auto-recover при разрыве DHCP binding. Resolution: mask netplan+systemd-networkd, reboot, provider положил `/etc/network/interfaces.d/ifcfg-eth0` с /18 netmask. UPDATE concepts/vds-kzntsv-dhcp-outage-2026-05-28 (revised RCA + permanent-fix § + anti-pattern + revised lessons-learned) + UPDATE sources/vds-kzntsv-incident-2026-05-28 (timeline до 14:00 + final config) + UPDATE entities/vds-kzntsv (mask /18, ifupdown stack, kernel cmdline net.ifnames=0) + UPDATE concepts/rusonyx-vps-onboarding-quirks (quirk #9 переписан про /18, quirk #10 NEW про ifupdown vs netplan stack). Memory `vds-kzntsv-rusonyx-network-recovery` переписан с новыми фактами.
|
||||
|
||||
126
.wiki/sources/vds-kzntsv-incident-2026-05-28.md
Normal file
126
.wiki/sources/vds-kzntsv-incident-2026-05-28.md
Normal file
@@ -0,0 +1,126 @@
|
||||
---
|
||||
title: vds-kzntsv outage incident — session chronology 2026-05-28
|
||||
type: source
|
||||
tags: [vds, rusonyx, network, dhcp, outage, session-trace]
|
||||
ingested: 2026-05-28
|
||||
raw_path: (none — session-live, no external raw)
|
||||
updated: 2026-05-28
|
||||
---
|
||||
|
||||
# vds-kzntsv incident chronology 2026-05-28
|
||||
|
||||
Live-session трасса диагностики и восстановления отказа [[../entities/vds-kzntsv]]. Полный разбор паттерна + recovery runbook — в [[../concepts/vds-kzntsv-dhcp-outage-2026-05-28]].
|
||||
|
||||
## Timeline (MSK)
|
||||
|
||||
| Время | Событие | Источник |
|
||||
|---|---|---|
|
||||
| 2026-05-28 05:25 | Daily backup pipeline `vds-backup-rsync-kreknin` стартует | ntfy-уведомление пользователю |
|
||||
| 2026-05-28 05:45 | Backup завершён успешно — 19m51s, 69G, 7 snapshots передано на kreknin | ntfy + backup log |
|
||||
| 2026-05-28 ~06:00–08:00 | (окно отказа DHCP — точное время неизвестно) | — |
|
||||
| 2026-05-28 ~08:15 | User обнаруживает что vds-kzntsv недоступен по сети, пинг падает на хостер-gateway | user message |
|
||||
| 2026-05-28 08:20 | Сессия с агентом начинается, запрос креды на VDS | conversation |
|
||||
| 2026-05-28 08:25 | Probe с workstation и с [[../entities/books-vds]] (same hoster) — оба `Destination Host Unreachable` на `89.253.192.40` | bash output |
|
||||
| 2026-05-28 08:30 | User открывает Rusonyx panel → VNC console, шлёт скриншот журнала | screenshot |
|
||||
| 2026-05-28 08:35–08:42 | Диагностика через VNC: `ip -br link` → eth0 UP без IPv4; `networkctl status` → degraded (configuring), LLDP видит `hw80.rusonyx.ru` | screenshots |
|
||||
| 2026-05-28 08:43 | Recovery через статику (3 команды + DNS) — IP получен, маршруты добавлены | user confirms "Заработало!" |
|
||||
| 2026-05-28 08:44 | SSH с workstation работает; uptime 1h (VDS был ребутнут ~07:44, но IP DHCP всё равно не пришёл) | `ssh vitya@89.253.255.94 hostname` |
|
||||
| 2026-05-28 08:44 | 18 docker контейнеров поднялись через restart policy — gitea, registry, verdaccio, postgres, mariadb, mongo, owncloud, oCIS, modulair-rag стэк и пр. | `docker ps` |
|
||||
| 2026-05-28 08:50 | Disk cleanup: docker builder prune (10.6G) + image prune (0.3G) + truncate container logs (~3G); disk 89% → 79% | `df -h /` before/after |
|
||||
| 2026-05-28 09:00 | Тикет в Rusonyx отправлен | user sends |
|
||||
| 2026-05-28 ~12:20 | Rusonyx отвечает: «возможно потребуется перезагрузка», запрашивают разрешение | helpdesk |
|
||||
| 2026-05-28 ~12:25 | Даём разрешение с условиями (5-10мин уведомление + готовность VNC к recovery) | helpdesk |
|
||||
| 2026-05-28 ~13:00 | Rusonyx: «настройте дефолт — `mask netplan + systemd-networkd`, `enable networking`» | helpdesk |
|
||||
| 2026-05-28 ~13:20 | После уточнений согласовали что они сами пропишут конфиг через свой `start/ipadd` | helpdesk |
|
||||
| 2026-05-28 ~13:30 | Выполнен `systemctl disable+mask netplan + systemd-networkd.{service,socket,wait-online}` через SSH. IP и SSH остались живые. | session bash |
|
||||
| 2026-05-28 ~13:52 | Rusonyx ребутает VM с reset-конфига через их provisioning | их сторона |
|
||||
| 2026-05-28 14:00 | Smoke: SSH + 24 контейнера up + `api.ipify.org → 89.253.255.94`. Сервер полностью восстановлен. | session bash |
|
||||
|
||||
## Что сломалось
|
||||
|
||||
- DHCP lease для VM `vps534388` (MAC `52:54:00:9c:63:01`) на гипервизоре `hw80.rusonyx.ru` не возобновлялся.
|
||||
- VM выпала из L3-сети полностью: своя сторона корректна (link UP, networkd шлёт DHCP discover), хостер не отвечает offer'ом.
|
||||
- Reboot VM не помог.
|
||||
|
||||
Подробные подтверждающие сигналы — в [[../concepts/vds-kzntsv-dhcp-outage-2026-05-28]] § Симптомокартина.
|
||||
|
||||
## Что починили
|
||||
|
||||
Статика на eth0 через 3 ip-команды:
|
||||
|
||||
```bash
|
||||
sudo ip addr add 89.253.255.94/24 dev eth0
|
||||
sudo ip route add 89.253.192.1 dev eth0
|
||||
sudo ip route add default via 89.253.192.1
|
||||
```
|
||||
|
||||
DNS: `nameserver 89.253.252.30/.31` (Rusonyx).
|
||||
|
||||
**Эфемерно.** Persistence в netplan **отложен** до ответа хостера — если они починят DHCP, persistent статика конфликтнёт.
|
||||
|
||||
## Gateway discovery — как нашли 89.253.192.1
|
||||
|
||||
Gateway у Rusonyx сидит в /18 надсети `89.253.192.0/18`, а не в нашей /24. Источник — `ip route` на [[../entities/books-vds]] (sibling VPS у того же хостера):
|
||||
|
||||
```
|
||||
$ ssh root@89.253.255.133 'ip route'
|
||||
default via 89.253.192.1 dev eth0 metric 400
|
||||
89.253.192.0/18 via 89.253.192.1 dev eth0 src 89.253.255.133 metric 400
|
||||
89.253.192.1 dev eth0 scope link metric 400
|
||||
89.253.255.0/24 dev eth0 proto kernel scope link src 89.253.255.133
|
||||
```
|
||||
|
||||
См. также quirk #9 в [[../concepts/rusonyx-vps-onboarding-quirks]].
|
||||
|
||||
## Финальная конфигурация (после resolution хостером 13:52 MSK)
|
||||
|
||||
`/etc/network/interfaces.d/ifcfg-eth0` (положен их `start/ipadd` procedure):
|
||||
|
||||
```
|
||||
auto eth0
|
||||
allow-hotplug eth0
|
||||
iface eth0 inet static
|
||||
address 89.253.255.94
|
||||
netmask 255.255.192.0
|
||||
post-up ip ro add 169.254.0.0/16 dev eth0 metric 400
|
||||
post-up ip ro add 89.253.192.1 dev eth0 metric 400
|
||||
post-up ip ro add default via 89.253.192.1 dev eth0 metric 400
|
||||
post-up ip ro add 89.253.192.0/18 via 89.253.192.1 dev eth0 src 89.253.255.94 metric 400
|
||||
post-up ip ro del 89.253.192.0/18 dev eth0 proto kernel scope link src 89.253.255.94
|
||||
```
|
||||
|
||||
Изменение по сравнению с тем что было до инцидента:
|
||||
- **Сетевой стек** — был mixed (netplan + networkd поверх ifupdown), стал чистый ifupdown
|
||||
- **Netmask** — стал /18 явно (`255.255.192.0`) вместо неявного /24 + link-route trick
|
||||
- **systemd unit state:** `netplan` masked, `systemd-networkd*` masked, `networking` enabled
|
||||
|
||||
Kernel cmdline без изменений: `net.ifnames=0 biosdevname=0` (Rusonyx force eth0 naming).
|
||||
|
||||
## Тикет в Rusonyx — итоговый текст
|
||||
|
||||
Тикет отправлен через myvm.rusonyx.ru helpdesk, account `21075162`, тема: «VPS 534388 (vps-21075162-534388) — нет DHCP lease ~05:45 28.05.2026 MSK».
|
||||
|
||||
Основная часть:
|
||||
- Подтверждённое окно простоя ~2.5ч (с 05:45 — последний успешный backup — до 08:30 recovery).
|
||||
- Отсутствие уведомления с их стороны.
|
||||
- Корневая причина на стороне хостера, с конкретикой (LLDP, networkd journal, отсутствие DHCPv4 offer'ов).
|
||||
- Диагностика клиентом, не support'ом — что не норма для production-уровня услуги.
|
||||
- Запрос: (a) технический RCA, (b) SLA-компенсация, (c) procedural followup по их мониторингу VM-уровня, (d) статус DHCP — починен или фиксируем статику постоянно.
|
||||
|
||||
Полный текст — в сессионной переписке `~/.claude/projects/C--Users-vitya-projects--admin/` (conversation log).
|
||||
|
||||
Ответ хостера ещё не получен (на момент ingest этого source).
|
||||
|
||||
## Что обнаружили попутно
|
||||
|
||||
1. **Диск 89% → 79% после GC** — освободили 14G (build cache 10.6G + dangling images 0.3G + container logs ~3G). Disk-GC pending давно, см. `vds-kzntsv` § Open issues. Поставлена task [[../../.tasks/vds-kzntsv-disk-gc-followup]] на полный registry-GC (20G возможный reclaim).
|
||||
2. **`board-viewer-build` unhealthy** — отдельная история, не блокер сейчас.
|
||||
3. **`ping` не установлен** на VDS — Ubuntu 24.04 base не включает iputils-ping. Использовали curl для проверки сети. Можно установить `apt install iputils-ping` при следующем maintenance.
|
||||
|
||||
## Cross-refs
|
||||
|
||||
- [[../concepts/vds-kzntsv-dhcp-outage-2026-05-28]] — runbook + RCA-pattern.
|
||||
- [[../entities/vds-kzntsv]] — host details.
|
||||
- [[../entities/books-vds]] — sibling, source для gw discovery.
|
||||
- [[../concepts/rusonyx-vps-onboarding-quirks]] — vendor quirks, дополнен quirk #9.
|
||||
- [[vds-kzntsv-bootstrap-2026-05-20]] — оригинальный bootstrap.
|
||||
Reference in New Issue
Block a user