null

Диагностика сетевой активности Linux в условиях потерь

Недавно столкнулись с интересной задачкой, которая возникла из-за странного стечения обстоятельств.

Вкратце, проблема связана с задержками в работе пользователей и изначально представлялась потерями пакетов, что подтверждается даже штатной утилитой ping:

$ ping -i 0.2 mail.ru # mail
PING mail.ru (94.100.180.200) 56(84) bytes of data.
64 bytes from cp.mail.ru (94.100.180.200): icmp_req=3 ttl=58 time=11.2 ms
...
64 bytes from cp.mail.ru (94.100.180.200): icmp_req=109 ttl=58 time=21.9 ms
--- mail.ru ping statistics ---
109 packets transmitted, 66 received, 39% packet loss, time 307289ms
rtt min/avg/max/mdev = 11.130/11.369/21.975/1.323 ms


$ ping -i 0.2 ya.ru # yandex
PING ya.ru (213.180.193.3) 56(84) bytes of data.
64 bytes from www.yandex.ru (213.180.193.3): icmp_req=2 ttl=56 time=10.8 ms
...
64 bytes from www.yandex.ru (213.180.193.3): icmp_req=7 ttl=56 time=10.8 ms
--- ya.ru ping statistics ---
7 packets transmitted, 6 received, 14% packet loss, time 10861ms
rtt min/avg/max/mdev = 10.789/10.906/11.088/0.155 ms


$ ping -i 0.2 8.8.8.8 # google
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_req=1071 ttl=58 time=8.74 ms
...
64 bytes from 8.8.8.8: icmp_req=1073 ttl=58 time=8.69 ms
--- 8.8.8.8 ping statistics ---
1073 packets transmitted, 990 received, 7% packet loss, time 216005ms
rtt min/avg/max/mdev = 8.623/8.968/52.273/2.152 ms

$ ping -i 0.2 192.168.1.2 # default gateway
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_req=1 ttl=64 time=0.088 ms
...
64 bytes from 192.168.1.2: icmp_req=305 ttl=64 time=0.029 ms
--- 192.168.1.2 ping statistics ---
305 packets transmitted, 303 received, 0% packet loss, time 60808ms
rtt min/avg/max/mdev = 0.018/0.117/14.024/1.008 ms

Для того, чтобы эту информацию детализировать, я предлагаю воспользоваться утилитой MTR. Она совмещает в себе ping и traceroute, определяя задержки до каждого хопа. Отметим, что она использует меньшие интервалы между запросами, поэтому требует прав суперпользователя.

Устновим CLI версию утилиты. Для debian это можно сделать так:

# apt-get install mtr-tiny

Основные используемые ключи:

-r -- сформировать отчёт

-w -- сделать отчёт более детальным

-c COUNT -- количество отправляемых пингов

 

Для проверки был выбран хост 8.8.8.8:

# mtr -rwc 5 8.8.8.8
HOST: alpha                          Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 192.168.1.2                    40.0%     5    0.0   0.0   0.0   0.0   0.0
  2.|-- gw-01-14.~~~~~~~~~~            40.0%     5    0.2   0.2   0.2   0.2   0.0
  3.|-- ptgcr1-rad2cr1.~~~~~~~~~       40.0%     5    0.5   0.5   0.5   0.5   0.0
  4.|-- ae0-3002.rt1.~~~~~~~~~~~~~~~~  60.0%     5   20.1  10.4   0.7  20.1  13.8
  5.|-- ae6-215-rt1.~~~~~~~~~~~~~~~~   60.0%     5    8.5   8.2   7.9   8.5   0.4
  6.|-- google-gw.~~~~~~~~~~~~~~~~     60.0%     5   10.1   9.2   8.3  10.1   1.3
  7.|-- 216.239.47.125                 60.0%     5    9.0   9.0   9.0   9.0   0.0
  8.|-- google-public-dns-a.google.com 60.0%     5    8.7   8.7   8.7   8.8   0.1

И то же самое, при использовании UDP:

