7.2 KiB
Error Log: 65KB+ Payload Timeout — 2026-04-11
Update — 2026-04-12
После дополнительного расследования в кластере инцидент переклассифицирован.
Финальный статус
- shared-sqs backend не является первичной причиной зависания;
- проблема локализована на стороне platform ingress path;
- конкретно: ingress controller штурвала не применяет
nginx.ingress.kubernetes.io/proxy-request-buffering: "off", хотя upstream ingress-nginx эту аннотацию поддерживает; - часть других аннотаций при этом применяется корректно, значит речь не о полном игноре ingress-ресурса, а о selective handling/bug/platform override.
Дополнительные подтверждения
- Для host
qu.kube5s.ruсуществует только один ingress —shared-sqs-ingress, значит это не конфликт нескольких ingress-объектов. - В объекте ingress аннотация
proxy-request-buffering: "off"присутствует. - В итоговом
nginx.confдляqu.kube5s.ruостаётсяproxy_request_buffering on;. - В шаблоне контроллера
/etc/nginx/template/nginx.tmplдиректива не захардкожена; там используется значениеlocation.Proxy.RequestBuffering, то есть проблема происходит до фазы рендеринга финального location config. server-snippet/configuration-snippetнельзя считать рабочим обходным путём без platform-level изменений, так как snippet-аннотации контролируютсяallow-snippet-annotations, а по умолчанию этот режим отключён.
Операционный вывод
Это известное ограничение инфраструктуры, а не дефект бизнес-логики shared-sqs.
Итоговое решение
- hard-limit 32KB в код shared-sqs не внедряется;
- 32KB остаётся практической рекомендацией для AWS CLI/botocore-клиентов в текущей инфраструктуре;
- приоритет дальнейших работ по этой теме переносится с shared-sqs на platform ingress controller.
Симптом
SendMessage с телом ≥64740 байт зависает на 10-52 секунды и возвращает ошибку (ConnectionClosedError / exit=254).
Воспроизведение:
# Генерим payload 65KB
python3 -c "print('A'*65536)" > /tmp/big.txt
# Отправляем через AWS CLI — зависает на ~52 секунды
aws --endpoint-url https://qu.kube5s.ru sqs send-message \
--queue-url "https://qu.kube5s.ru/TENANT_ID/QUEUE_NAME" \
--message-body "file:///tmp/big.txt"
Диагностика
1. Сервер — OK
Port-forward (обход nginx): 65KB за 831ms. Сервер не виноват.
2. nginx ingress — частично виноват
client_body_timeout: 10s — nginx закрывает соединение если тело не пришло за 10 секунд.
3. Root Cause — botocore + urllib3 2.0 + TLS + Nagle
urllib3 2.0 посылает headers и body двумя отдельными send():
send#1: len=774 (headers)
send#2: len=65629 (body)
botocore ставит socket_options=[] → убирает TCP_NODELAY → Nagle ON.
Body шифруется TLS в 4 записи по ~16KB. Первые 3 уходят, 4-я застревает из-за Nagle + delayed ACK deadlock.
nginx access.log:
POST status=408 req_len=49926 bytes_sent=0 time=10.001s
Получено 49926 байт = headers(774) + 3 × TLS(~16384). Не хватает ровно 1 TLS-записи.
4. Порог
| Размер | Время | Статус |
|---|---|---|
| 64000B | 825ms | ✅ |
| 64720B | 799ms | ✅ |
| 64740B | 30806ms | ❌ intermittent |
| 65536B | 51843ms | ❌ всегда |
5. Версии ПО
| Компонент | Версия |
|---|---|
| nginx ingress | shturval-ingress-controller v1.12.6 |
| AWS CLI | v2.34.27 |
| AWS CLI Python | 3.14.3 (bundled) |
| System Python | 3.12.3 |
| System urllib3 | 2.0.7 |
| System botocore | 1.42.86 |
Что пробовали
Помогло частично:
- ConfigMap
client-body-timeout: "120"— pip boto3 (Python 3.12) стал работать (84ms → 13ms) - ConfigMap
client-body-buffer-size: "2m"— применилось глобально
Не помогло:
- Аннотация
proxy-request-buffering: "off"— shturval controller не применяет server-snippet: client_body_timeout 120s;— применилось но AWS CLI всё равно зависает- TCP_NODELAY patch через monkey-patch — нестабильно (1-й запрос fails)
Решение
Кодовый hard-limit не вводим.
Практическое правило эксплуатации:
- для AWS CLI / botocore в текущей ingress-инфраструктуре безопасно ориентироваться на 32KB;
- протокольный лимит SQS остаётся 256KB;
- проблема 64KB+ описывается как platform ingress limitation.
См. решение.
Статус
✅ Исследование завершено. Root cause локализован до platform ingress layer; изменение в коде shared-sqs не требуется.
Внешние ссылки
Для следующего захода в проблему использовать эти ссылки как стартовые:
-
Штурвал Community Edition, архитектура платформы: https://docs.k8s.ngcloud.ru/2.12/docs/common/structure/
-
ingress-nginx annotations: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/
-
ingress-nginx configmap options: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/
-
parser
proxy-request-bufferingв upstream ingress-nginx: https://github.com/kubernetes/ingress-nginx/blob/main/internal/ingress/annotations/proxy/main.go -
e2e test
should turn off proxy-request-buffering: https://github.com/kubernetes/ingress-nginx/blob/main/test/e2e/annotations/proxy.go
Краткий смысл ссылок:
- Штурвал: подтверждает, что Nginx Ingress Controller является частью platform stack;
- ingress-nginx docs/source: подтверждают, что
proxy-request-buffering— штатная поддерживаемая фича upstream, а значит текущее поведение похоже именно на platform-specific limitation/bug.