• Русский
  • Как настроить таймаут и размер тела Webservice Ingress

    В этой статье описано, как настроить три параметра NGINX Ingress, доступные в gitlab.webservice.ingress, когда их следует изменять и как применить тот же подход для других Ingress controllers.

    Применимые сценарии:

    • При отправке крупных репозиториев, LFS-объектов или container images возникает ошибка 413 Request Entity Too Large.
    • git clone / git push / импорт проекта для крупных репозиториев завершается по таймауту с 502 Bad Gateway примерно через ~10 минут.
    • 502 Bad Gateway ненадолго появляется после обновления или перезапуска webservice.

    Общая информация

    GitLab webservice доступен через NGINX Ingress. Встроенный Helm chart экспонирует три параметра в spec.helmValues.gitlab.webservice.ingress объекта GitlabOfficial CR. Они преобразуются в аннотации NGINX Ingress для объекта Ingress <RELEASE>-webservice-default:

    apiVersion: operator.alaudadevops.io/v1alpha1
    kind: GitlabOfficial
    metadata:
      name: sample
    spec:
      helmValues:
        gitlab:
          webservice:
            ingress:
              proxyConnectTimeout: 15    # seconds, -> nginx.ingress.kubernetes.io/proxy-connect-timeout
              proxyReadTimeout: 600      # seconds, -> nginx.ingress.kubernetes.io/proxy-read-timeout
              proxyBodySize: "512m"      # size,    -> nginx.ingress.kubernetes.io/proxy-body-size
    ПараметрЗначениеПо умолчанию
    proxyConnectTimeoutВремя, в течение которого NGINX ожидает установления TCP-соединения с Pod webservice.15s
    proxyReadTimeoutВремя, в течение которого NGINX ожидает между двумя последовательными чтениями от upstream Pod.600s
    proxyBodySizeМаксимальный размер тела запроса клиента, который NGINX примет и передаст дальше.512m

    Значения по умолчанию подходят для большинства установок. Эти три параметра тесно связаны между собой — крупные репозитории обычно требуют как большего размера тела, так и более длительного таймаута чтения, — поэтому их обычно настраивают совместно, а не по одному.

    Предварительные требования

    • Разрешение на редактирование объекта GitlabOfficial CR (kubectl edit gitlabofficial <NAME> -n <NS>).
    • Поля proxyConnectTimeout / proxyReadTimeout / proxyBodySize учитываются только тогда, когда кластер использует community ingress-nginx controller (kubernetes/ingress-nginx), поскольку chart рендерит их в пространство аннотаций nginx.ingress.kubernetes.io/*. Для любого другого controller см. раздел Настройка других Ingress controllers ниже.
    • Проверьте каждый участок пути запроса. Если перед собственным Ingress GitLab находится platform-level LB или reverse proxy, там тоже нужно увеличить те же ограничения — фактический лимит определяется минимальным значением во всей цепочке.

    Настройка для крупных репозиториев / загрузок (ingress-nginx)

    Для установок, которые обслуживают крупные репозитории, LFS-объекты или трафик container/package registry, обычно одновременно проявляются три симптома, и у них одно и то же решение — увеличить все три параметра вместе:

    СимптомПараметр для увеличения
    413 Request Entity Too Large при git push / загрузке через UI / LFS / Registry. В логах: client intended to send too large body.proxyBodySize
    git clone / git push / импорт проекта зависает примерно на ~10 минут, затем завершается с 502 или RPC failed. В логах: upstream timed out (110: Connection timed out).proxyReadTimeout
    Кратковременный 502 Bad Gateway во время rollout webservice (исчезает, когда Pods становятся Ready).proxyConnectTimeout

    Рекомендуемая отправная точка для экземпляра GitLab с крупными репозиториями / LFS / Registry:

    spec:
      helmValues:
        gitlab:
          webservice:
            ingress:
              proxyConnectTimeout: 30      # 15 -> 30; modest bump to absorb pod-restart jitter
              proxyReadTimeout: 1800       # 600 -> 1800; 30 min for large clone/push/import
              proxyBodySize: "5g"          # 512m -> 5g;  fits LFS / registry blobs

    Выбирайте значения на основе фактического использования:

    СценарийproxyBodySizeproxyReadTimeout
    Только исходный код, небольшие репозитории512m (по умолчанию)600 (по умолчанию)
    Git LFS / крупные binary assets2g ~ 5g1800
    Container / Package Registry5g ~ 10g1800 ~ 3600

    proxyConnectTimeout обычно является симптомом, а не регулятором. Кратковременный 502 во время rollout обычно означает, что Pods webservice медленно запускаются или неверно настроен readiness probe — сначала исправьте это. Увеличивайте значение только до 30–60s, если в среде действительно медленно устанавливается TCP-соединение, например при межзоновой сети. Установка больших значений, например 600, лишь скроет реальные ошибки backend и создаст накопление worker threads NGINX.

    proxyBodySize управляет только уровнем Ingress. У самого GitLab есть ограничения на уровне приложения, которые настраиваются в Admin Area → Settings → General → Account and limit (max push size, max attachment size, max import size, ...). При необходимости увеличьте их параллельно.

    Совет: для очень больших операций Git предпочтительнее использовать SSH (git@), а не HTTPS. Трафик SSH не проходит через HTTP Ingress и не подчиняется ни одному из этих трёх параметров.

    Настройка других Ingress controllers

    Три приведённых выше верхнеуровневых поля только создают аннотации в пространстве nginx.ingress.kubernetes.io/* и игнорируются следующими компонентами:

    • Traefik, HAProxy, Contour, Istio Gateway и другими controller, не относящимися к NGINX.
    • nginxinc/kubernetes-ingress от F5 NGINX Inc. — он использует другое пространство аннотаций (nginx.org/*).

    Для этих controller задавайте эквивалентные аннотации напрямую через gitlab.webservice.ingress.annotations, которые будут объединены с отрендеренным объектом Ingress.

    Пример для F5 NGINX Inc. (nginx.org/*):

    spec:
      helmValues:
        gitlab:
          webservice:
            ingress:
              annotations:
                nginx.org/client-max-body-size: "5g"
                nginx.org/proxy-read-timeout: "1800s"
                nginx.org/proxy-connect-timeout: "30s"

    Для Traefik аналогом proxyBodySize является ресурс Middleware с параметром buffering.maxRequestBodyBytes, а таймауты настраиваются на уровне IngressRoute / EntryPoint, а не через аннотации per-Ingress. Определите эти ресурсы отдельно и при необходимости укажите на них через traefik.ingress.kubernetes.io/router.middlewares в annotations.

    Если global.ingress.provider установлен в значение, отличное от nginx, аннотации nginx.ingress.kubernetes.io/* не внедряются, но сам ресурс Ingress всё равно рендерится — значения из annotations сохраняются. Если выбранный controller вообще не поддерживает аннотации per-Ingress для этих ограничений, настройте их на самом controller.

    Проверка применённой конфигурации

    После обновления CR и ожидания reconciliation проверьте аннотации на объекте Ingress:

    kubectl -n <NAMESPACE> get ingress <RELEASE>-webservice-default \
      -o jsonpath='{.metadata.annotations}' | tr ',' '\n' \
      | grep -E 'body-size|read-timeout|connect-timeout'

    Ожидаемый вывод (пример для ingress-nginx):

    "nginx.ingress.kubernetes.io/proxy-body-size":"5g"
    "nginx.ingress.kubernetes.io/proxy-connect-timeout":"30"
    "nginx.ingress.kubernetes.io/proxy-read-timeout":"1800"

    Если значения не совпадают:

    • Убедитесь, что CR был обновлён в spec.helmValues.gitlab.webservice.ingress (а не в spec.helmValues.nginx-ingress.controller.*, что относится к другому уровню).
    • Проверьте, что operator успешно выполнил reconciliation: kubectl describe gitlabofficial <NAME> -n <NS>.
    • Убедитесь, что upstream Ingress / LB перед собственным Ingress GitLab не применяет более жёсткий лимит.

    Всегда ли большие значения лучше?

    Нет. У каждого параметра есть своя цена:

    • Слишком большой proxyBodySize — NGINX буферизует (или потоково передаёт) всё тело; одна очень большая загрузка может резко увеличить потребление памяти и диска на узле Ingress Controller. Задайте значение лишь немного выше вашего реального максимума, а не произвольно большое.
    • Слишком большой proxyReadTimeout — медленные или зависшие upstream-соединения надолго занимают слоты worker NGINX, снижая доступную параллельность для других пользователей. Выбирайте значение, соответствующее вашему крупнейшему допустимому запросу, а не «как можно больше».
    • Слишком большой proxyConnectTimeout — скрывает реальные сбои backend (Pods не готовы, сеть нарушена), заставляя долго ждать перед выдачей ошибки. Держите его небольшим (15–60s) и исправляйте backend.

    Справка