• Русский
  • Как настроить тайм-аут Ingress и размер тела запроса для webservice

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

    Подходящие сценарии:

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

    Общие сведения

    GitLab webservice доступен через NGINX Ingress. В комплекте Helm chart предусмотрены три параметра в spec.helmValues.gitlab.webservice.ingress объекта GitlabOfficial CR. Они преобразуются в annotations 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

    Параметры по умолчанию подходят для большинства установок. Эти три параметра тесно связаны: для больших repositories обычно требуется и больший размер тела запроса, и больший read timeout, поэтому их обычно настраивают совместно, а не по одному.

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

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

    Настройка для больших repositories / загрузок (ingress-nginx)

    Для установок, которые обслуживают большие repositories, объекты 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 (исчезает, когда Pod'ы становятся Ready).proxyConnectTimeout

    Рекомендуемая отправная точка для экземпляра GitLab с большими repositories / 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
    Только исходный код, небольшие repositories512m (по умолчанию)600 (по умолчанию)
    Git LFS / крупные binary assets2g ~ 5g1800
    Container / Package Registry5g ~ 10g1800 ~ 3600

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

    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

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

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

    Для этих controllers задавайте эквивалентные annotations напрямую через 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 является значение buffering.maxRequestBodyBytes ресурса Middleware, а тайм-ауты настраиваются на уровне 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 соединения надолго занимают слоты NGINX worker, снижая доступную параллельность для других пользователей. Выбирайте значение, соответствующее вашему крупнейшему допустимому запросу, а не «как можно больше».
    • Слишком большой proxyConnectTimeout — маскирует реальные проблемы backend (Pod'ы не Ready, проблемы в сети), заставляя ждать много минут перед возвратом ошибки. Оставляйте его небольшим (15–60s) и исправляйте backend.

    Справка