BPF: профессиональная оценка производительности - Брендан Грегг - E-Book

BPF: профессиональная оценка производительности E-Book

Брендан Грегг

0,0

Beschreibung

Инструменты оценки производительности на основе BPF дают беспрецедентную возможность анализа систем и приложений. Вы сможете улучшить производительность, устранить проблемы в коде, повысить безопасность и сократить расходы. Книга «BPF: профессиональная оценка производительности» — ваш незаменимый гайд по применению этих инструментов. Брендан Грегг — эксперт и пионер проекта BPF — представляет более 150 готовых инструментов анализа и отладки, рекомендации по их применению, а также пошаговые инструкции по разработке ваших собственных инструментов. Вы узнаете, как анализировать процессоры, память, дисковый ввод/вывод, файловую систему, сети, языки программирования, приложения, контейнеры, гипервизоры, безопасность и ядро. Вы сможете выработать глубокое понимание того, как улучшить буквально любую Linux-систему или приложение.

Sie lesen das E-Book in den Legimi-Apps auf:

Android
iOS
von Legimi
zertifizierten E-Readern

Seitenzahl: 960

Das E-Book (TTS) können Sie hören im Abo „Legimi Premium” in Legimi-Apps auf:

Android
iOS
Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Брендан Грегг
BPF: профессиональная оценка производительности

Переводчик А. Киселев

Брендан Грегг

BPF: профессиональная оценка производительности. — СПб.: Питер, 2024.

ISBN 978-5-4461-1689-8

© ООО Издательство "Питер", 2023

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

Предисловие

Иногда программисты говорят, что они «стряпают патч» («cook a patch»), а не «реализуют» (implement). Я начал увлекаться программированием еще в школе. Чтобы получить хороший код, программист должен выбрать лучшие «ингредиенты». Разные языки программирования предлагают множество разных строительных блоков — «ингредиентов», но когда дело доходит до программирования ядра Linux, то кроме самого ядра у вас ничего нет.

В 2012 году я занимался добавлением новых возможностей в ядро, но нужных мне «ингредиентов» тогда не оказалось. Я мог бы начать писать строительные блоки внутри ядра, и они были бы готовы к использованию годы спустя. Но я решил создать «универсальный ингредиент», который в руках опытного программиста мог бы стать сетевым мостом уровня 2 или сетевым маршрутизатором уровня 3 внутри ядра.

У меня было несколько важных требований: «универсальный ингредиент» должен быть безопасным в использовании независимо от уровня подготовки программиста, использующего его. Он не должен давать возможности злонамеренному или неопытному разработчику приготовить из него вирус — «универсальный ингредиент» не должен допускать этого.

В ядре Linux уже был похожий механизм, известный как BPF (Berkeley Packet Filter — пакетный фильтр Беркли), поддерживавший минимальный набор команд, которые можно использовать для фильтрации пакетов перед передачей их приложениям, таким как tcpdump. Я заимствовал это имя и назвал свой «ингредиент» eBPF, где «e» означает «extended» — расширенный.

Через несколько лет различия между eBPF и классическим BPF стерлись. Мой «универсальный ингредиент» повсеместно стали называть BPF. Известные корпорации создали на его основе большие системы для обслуживания миллиардов людей, в том числе меня и вас. Заложенный в него принцип «быть безопасным при любых условиях» позволил многим «поварам» стать всемирно известными «шефами».

Первым шеф-поваром BPF был Брендан Грегг. Он увидел, что BPF можно использовать не только для обеспечения работы сети и ее безопасности, но также для анализа производительности, самодиагностики и наблюдения. Однако для создания таких инструментов и интерпретации их результатов измерений нужны большой опыт и знания.

Надеюсь, что эта книга станет вашей настольной «кулинарной книгой», в которой известный шеф-повар учит, как использовать BPF на Linux-кухне.

Алексей Старовойтов (Alexei Starovoitov) Сиэтл, штат Вашингтон. Август, 2019

Вступление

...Расширенные сценарии использования BPF: ...безумные...

Алексей Старовойтов, создатель нового BPF, февраль 20151

В июле 2014 года Алексей Старовойтов посетил офисы Netflix в калифорнийском Лос-Гатосе, чтобы обсудить новую захватывающую технологию, которую разрабатывал: расширенный пакетный фильтр Беркли (сокращенно eBPF, или просто BPF). В то время BPF был малопонятной технологией, ускоряющей фильтрацию пакетов, и у Алексея была идея, как расширить область ее применения за рамки сетевых пакетов. Алексей работал в паре с другим сетевым инженером, Дэниелом Боркманом (Daniel Borkmann), поставив себе цель превратить BPF в универсальную виртуальную машину, способную выполнять продвинутые сетевые и другие программы. Это была невероятная идея. Но меня особенно заинтересовала возможность использования BPF в качестве инструмента анализа производительности, и я увидел, как BPF может дать мне необходимые программные возможности. Мы договорились с Алексеем, что если он сумеет реализовать свою идею, то я разработаю инструменты анализа производительности, использующие BPF.

