Медленный линк без видимой причины и первые шаги диагностики
Жалоба звучит знакомо каждому администратору: сервер вроде жив, диски не скрипят, процессор не раскалён, а файл размером в гигабайт копируется по сети десять минут. Пользователи ругаются, мониторинг молчит, и первое желание - обвинить приложение. Честно говоря, в доброй половине таких случаев виноват не софт, а самый нижний уровень: сетевой интерфейс, который тихо договорился со свитчом на 100 Mb/s Half duplex вместо положенных 1000 Mb/s Full. Это классический footgun auto-negotiation: всё "работает", линк есть, пинги бегают, но реальная полоса просела в десять раз, а duplex mismatch добавляет потери пакетов. Хорошая новость в том, что диагностируется это за минуту с помощью ethtool, и дальше статья разбирает весь путь от первого взгляда на линк до устойчивого исправления.
Базовый диагноз с ethtool и чтение Speed Duplex Link detected
Первое действие на подозрительном сервере предельно простое:
ethtool eth0
Типовой вывод на больной машине выглядит так:
Settings for eth0:
Supported ports: [ TP ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Supported pause frame use: Symmetric
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
Advertised pause frame use: Symmetric
Advertised auto-negotiation: Yes
Speed: 100Mb/s
Duplex: Half
Port: Twisted Pair
PHYAD: 1
Transceiver: internal
Auto-negotiation: on
MDI-X: on (auto)
Link detected: yes
Разбор по ключевым строкам. Supported link modes перечисляет всё, что умеет карта: здесь и 10, и 100, и 1000 Мбит, значит железо исправно и гигабит ему доступен. Advertised link modes - это то, что карта сама предлагает партнёру по кабелю во время auto-negotiation, и вот тут уже видно подвох: гигабитный режим 1000baseT/Full в список не попал. Speed показывает фактическую скорость установленного линка - 100Mb/s, а Duplex: Half означает, что больше одной стороны одновременно передавать не может, коллизии и ретрансляции обеспечены. Link detected: yes говорит, что физический линк поднят, то есть кабель вставлен и сигнал есть, но качество соглашения оставляет желать лучшего. Поле MDI-X время от времени вводит в заблуждение: оно про автоопределение прямого или кроссового кабеля, к скорости отношения не имеет.
Здоровый вывод для сравнения содержал бы Speed: 1000Mb/s, Duplex: Full и 1000baseT/Full среди advertised режимов. Разница в пропускной способности не двадцать процентов, а порядок: гигабит Full duplex даёт на практике около 940 Мбит/с полезного TCP-трафика, а 100 Half едва вытягивает 40-45 Мбит/с с потерями.
Драйвер прошивка и счётчики ошибок как вторая линия улик
Следующий шаг - понять, какой драйвер обслуживает интерфейс и насколько свежая у него прошивка:
ethtool -i eth0
driver: e1000e
version: 3.8.4-NAPI
firmware-version: 0.5-3
expansion-rom-version:
bus-info: 0000:00:19.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: yes
Здесь важны три поля: driver показывает модуль ядра (для серверных Intel-адаптеров чаще всего e1000e, igb или ixgbe, у Realtek встречается r8169, известный капризным поведением на гигабите), firmware-version позволяет сверить прошивку PHY с рекомендованной вендором, а bus-info пригодится, чтобы сопоставить интерфейс со слотом PCI и не перепутать порты на четырёхголовой карте. Старые версии r8169, например, исторически имели ошибки в реализации auto-negotiation, и обновление на r8168 от производителя решало проблему без замены железа.
Теперь статистика ошибок:
ethtool -S eth0 | grep -iE "error|crc|drop|collision"
rx_crc_errors: 14832
rx_errors: 14901
tx_errors: 0
rx_missed_errors: 17
collisions: 9204
rx_length_errors: 0
rx_over_errors: 0
rx_frame_errors: 264
tx_aborted_errors: 0
Это уже похоже на признание вины. Поле rx_crc_errors росло на десятки в секунду - значит, кадры доезжают битыми, что типично для повреждённого кабеля, плохого коннектора или duplex mismatch. Счётчик collisions приличен сам по себе для Half duplex, но если Duplex: Full, а коллизии копятся, это верный признак, что вторая сторона линка работает в Half - классический mismatch, когда одна сторона смотрит на передачу партнёра как на коллизию, а вторая молча теряет кадры. Поле rx_missed_errors показывает, что карта не успевала забирать кадры, но здесь значения мизерные и вины системы нет. Общий приём: снимают значения ethtool -S дважды с интервалом в минуту и смотрят приросты - статические числа могут быть наследием прошлых лет, важна динамика.
Принудительная установка скорости и почему autoneg off опасен
Когда диагноз ясен, рука тянется исправить всё силой:
ethtool -s eth0 speed 1000 duplex full autoneg on
Команда устанавливает скорость 1000 Мбит/с, полный дуплекс и оставляет auto-negotiation включённым - для витой пары на гигабите это единственно корректный режим, потому что стандарт 1000base-T прямо требует автосогласования для выбора master/slave и синхронизации тактирования. Вариант с autoneg off выглядит заманчиво, но таятся два подводных камня. Первый: при выключенной автосогласованности карта перестаёт сообщать партнёру свои возможности, и свитч по стандарту обязан откатиться на 100base-TX Half duplex - получаем ровно тот footgun, с которого начали. Второй: принудительная установка действует до перезагрузки или до переподнятия интерфейса, и после ребута всё вернётся на круги своя, если настройку не зафиксировать в конфигурации NetworkManager (параметры 802-3-ethernet.speed и 802-3-ethernet.duplex в nmcli) или в /etc/network/interfaces через pre-up ethtool.
Ключевая разница подходов: auto-negotiation - это переговоры, где обе стороны публикуют список режимов и выбирают лучший общий, а принудительная фиксация - односторонний приказ, который партнёр может не понять. На оптических линках 1G SFP фиксация скорости иногда оправдана и даже требуется вендором, но на меди правило простое: либо обе стороны в autoneg, либо жди неприятностей. Проверка после любых изменений - снова ethtool eth0 и контроль строк Speed и Duplex, плюс повторный iperf3.
Кабель и порт свитча как физические виновники просадки
Сценарий из жизни: сервер пять лет стоял в стойке, тянул гигабит, и вдруг после перестановки скорость упала до 100 Мбит. Виноват оказался патч-корд. Кабель категории 5 официально рассчитан на 100base-TX, и хотя короткий целый кусок cat5 иногда поднимает гигабит, стоит появиться одной плохой обжимке или повреждённой паре - и auto-negotiation честно договаривается до сотни. Гигабитный 1000base-T использует все четыре пары витой пары, тогда как 100base-TX довольствуется двумя. Перебитая или непропаянная пара в кабеле cat5 означает: сотня есть, гигабита не будет никогда. Категории 5e и 6 гарантируют нужные характеристики затухания и перекрёстных наводок, поэтому для серверной патч-корды категории не ниже 5e - не роскошь, а гигиена.
Проверка со стороны свитча не менее обязательна. На управляемом свитче смотрят состояние порта: счётчики CRC на стороне свитча, history логов link up/down, настроенный режим порта. Нередко порт на свитче кто-то когда-то зафиксировал в 100 full "для надёжности", и тогда сервер с autoneg получает ровно то, что ему диктуют, либо duplex mismatch, если времена фиксации на двух сторонах разошлись. Быстрый тест без доступа к свитчу - переставить патч-корд в соседний заведомо гигабитный порт и посмотреть, изменится ли Speed в выводе ethtool. Если скорость поднялась - виноват порт или его конфигурация, если нет - кабель или сама карта. На заметку: iperf3 между сервером и заведомо здоровым соседом подтверждает диагноз цифрой, а не ощущением.
Замер реальной полосы с iperf3 и обход без ethtool
iperf3 - стандартный способ измерить пропускную способность, а не верить выводу ethtool на слово. На соседней машине запускают сервер:
iperf3 -s
На диагностируемом сервере - клиент:
iperf3 -c 192.168.10.5 -t 30 -P 4
Опция -t 30 задаёт длительность теста в 30 секунд, -P 4 поднимает четыре параллельных потока, что снимает ограничение одного TCP-окна. Здоровый гигабитный линк покажет суммарно 930-950 Mbits/sec. Линк 100 Mb/s Half duplex выдаст 30-45 Mbits/sec с приличным числом ретрансляций в колонке Retr - их счёт в выводе iperf3 хорошо коррелирует с collisions из ethtool -S.
Запасные пути, когда ethtool под рукой нет или он не поддержан драйвером. Ядро публикует скорость через sysfs - читается прямо из файла:
cat /sys/class/net/eth0/speed
cat /sys/class/net/eth0/duplex
Первый файл вернёт 100 или 1000, второй - full или half. Учтите: при опущенном линке чтение /sys/class/net/eth0/speed вернёт ошибку "Invalid argument", это нормально и означает лишь отсутствие линка. Утилита mii-tool из пакета net-tools - старейшая альтернатива, выводит что-то вроде "eth0: negotiated 100baseTx-HD, link ok", но считается устаревшей: она общается с PHY через устаревший MII-регистровый интерфейс, не знает про гигабитные и более скоростные режимы и на современных адаптерах часто врёт или не работает вовсе. Держите её в голове только как экспонат.
Лог link-событий смотрят в журнале ядра:
dmesg | grep -i eth0
journalctl -k | grep -i link
[ 12.418203] e1000e 0000:00:19.0 eth0: NIC Link is Up 100 Mbps Half Duplex, Flow Control: None
[ 4210.771950] e1000e 0000:00:19.0 eth0: NIC Link is Down
[ 4213.884120] e1000e 0000:00:19.0 eth0: NIC Link is Up 100 Mbps Half Duplex, Flow Control: None
Периодические пары Link Down / Link Up в dmesg - отпечаток нестабильного контакта или проблем с портом свитча, а строка "Link is Up 100 Mbps Half Duplex" прямо фиксирует момент, когда карта согласовала убогий режим. Если интерфейс переименован через predictable names (enp0s25 и подобные), подставьте актуальное имя во все команды.
Пошаговый план администратора и профилактика повторений
Практический порядок действий на продакшене выглядит так:
- Выполнить ethtool eth0 и зафиксировать Speed, Duplex, Link detected, advertised режимы;
- Посмотреть ethtool -S eth0, повторить через минуту и оценить прирост crc_errors, rx_errors, collisions;
- Проверить dmesg и journalctl -k на предмет Link Down/Up и зафиксированной скорости;
- Прогнать iperf3 с соседним хостом для объективной цифры полосы и числа ретрансляций;
- Переставить кабель в заведомо исправный порт свитча и заменить патч-корд на cat5e или cat6;
- Проверить конфигурацию порта свитча, убрать ручную фиксацию скорости, оставить autoneg с обеих сторон;
- При необходимости принудительно выставить ethtool -s eth0 speed 1000 duplex full autoneg on и зафиксировать настройку в конфигурации сетевого менеджера, чтобы пережить перезагрузку.
Профилактика проста и дешевле ночных инцидентов. Мониторинг должен читать /sys/class/net/*/speed и опережающе алертить, если серверный интерфейс вдруг договорился ниже ожидаемой скорости - это одна строка в скрипте проверки и одна метрика для системы наблюдения. При приёмке нового сервера в стойку полезно сразу снять вывод ethtool и iperf3 как эталон, а при каждой смене патч-кордов фиксировать категорию кабеля. Маркируйте кабели, не жалейте cat6 на серверные порты и не позволяйте никому фиксировать скорость на портах свитча без ведома администраторов серверов. И храните эталонные выводы ethtool для каждого узла: когда через полгода что-то просядет, сравнение с эталоном сократит диагностику с часа до пяти минут.
Отдельного упоминания заслуживает привычка фиксировать диагностику в тикетах. Строка "Speed: 100Mb/s, Duplex: Half, crc_errors растут" в журнале инцидента экономит часы того, кто разберёт похожую жалобу через год. Администраторы с опытом знают: проблемы физического уровня почти никогда не лечатся сами, они лишь маскируются, пока нагрузка невелика, и всплывают в самый неудобный момент, например во время ночного бэкапа или бухгалтерской отчётности.
Медленная сеть почти всегда честно рассказывает о себе сама - нужно только знать, у кого спросить. ethtool спрашивает у карты и у PHY напрямую, dmesg помнит историю, iperf3 даёт беспристрастную цифру. Пять команд, десять минут, и загадочная "тормозящая сеть" превращается в конкретный патч-корд cat5, пережатый кабель-менеджером стойки.