Хабрахабр

[Из песочницы] Изучаем трассировку с помощью eBPF: Руководство и примеры

Предлагаю вашему вниманию перевод статьи Брендана Грегга, посвящённой изучению eBPF Привет, Хабр!

Он быстро стал не просто бесценной технологией, но и востребованным навыком. На конференции Linux Plumbers было как минимум 24 выступления по eBPF. Возможно, вам хотелось бы поставить какую-то цель на новый год — изучите eBPF!

Он применим во многих областях, таких как производительность сети, фаерволлы, безопасность, трассировка и драйвера устройств. Термин eBPF должен означать что-то существенное, как например Virtual Kernel Instruction Set (VKIS), но по своему происхождению это расширенный Berkeley Packet Filter. Термин трассировка относится к инструментам анализа производительности и наблюдения, которые могут генерировать информацию по каждому событию. По некоторым из них есть много свободно доступной информации в интернете — например, по трассировке, а по другим ещё нет. Возможно, вы уже использовали трассировщик — tcpdump и strace являются специализированными трассировщиками.

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

  • Начинающим: запуск инструментов bcc
  • Опытным: разработка инструментов bpftrace
  • Продвинутым: разработка инструментов bcc, вклад в bcc и bpftrace

1. Что такое eBPF, bcc, bpftrace и iovisor?

Так, вместо статического сайта на HTML, JavaScript позволяет вам задавать мини-программы, которые выполняются по событиям — вроде щелчка мышкой — которые запускаются в безопасной виртуальной машине в браузере. eBPF делает для Linux тоже самое, что и JavaScript делает для HTML, ну вроде того. На самом деле eBPF больше похож на виртуальную машину v8, запускающую JavaScript, чем на сам JavaScript. И с eBPF — вместо правки ядра, вы можете теперь писать мини-программы, которые запускаются при событиях вроде дисковых операций ввода-вывода, на безопасной виртуальной машине в ядре. eBPF является частью ядра Linux.

Но никто не кодит в v8: все пишут на JavaScript, или часто на фреймворке поверх JavaScript (jQuery, Angular, React, и т.д.). Программирование напрямую в eBPF невероятно сложно, так же, как и в байт-коде на v8. Люди будут использовать его, а писать код — посредством фреймворков. Тоже самое и с eBPF. Они не живут в кодовой базе ядра, они обитают в проекте Linux Foundation на гитхабе, называющемся iovisor. Для трассировки основными являются bcc и bpftrace.

2. Можно пример трассировки с помощью eBPF?

Эта основанная на eBPF утилита демонстрирует полностью установленные TCP сессии с их ID процесса (PID), именем команды (COMM), отправленными и полученными байтами (TX_KB, RX_KB), а также длительность в миллисекундах (MS):

# tcplife

PID COMM LADDR LPORT RADDR RPORT TX_KB RX_KB MS
22597 recordProg 127.0.0.1 46644 127.0.0.1 28527 0 0 0.23
3277 redis-serv 127.0.0.1 28527 127.0.0.1 46644 0 0 0.28
22598 curl 100.66.3.172 61620 52.205.89.26 80 0 1 91.79
22604 curl 100.66.3.172 44400 52.204.43.121 80 0 1 121.38
22624 recordProg 127.0.0.1 46648 127.0.0.1 28527 0 0 0.22
3277 redis-serv 127.0.0.1 28527 127.0.0.1 46648 0 0 0.27
22647 recordProg 127.0.0.1 46650 127.0.0.1 28527 0 0 0.21
3277 redis-serv 127.0.0.1 28527 127.0.0.1 46650 0 0 0.26
[...]

Но если бы я это сделал, мы бы никогда не запустили такой инструмент в продакшне из-за снижения производительности, проблем с безопасностью или сразу и того и другого. Не это eBPF делает возможным — я могу переписать tcplife, чтобы использовать более старые технологии ядра. Например, он не отслеживает каждый пакет, как делалось при прежних подходах и что могло приводить к чрезмерному снижению производительности. eBPF сделал этот инструмент практичным: он эффективен и безопасен. Это делает накладные расходы настолько низкими, что мы можем запустить этот инструмент в режиме 24x7. Вместо этого он отслеживает лишь события TCP-сессии, которые происходят куда реже.

3. Как мне это использовать?

Посмотрите инструкции по установке bcc под вашу операционную систему. Начинающим стоит начать знакомство с bcc. Для Ubuntu это выглядит как-то так:

# sudo apt-get update
# sudo apt-get install bpfcc-tools
# sudo /usr/share/bcc/tools/opensnoop

PID COMM FD ERR PATH
25548 gnome-shell 33 0 /proc/self/stat
10190 opensnoop -1 2 /usr/lib/python2.7/encodings/ascii.x86_64-linux-gnu.so
10190 opensnoop -1 2 /usr/lib/python2.7/encodings/ascii.so
10190 opensnoop -1 2 /usr/lib/python2.7/encodings/asciimodule.so
10190 opensnoop 18 0 /usr/lib/python2.7/encodings/ascii.py
10190 opensnoop 19 0 /usr/lib/python2.7/encodings/ascii.pyc
25548 gnome-shell 33 0 /proc/self/stat
29588 device poll 4 0 /dev/bus/usb
^C

