Утечка файловых дескрипторов в rw-node: fd растут непрерывно, conntrack стоит на месте
Окружение:
- Образ: remnawave/node:latest
- Xray Core: 26.7.28 (go1.26.5 linux/amd64)
- Хост: Ubuntu, ядро 6.8.0-139-generic, KVM, 6 vCPU / 9 ГБ RAM
- Инбаунд: один VLESS XHTTP + Reality на :443
- ~67 одновременных пользователей
- Включённые плагины: Torrent-Blocker, Egress Filter
Проблема:
Процесс rw-core накапливает сокетные файловые дескрипторы и не освобождает
их. Как следствие, RSS растёт примерно на 1 ГБ в сутки.
Замеры за 4 часа (снимок каждые 10 минут):
время rss_mb fd conntrack
11:30 7077 103559 83911
12:30 7266 104391 86124
13:30 7267 104997 83179
14:30 7268 105459 81914
15:10 7268 106395 80996
– перезапуск контейнера –
15:20 204 1396 6144
Ключевое наблюдение: conntrack держится на месте (~83k, колеблется в
пределах нормы), а количество fd только растёт — примерно +750 в час.
Ядро эти соединения уже освободило, rw-core свои сокеты не закрыл.
Подтверждается через /proc/1/net/sockstat внутри контейнера, примерно
через час после чистого перезапуска, когда установленных входящих
соединений всего 877:
sockets: used 2252
TCP: inuse 602 orphan 1 tw 334 alloc 1819 mem 0
alloc (1819) сильно превышает inuse (602) — сокеты выделены и не
возвращены, и разрыв со временем растёт.
Состав дескрипторов до перезапуска:
103429 socket:
28 pipe:
2 anon_inode:
Состояния сокетов внутри контейнера (/proc/net/tcp) до перезапуска:
103131 ESTABLISHED
534 TIME_WAIT
6 CLOSE_WAIT
Обратите внимание: сокеты числятся как ESTABLISHED, а не CLOSE_WAIT —
то есть это не похоже на пропущенный Close() при разрыве со стороны пира.
После перезапуска: 1396 fd, 204 МБ RSS, 877 установленных входящих
соединений со 171 уникального адреса, что соответствует реальному числу
пользователей. То есть те ~106k дескрипторов — накопленный за 4 дня
аптайма мусор, а не реальная нагрузка.
Воспроизводится на двух независимых нодах у разных хостеров, так что от
конкретного хоста не зависит.
Временное решение: перезапуск контейнера раз в сутки.
Подскажите, что полезнее всего снять дальше? Готов запустить с включённым
pprof или собрать goroutine dump, если образ это поддерживает.