docs: finalize 64kb ingress investigation
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
# 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.
|
||||
|
||||
### Дополнительные подтверждения
|
||||
1. Для host `qu.kube5s.ru` существует только один ingress — `shared-sqs-ingress`, значит это не конфликт нескольких ingress-объектов.
|
||||
2. В объекте ingress аннотация `proxy-request-buffering: "off"` присутствует.
|
||||
3. В итоговом `nginx.conf` для `qu.kube5s.ru` остаётся `proxy_request_buffering on;`.
|
||||
4. В шаблоне контроллера `/etc/nginx/template/nginx.tmpl` директива не захардкожена; там используется значение `location.Proxy.RequestBuffering`, то есть проблема происходит до фазы рендеринга финального location config.
|
||||
5. `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).
|
||||
|
||||
**Воспроизведение:**
|
||||
```bash
|
||||
# Генерим 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.
|
||||
|
||||
См. [решение](../decisions/message-size-limit-2026-04-11.md).
|
||||
|
||||
## Статус
|
||||
✅ Исследование завершено. Root cause локализован до platform ingress layer; изменение в коде shared-sqs не требуется.
|
||||
Reference in New Issue
Block a user