# Runbook развёртывания SigNoz (ВМ3) Это единственный исполняемый runbook раскатки self-hosted SigNoz для HAN Chat. Команды выполняет оператор; repository automation их не запускает. ВМ3 — private/no-egress узел по [`arch-06-service-hosting-security.md`](../../../architectory/arch-06-service-hosting-security.md): после приёмки нет internet ingress, нет постоянного internet egress, UI не публикуется, OTLP доступен только из приватной сети. Раскатка не завершена, пока не закрыт lockdown и обе группы проверок (снаружи и из private network). Эксплуатация UI, разбор инцидентов и алерты — в [`SIGNOZ_RUNBOOK.md`](SIGNOZ_RUNBOOK.md). Подключение приложений — [`BACKEND_OTLP.md`](BACKEND_OTLP.md). Сеть и группы безопасности — [`NETWORK.md`](NETWORK.md). Установка host KESL 12.4 — отдельное окно, [`kesl/RUNBOOK.KESL.ru.md`](kesl/RUNBOOK.KESL.ru.md); не совмещать с раскаткой, lockdown или обновлением стека. ## 0. Назначение, инвентарь и stop conditions Каталог репозитория: `HAN_chat_specification/VM3_signoz/Signoz/`. Рабочий каталог на ВМ: `/opt/signoz`. Compose Foundry создаёт в `pours/deployment/compose.yaml`; этот каталог принадлежит runtime ВМ и не хранится в git. Текущее окружение (подставьте актуальные значения, если они изменились): | Узел | Публичный IP | Приватный IP | |---|---|---| | ВМ1 HAN Chat (jump) | `135.106.164.58` | `192.168.0.1` | | ВМ2 Processing | — | `192.168.0.4` | | ВМ3 SigNoz | `135.106.166.7` только на bootstrap | `192.168.0.5` | Порты: - OTLP/gRPC: `192.168.0.5:4317` — основной ingest ВМ1 и ВМ2; - OTLP/HTTP: `192.168.0.5:4318` — диагностика, после приёмки можно закрыть; - UI/API: `127.0.0.1:8080` на ВМ3, доступ только через SSH-туннель; - ClickHouse `8123/9000`, PostgreSQL `5432`, ClickHouse Keeper `9181` наружу не публикуются. SSH-ключи (не коммитьте private keys): - jump/ВМ1: `C:\Users\MI\.ssh\hansel`; - приватный вход на ВМ3: `C:\Users\MI\.ssh\hansel-private`. Stop condition: нет приватного `192.168.0.5`, MAC `eth1` не совпал, нет исходящего HTTPS на bootstrap, заняты `8080/4317/4318`, Compose публикует служебный порт на `0.0.0.0`, не создан первый администратор SigNoz, verify скрипт завершился ошибкой, нет альтернативного SSH через jump, нет snapshot диска перед lockdown/обновлением. Запрещены: `docker compose down -v`, `docker volume prune`, `docker system prune --volumes`; ручное редактирование `pours/`; `rsync --delete` без исключений `pours/` и `casting.yaml.lock`; публикация `8080/4317/4318` на всех интерфейсах; постоянный public SSH «на будущее». Текущие host-скрипты выполняются от `root`. Роли `deploy`/`admin` из arch-06 на ВМ3 ещё не автоматизированы; не имитируйте их вручную поверх Foundry. ## 1. Предварительные условия (облако) До копирования файлов на ВМ подготовьте вне Compose: 1. Fresh Ubuntu 24.04, минимум 4 GiB RAM (лучше 8 GiB) и 30 GiB свободно в `/opt`. Для эксплуатации ClickHouse закладывайте запас диска под retention. 2. Private subnet `192.168.0.0/24` с ВМ1, ВМ2 и managed PostgreSQL. Приватный адрес ВМ3 — `192.168.0.5`. 3. Временный public IP только на окно bootstrap. Cloud SG на этом этапе: SSH TCP 22 с trusted ops CIDR, исходящий HTTPS/DNS к Docker Hub, GitHub, `signoz.io`, Ubuntu archive. Порты `8080/4317/4318/5432/8123/9000/9181` из интернета запрещены. 4. После lockdown целевая SG: - TCP 22 от jump/приватной подсети (`192.168.0.1` или SG ВМ1); - TCP 4317 от приватных IP/SG ВМ1 и ВМ2; - TCP 4318 только если оставлен HTTP ingest; - никакого internet ingress; - internet egress закрыт, кроме согласованного break-glass окна. 5. Зафиксируйте MAC приватного NIC. Скрипт `05-configure-private-network.sh` по умолчанию ждёт `eth1` / `fa:16:3e:b6:c6:70`. Если MAC другой — передайте `PRIVATE_MAC` явно, не правьте cloud-init `eth0`. ## 2. SSH-доступ оператора На Windows добавьте в `C:\Users\MI\.ssh\config`: ```sshconfig Host han-jump HostName 135.106.164.58 User root IdentityFile C:\Users\MI\.ssh\hansel Host signoz-bootstrap HostName 135.106.166.7 User root IdentityFile C:\Users\MI\.ssh\hansel Host signoz-private HostName 192.168.0.5 User root IdentityFile C:\Users\MI\.ssh\hansel-private ProxyJump han-jump Host signoz-ui HostName 192.168.0.5 User root IdentityFile C:\Users\MI\.ssh\hansel-private ProxyJump han-jump LocalForward 8080 127.0.0.1:8080 ``` До lockdown: `ssh signoz-bootstrap`. После появления приватного адреса проверьте `ssh signoz-private`, не закрывая bootstrap-сессию. Для UI: ```powershell ssh signoz-ui -N ``` Откройте `http://127.0.0.1:8080`. Туннель обязан указывать на loopback **ВМ3**. Не используйте `-L 8080:192.168.0.5:8080` через jump: UI слушает `127.0.0.1:8080` на SigNoz, а не на `192.168.0.5`. ## 3. Передача каталога на ВМ С WSL, не закрывая исключений. `pours/` и `casting.yaml.lock` создаёт Foundry на ВМ; без исключений `rsync --delete` уничтожит runtime. Первичная установка (публичный IP ещё есть): ```bash rsync -rltD --no-perms --no-owner --no-group -ivc \ --exclude='.env' \ --exclude='dist/' \ --exclude='secrets/' \ --exclude='pours/' \ --exclude='casting.yaml.lock' \ -e "ssh -i ~/.ssh/hansel" \ /mnt/c/Users/MI/Documents/Assistent/HAN_chat_specification/VM3_signoz/Signoz/ \ root@135.106.166.7:/opt/signoz/ ``` Повторная синхронизация после lockdown — через jump (`signoz-private`) и с `--delete`, сохранив те же exclude. На ВМ: ```bash cd /opt/signoz sed -i 's/\r$//' scripts/*.sh chmod +x scripts/*.sh ``` Не копируйте `.env`, ключи и `pours/`. Постоянные правки портов вносятся только в `casting.yaml`, затем снова запускается `20-deploy-signoz.sh`. ## 4. Приватный интерфейс Сохраните диагностику по [`NETWORK.md`](NETWORK.md). Default route должен остаться на публичном `eth0`; у `eth1` gateway нет. ```bash cd /opt/signoz sudo ./scripts/05-configure-private-network.sh ``` Пока `netplan try` ждёт 120 секунд, во **второй** сессии проверьте: ```bash ip -br -4 address show eth1 ip route get 192.168.0.1 ``` С ВМ1. ICMP в SG обычно закрыт, `ping` не используйте: ```bash ssh -i ~/.ssh/hansel-private -o ConnectTimeout=5 root@192.168.0.5 ``` Подтверждайте Netplan Enter только после успешного SSH с ВМ1. ## 5. Preflight и Docker Исходящий интернет на этом шаге ещё нужен. ```bash cd /opt/signoz sudo PRIVATE_IP=192.168.0.5 ./scripts/00-check-vm.sh sudo ./scripts/10-install-docker.sh ``` `00-check-vm.sh` требует Ubuntu 24.04, ≥4 GiB RAM, ≥30 GiB в `/opt`, адрес `192.168.0.5`, DNS/HTTPS к Docker Hub, GitHub и SigNoz, свободные `8080/4317/4318`. Любой `FAIL` — stop. ## 6. Первый запуск SigNoz `casting.yaml` обязан содержать bind `192.168.0.5:4317/4318` и `127.0.0.1:8080`. Скрипт остановится, если Foundry опубликует эти порты на `0.0.0.0`. ```bash cd /opt/signoz sudo PRIVATE_IP=192.168.0.5 ./scripts/20-deploy-signoz.sh ``` Ожидается: `foundryctl gauge/forge`, `compose pull/up`, UI health на `http://127.0.0.1:8080/api/v1/health` за ≤5 минут. Контейнеры `running` ещё не означают готовый ingest: до создания организации OpAMP не выдаёт ingester рабочую OTLP-конфигурацию. ## 7. Первый администратор На рабочей станции: ```powershell ssh signoz-ui -N ``` Откройте `http://127.0.0.1:8080`, создайте организацию и администратора. Пароль не сохраняйте в репозитории и history. Затем на ВМ3: ```bash cd /opt/signoz sudo docker compose -f pours/deployment/compose.yaml restart ingester ``` Без этого шага TCP `4317` может слушаться, а телеметрия — не приниматься. ## 8. Verify стека ```bash cd /opt/signoz sudo PRIVATE_IP=192.168.0.5 ./scripts/30-verify-signoz.sh sudo docker compose -f pours/deployment/compose.yaml ps -a ss -lntp '( sport = :8080 or sport = :4317 or sport = :4318 )' ``` Ожидается healthy PostgreSQL, ClickHouse Keeper, ClickHouse, SigNoz UI; TCP `4317` на `192.168.0.5`; HTTP `4318` принимает пустой OTLP JSON; `8080` только на `127.0.0.1`. Любой `FAIL` — смотрите `docker compose -f pours/deployment/compose.yaml logs --tail=200`, не продолжайте к firewall/lockdown. С ВМ1 и ВМ2: ```bash timeout 3 bash -c 'exec 3<>/dev/tcp/192.168.0.5/4317' \ && echo 'OTLP gRPC reachable' ``` ## 9. Host firewall и cloud SG Скрипт интерактивный: введите `APPLY` только после второй живой SSH-сессии. Он сбрасывает UFW и ставит: - TCP 22 с любого источника — allow-list IP задаёте в SG/файрволе приватной сети провайдера; - TCP 4317 и 4318 на `192.168.0.5` только из `192.168.0.0/24` (ВМ1 и ВМ2); - 8080 не открывается. UI остаётся на `127.0.0.1:8080` и доступен так: ```powershell ssh -i C:\Users\MI\.ssh\hansel -L 8080:127.0.0.1:8080 root@ -N ``` ```bash cd /opt/signoz sudo PRIVATE_IP=192.168.0.5 \ PRIVATE_CIDR=192.168.0.0/24 \ ./scripts/40-configure-firewall.sh ``` UFW INPUT не фильтрует все Docker-публикации. Источник OTLP дополнительно держите в SG. `casting.yaml` биндит OTLP на приватный IP, UI — на loopback. В SG не открывайте публично 8080/5432/8123/9000/9181. SSH 22 режьте источником на стороне провайдера, не на UFW. ## 10. Подключение ВМ1 и ВМ2 Не считайте раскатку ВМ3 законченной по одной проверке TCP `4317`. Канал ingest настраивается на application VM по [`BACKEND_OTLP.md`](BACKEND_OTLP.md): ```dotenv OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317 OTEL_REMOTE_ENDPOINT=192.168.0.5:4317 OTEL_REMOTE_AUTH_HEADER= OTEL_REMOTE_TLS_INSECURE=true ``` `OTEL_REMOTE_TLS_INSECURE=true` допустим только в этой изолированной приватной сети. После recreate collector на каждой VM отправьте canary traces и найдите в SigNoz: ```text service.name = han-chat-otlp-smoke service.namespace = han-chat deployment.environment = production-like ``` Collector сохраняет около 10% успешных traces: для smoke нужно порядка 100 traces, не 10. End-to-end и outage/recovery acceptance описаны в `BACKEND_OTLP.md`; без них отсутствие ошибок в UI не доказывает здоровье HAN Chat. ## 11. Snapshot, reboot gate и lockdown До удаления public IP: 1. `ssh signoz-private` открывается отдельной сессией. 2. Туннель `signoz-ui` показывает UI, администратор существует. 3. `30-verify-signoz.sh` без ошибок. 4. С ВМ1 и ВМ2 доступен `192.168.0.5:4317`. 5. В SigNoz есть свежий canary или production-like trace. 6. Все критичные контейнеры `running`/`healthy`. 7. Создан snapshot диска ВМ3. 8. В SG нет публичного доступа к служебным портам. Reboot gate. Не закрывайте jump/console доступ: ```bash cd /opt/signoz sudo ./scripts/30-verify-signoz.sh sudo systemctl is-enabled docker.service sudo systemctl reboot ``` После reconnect через `signoz-private` повторите verify, `compose ps`, слушатели портов и canary с ВМ1. Lockdown по arch-06: - удалите public IP `135.106.166.7`; - уберите internet ingress из SG, включая public SSH; - закройте общий internet egress (DNS/NTP/private OTLP остаются); - с внешней сети SSH и `8080/4317` недоступны; - из private network SSH через jump и OTLP `4317` работают; - bootstrap installer-файлы и ненужные package caches можно удалить. Раскатка не завершена, пока lockdown не зафиксирован. Постоянно оставлять public IP «для обновлений» запрещено. ## 12. Штатное обслуживание и обновление Проверка: ```bash cd /opt/signoz sudo ./scripts/30-verify-signoz.sh sudo docker compose -f pours/deployment/compose.yaml ps sudo docker compose -f pours/deployment/compose.yaml logs --since=30m df -h docker system df ``` Не редактируйте `pours/` вручную. Изменение bind-адресов — только `casting.yaml` + `20-deploy-signoz.sh`. Обновление — break-glass по arch-06: временный исходящий HTTPS к Docker Hub, GitHub и SigNoz, минимальное окно, затем повтор lockdown. Узкий egress host KESL к серверам обновления Kaspersky задаётся runbook KESL и этим окном не подменяется. ```bash cd /opt/signoz # 1. snapshot диска # 2. временный egress sudo df -h sudo ./scripts/20-deploy-signoz.sh sudo ./scripts/30-verify-signoz.sh # 3. проверить сохранность старых traces/metrics # 4. закрыть egress ``` Перед обновлением синхронизируйте git-каталог на ВМ с теми же exclude, что в §3. После обновления повторите smoke canary с ВМ1. ## 13. Rollback и потеря ВМ Откат приложения: предыдущий проверенный `casting.yaml` + повтор `20-deploy-signoz.sh` **без** `-v`. Данные живут в Docker volumes ClickHouse и PostgreSQL; их удаление — потеря телеметрии. Потеря ВМ3: новая Ubuntu 24.04 этим runbook, тот же приватный `192.168.0.5` (или согласованная смена endpoint на ВМ1/ВМ2), новые volumes пустые. Исторические traces не восстанавливаются без snapshot диска. Collectors на ВМ1/ВМ2 fail-open для бизнеса и буферизуют в bounded queue; это не замена SigNoz. Компрометация host: не «чистите» ВМ. Изолируйте, сохраните evidence, ротируйте доступ и раскатывайте заново из trusted image. ## 14. Acceptance record Сохраните без паролей: - дата/UTC окна, исполнитель, approver; - публичный IP bootstrap и факт его удаления; - приватный IP, MAC `eth1`, правила SG и `ufw status`; - вывод `00-check-vm.sh` и `30-verify-signoz.sh`; - `docker compose ps` и image ids; - факт создания организации/администратора (без секрета); - ссылка на canary trace `han-chat-otlp-smoke`; - snapshot id, reboot gate, lockdown checks снаружи и из private network; - следующее согласованное окно для dashboards/alerts по [`MVP_DASHBOARDS_ALERTS.md`](MVP_DASHBOARDS_ALERTS.md). После приёмки ежедневная работа — [`SIGNOZ_RUNBOOK.md`](SIGNOZ_RUNBOOK.md). Dashboards и paging alerts создавайте только после baseline, не в этом же окне раскатки.