- PVSM.RU - https://www.pvsm.ru -

Мониторинг сетевого стэка linux

Мониторинг сетевого стэка linux - 1Часто мониторинг сетевой подсистемы операционной системы заканчивается на счетчиках пакетов, октетов и ошибок сетевых интерфейсах. Но это только 2й уровень модели OSI [1]!
С одной стороны большинство проблем с сетью возникают как раз на физическом и канальном уровнях, но с другой стороны приложения, работающие с сетью оперируют на уровне TCP сессий и не видят, что происходит на более низких уровнях.

Я расскажу, как достаточно простые метрики TCP/IP стэка могут помочь разобраться с различными проблемами в распределенных системах.

Netlink

Почти все знают утилиту netstat [2] в linux, она может показать все текущие TCP соединения и дополнительную информацию по ним. Но при большом количестве соединений netstat может работать достаточно долго и существенно нагрузить систему.

Есть более дешевый способ получить информацию о соединениях — утилита ss [3] из проекта iproute2.

Для сравнения:

$ time netstat -an|wc -l
62109

real    0m0.467s
user    0m0.288s
sys     0m0.184s

$ time ss -ant|wc -l
62111

real    0m0.126s
user    0m0.112s
sys     0m0.016s

Ускорение достигается за счет использования протола netlink [4] для запросов информации о соединениях у ядра. Наш агент использует netlink напрямую.

Считаем соединения

Disclaimer: для иллюстрации работы с метриками в разных срезах я буду показывать наш интерфейс (dsl) работы с метриками, но это можно сделать и на opensource хранилищах.

В первую очередь мы разделяем все соединения на входящие (inbound) и исходящие (outbound) по отношению к серверу.

Каждое TCP соединения в определенный момент времени находится в одном из состояний [5], разбивку по которым мы тоже сохраняем (это иногда может оказаться полезным):

Мониторинг сетевого стэка linux - 2

По этому графику можно оценить общее количество входящих соединений, распределение соединений по состояниям.

Здесь так же видно резкое падение общего количества соединений незадолго до 11 Jun, попробуем посмотреть на соединения в разрезе listen портов:

Мониторинг сетевого стэка linux - 3

На этом графике видно, что самое значительное падение было на порту 8014, посмотрим только 8014 (у нас в интерфейсе можно просто нажать на нужном элементе легенды):

Мониторинг сетевого стэка linux - 4

Попробуем посмотреть, изменилось ли количество входящий соединений по всем серверам?

Выбираем серверы по маске “srv10*”:

Мониторинг сетевого стэка linux - 5

Теперь мы видим, что количество соединений на порт 8014 не изменилось, попробуем найти на какой сервер они мигрировали:

Мониторинг сетевого стэка linux - 6

Мы ограничили выборку только портом 8014 и сделали группировку не по порту, а по серверам.

Теперь понятно, что соединения с сервера srv101 перешли на srv102.

Разбивка по IP

Часто бывает необходимо посмотреть, сколько было соединений с различных IP адресов. Наш агент снимает количество TCP соединений не только с разбивкой по listen портам и состояниям, но и по удаленному IP, если данный IP находится в том же сегменте сети (для всех остальный адресов метрики суммируются и вместо IP мы показываем “~nonlocal”).

Рассмотрим тот же период времени, что и в предыдущих случаях:

Мониторинг сетевого стэка linux - 7

Здесь видно, что соединений с 192.168.100.1 стало сильно меньше и в это же время появились соединения с 192.168.100.2.

Детализация рулит

На самом деле мы работали с одной метрикой, просто она была сильно детализирована, индентификатор каждого экземпляра выглядит примерно так:

{name="netstat.connections.inbound.count", state="<TCP_STATE>", listen_ip="<IP>" listen_port="<PORT>" remote_ip="<REMOTE_IP>"}

Например, у одно из клиентов на нагруженном сервере-фронтенде снимается ~700 экземпляров этой метрики

TCP backlog

По метрикам TCP соединений можно не только диагностировать работу сети, но и определять проблемы в работе сервисов.

Например, если какой-то сервис, обслуживающий клиентов по сети, не справляется с нагрузкой и перестает обрабатывать новые соединения, они ставятся в очередь (backlog [6]).

На самом деле очереди две:

  • SYN queue — очередь неустановленных соединений (получен пакет SYN, SYN-ACK еще не отправлен), размер ограничен согласно sysctl net.ipv4.tcp_max_syn_backlog;
  • Accept queue — очередь соединений, для которых получен пакет ACK (в рамках "тройного рукопожатия" [7]), но не был выполнен accept [8] приложением (очередь ограничивается приложением)

При достижении лимита accept queue ACK пакет удаленного хоста просто отбрасывается или отправляется RST (в зависимости от значения переменной sysctl net.ipv4.tcp_abort_on_overflow).

