25 lines
2.4 KiB
Markdown
25 lines
2.4 KiB
Markdown
---
|
||
title: registry-traefik-buffering — большие пуши умирают (Client Closed Request)
|
||
status: live
|
||
tags: [registry, traefik, buffering, push, gotcha]
|
||
---
|
||
|
||
# Большие (>1.5GB) пуши в registry.kzntsv.site через traefik — умирают
|
||
|
||
## Симптом
|
||
`docker buildx build --push` (или `docker push`) слоя ~2GB через `registry.kzntsv.site` → `ERROR: unknown: Client Closed Request` (499), обычно после ~5 мин / ~600-800MB. В логах реестра: клиент открывает `POST /v2/<repo>/blobs/uploads/` каждые ~70с, но `PATCH` до реестра НЕ доходит.
|
||
|
||
## Причина
|
||
Traefik-роут реестра имеет buffering middleware (`traefik.http.middlewares.registry-buffering.buffering.maxRequestBodyBytes=4000000000`): traefik буферизует ВЕСЬ body в RAM vds-kzntsv (7.7GB, свободно ~1GB) перед forwarding. Плюс медленное чтение 2GB слоя из buildkit-кэша на books-vds (3.9GB RAM) → OOM-killer режет процесс → «Client Closed Request». curl с /dev/zero (2GB, chunked, 38с) — проходит (нет дискового рида/кэша).
|
||
|
||
## Обход (без изменения traefik)
|
||
- Монолитные uploads curl'ом: `POST /v2/<repo>/blobs/uploads/` → `PUT <Location-from-POST>&digest=sha256:<d>` с телом (Content-Length). Мелкие блобы — так, 201.
|
||
- Большой слой: `sync; echo 3 > /proc/sys/vm/drop_caches` → `cat blob | curl -X PATCH -T -` (chunked, стримом) → финальный `PUT <Location-ИЗ-PATCH-ответа>&digest=sha256:<d>` (Location меняется после PATCH!). 202+201.
|
||
- Либо собрать образ ТАМ, где живёт реестр (vds-kzntsv), и пушить напрямую в контейнер реестра (мимо traefik).
|
||
|
||
## Если понадобится починить навсегда
|
||
Убрать/поднять buffering middleware на роуте registry (Portainer stack 5 на vds-kzntsv, `/opt/stacks/registry/docker-compose.yml`) — traefik будет стримить body. Требует отмашки (инфра-изменение на проде).
|
||
|
||
## Связано
|
||
[[books-vds-no-gitea-actions]] (локальная сборка + заливка), [[registry-kzntsv-auth-model]] (креды).
|