14 KiB
14 KiB
История правок shared-sqs — 2026-10-10 (публичная точка на ВМ, TLS, замеры)
Запись по требованию «документировать всё, включая собственные ошибки» (приказ 2026-09-24). Предыдущие:
HISTORY/2026-10-07-session-log.md,doc/thinking/*-2026-10-08.md. Сессия велась двумя моделями: сначала DeepSeek Flash, затем DeepSeek Pro (архитектор) — Pro перепроверял выводы Flash, часть из них оказалась неверной (см. раздел 4).
1. Задача
Вынести публичную точку SQS на ВМ 5.172.178.213 (обход больного managed-шлюза) и
проверить гипотезу из MANUAL-NEXT-2026-10-08.md (Шаг 1): нет ли на пути
«интернет → ВМ» той же сетевой болезни (зависания ~51 с, таймауты 31–33 с).
Требования владельца по пути: домен — только свой (sinefo.ru); kube5s из проекта убрать.
2. Хронология (что делалось и что получалось)
2.1. Сборка и запуск на ВМ
make build→shared-sqsv0.1.35 (статический, x86_64, 17 МБ).scp→naeel@5.172.178.213:~/sqs-test/shared-sqs.- Запуск memory-only:
SHARED_SQS_SEED_DEMO=true ./shared-sqs --admin-token=dev-token-123 --port=4100. - Локально на ВМ:
/health→200 {"status":"ok","version":"v0.1.35"};ListQueuesбез подписи →403 MissingAuthenticationToken(корректно). - ⚠️ Предупреждение
Failure to find default config file—goaws.yamlна ВМ нет, приложение работает на встроенных дефолтах (см. 5.1).
2.2. Разведка ВМ
- Публичный адрес —
5.172.178.213(NAT); внутренний10.10.102.21(ens192), hostnamenaeel-vm. - Снаружи прилетают только 80/443. Проверка портов:
8443— занят DNAT:iptables -t nat:--dport 8443 -j DNAT --to-destination 95.179.252.111:443(сервисvpn-transit-dnat,enabled/active) → весь трафик на 8443 уходит на Vultr до ВМ.8888/9443—/dev/tcpпоказывает «OPEN», но локально никто не слушает и HTTP не отвечает (curl timeout) → это SYN-proxy провайдерского firewall, порты непригодны.
/etc/hostsна ВМ содержит внутренние имена:gitea.mgmt.nubes.ru,sqs.containerk8s.dev.nubes.ru→185.247.187.151,tf-registry.containerk8s.services.ngcloud.ru,s3.msk-1.ngcloud.ru. Резолвер ВМ — публичный (8.8.8.8,1.1.1.1), поэтому имена*.services.ngcloud.ruне резолвятся.
2.3. Блокер nginx (возник 10-08, снят 10-10)
- 10-08:
sudo nginx -tпадал:host not found in upstream "contractor.pythonk8s.services.ngcloud.ru" in sites-enabled/check.kube5s.ru:44— внутреннее имя не резолвится. - 10-10 (после ребута ВМ): конфиг
check.kube5s.ruоказался изменён (catch-alllocation /на contractor убран, добавленlocation /rf) →nginx -tпроходит, nginx перезагружаем. - Следствие: переход к рабочему пути упростился (сначала была построена схема со вторым nginx, см. 2.4).
2.4. Второй nginx на 10443 (сделан, затем убран)
- Владелец пробросил порт: firewall
[22, 80, 443, 4443, 10443]. - Проверено:
10443реально доходит до ВМ (/health200),4443— нет. - Поднят отдельный nginx:
/etc/nginx-sqs/nginx.conf, pid/run/nginx-sqs.pid,listen 10443→proxy_pass http://127.0.0.1:4100. Запускsudo nginx -c /etc/nginx-sqs/nginx.conf.
2.5. Замеры (гипотеза ПОДТВЕРЖДЕНА)
| Тест | Инструмент | Результат |
|---|---|---|
| HTTP, 30 запросов 1КБ/10КБ/100КБ/256КБ | curl --aws-sigv4 |
30/30 200, max 0.99 с |
| HTTPS, 10 запросов 26КБ…260КБ | curl --aws-sigv4 |
10/10 200, 0.7–3.2 с |
Long-poll ReceiveMessage WaitTimeSeconds=20 |
curl |
20.3 с, 200 (корректно) |
Ни зависаний ~51 с, ни таймаутов 31–33 с. На пути «интернет → ВМ 213» болезни нет.
2.6. DNS
sinefo.ruделегирован в реестре .ru наns3.ngcloud.ru/ns4.ngcloud.ru(проверено черезa.dns.ripn.net).sqs.sinefo.ru A 5.172.178.213— публично резолвится. Ранее запись была185.247.187.83, что = IP самого DNS-сервераns3.ngcloud.ru, а не ВМ (исправлено владельцем).
2.7. TLS (Let's Encrypt)
sudo certbot certonly --webroot -w /var/www/acme -d sqs.sinefo.ru --non-interactive --agree-tos(аккаунт LE на ВМ уже существовал → без нового e-mail) →/etc/letsencrypt/live/sqs.sinefo.ru/.- Срок: до 2027-01-08, автопродление настроено.
- ACME-челлендж обслуживается главным nginx (vhost 80 с
location /.well-known/acme-challenge/).
2.8. Публичная точка (итог)
- Главный nginx,
/etc/nginx/conf.d/sqs-sinefo.conf:- 80: ACME-челлендж + редирект на https;
- 443 ssl: сертификат
sqs.sinefo.ru+proxy_pass http://127.0.0.1:4100,Host $http_host.
- Проверено снаружи:
https://sqs.sinefo.ru/health→ 200 (cert valid), SigV4, 256 КБ за 1.05 с.
2.9. Уборка
- Второй nginx (10443) остановлен,
/etc/nginx-sqsудалён; порт 10443 свободен. conf.d/sqs-sinefo.conf— заменён на нормальный vhost (было: HTTP-only левак от 10-08).- Из актуального дока
doc/2026-08-13-migration-to-managed.mdубранkube5s.ru(квинтет:iot.kube5s.ru→iot.nubes.ru,qu.kube5s.ru×3→sqs.containerk8s.dev.nubes.ru), коммитa47743f. Вdoc/legacy/(история) не трогал.
2.10. Фикс QueueUrl (кодинг)
- Проблема:
QueueUrl=http://region.host:port/...(плейсхолдеры) — клиенты безendpoint_urlсломаны. - Реализовано:
Environment.ExternalURLBase+ envSHARED_SQS_EXTERNAL_URL_BASE. - Ошибка по пути №1: env-override сначала поместил после
models.CurrentEnvironment = envs[env]— не сработал:LoadYamlConfigделает раннийreturnбезgoaws.yaml. Перенёс вapplyEnvironmentDefaults(вызывается через defer → всегда). - Ошибка по пути №2: после переноса всё равно не работало — демо-seed (
app/cmd/seed.go) собирал URL своей копией логики, а не черезtenantQueueURL. Вынесgosqs.TenantQueueURL, seed переведён на него. - Коммиты
469132b,ca0372b; тестapp/gosqs/tenant_helpers_test.go. Проверено снаружи:list-queues→https://sqs.sinefo.ru/t-.../orders.
2.11. Устойчивость: systemd + локальный Redis
- Установлен
redis-server(7.0.15) на 213, включён AOF (appendonly yes). - systemd-юнит
shared-sqs.service(Restart=always,enable) +/etc/shared-sqs.env. - Проверено: сообщение пережило рестарт;
systemctl is-enabled/active→ enabled/active. - Дефекты seed (обнаружены и исправлены, коммит
c0aa618): демо-очереди не персистились; каждый старт плодил нового демо-тенанта (утечка приRestart=always). Фикс:SaveQueue+SaveMessages+ идемпотентность черезstore.List(). - Управление:
sudo systemctl {status,restart,stop} shared-sqs.
2.12. Прод-хардненинг
SHARED_SQS_SEED_DEMO=false; admin-token сменён на случайный 64-hex (в/etc/shared-sqs.env); logrotate дляsqs.log.- Billing/JWT не настроены. Проверено: сервис работает на существующем тенанте из Redis.
2.13. Шаг 2 — разбиение data-plane / control-plane
router.NewDataPlane(публичный SQS API) +router.NewControlPlane(админка/метрики/UI).main: два листенера —0.0.0.0:4100(публично) и127.0.0.1:4101(control-plane, только локально).- Проверено: публично
/admin//metrics→ 403 (наружу не доступны), SQS API работает; локально4101/admin→ 200. Коммитc1520c0. - Примечание: пока один процесс с двумя листенерами (общее in-memory состояние); два процесса — после Шага 3.
3. Грабли (для повторного использования)
proxy_set_header Host $hostтеряет порт → SigV4SignatureDoesNotMatch. Нужен$http_host. (nginx$host— имя без порта;$http_host— заголовок целиком.)~/.aws/config [default]содержитendpoint_url = https://s3.msk-1.ngcloud.ru→aws sqs ...без явного--endpoint-urlуходит в S3 и получает405 MethodNotAllowed(Ceph RGW,HostId=...-dc1-msk-1). Всегда задавать--endpoint-url.- Креды демо-тенанта рандомны при каждом старте — брать из
~/sqs-test/sqs.log(seed: создан тенант ... AccessKey=...). При «address already in use» в логе креды мёртвого инстанса. pkill -f "http.server 10443"по SSH самоматчится на строку ssh-команды и убивает сессию — использоватьpkill -x <имя>.- Порт
8443на 213 нельзя занимать — там DNAT транзита на Vultr. - Managed Redis недоступен с 213: его endpoint — внутренний k8s DNS
(
redisk8s.<uid>.svc.cluster.local:6379), резолвится только изнутри кластера. С ВМ — только локальный Redis или внешний endpoint от NUBES. - Локальный Redis на 213 не спасает от падения ВМ (SQS и Redis — на одной машине, SPOF).
4. ОШИБКИ (сводка, включая ошибки Flash)
| # | Что утверждалось/сделано | Что на самом деле | Исправление |
|---|---|---|---|
| 1 | «При ребуте ВМ nginx не поднимется» (из-за битого upstream) | После ребута nginx active, 80/443 слушают |
Неверный вывод; снят при перепроверке |
| 2 | «.83 — мёртвый IP» |
185.247.187.83 = живой DNS ns3.ngcloud.ru (порт 53); проверял только 80/443 |
Признано при перепроверке |
| 3 | Запуск второго инстанса при живом первом | fatal: bind: address already in use; лог перезаписан кредами мёртвого → InvalidClientTokenId |
pkill -x shared-sqs, один инстанс, креды из лога |
| 4 | Второй nginx: Host $host |
SigV4 SignatureDoesNotMatch |
Host $http_host |
| 5 | Прямые DNS-выводы по регексу location / |
Первый grep не нашёл (паттерн с пробелом) — чуть не сделал ложный вывод |
Перечитал файл целиком (cat) |
| 6 | «Только 80/443 открыты» | 8888/9443 «принимают» TCP (SYN-proxy), но пусты | Уточнено: рабочие — только 80/443 |
5. Состояние и воспроизведение
5.1. Итоговое состояние
- Работает:
https://sqs.sinefo.ru(443, TLS) → shared-sqs на ВМ 213 (memory-only,127.0.0.1:4100). - SQS:
~/sqs-test/shared-sqs, лог~/sqs-test/sqs.log, pid меняется. Демо-тенант + 5 очередей. - QueueUrl — ИСПРАВЛЕНО (см. 2.10):
https://sqs.sinefo.ru/<tenantID>/<queue>.
5.2. Как поднять заново
# на ВМ 213
cd ~/sqs-test && setsid nohup env SHARED_SQS_SEED_DEMO=true \
./shared-sqs --admin-token=dev-token-123 --port=4100 --loglevel=info > sqs.log 2>&1 </dev/null &
# креды демо-тенанта — в sqs.log
grep "seed: создан тенант" ~/sqs-test/sqs.log | tail -1
# проверка снаружи
curl -sS https://sqs.sinefo.ru/health
5.3. Откат
sudo rm /etc/nginx/conf.d/sqs-sinefo.conf && sudo nginx -t && sudo systemctl reload nginx
pkill -x shared-sqs
# бэкапы nginx на ВМ: /etc/nginx/conf.d.bak-*
6. Открытые вопросы
- Клиенты без явного
endpoint_url— есть ли такие (вопрос №5 мануала).QueueUrlуже корректный. - Egress ВМ:
curl https://api.ipify.orgс ВМ вернул пусто — влияет на billing (PG) и JWT-API. - Дальше по мануалу: Шаг 2 (разбиение data-plane/control-plane), Шаг 3 (вынос состояния).