Files
loop-ops/README.md
T
2026-10-27 14:29:43 +03:00

60 lines
5.4 KiB
Markdown

# 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`. Секретов в репозитории нет:
| Что | Откуда |
|---|---|
| пароли баз инстансов | секреты `<id>-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 <куб> <id> <lm|lp3|ff|wilix> [--scale-0] перенос базы целиком
loopctl db migrate | verify | cutover | bind те же шаги по одному
loopctl k8s move <id>... перенос инстанса на DST (loop-3)
loopctl k8s rebind <id> только секреты + привязка в визоре
loopctl proxy make <id> <исходный куб> манифест временного прокси
loopctl proxy traffic <исходный куб> [секунд] запросы через прокси (0 = можно снимать)
loopctl dns show|ttl|cname <поддомен> [значение]
loopctl check <id>... | --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`) почти выбран: массовый рестарт упирается в лимит.