Список задач обновлен Проверялись следующие endpoint’ы registry: ```text https://tf-registry.containerk8s.services.ngcloud.ru/.well-known/terraform.json ``` Результат: `HTTP 200` ```json {"providers.v1":"/v1/providers/"} ``` Список версий: ```text https://tf-registry.containerk8s.services.ngcloud.ru/v1/providers/nubes-test/nubes/versions ``` Результат: `HTTP 200` Опубликованы: ```text 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.1.17 ``` Download metadata для `5.0.5`: ```text https://tf-registry.containerk8s.services.ngcloud.ru/v1/providers/nubes-test/nubes/5.0.5/download/linux/amd64 ``` Результат: `HTTP 200`, ответ около `8 KB`, содержит: ```text filename: terraform-provider-nubes_5.0.5_linux_amd64.zip download_url: https://tf-registry.containerk8s.services.ngcloud.ru/v1/proxy?key=... ``` Фактический proxy URL: ```text https://tf-registry.containerk8s.services.ngcloud.ru/v1/proxy?key=tf-registry.containerk8s.services.ngcloud.ru%2Fnubes-test%2Fnubes%2F5.0.5%2Fterraform-provider-nubes_5.0.5_linux_amd64.zip ``` Проверка proxy: ```text HTTP: 200 Content-Type: application/octet-stream Content-Length: 13083236 ``` Но фактически за 40 секунд скачалось только: ```text 20983 байт ``` и затем: ```text curl: (28) Operation timed out ``` Дополнительно проверялись: ```text nubes-test/nubes:5.1.17 nubes/nubes:2.0.6 ``` На них результат такой же: metadata отдается быстро, а ZIP через `/v1/proxy` обрывается примерно на `18–23 KB`. Проверялся также заголовок: ```text Range: bytes=0-1023 ``` и диапазон из середины файла: ```text Range: bytes=1048576-1049599 ``` Proxy игнорирует `Range`, отвечает `HTTP 200` и снова начинает отдавать весь файл, после чего передача зависает. Проверка DNS: ```text getent hosts tf-registry.containerk8s.services.ngcloud.ru ``` Результат: ```text 5.172.178.231 ``` Также проверялся Kubernetes API: ```text kubectl get ingress -A kubectl get pods -A kubectl get svc -A kubectl get deploy -A kubectl get configmap -A ``` Но текущий kubeconfig не имеет credentials: ```text the server has asked for the client to provide credentials Unauthorized ``` Итог: API registry и metadata работают. Проблемный участок: ```text /v1/proxy -> S3 object -> HTTP streaming через Kubernetes ``` Именно там большой ZIP возвращается с `HTTP 200`, но поток фактически обрывается на десятках килобайт. Список задач обновлен Read Read memory Read , lines 1 to 80 Read , lines 1 to 80 Read , lines 1 to 80 Теперь у меня есть контекст по drhider. Давай сравню симптомы: Read Read ## Анализ: сравнение проблем drhider и registry ### Проблема в drhider (решена) | Аспект | Детали | |--------|--------| | Симптом | POST из браузера → тело запроса обрывалось на ~64КБ (HTTP 000, ~10с) | | Направление | **Входящий** трафик: браузер → кластер | | Корень | Managed-кластер, шлюз ingress обрывает тела входящих запросов >64КБ | | Решение | Браузер PUT файл на ВМ-буфер (обходит шлюз) → Flask тянет с ВМ (egress, без лимита) | ### Проблема в registry (сейчас) | Аспект | Детали | |--------|--------| | Симптом | `GET /v1/proxy?key=...` → HTTP 200 мгновенно, но данные обрываются на 18–23 КБ | | Направление | **Исходящий** трафик: кластер → Terraform клиент | | Корень | Тот же кластерный шлюз, но теперь режет **streaming-ответ** (буферизация / flush-лимит) | ### Это та же проблема? **Да, вероятно одна и та же инфраструктура** (`services.ngcloud.ru` — managed Nubes, тот же managed-кластер что и `pythonk8s.dev.nubes.ru`). Только направление противоположное: - drhider: шлюз режет входящее тело - registry: шлюз режет исходящий stream большого файла Дополнительный признак: у вас есть ещё одна задокументированная проблема — HTTP/2 резал git push к gitea (тот же шлюз, тот же паттерн). Range-запросы игнорируются — тоже поведение промежуточного буферизующего прокси. --- ### Применим ли обход через ВМ? **Да, но схема зеркальная.** В drhider проблема была на входе — данные шли в кластер. Здесь проблема на выходе — данные идут из кластера к Terraform. **Варианты обхода:** **Вариант A — Redirect на S3 pre-signed URL (чище всего)** `/v1/proxy` вместо стриминга генерирует временную pre-signed S3 ссылку и возвращает `302 Location: `. Terraform следует редиректу и скачивает ZIP напрямую с S3, минуя кластерный шлюз полностью. ``` Terraform → /v1/proxy?key=... → 302 Location: https://s3.../object?X-Amz-Expires=... Terraform → S3 напрямую → 200 + 13MB ✅ ``` Terraform `go-getter` (используется в `terraform init`) редиректы поддерживает. **Вариант B — Redirect на ВМ-прокси** Если S3 не публичный / нет pre-signed URL — `/v1/proxy` отдаёт `302` на эндпоинт ВМ (`contracts.kube5s.ru/tf-proxy?key=...`). ВМ скачивает файл с S3 и стримит Terraform клиенту. ВМ находится вне шлюза managed-кластера. **Вариант C — Через download_url в metadata (самое прозрачное)** Вместо того чтобы `download_url` указывал на `/v1/proxy` внутри кластера — указывать сразу на S3 pre-signed URL или ВМ-прокси. Не нужно менять `/v1/proxy` вообще. --- ### Рекомендация Вариант A или C — наиболее чистые. Смотреть, есть ли доступ к S3 с кредами для pre-signed URL из кода registry. Если есть — минимальное изменение: в `/v1/proxy` заменить стриминг на `redirect(presigned_url, 302)`. Нужно смотреть код registry (`/v1/proxy` handler) чтобы подтвердить технически — он в этом же репозитории или в отдельном? Создано задач: 3 Список задач обновлен Read Read Read Read Read Read Read Картина полная. Вот анализ: --- ## Диагностика: та же проблема, другая сторона **Код проблемы — `proxy.go`, `proxyHandler`:** ```go obj, _ := s3Client.GetObject(ctx, bucketName, key, ...) io.Copy(w, obj) // ← Kubernetes шлюз режет этот stream ``` Тот же managed-кластер (`containerk8s.services.ngcloud.ru` — Nubes), тот же шлюз. В drhider он резал входящие тела >64KB. Здесь режет исходящий stream с S3 (~18–23KB — это первый буфер ответа, который шлюз успел пропустить до блокировки). `Content-Length: 13083236` выставляется, но данных доходит ~20KB — шлюз буферизует и не флашит остаток. --- ## Решение: presigned URL redirect `minio-go` уже импортирован, он умеет генерировать pre-signed URL: ```go // вместо GetObject + io.Copy: presigned, err := s3Client.PresignedGetObject(ctx, bucketName, key, 15*time.Minute, url.Values{}) http.Redirect(w, r, presigned.String(), http.StatusFound) ``` Terraform следует 302. Terraform client скачивает ZIP **напрямую с S3**, кластерный шлюз больше не участвует. Это затрагивает только `proxy.go` — 1 файл, примерно 10 строк замены. `ShasumsURL` и `ShasumsSignatureURL` тоже идут через `/v1/proxy` — они маленькие (<10KB), работают и сейчас, но с redirect тоже будут работать корректно. --- ## План **Файл:** server/proxy.go **Изменение:** в `proxyHandler` — убрать `GetObject` / `Stat` / `io.Copy` / установку заголовков, заменить на `PresignedGetObject` + `http.Redirect 302`. Добавить `"net/url"` в imports. **Верификация:** 1. `go build `nubes`.` — компиляция 2. `curl -v 'https://...registry.../v1/proxy?key=...' -L` — должен получить 302, затем скачать 13MB полностью 3. `terraform init` в тестовом проекте с этим провайдером Делать? Создано задач: 4 НИЧЕГО НЕ ДЕЛАЙ. КРАТКО ОТВЕТ ДАВАЙ - это надо менять код регистри ? и всё ? 10:03 Да. Только server/proxy.go — заменить стриминг на redirect к pre-signed S3 URL. Больше ничего.