From 48a7cbb7c05574a7987b59c82aff7e7ab24ec3ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Sun, 23 Aug 2026 06:39:17 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BC=D0=B0=D0=BD=D1=83=D0=B0=D0=BB=20=D0=92?= =?UTF-8?q?=D0=9C:=20+=D1=80=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB=20=D0=9F=D0=9E?= =?UTF-8?q?=D0=A7=D0=95=D0=9C=D0=A3=20=D0=92=D0=9C=20(=D0=BE=D0=BF=D1=8B?= =?UTF-8?q?=D1=82=20=D1=87=D0=B5=D1=80=D0=B5=D0=B7=20=D0=BA=D0=BB=D0=B0?= =?UTF-8?q?=D1=81=D1=82=D0=B5=D1=80),=20=D0=BF=D1=80=D0=B8=D1=91=D0=BC=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=92=D0=9C,=20=D1=81=D0=BA=D0=B2=D0=BE=D0=B7?= =?UTF-8?q?=D0=BD=D0=BE=D0=B9=20=D1=81=D1=86=D0=B5=D0=BD=D0=B0=D1=80=D0=B8?= =?UTF-8?q?=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- History/2026-08-21-pattern-vm-buffer-pull.md | 55 ++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/History/2026-08-21-pattern-vm-buffer-pull.md b/History/2026-08-21-pattern-vm-buffer-pull.md index 90a3e33..352f70b 100644 --- a/History/2026-08-21-pattern-vm-buffer-pull.md +++ b/History/2026-08-21-pattern-vm-buffer-pull.md @@ -5,7 +5,25 @@ _Назначение: руководство для переделки логи не проходит через managed-кластер._ --- +## 0. ПОЧЕМУ через ВМ — хронология попыток через кластер (все провалились) +Что пробовали, чтобы большой файл прошёл ВХОД на managed-кластер, — и итог: + +| Попытка | Результат | Итог | +|---|---|---| +| Прямой `POST /upload` (multipart) | тела >~64КБ → HTTP 000 ~10с | блокер входа | +| Аннотации ingress (`proxy-body-size`, таймауты, `request-buffering`, `client-body-*`) | не влияют | бесполезно (обрыв на внешнем шлюзе) | +| `Transfer-Encoding: chunked` (чанки 32КБ) | обрыв ~10-15с при любом размере | бесполезно | +| Чанки на клиенте (POST по 50КБ, в т.ч. в БД) | только первый чанк доходит | бесполезно | +| ConfigMap ingress (`client-body-timeout 60`, `proxy-body-size 1024m`) + replicas=число нод | РАБОТАЕТ, но ТОЛЬКО на своём кластере (kubectl) | костыль; на чужом кластере нельзя | +| **Egress (Flask сам тянет с ВМ)** | 1-50МБ стабильно 200 | ✅ единственный универсальный путь | + +**Вывод:** вход в managed-кластер физически ограничен (~64КБ / ~10с) и не настраивается через +UI/аннотации. Выход (egress) — НЕ ограничен. Поэтому: файлы входят через ВМ, а Flask тянет их +сам (pull). Детали неудач: `History/2026-08-21-annotation-tests.md`, +`History/2026-08-21-root-cause-found.md`. + +--- ## 1. Проблема (что и почему не работает) **Входной шлюз managed-кластеров Nubes** (внешний балансировщик перед кластером): @@ -52,6 +70,35 @@ _Назначение: руководство для переделки логи ## 3. Как повторить (пошагово) +### 3.0 Приём файла на ВМ (первая половина схемы) + +1. Браузер шлёт файл на ВМ напрямую (минуя managed). На ВМ нужен приёмный endpoint. + На ВМ уже работает `convert_server.py` (:8766) — добавить туда endpoint, либо отдельный + маленький сервис. Пример (Flask на ВМ): + + ```python + # ВМ: приём и временное хранение + @app.route("/upload-lt", methods=["POST"]) + def upload_lt(): + f = request.files["file"] + fid = uuid4().hex + path = f"/var/www/lt-serve/{fid}" + f.save(path) + return jsonify({ + "ok": True, "id": fid, "size": os.path.getsize(path), + "url": f"https://contracts.kube5s.ru/lt-serve/{fid}", + }) + ``` + +2. nginx на ВМ: для этого пути `client_max_body_size 100m` (или больше) — БЕЗ лимита 64КБ. + +3. После сохранения ВМ сообщает Flask: **маленький POST (<64КБ — проходит шлюз)** с метаданными: + ```json + { "id": "...", "url": "https://contracts.kube5s.ru/lt-serve/", "name": "файл.pdf", "size": 47729215 } + ``` + +4. Flask получает метаданные и САМ тянет файл по `url` (egress GET, см. `/fetch` в 3.2). + ### 3.1 На ВМ (5.172.178.213) — раздача файлов через существующий nginx 1. Каталог: `/var/www/lt-serve/` (nginx-юзер `www-data` имеет доступ; `/home/naeel` — НЕТ, 403). 2. В `nginx-contracts.conf` (sites-enabled) добавлен location (отдельный блок, рядом с `/docs/`): @@ -105,6 +152,14 @@ def fetch_url(): Добавление остальных (таймауты, request-buffering) → падение скрипта платформы (`script returned exit code 1`, `No such property: name for class: Script2`). +### 3.4 Полный сквозной сценарий (5 шагов) + +1. **Браузер** → `POST https://contracts.kube5s.ru/upload-lt` (nginx ВМ), файл 45МБ. +2. **ВМ** сохраняет в `/var/www/lt-serve/`, отвечает `{id, size, url}`. Без лимита 64КБ. +3. **ВМ** (или клиент) → маленький `POST` на managed `.../upload-meta` `{url, name, size}` — проходит шлюз. +4. **Flask** по метаданным делает исходящий `GET url` (egress) и читает файл. +5. Flask обрабатывает (парсинг/БД/статусы). ВМ удаляет файл после загрузки или по TTL. + --- ## 4. Кластеры (наблюдения 2026-08-21)