Если вы дошли так далеко, вы точно пользовались eBPF! Здесь я закончил запуском opensnoop, чтобы проверить работоспособность инструментов.

Может быть и вы захотите поступить также. В таких компаниях, как Netflix и Facebook, bcc установлен на всех серверах по умолчанию.

4. Имеется ли руководство для начинающих?

Да, я написал руководство по bcc, которое является хорошей отправной точкой для новичков в трассировке с помощью eBPF:

bcc уже содержит более, чем 70 инструментов, которые вы можете сразу использовать. Как новичку, вам нет необходимости писать какой-либо код для eBPF. Это руководство проведёт вас по шагам через следующие одиннадцать: execsnoop, opensnoop, ext4slower (или btrfs*, xfs*, zfs*), biolatency, biosnoop, cachestat, tcpconnect, tcpaccept, tcpretrans, runqlat и profile.

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

Файлы примеров (*_example.txt в bcc/tools) содержат скриншоты с объяснениями: например, biolatency_example.txt. Они также полностью обеспечены документацией средствами man-страниц и файлами с примерами. Я написал многие из них (и man-страниц, и инструментов), которые похожи на дополнительные 50 постов в блоге, вы найдёте их в репозитории bcc.

Я написал эту документацию, когда eBPF был настолько новым, что он был доступен только в наших тестовых средах, так что большинство примеров являются искусственными. Чего не хватает, так это реальных примеров с продакшна. Это та область, где новички могут помочь: если вы решаете проблему, подумайте над тем, чтобы написать статью и поделиться скриншотами или добавить их в качестве файлов с примерами. Со временем мы добавим примеры из реального мира.

Лучший способ – это перейти на bpftrace, содержащий язык высокого уровня, который намного проще изучить. На этом этапе вы уже должны запустить bcc и опробовать эти инструменты, а также быть заинтересованными в их модификации и написании своих собственных инструментов. Недостатком является то, что он не так гибок в настройке, как bcc, так что вы можете столкнуться с ограничениями и захотеть вернуться обратно к bcc.

Это более новый проект, поэтому на момент написания этой статьи пакеты собраны еще не для всех систем. Обратитесь к инструкциям по установке bpftrace. В будущем это должно быть просто apt-get install bpftrace или что-то аналогичное.

1. Учебник по bpftrace

Я разработал учебник, который обучает использованию bpftrace через серию однострочников:

Вот пример: Там даётся 12 уроков, которые шаг за шагом обучат вас работе с bpftrace.

# bpftrace -e 'tracepoint:syscalls:sys_enter_open '

Attaching 1 probe...
181 /proc/cpuinfo
181 /proc/stat
1461 /proc/net/dev
1461 /proc/net/if_inet6
^C

Здесь используется системный вызов open как точка трассировки для отслеживания PID и путей открытых файлов.

2. Справочное руководство по bpftrace

Для получения подробностей о bpftrace, я написал руководство, содержащее примеры синтаксиса, тестов и встроенных команд:

Я думаю, что это слишком долго — если вы ищете что-то и вам нужно несколько раз пролистать страницу. Это ради краткости: я стараюсь разместить заголовок, резюме и скриншот на одной странице.

3. bpftrace в примерах

Есть более 20 инструментов в репозитории bpftrace, которые вы можете рассмотреть на примерах:

Например:

# cat tools/biolatency.bt

[...]
BEGIN
{ printf("Tracing block device I/O... Hit Ctrl-C to end.\n");
} kprobe:blk_account_io_start
{ @start[arg0] = nsecs;
} kprobe:blk_account_io_completion
/@start[arg0]/ { @usecs = hist((nsecs - @start[arg0]) / 1000); delete(@start[arg0]);
}

Например, biolatency_example.txt. Подобно bcc, эти утилиты имеют справочные страницы man pages и файлы примеров.

1. Изучаем разработку bcc

Я создал два руководства в помощь:

Инструменты bcc состоят из двух частей: кода BPF для ядра, написанного на C, и инструмента уровня пространства пользователя, написанного на Python (или lua, или C++). Там также много примеров в bcc/tools/*.py. Разработка инструментов bcc довольно продвинута и может включать некоторые мелкие компоненты ядра или внутренних прикладных элементов.

2. Участие в разработке

Приветствуется помощь с:

Это трудно, когда программируешь в llvm IR, но если вы готовы принять вызов... Для bpftrace я создал Руководство по внутренней разработке bpftrace.

Например, тэг kernel в bpftrace. Есть также ядро eBPF (он же BPF): если вы посмотрите bcc и bpftrace issues, вы увидите там несколько реквестов на улучшения. Также посмотрите список рассылки netdev на предмет последних разработок ядра BPF, которые добавляются в net-next до их слияния с мейнлайном Linux.

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

В данном посте я рассмотрел освоение eBPF в целях трассировки и анализа производительности. eBPF умеет много разных вещей. В итоге:

  • Начинающим: запуск инструментов bcc
  • Опытным: разработка инструментов bpftrace
  • Продвинутым: разработка инструментов bcc, вклад в bcc и bpftrace

Успехов! У меня также есть отдельная страница про Инструменты трассировки eBPF, охватывающая всё это более подробно.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть