# loop-ops Скрипты эксплуатации Loop, собранные после переезда с Yandex на Selectel (октябрь 2026): перенос баз между Postgres-кластерами, перенос инстансов между кубами, временные прокси, DNS, проверка здоровья. Одна точка входа: `loopctl`. ## Установка ``` cp config.env.example config.env # пути к kubeconfig, целевой куб ln -s "$PWD/loopctl" /usr/local/bin/loopctl ``` Нужны `kubectl`, `jq`, `curl`, `dig`, `python3`. Секретов в репозитории нет: | Что | Откуда | |---|---| | пароли баз инстансов | секреты `-db-credentials` в кубе | | пароль базы визора | секрет `loop-support/loop-vizor-production-secrets` | | токен визора | `~/.vizor-token` / `~/.vizor-refresh`, обновляется из буфера (JSON ответа Keycloak `/token` из DevTools) | | доступ к Selectel DNS | `~/.selectel-dns.env` (разбирается, не исполняется) | Всё, что меняет состояние, спрашивает подтверждение. `LOOPCTL_YES=1` — не спрашивать. ## Команды ``` loopctl db move <куб> [--scale-0] перенос базы целиком loopctl db migrate | verify | cutover | bind те же шаги по одному loopctl k8s move ... перенос инстанса на DST (loop-3) loopctl k8s rebind только секреты + привязка в визоре loopctl proxy make <исходный куб> манифест временного прокси loopctl proxy traffic <исходный куб> [секунд] запросы через прокси (0 = можно снимать) loopctl dns show|ttl|cname <поддомен> [значение] loopctl check ... | --db <хост> | --all ``` ### Перенос базы (`db move`) 1. `migrate`: роль и база на целевом CNPG, Job `pg_dump | psql` в кубе инстанса. `--scale-0` гасит инстанс до конца cutover (иначе посты за время копии останутся в старой базе); если копия или сверка не прошли, реплики возвращаются и инстанс остаётся на старой базе. Статус в локальном registry `db move` не останавливает. 2. `verify`: сравнение количества users/channels/posts. 3. `cutover`: секрет + env в CR на новую базу, рестарт, ожидание Ready. Свои ресурсы и probes инстанса не понижает, приостановленный (replicas 0) не будит: ему только меняет DSN. 4. `bind`: новая база в визоре (провайдер + env через API). **Без этого шага следующий sync визора вернёт инстанс на старую базу.** Параметры кластеров БД (хосты, порты, пулеры) — `apply_cnpg_cluster_profile` в `db/lib.sh`, тонкая настройка копии — `db/config.env`. Работает только `TRANSFER_MODE=stream`: режим `file` отключён, пока не исправлена проверка полноты дампа. ### Перенос инстанса между кубами (`k8s move`) Секреты и TLS на DST → привязка в визоре → env → sync → проверка (ping с БД, лицензия, env против исходного CR) → прокси на старом кубе и `replicas 0` → CNAME на `DST_DNS`. До прокси исходный инстанс не трогается. Остановка на первой ошибке; `PARALLEL=1` — до 10 инстансов, каждый в свой лог в `state/batch-logs/`. Прокси снимать по факту трафика, а не по времени: `loopctl proxy traffic loop-2 300` — у кого 0 запросов за интервал, можно удалять. Для редких клиентов (webhook раз в сутки) сравнить снимок счётчиков через сутки. Список прокси — `state/proxy-cleanup.txt`. ## Проверки `bash tests/cutover-patch.sh` — патч CR при cutover (ресурсы, probes, replicas). ## Известные ограничения - Движок копии: `wait_job` считает Job упавшим в паузе между перезапусками пода; при Job, оставленном после таймаута, у роли снимается SUPERUSER до конца restore. При ручном наблюдении не мешает, исправить отдельно. - DSN баз указывают на IP одной ноды с `externalTrafficPolicy: Local`: если пулер уедет с этой ноды, база недоступна (сбой lp3 24.10.2026). Нужны FQDN для баз. - Пул соединений lp3 (`max_connections=1000`, pgbouncer `session`) почти выбран: массовый рестарт упирается в лимит.