Сейчас BPF может подключаться к самым разным источникам событий. Он превратился в новую популярную технологию системной инженерии, разработкой которой занимается множество активных специалистов. Я разработал и опубликовал уже более 70 инструментов анализа производительности на основе BPF, которые используются во всем мире, в том числе на серверах Netflix, Facebook и других компаний. Специально для этой книги я написал еще несколько разработок, а также включил в нее инструменты, созданные другими авторами. И теперь рад поделиться плодами своего труда в книге «BPF: профессиональная оценка производительности», чтобы вы могли воспользоваться ими на практике для анализа производительности, устранения неполадок и многого другого.

Как перформанс-инженер, я одержим использованием инструментов производительности в стремлении достичь совершенства. Слепыми пятнами в системах называют узкие места в производительности и ошибки в программном обеспечении. В своей предыдущей работе я использовал технологию DTrace и посвятил ей книгу «DTrace: Dynamic Tracing in Oracle Solaris, Mac OS X, and FreeBSD», изданную Prentice Hall в 2011 году. В ней я поделился инструментами, использующими DTrace и разработанными для этих операционных систем. Теперь мне выпала интересная возможность поделиться похожими инструментами для Linux — инструментами, способными видеть и делать намного больше.

Где могут пригодиться инструменты оценки производительности BPF?

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

Об этой книге

Эта книга рассказывает об инструментах на основе BPF, которые применяются в основном для анализа и оценки производительности, но их можно использовать и в других областях: для поиска и устранения неполадок в ПО, для анализа безо­пасности и многого другого. Самое сложное в изучении BPF — не как писать код: любой интерфейс вы можете изучить примерно за день. Намного сложнее понять, что именно делать: какие из многих тысяч событий анализировать? Эта книга поможет найти ответ на этот вопрос, предоставив всю необходимую информацию об анализе производительности на множестве примеров анализа различных программных и аппаратных целей с помощью инструментов оценки производительности BPF на промышленных серверах Netflix.

Технология BPF обладает уникальными особенностями, но только потому, что расширяет круг доступных возможностей, а не дублирует их. Для эффективного использования BPF важно понимать, в каких случаях лучше применять традиционные инструменты анализа производительности, включая iostat(1) и perf(1), а в каких — инструменты BPF. Традиционные инструменты (они также описаны здесь) могут напрямую решать проблемы с производительностью, а если нет, позволяют получить полезный контекст и подсказки для дальнейшего анализа с помощью BPF.

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

Многие описанные в книге инструменты на основе BPF взяты из репозиториев BCC и bpftrace, являющихся частью проекта Linux Foundation IO Visor. У них открытый исходный код, они доступны бесплатно не только на сайтах репозитория, но и в различных дистрибутивах Linux. Я также написал много новых инструментов bpftrace для этой книги и включил в нее их исходный код.

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

Исходный код инструментов, реализованных на bpftrace, я также включил в книгу. Если вы хотите модифицировать или разработать новые инструменты bpftrace, то можете изучить язык bpftrace из главы 5, а также учиться на примерах из многочисленных листингов кода, приведенных ниже. Этот код помогает понять, что делает каждый инструмент и какие события он использует: это все равно что включить в книгу псевдокод, который можно запустить.

Программные интерфейсы BCC и bpftrace достигли зрелости, но может случиться и так, что изменения в них в будущем нарушат работоспособность каких-то инструментов, код которых включен в книгу, и их потребуется обновить. Если это произойдет с инструментом, использующим BCC или bpftrace, загляните в их репозитории и проверьте наличие обновленных версий. Если инструмент написан для этой книги, зайдите на сайт книги: http://www.brendangregg.com/bpf-performance-tools-book.html. Но самое важное не работоспособность инструмента, а ваше знание того, как он устроен, и желание, чтобы он работал. Самое сложное в практике использования BPF — знать и понимать, что с ним делать. Даже неработающие инструменты могут служить источником полезных идей.

Новые инструменты

Для этой книги я разработал более 80 новых инструментов анализа, чтобы предоставить вам исчерпывающий набор инструментов. Одновременно они служат как примеры кода. Многие из них показаны на рис. В.1. Названия уже существовавших ранее инструментов показаны черным, а новые, созданные для этой книги, — серым шрифтом. В книге будут рассмотрены и существующие, и новые инструменты, но на многих последующих диаграммах черно-серая дифференциация не используется.

О графическом пользовательском интерфейсе

Некоторые из инструментов BCC уже применяются как источники информации для графических интерфейсов — предоставляют временные ряды данных для отображения линейных графиков, трассировку стека для построения флейм-графиков или посекундные гистограммы для тепловых карт. Я предполагаю, что все больше людей будет использовать инструменты BPF не напрямую, а через графические интерфейсы. Но независимо от способа использования, они могут предложить огромный объем информации. Я расскажу об этих данных — как их интерпретировать и как создавать новые инструменты самостоятельно.

Рис. В.1. Инструменты анализа производительности на основе BPF: ранее существовавшие и новые инструменты, написанные для этой книги

О версиях Linux

В этой книге представлено много технологий Linux, часто с номером версии ядра и годом появления. Кое-где я также называю разработчиков, чтобы вы могли найти вспомогательные материалы, написанные авторами этих технологий.

Расширенный BPF добавлялся в Linux по частям. Первая часть была добавлена в ядро 3.18 в 2014 году, и следующие продолжали добавляться в ядра 4.x и 5.x. Для опробования инструментов BPF, представленных здесь, рекомендуется использовать Linux 4.9 или выше. Примеры для книги взяты из ядер с версиями от 4.9 до 5.3.