# mtr -rwuc 5 8.8.8.8
HOST: alpha                         Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 192.168.1.2                   40.0%     5    0.0   0.0   0.0   0.0   0.0
  2.|-- gw-01-14.~~~~~~~~~~           40.0%     5    0.2   0.3   0.2   0.4   0.1
  3.|-- ptgcr1-rad2cr1.~~~~~~~~~      40.0%     5    0.5   0.5   0.5   0.6   0.0
  4.|-- ae0-3002.rt1.~~~~~~~~~~~~~~~~ 20.0%     5    0.7   0.7   0.6   0.7   0.0
  5.|-- ae6-215-rt1.~~~~~~~~~~~~~~~~  80.0%     5    8.0   8.0   8.0   8.0   0.0
  6.|-- ???                           100.0     5    0.0   0.0   0.0   0.0   0.0

В этом случае, очевидно, проблема на нашей системе.

Это подтверждается, если заглянуть в /var/log/messages:

Feb 20 11:17:42 ~~~ kernel: [1366055.534335] nf_conntrack: table full, dropping packet.
Feb 20 11:17:42 ~~~ kernel: [1366055.541823] nf_conntrack: table full, dropping packet.
Feb 20 11:17:42 ~~~ kernel: [1366055.725239] nf_conntrack: table full, dropping packet.

Посмотреть соединения можно используя подсистему conntrack:

# wc -l /proc/net/nf_conntrack
63331 /proc/net/nf_conntrack
# grep -c TIME_WAIT /proc/net/nf_conntrack
2760

В нашем случае проблема решилась просто:

# echo net.netfilter.nf_conntrack_max=1048576 >> /etc/sysctl.conf
# sysctl -p
net.ipv4.ip_forward = 1
net.netfilter.nf_conntrack_max = 1048576

Сообщения в messages попадать перестали, а mtr (в том числе, с маршрутизатора - 192.168.1.2) теперь показывает 0% потерь:

# mtr -rwc 5 8.8.8.8
HOST: 192.168.1.2                    Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- gw-01-14.~~~~~~~~~~             0.0%     5    0.2   0.2   0.2   0.2   0.0
  2.|-- ptgcr1-rad2cr1.~~~~~~~~~        0.0%     5    0.5   0.5   0.4   0.5   0.0
  3.|-- ae0-3002.rt1.~~~~~~~~~~~~~~~~   0.0%     5    0.8   0.6   0.6   0.8   0.1
  4.|-- ae6-215-rt1.~~~~~~~~~~~~~~~~    0.0%     5    7.9  16.5   7.9  46.6  16.9
  5.|-- google-gw.~~~~~~~~~~~~~~~~      0.0%     5    8.3   8.3   8.3   8.3   0.0
  6.|-- 216.239.47.125                  0.0%     5    9.1   9.0   8.9   9.1   0.1
  7.|-- google-public-dns-a.google.com  0.0%     5    8.7   8.7   8.7   8.8   0.0

Итого, резюмируя понимание проблемы:

В ЦОД лёг один из провайдеров, весь трафик был целиком переведён на второго и начались задержки.

В это время, трафик через наш сервер начал порождать большое количество открытых соединений и переполнилась таблица соединений в ядре.

Совместными усилиями наших инженеров и специалистов ЦОД, проблема была устранена. Трафик ходит, задержек нет, заказчик доволен.

 

Но проблема имеет такое простое решение только если есть возможность выполнить подобные настройки. Зачастую, приходится обслуживать большие потоки данных. В нашем случае, используя tcpdump, было выявлено большое количество ACK на несуществующие соединения. Для того, чтобы не загружать систему, можно воспользоваться встроенной в ядро подсистемой защиты от ACK-флудов. Проще всего это сделать установив значение переменной new.ipv4.ip_conntrack_loose в 0. Это позволит отбрасывать INVALID-пакеты.

korg

 

Коротко о себе

Работаю в компании Tune-IT, администрирую инфраструктуру компании и вычислительную сеть кафедры Вычислительной ТехникиСПбНИУ ИТМО.

Интересы: администрирование UNIX и UNIX-like систем и активного сетевого оборудования, написание shell- и perl-скриптов, изучение технологий глобальных сетей.
Люблю собирать GNU/Linux и FreeBSD, использовать тайлинговые оконные менеджеры и писать системный софт.