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

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

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

    • Не удается выполнить push больших repositories, LFS objects или 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 CR GitlabOfficial. Они преобразуются в 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Максимальный размер body запроса клиента, который NGINX примет и передаст дальше.512m

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

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

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

    Настройка для больших Repositories / Uploads (ingress-nginx)

    Обычно для установок, которые обслуживают большие repositories, LFS objects или traffic к container/package registry, одновременно проявляются три симптома, и у них одно и то же решение — увеличить все три параметра вместе:

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

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

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

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

    Совет: Для очень больших Git operations отдавайте предпочтение 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 annotations (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 является ресурс Middleware с параметром buffering.maxRequestBodyBytes, а timeouts настраиваются на уровне IngressRoute / EntryPoint, а не через annotations каждого Ingress. Создайте эти ресурсы отдельно и при необходимости укажите на них через traefik.ingress.kubernetes.io/router.middlewares в annotations.

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

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

    После обновления CR и ожидания reconciliation проверьте annotations на объекте 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 буферизует (или потоково обрабатывает) все body; одна очень большая загрузка может резко увеличить потребление memory и disk на node Ingress Controller. Устанавливайте значение немного выше вашего реального максимума, а не произвольно высоким.
    • Слишком большой proxyReadTimeout — медленные или зависшие upstream-соединения надолго занимают рабочие слоты NGINX, уменьшая доступную concurrency для других пользователей. Выбирайте значение, соответствующее вашему крупнейшему легитимному запросу, а не «как можно больше».
    • Слишком большой proxyConnectTimeout — скрывает реальные сбои backend (Pod'ы не готовы, networking нарушен), ожидая много минут перед возвратом ошибки. Держите его небольшим (15–60s) и исправляйте backend вместо этого.

    Справка