Начата работа по внедрению расширенного BPF в другие ядра, и в будущем издании этой книги вполне может рассматриваться не только Linux.

О чем здесь не рассказывается

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

Эта книга посвящена использованию инструментов bpftrace и BCC, а также разработке новых инструментов bpftrace, но в ней не затронуты вопросы разработки новых инструментов для BCC. Листинги кода инструментов BCC, как правило, слишком длинные, чтобы включить их в книгу, но я все же представлю некоторые примеры в приложении C. В приложении D вы найдете примеры разработки инструментов на языке C, а в приложении E — список инструкций BPF с описаниями, который поможет желающим глубже понять, как работают инструменты BPF.

Эта книга не специализируется на использовании одного языка или приложения, как многие другие, в которых описаны средства анализа и отладки. Скорее всего, вы будете использовать некоторые из этих инструментов наряду с инструментами BPF для решения проблем и обнаружите, что разные наборы инструментов могут дополнять друг друга и дают различные подсказки. Здесь приведены основные инструменты анализа, которые есть в Linux. Владение ими поможет найти простые решения, прежде чем перейти к инструментам BPF и заглянуть еще дальше и глубже.

Эта книга содержит краткое описание основ и стратегии для каждого вида анализа. Более подробную информацию ищите в моей предыдущей книге «Systems Performance: Enterprise and the Cloud»3 [Gregg 13b].

Структура

Книга делится на три части. Первая часть, главы с 1-й по 5-ю, охватывает основы, знание которых необходимо для использования BPF: анализ производительности, технологии трассировки ядра и два основных интерфейса трассировки BPF: BCC и bpftrace.

Вторая часть включает главы с 6-й по 16-ю и описывает цели трассировки с использованием BPF: процессоры, память, файловые системы, дисковый ввод/вывод, сетевые операции, безопасность, языки, приложения, ядро, контейнеры и гипервизоры. Можно читать по порядку, а можно произвольно переходить к любой главе, представляющей для вас интерес. Все эти главы написаны по общему шаблону: предварительное обсуждение, предложения по стратегии анализа, а затем описание конкретных инструментов BPF. В текст также включены функциональные схемы, помогающие освоить сложные темы и получить более полное представление об используемых инструментах.

Последняя часть, включающая главы 17 и 18, охватывает некоторые дополнительные темы: другие инструменты BPF, а также советы, приемы и типичные проблемы.

В приложениях приводятся однострочные примеры использования bpftrace и краткие инструкции по его применению, введение в разработку инструментов для BCC, а также инструментов на C для BPF, в том числе с использованием perf(1) (инструмент Linux), и, наконец, список инструкций BPF с краткими описаниями.

В книге вы встретите много терминов и сокращений. Где это возможно, они объясняются. Полное описание приводится в глоссарии.

В конце вступления есть раздел «Дополнительные материалы и ссылки», где перечислены дополнительные источники информации. В конце книги вы найдете список использованной литературы.

Для кого эта книга

Книга адресована широкому кругу читателей. Для применения инструментов BPF, о которых я рассказываю, вам не потребуется писать программы: вы можете использовать книгу как сборник рецептов с уже готовыми инструментами. Если вы решите создавать свои инструменты, то приведенные примеры исходного кода и глава 5 помогут быстро научиться этому.

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

В частности, книга адресована:

• Системным администраторам, SRE-инженерам, администраторам баз данных, перформанс-инженерам и сотрудникам служб поддержки, отвечающим за эксплуатацию систем. Они могут использовать ее как справочник по диагностике проблем производительности, анализу использования ресурсов и устранению неполадок.

• Разработчикам приложений, которые могут использовать описанные здесь инструменты для анализа собственного кода и его исследования в комплексе с системными событиями. Например, события дискового ввода/вывода можно исследовать в совокупности с кодом приложения, вызвавшим их. Это позволит получить более полное представление о поведении, чем это делается с помощью типичных прикладных инструментов, не имеющих прямого доступа к событиям ядра.

• Инженерам по безопасности, которые могут узнать, как отслеживать все события, обнаруживать подозрительное поведение и создавать белые списки типичной активности (см. главу 11).

• Разработчикам средств мониторинга производительности, которые могут почерпнуть идеи по добавлению новых возможностей в свои продукты.

• Разработчикам ядра, которые могут научиться писать однострочные инструменты для bpftrace с целью отладки собственного кода.

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

Проще говоря, эта книга фокусируется на использовании инструментов BPF и предполагает минимальный уровень знаний, включая знание сетей (например, что такое адрес IPv4) и владение командной строкой.

Авторские права на исходный код

Здесь содержится исходный код многих инструментов BPF. В код каждого инструмента включен комментарий с описанием источника: взят из BCC, bpftrace или написан специально для этой книги. Полный текст примечания об авторских правах для любого инструмента из BCC или bpftrace ищите в соответствующем репозитории.

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

/*

* Copyright 2019 Brendan Gregg.

* Licensed under the Apache License, Version 2.0 (the "License").

* This was originally created for the BPF Performance Tools book

* published by Addison Wesley. ISBN-13: 9780136554820

* When copying or porting, include this comment.

*/

