10 KiB
Список задач обновлен
Проверялись следующие endpoint’ы registry:
https://tf-registry.containerk8s.services.ngcloud.ru/.well-known/terraform.json
Результат: HTTP 200
{"providers.v1":"/v1/providers/"}
Список версий:
https://tf-registry.containerk8s.services.ngcloud.ru/v1/providers/nubes-test/nubes/versions
Результат: HTTP 200
Опубликованы:
5.0.1
5.0.2
5.0.3
5.0.4
5.0.5
5.1.17
Download metadata для 5.0.5:
https://tf-registry.containerk8s.services.ngcloud.ru/v1/providers/nubes-test/nubes/5.0.5/download/linux/amd64
Результат: HTTP 200, ответ около 8 KB, содержит:
filename:
terraform-provider-nubes_5.0.5_linux_amd64.zip
download_url:
https://tf-registry.containerk8s.services.ngcloud.ru/v1/proxy?key=...
Фактический proxy URL:
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:
HTTP: 200
Content-Type: application/octet-stream
Content-Length: 13083236
Но фактически за 40 секунд скачалось только:
20983 байт
и затем:
curl: (28) Operation timed out
Дополнительно проверялись:
nubes-test/nubes:5.1.17
nubes/nubes:2.0.6
На них результат такой же: metadata отдается быстро, а ZIP через /v1/proxy обрывается примерно на 18–23 KB.
Проверялся также заголовок:
Range: bytes=0-1023
и диапазон из середины файла:
Range: bytes=1048576-1049599
Proxy игнорирует Range, отвечает HTTP 200 и снова начинает отдавать весь файл, после чего передача зависает.
Проверка DNS:
getent hosts tf-registry.containerk8s.services.ngcloud.ru
Результат:
5.172.178.231
Также проверялся Kubernetes API:
kubectl get ingress -A
kubectl get pods -A
kubectl get svc -A
kubectl get deploy -A
kubectl get configmap -A
Но текущий kubeconfig не имеет credentials:
the server has asked for the client to provide credentials
Unauthorized
Итог: API registry и metadata работают. Проблемный участок:
/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: <s3-presigned-url>. 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:
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:
// вместо 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.
Верификация:
go buildnubes.— компиляцияcurl -v 'https://...registry.../v1/proxy?key=...' -L— должен получить 302, затем скачать 13MB полностьюterraform initв тестовом проекте с этим провайдером
Делать?
Создано задач: 4
НИЧЕГО НЕ ДЕЛАЙ. КРАТКО ОТВЕТ ДАВАЙ - это надо менять код регистри ? и всё ?
10:03 Да. Только server/proxy.go — заменить стриминг на redirect к pre-signed S3 URL. Больше ничего.