Наш агент снимает текущее и максимальное значение accept queue для всех listen сокетов на сервере.

Для этих метрик есть график и преднастроенный триггер, который уведомит, если backlog любого сервиса использован более чем на 90%:

Мониторинг сетевого стэка linux - 8

Счетчики и ошибки протоколов

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

В данный момент однозначного ответа на этот вопрос окметр дать по-прежнему не может, так как сниффинг мы только начали осваивать [9], но мы немного продвинулись в этом вопросе.

Попробуем что-то понять про эти выбросы входящего трафика:

Мониторинг сетевого стэка linux - 9

Мониторинг сетевого стэка linux - 10

Теперь мы видим, что это входящий UDP трафик, но здесь не видно первых из трех выбросов.
Дело в том, что счетчики пакетов по протоколам в linux увеличиваются только в случае успешной обработки пакета.

Попробуем посмотреть на ошибки:

Мониторинг сетевого стэка linux - 11

А вот и наш первый пик — ошибки UDP:NoPorts (количество датаграмм, пришедших на UPD порты, которые никто не слушает)

Данный пример мы эмулировали с помощью iperf, и в первый заход не включили на сервер-приемщик пакетов на нужном порту.

TCP ретрансмиты

Отдельно мы показываем количество TCP ретрансмитов (повторных отправок TCP сегментов [10]).

Само по себе наличие ретрансмитов не означает, что в вашей сети есть потери пакетов.
Повторная передача сегмента осуществляется, если передающий узел не получил от принимающего подтверждение (ACK) в течении определенного времени (RTO).

Данный таймаут расчитывается динамически [11] на основе замеров времени передачи данных между конкретными хостами (RTT) для того, чтобы обеспечивать гарантированную передачу данных при сохранении минимальных задержек.

На практике количество ретрансмитов обычно коррелирует с нагрузкой на серверы и важно смотреть не на абсолютное значение, а на различные аномалии:

Мониторинг сетевого стэка linux - 12

На данном графике мы видим 2 выброса ретрансмитов, в это же время процессы postgres утилизировали CPU данного сервера:

Мониторинг сетевого стэка linux - 13

Cчетчики протоколов мы получаем из /proc/net/snmp.

Conntrack

Еще одна распространенная проблема — переполнение таблицы ip_conntrack в linux (используется iptables [12]), в этом случае linux начинает просто отбрасывать пакеты.

Это видно по сообщению в dmesg:

ip_conntrack: table full, dropping packet

Агент автоматически снимает текущий размер данной таблицы и лимит с серверов, использующих ip_conntrack.

В окметре так же есть автоматический триггер, который уведомит, если таблица ip_conntrack заполнена более чем на 90%:

Мониторинг сетевого стэка linux - 14

На данном графике видно, что таблица переполнялась, лимит подняли и больше он не достигался.

Вместо заключения

  • детализация метрик очень важна
  • если где-то что-то может переполниться, нужно обязательно покрывать мониторингом такие места
  • мы снимаем еще много разного по TCP/IP (RTT, соединения с непустыми send/recv очередями), но пока не придумали, как c этим правильно работать

Примеры наших стандартных графиков можно посмотреть в нашем демо-проекте [13].
Там же можно постмотреть графики Netstat [14] одного из серверов.

Автор: okmeter.io

Источник [15]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/monitoring/185670

Ссылки в тексте:

[1] OSI: https://ru.wikipedia.org/wiki/%D0%A1%D0%B5%D1%82%D0%B5%D0%B2%D0%B0%D1%8F_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C_OSI

[2] netstat: http://man7.org/linux/man-pages/man8/netstat.8.html

[3] ss: http://man7.org/linux/man-pages/man8/ss.8.html

[4] netlink: http://man7.org/linux/man-pages/man7/netlink.7.html

[5] состояний: https://tools.ietf.org/html/rfc793#page-21

[6] backlog: http://veithen.github.io/2014/01/01/how-tcp-backlog-works-in-linux.html

[7] "тройного рукопожатия": http://www.inetdaemon.com/tutorials/internet/tcp/3-way_handshake.shtml

[8] accept: http://man7.org/linux/man-pages/man2/accept.2.html

[9] начали осваивать: https://habrahabr.ru/company/okmeter/blog/308328/

[10] повторных отправок TCP сегментов: https://en.wikipedia.org/wiki/Retransmission_(data_networks)

[11] расчитывается динамически: http://sgros.blogspot.ru/2012/02/calculating-tcp-rto.html

[12] iptables: https://en.wikipedia.org/wiki/Iptables

[13] демо-проекте: https://okmeter.io/example

[14] Netstat: https://okmeter.io/example/hosts/db2/Netstat

[15] Источник: https://habrahabr.ru/post/309600/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best