Допускаю, что какие-то из этих инструментов будут включены в коммерческие продукты для целей мониторинга, как это было с моими более ранними разработками. Если вы возьмете на вооружение инструмент, созданный для этой книги, добавьте в документацию ссылку на эту книгу, технологию BPF и на меня.

Авторские права на рисунки:

Рисунки с 17.2 по 17.9: скриншоты инструмента Vector, © 2016 Netflix, Inc.

Рисунок 17.10: скриншот grafana-pcp-live, Copyright 2019 © Grafana Labs

Рисунки с 17.11 по 17.14: скриншоты Grafana, Copyright 2019 © Grafana Labs

Дополнительные материалы и ссылки

Сайт этой книги:

http://www.brendangregg.com/bpf-performance-tools-book.html

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

Многие из представленных здесь инструментов доступны и в репозиториях проектов, где они поддерживаются и совершенствуются. Там можно найти самые последние версии этих инструментов:

https://github.com/iovisor/bcc

https://github.com/iovisor/bpftrace

В репозиториях есть и подробные справочные и учебные руководства, которые написал я, а сообщество BPF продолжает поддерживать и обновлять.

Условные обозначения

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

В листингах, показывающих вывод инструментов, жирный шрифт указывает на выполняемую команду или на что-то интересное. Приглашение к вводу в виде хеша (#) означает, что команда или инструмент запущены от имени суперпользователя root (администратора). Например:

# id

uid=0(root) gid=0(root) groups=0(root)

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

$ id

uid=1000(bgregg) gid=1000(bgregg) groups=1000(bgregg),4(adm),27(sudo)

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

bpftrace/tools$ ./biolatency.bt

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

Большинству инструментов, представленных здесь, для запуска необходимы привилегии суперпользователя root, о чем говорит приглашение к вводу в виде хеша. Чтобы инструмент мог запустить не суперпользователь, в начало строки нужно добавить команду sudo(8) (расшифровывается как super-user do — выполнить с привилегиями суперпользователя).

Для некоторых команд требуются одиночные кавычки, чтобы командная оболочка случайно не выполнила ненужную (хотя и маловероятную) операцию подстановки. Это хорошая привычка, рекомендую взять ее на вооружение. Например:

# funccount 'vfs_*'

За именами команд и системных вызовов Linux следует номер раздела справочного руководства man, заключенный в круглые скобки, например команда ls(1), системный вызов read(2) и команда системного администрирования funccount(8). Пустые скобки обозначают вызовы функций на языке программирования, например функция ядра vfs_read(). При включении команды с аргументами в текст абзацев они выделяются моноширинным шрифтом.

Длинный вывод команды, не умещающийся по ширине страницы, усекается и в конец добавляется многоточие в квадратных скобках ([...]). Строки, содержащие только пару символов ^C, указывают, что была нажата комбинация Ctrl-C для завершения программы.

Библиографические ссылки оформляются в виде чисел в квадратных скобках, например [123].

Благодарности

Над созданием компонентов, нужных для инструментов BPF, работали многие люди. Их вклад может быть малозаметным: решение непонятных проблем в инфраструктуре трассировки ядра, инструментах компиляции, верификаторе инструкций или в других сложных компонентах. Такая работа часто недооценивается и остается незамеченной. Тем не менее именно благодаря их усилиям вы можете использовать инструменты BPF. Многие из этих инструментов были написаны мной. Может сложиться ложное представление, будто я написал их в одиночку, — на самом деле я опирался на множество различных технологий и плоды труда других людей. Я хотел бы поблагодарить за работу их, а также всех тех, кто участвовал в создании этой книги.

Технологии, затронутые в книге, и их авторы:

• eBPF: спасибо Алексею Старовойтову (Facebook; ранее PLUMgrid) и Дэниелу Боркману (Isovalent; ранее Cisco, Red Hat) за создание технологии, управление разработкой, поддержку кода BPF в ядре и реализацию их идеи eBPF. Спасибо всем другим участникам eBPF и особенно Дэвиду С. Миллеру (David S. Miller, Red Hat) за поддержку и совершенствование технологии. На момент написания этой книги в BPF-сообществе насчитывалось 249 человек, внесших свой вклад в код BPF, а общее число коммитов, отправленных с 2014 года, составило 3224. Основными разработчиками BPF после Дэниеля и Алексея, если судить по числу коммитов, являются: Якуб Кичински (Jakub Kicinski, Netronome), Йонгхонг Сонг (Yonghong Song, Facebook), Мартин Ка Фай Лау (Martin KaFai Lau, Facebook), Джон Фастабенд (John Fastabend, Isovalent; ранее Intel), Квентин Моне (Quentin Monnet, Netronome), Джеспер Дангаард Брауэр (Jesper Dangaard Brouer, Red Hat), Андрей Игнатов (Andrey Ignatov, Facebook) и Станислав Фомичев (Stanislav Fomichev, Google).

• BCC: спасибо Брэндану Бланко (Brenden Blanco, VMware; ранее PLUMgrid) за создание и развитие BCC. К числу основных участников этого проекта относятся: Саша Гольдштейн (Sasha Goldshtein, Google; ранее SELA), Йонгхонг Сонг (Yonghong Song, Facebook; ранее PLUMgrid), Тен Цинь (Teng Qin, Facebook), Поль Шиньон (Paul Chaignon, Orange), Висент Марти (Vicent Martí, github), Марк Дрейтон (Mark Drayton, Facebook), Алан Макаливи (Allan McAleavy, Sky) и Гари Чинг-Пан Лин (Gary Ching-Pang Lin, SUSE).

• bpftrace: спасибо Аластеру Робертсону (Alastair Robertson, Yellowbrick Data; ранее G-Research, Cisco) за создание bpftrace и за высокие требования к качеству кода и наличию всеобъемлющих тестов. Спасибо всем остальным авторам bpftrace, особенно Матеусу Марчини (Matheus Marchini, Netflix; ранее Shtima), Виллиану Гасперу (Willian Gasper, Shtima), Дейлу Хэмелю (Dale Hamel, Shopify), Аугусто Меккингу Каринги (Augusto Mecking Caringi, Red Hat) и Дэну Сюю (Dan Xu, Facebook).

• ply: спасибо Тобиасу Вальдекранцу (Tobias Waldekranz) за разработку первого высокоуровневого инструмента трассировки на основе BPF.

• LLVM: спасибо Алексею Старовойтову, Чандлеру Карруту (Chandler Carruth, Google), Йонгхонг Сонгу и другим за поддержку BPF для LLVM, на которой основаны BCC и bpftrace.

• kprobes: спасибо всем, кто проектировал, разрабатывал и работал над поддержкой динамического анализа ядра Linux, которая широко используется в этой книге. Среди них Ричард Мур (Richard Moore, IBM), Супарна Бхаттачарья (Suparna Bhattacharya, IBM), Вамси Кришна Сангаварапу (Vamsi Krishna Sangavarapu, IBM), Прасанна С. Панчамухи (Prasanna S. Panchamukhi, IBM), Анант Н. Мавинакаянахалли (Ananth N. Mavinakayanahalli, IBM), Джеймс Кенистон (James Keniston, IBM), Навин Н Рао (Naveen N Rao, IBM), Хьен Нгуен (Hien Nguyen, IBM), Масами Хирамацу (Masami Hiramatsu, Linaro; ранее Hitachi), Расти Линч (Rusty Lynch, Intel), Анил Кешавамурти (Anil Keshavamurthy, Intel), Расти Рассел (Rusty Russell), Уилл Коэн (Will Cohen, Red Hat) и Дэвид С. Миллер (David S. Miller, Red Hat).

• uprobes: спасибо Шрикару Дронамражу (Srikar Dronamraju, IBM), Джиму Кенистону (Jim Keniston) и Олегу Нестерову (Oleg Nesterov, Red Hat) за разработку инструментов уровня пользователя для динамического анализа ядра Linux и Петеру Зийльстре (Peter Zijlstra) за рецензирование этой книги.

• точки трассировки: спасибо Матье Деснойерсу (Mathieu Desnoyers, EfficiOS) за его вклад в технологию трассировки для Linux. В частности, Матье разработал и предложил статические точки трассировки для включения в ядро, что позволило создавать стабильные инструменты трассировки и приложения.

• perf: спасибо Арнальдо Карвальо де Мело (Arnaldo Carvalho de Melo, Red Hat) за его работу над утилитой perf(1), добавившей в ядро новые возможности, которые используются инструментами BPF.

• Ftrace: спасибо Стивену Ростедту (Steven Rostedt, VMware; ранее Red Hat) за трассировщик Ftrace и вообще за его вклад в технологию трассировки. Ftrace помог в разработке инструментов трассировки на основе BPF, так как я по возможности перепроверял вывод своих инструментов, сопоставляя его с выводом эквивалентных инструментов в Ftrace. Спасибо также Тому Занусси (Tom Zanussi, Intel), недавно внесшему свой вклад в историю Ftrace.

• (Классический) BPF: спасибо Ван Якобсону (Van Jacobson) и Стиву Маккану (Steve McCanne).

• Динамическая инструментация: спасибо профессору Бартону Миллеру (Barton Miller, Университет штата Висконсин в городе Мэдисон) и его студенту Джеффри Холлингсворту (Jeffrey Hollingsworth) за создание области динамической инструментации в 1992 году [Hollingsworth 94], которая во многом обусловила появление DTrace, SystemTap, BCC, bpftrace и других динамических трассировщиков. Большинство инструментов в этой книге основаны на динамической инструментации (точнее, те из них, что используют kprobes и uprobes).

• LTT: спасибо Кариму Ягмуру (Karim Yaghmour) и Мишелю Р. Дагенаису (Michel R. Dagenais) за разработку LTT — первого трассировщика для Linux — в 1999 году. Также спасибо Кариму за его неустанные усилия по продвижению технологий трассировки в сообществе Linux, а также за создание и поддержку более поздних трассировщиков.

• Dprobes: Спасибо Ричарду Дж. Муру (Richard J. Moore) и его команде в IBM за разработку DProbes в 2000 году — первой технологии динамической инструментации для Linux, которая привела к появлению современной технологии kprobes.

• SystemTap: несмотря на то что SystemTap не используется в этой книге, работа Фрэнка Ч. Иглера (Frank Ch. Eigler, Red Hat) и других пользователей SystemTap очень способствовала совершенствованию технологий трассировки в Linux. Часто они первыми внедряли трассировку в новые области и обнаруживали ошибки в технологиях трассировки ядра.

• ktap: спасибо Джови Чжанвэю (Jovi Zhangwei) за ktap — высокоуровневый трассировщик, который помог в создании поддержки трассировщиков для Linux на основе виртуальных машин.

• Также спасибо инженерам Sun Microsystems Брайану Кантриллу (Bryan Cantrill), Майку Шапиро (Mike Shapiro) и Адаму Левенталю (Adam Leventhal) за их выдающуюся работу по разработке DTrace — первой технологии динамической инструментации, появившейся в 2005 году и получившей широкое распространение. Спасибо специалистам по маркетингу и продажам в Sun, популяризаторам и многим другим, как внутри, так и за пределами Sun, что помогли сделать DTrace широко известной в мире и увеличить спрос на трассировщики в Linux.

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

Кроме создания перечисленных технологий, многие из этих людей помогли в работе над моей книгой: Дэниел Боркман сделал весьма ценные технические замечания и предложения для нескольких глав. Алексей Старовойтов дал критические отзывы и советы к тексту с описанием ядра eBPF (а также написал предисловие для книги). Аластер Робертсон поделился информацией для главы о bpftrace, а Йонгхонг Сонг давал консультации по BTF во время разработки BTF.

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

Спасибо Матеусу Марчини (Matheus Marchini, Netflix), Полу Шеньону (Paul Chaignon, Orange), Дейлу Хэмелу (Dale Hamel, Shopify), Амеру Азеру (Amer Ather, Netflix), Мартину Спайеру (Martin Spier, Netflix), Брайану В. Кернигану (Brian W. Kernighan, Google), Джоэлу Фернандесу (Joel Fernandes, Google), Джесперу Брауэру (Jesper Brouer, Red Hat), Грегу Данну (Greg Dunn, AWS), Джулии Эванс (Julia Evans, Stripe), Токе Хойланд-Йоргенсену (Toke Høiland-Jørgensen, Red Hat), Станиславу Козине (Stanislav Kozina, Red Hat), Иржи Ольсу (Jiri Olsa, Red Hat), Дженсу Аксбо (Jens Axboe, Facebook), Джону Хасламу (Jon Haslam, Facebook), Андрию Накрийко (Andrii Nakryiko, Facebook), Саргуну Диллону (Sargun Dhillon, Netflix), Алексу Маэстретти (Alex Maestretti, Netflix), Джозефу Линчу (Joseph Lynch, Netflix), Ричарду Эллингу (Richard Elling, Viking Enterprise Solutions), Брюсу Кертису (Bruce Curtis, Netflix) и Хавьеру Гондувилле Кото (Javier Honduvilla Coto, Facebook). Благодаря им многие разделы были переписаны, дополнены и улучшены. C некоторыми разделами мне помогли Матье Деснойер (Mathieu Desnoyers, EfficiOS) и Масами Хирамацу (Masami Hiramatsu, Linaro). Клэр Блэк (Claire Black) выполнила окончательную проверку глав и дала свои замечания.

Мой коллега Джейсон Кох (Jason Koch) написал бо́льшую часть главы «Другие инструменты» и прокомментировал почти все главы (он писал замечания вручную в печатной копии толщиной около двух дюймов).

Ядро Linux — сложный и постоянно меняющийся программный продукт, и я высоко ценю труд Джонатана Корбета (Jonathan Corbet) и Джейка Эджа (Jake Edge) из lwn.net по обобщению большого числа сложнейших тем. Многие из их статей упоминаются в библиографии в конце книги.

Для завершения этой книги также потребовалось добавить множество новых возможностей в интерфейсы BCC и bpftrace и устранить ряд проблемы. Я и мои коллеги написали тысячи строк кода, чтобы обеспечить возможность создания инструментов, представленных в этой книге. В связи с этим я хочу выразить особую благодарность Матеусу Марчини (Matheus Marchini), Виллиану Гасперу (Willian Gasper), Дейлу Хэмелу (Dale Hamel), Дэну Сюю (Dan Xu) и Аугусто Каринги (Augusto Caringi) за своевременные исправления.

Спасибо моим нынешнему и бывшему руководителям в Netflix Эду Хантеру (Ed Hunter) и Кобурну Уотсону (Coburn Watson) за поддержку моей работы над BPF. Также спасибо моим коллегам Скотту Эммонсу (Scott Emmons), Брайану Майлзу (Brian Moyles) и Габриелю Муносу (Gabrielle Munoz) за помощь в установке BCC и bpftrace на производственных серверах в Netflix, благодаря которым мне удалось получить множество примеров скриншотов.

Спасибо моей жене Дейрдре Страуган (Deirdré Straughan, AWS) за ее научную редактуру и предложения, а также за поддержку еще одной книги. Мои навыки писателя заметно усовершенствовались благодаря ее многолетней помощи. И спасибо моему сыну Митчеллу за поддержку и терпение, пока я был занят написанием.

Написать эту книгу меня вдохновила книга о DTrace, написанная мной и Джимом Мауро (Jim Mauro). Упорный труд Джима, направленный на достижение максимального успеха книги о DTrace, и наши бесконечные дискуссии о структуре и описаниях инструментов во многом помогли повысить качество этой книги. Джим, спасибо за все.

Отдельное спасибо старшему редактору издательства Pearson Грегу Доенчу (Greg Doench) за помощь и энтузиазм, проявленный при работе над этим проектом.

Эта работа дала мне шанс показать возможности BPF. Из 156 инструментов, представленных здесь, 135 написаны мной, в том числе 89 новых инструментов, созданных специально для этой книги (вообще их больше ста, если считать все разновидности, хотя я не рассчитывал достигнуть этого рубежа). Для создания новых инструментов потребовалось заняться дополнительными исследованиями, выполнить настройки сред серверных и клиентских приложений, провести эксперименты и произвести тестирование. Порой это было очень утомительно, но в итоге я испытал приятное чувство глубокого удовлетворения, зная, что эти инструменты для многих будут иметь немалую ценность.

Брендан Грегг (Brendan Gregg), Сан-Хосе, Калифорния (а перед этим Сидней, Австралия), ноябрь 2019

Об авторе

Брендан Грегг — старший перформанс-инженер в Netflix, основной контрибьютор проекта BPF (eBPF), помогавший разрабатывать и поддерживать оба интерфейса BPF. Впервые применил BPF для анализа производительности и создал десятки инструментов на основе BPF. Автор бестселлера «Systems Performance: Enterprise and the Cloud»4.

От издательства

Ваши замечания, предложения, вопросы отправляйте по адресу [email protected] (­издательство «Питер», компьютерная редакция).

Мы будем рады узнать ваше мнение!

На веб-сайте издательства www.piter.com вы найдете подробную информацию о наших книгах.

1https://events.static.linuxfound.org/sites/events/files/slides/bpf_collabsummit_2015feb20.pdf

2 В число упражнений включены также некоторые сложные и «нерешенные» проблемы, для которых мне еще только предстоит найти рабочее решение. Возможно, что некоторые из этих проблем нельзя решить без изменения ядра или приложения.

3 Грегг Б. «Производительность систем». Санкт-Петербург, издательство «Питер».

4 Грегг Б. «Производительность систем». Санкт-Петербург, издательство «Питер».

Глава 2. Основы технологии

В главе 1 были представлены различные технологии, используемые инструментами BPF. В главе 2 они рассматриваются более подробно: история их развития, интерфейсы, внутреннее устройство и использование в комплексе с BPF.

Это самая техническая глава в книге, и для краткости изложения я предполагаю, что у вас есть некоторое представление о внутренних компонентах ядра и программировании на уровне инструкций16.

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

• познакомиться с историей происхождения BPF и современной ролью расширенного BPF;

• узнать, как выполнять обход фреймов стека и другие приемы;

• узнать, как читать флейм-графики;

• узнать, как использовать kprobes и uprobes, и познакомиться с причинами их нестабильности;

• разобраться с назначением точек трассировки, зондов USDT и динамического USDT;

• познакомиться со счетчиками мониторинга производительности (PMC) и приемами их использования с инструментами трассировки BPF;

• познакомиться с перспективными разработками: BTF и другими средствами обхода стека BPF.

Эта информация поможет освоить последующие главы, но если хотите, можете просто бегло просмотреть главу 2 и вернуться к ней позднее, когда потребуется более глубокое понимание. Глава 3 даст возможность начать практическое применение инструментов BPF для поиска и устранения узких мест производительности.

2.1. BPF в иллюстрациях

На рис. 2.1 показаны многие из технологий этой главы и то, как они связаны.

Рис. 2.1. Технологии трассировки BPF

2.2. BPF

Первоначально механизм BPF был разработан для ОС BSD и описан в 1992 году в статье «The BSD Packet Filter: A New Architecture for User-level Packet Capture» [McCanne 92]. Она была представлена на зимней конференции USENIX 1993 года в Сан-Диего вместе со статьей «Measurement, Analysis, and Improvement of UDP/IP Throughput for the DECstation 5000»17. Рабочие станции DEC давно ушли в прошлое, но технология BPF сохранилась как стандартное решение для фильтрации пакетов.

В BPF используется интересный принцип работы: выражение фильтра определяется конечным пользователем с помощью набора инструкций для виртуальной машины BPF (иногда их называют байт-кодом BPF) и передается ядру для выполнения интерпретатором. Это позволяет выполнять фильтрацию на уровне ядра без дорогостоящего копирования каждого пакета на уровне пользовательского процесса, что обеспечивает высокую производительность фильтрации пакетов, как, например, в tcpdump(8). Это решение также обеспечивает дополнительную безопасность, так как фильтры из пространства пользователя можно проверить на безопасность перед выполнением. Учитывая, что фильтрация пакетов происходит в пространстве ядра, требования к безопасности были очень жесткими. На рис. 2.2 показано, как это работает.

Рис. 2.2. tcpdump и BPF

При желании можно запустить команду tcpdump(8) с параметром -d, чтобы получить инструкции BPF, выражающие фильтр. Например:

# tcpdump -d host 127.0.0.1 and port 80

(000) ldh      [12]

(001) jeq      #0x800           jt 2     jf 18

(002) ld       [26]

(003) jeq      #0x7f000001      jt 6     jf 4

(004) ld       [30]

(005) jeq      #0x7f000001      jt 6     jf 18

(006) ldb      [23]

(007) jeq      #0x84            jt 10    jf 8

(008) jeq      #0x6             jt 10    jf 9

(009) jeq      #0x11            jt 10    jf 18

(010) ldh      [20]

(011) jset     #0x1fff          jt 18    jf 12

(012) ldxb     4*([14]&0xf)

(013) ldh      [x + 14]

(014) jeq      #0x50            jt 17    jf 15

(015) ldh      [x + 16]

(016) jeq      #0x50            jt 17    jf 18

(017) ret      #262144

(018) ret      #0

Оригинальный механизм BPF, который сейчас называют «классическим BPF», представлял собой ограниченную виртуальную машину. Она имела два регистра, внутреннее хранилище с 16 ячейками памяти и счетчик программных инструкций. Все они работали с 32-битными регистрами18. В Linux классический BPF появился в 1997 году, в ядре 2.1.7519.

После включения BPF в ядро Linux были реализованы некоторые важные улучшения. Эрик Думазет (Eric Dumazet) добавил в ядро Linux 3.0, вышедшее в июле 2011 года20, динамический (JIT) компилятор BPF, имеющий более высокую производительность по сравнению с интерпретатором. В 2012 году Уилл Дрюри (Will Drewry) добавил фильтры BPF для политик безопасности системных вызовов seccomp21. Это было первое использование BPF за рамками сетевого стека, показавшее потенциал применения BPF в роли универсального механизма выполнения.

2.3. Расширенный BPF (eBPF)

Расширенная версия BPF был спроектирована Алексеем Старовойтовым, тогда работавшим в компании PLUMgrid и изучавшим новые способы создания программно-определяемых сетевых решений. Она могла бы стать первым серьезным усовершенствованием BPF за последние 20 лет и подняла бы BPF до уровня виртуальной машины общего назначения22. Когда расширенный BPF находился еще на стадии предложения, Дэниел Боркман, специалист по ядру из Red Hat, помог переработать его для включения в ядро в качестве замены имеющегося BPF23. Эта расширенная версия BPF была успешно включена в ядро, и с тех пор в ее развитии участвовали многие другие разработчики (см. раздел «Благодарности»).

В расширенный BPF было добавлено больше регистров, вместо 32-разрядных слов стали использоваться 64-разрядные, создано гибкое хранилище «карт» и разрешены вызовы некоторых ограниченных функций ядра24. Он также включает JIT-компиляцию с отображением «один к одному» в машинные инструкции и регистры, что позволяет повторно использовать методы оптимизации команд, реализованные ранее для BPF. Верификатор BPF тоже обновился и теперь поддерживает обработку этих расширений и отклоняет любой небезопасный код.

Основные различия между классическим и расширенным BPF перечислены в табл. 2.1.

Таблица 2.1. Основные различия между классическим и расширенным BPF

Фактор

Классический BPF

Расширенный BPF

Количество регистров

2: A, X

10: R0–R9 и R10, как указатель на список фреймов стека, доступный только для чтения

Разрядность регистров

32 бита

64 бита

Хранилище

16 ячеек памяти: M[0–15]

512 байт в пространстве стека плюс неограниченное хранилище «карт»

Ограниченные вызовы ядра

Очень ограниченный круг, определяемый JIT-компилятором

Да, через инструкцию bpf_call

Целевые события

Пакеты, seccomp-BPF

Пакеты, функции в пространстве ядра, функции в пространстве пользователя, точки трассировки, пользовательские маркеры, счетчики производительности (PMC)

Первоначальное предложение Алексея, отправленное в сентябре 2013 года, было набором патчей «extended BPF»25. А в декабре 2013 года Алексей уже предложил использовать его для трассировки фильтров26. После обсуждения и разработки совместно с Дэниелем в марте 2014 года27,28 патчи начали включаться в ядро Linux29. Компоненты JIT-компилятора были включены в Linux 3.15 в июне 2014 года, а системный вызов bpf(2) для управления механизмом BPF был добавлен в Linux 3.18 в декабре 2014 года30. Позднее в ветку Linux 4.x была добавлена поддержка BPF для kprobes, uprobes, точек трассировки и perf_events.

В самых ранних наборах патчей эта технология сокращенно обозначалась как eBPF, но позже Алексей перешел к использованию более простого названия BPF31. Все сообщество разработчиков BPF теперь называют ее в списке рассылки net-dev32 просто BPF.

На рис. 2.3 показана архитектура среды выполнения BPF в Linux, где видно, как инструкции BPF проходят проверку в верификаторе BPF перед выполнением виртуальной машиной BPF. Реализация виртуальной машины BPF включает как интерпретатор, так и JIT-компилятор: JIT-компилятор генерирует машинные инструкции для выполнения непосредственно на процессоре. Верификатор отклоняет небезопасные операции, включая неограниченные циклы: программы BPF должны завершаться в ограниченное время.

Рис. 2.3. Архитектура среды выполнения BPF

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

В разделах ниже обсуждается, зачем инструментам оценки производительности нужен механизм BPF и как писать программы для расширенного BPF, а также дается обзор инструкций BPF, BPF API, ограничений BPF и BTF. Эти разделы закладывают основы понимания особенностей работы BPF при использовании bpftrace и BCC. В приложении D рассказано о программировании BPF на языке C, а в приложении E описаны инструкции BPF.

2.3.1. Зачем инструментам оценки производительности нужен BPF