- PVSM.RU - https://www.pvsm.ru -
Часто мониторинг сетевой подсистемы операционной системы заканчивается на счетчиках пакетов, октетов и ошибок сетевых интерфейсах. Но это только 2й уровень модели OSI [1]!
С одной стороны большинство проблем с сетью возникают как раз на физическом и канальном уровнях, но с другой стороны приложения, работающие с сетью оперируют на уровне TCP сессий и не видят, что происходит на более низких уровнях.
Я расскажу, как достаточно простые метрики TCP/IP стэка могут помочь разобраться с различными проблемами в распределенных системах.
Почти все знают утилиту 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], разбивку по которым мы тоже сохраняем (это иногда может оказаться полезным):
По этому графику можно оценить общее количество входящих соединений, распределение соединений по состояниям.
Здесь так же видно резкое падение общего количества соединений незадолго до 11 Jun, попробуем посмотреть на соединения в разрезе listen портов:
На этом графике видно, что самое значительное падение было на порту 8014, посмотрим только 8014 (у нас в интерфейсе можно просто нажать на нужном элементе легенды):
Попробуем посмотреть, изменилось ли количество входящий соединений по всем серверам?
Выбираем серверы по маске “srv10*”:
Теперь мы видим, что количество соединений на порт 8014 не изменилось, попробуем найти на какой сервер они мигрировали:
Мы ограничили выборку только портом 8014 и сделали группировку не по порту, а по серверам.
Теперь понятно, что соединения с сервера srv101 перешли на srv102.
Часто бывает необходимо посмотреть, сколько было соединений с различных IP адресов. Наш агент снимает количество TCP соединений не только с разбивкой по listen портам и состояниям, но и по удаленному IP, если данный IP находится в том же сегменте сети (для всех остальный адресов метрики суммируются и вместо IP мы показываем “~nonlocal”).
Рассмотрим тот же период времени, что и в предыдущих случаях:
Здесь видно, что соединений с 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 [6]).
На самом деле очереди две:
При достижении лимита accept queue ACK пакет удаленного хоста просто отбрасывается или отправляется RST (в зависимости от значения переменной sysctl net.ipv4.tcp_abort_on_overflow).
Наш агент снимает текущее и максимальное значение accept queue для всех listen сокетов на сервере.
Для этих метрик есть график и преднастроенный триггер, который уведомит, если backlog любого сервиса использован более чем на 90%:
Однажды сайт одного из наших клиентов подвергся DDOS атаке, в мониторинге было видно только увеличение трафика на сетевом интерфейсе, но мы не показывали абсолютно никаких метрик по содержанию этого трафика.
В данный момент однозначного ответа на этот вопрос окметр дать по-прежнему не может, так как сниффинг мы только начали осваивать [9], но мы немного продвинулись в этом вопросе.
Попробуем что-то понять про эти выбросы входящего трафика:
Теперь мы видим, что это входящий UDP трафик, но здесь не видно первых из трех выбросов.
Дело в том, что счетчики пакетов по протоколам в linux увеличиваются только в случае успешной обработки пакета.
Попробуем посмотреть на ошибки:
А вот и наш первый пик — ошибки UDP:NoPorts (количество датаграмм, пришедших на UPD порты, которые никто не слушает)
Данный пример мы эмулировали с помощью iperf, и в первый заход не включили на сервер-приемщик пакетов на нужном порту.
Отдельно мы показываем количество TCP ретрансмитов (повторных отправок TCP сегментов [10]).
Само по себе наличие ретрансмитов не означает, что в вашей сети есть потери пакетов.
Повторная передача сегмента осуществляется, если передающий узел не получил от принимающего подтверждение (ACK) в течении определенного времени (RTO).
Данный таймаут расчитывается динамически [11] на основе замеров времени передачи данных между конкретными хостами (RTT) для того, чтобы обеспечивать гарантированную передачу данных при сохранении минимальных задержек.
На практике количество ретрансмитов обычно коррелирует с нагрузкой на серверы и важно смотреть не на абсолютное значение, а на различные аномалии:
На данном графике мы видим 2 выброса ретрансмитов, в это же время процессы postgres утилизировали CPU данного сервера:
Cчетчики протоколов мы получаем из /proc/net/snmp.
Еще одна распространенная проблема — переполнение таблицы ip_conntrack в linux (используется iptables [12]), в этом случае linux начинает просто отбрасывать пакеты.
Это видно по сообщению в dmesg:
ip_conntrack: table full, dropping packet
Агент автоматически снимает текущий размер данной таблицы и лимит с серверов, использующих ip_conntrack.
В окметре так же есть автоматический триггер, который уведомит, если таблица ip_conntrack заполнена более чем на 90%:
На данном графике видно, что таблица переполнялась, лимит подняли и больше он не достигался.
Примеры наших стандартных графиков можно посмотреть в нашем демо-проекте [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
Нажмите здесь для печати.