Бесплатно Экспресс-аудит сайта:

23.08.2023

Больше, чем просто мониторинг: как eBPF задаёт новую планку для наблюдаемости

За последние 2 года было много разговоров об использовании eBPF в облачных сообществах. eBPF был одной из главных тем для обсуждения на KubeCon, а так называемые «дни eBPF» или «саммиты eBPF» быстро набирают популярность. Такие крупные компании, как Google и Netflix, используют eBPF в течение уже многих лет, да и вообще с каждым годом вариантов использования технологии появляется всё больше. Ожидается, что eBPF вскоре снова изменит правила игры, особенно в отношении наблюдаемости.

Итак, в этой статье посмотрим на eBPF: что это за технология, как она влияет на наблюдаемость, как соотносится с существующими практиками и что можно ожидать от неё в будущем?

Что такое eBPF на самом деле?

eBPF (Extended Berkeley Packet Filter) — это среда программирования, которая позволяет безопасно запускать изолированные программы в ядре Linux без изменения кода ядра.

Первоначально данная среда была разработана для Linux (и до сих пор наиболее развита именно там), но Microsoft также быстро развивает реализацию eBPF и для Windows.

Программы eBPF по своей природе очень эффективны и безопасны — они проверяются ядром, чтобы гарантировать, что они не рискуют стабильностью или безопасностью операционной системы.

Почему eBPF имеет такое большое значение?

Чтобы понять это, нам нужно разобраться, что такое «пространство пользователя» и «пространство ядра».

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

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

Исторически сложилось так, что по понятным причинам изменить что-либо в исходном коде ядра или на уровне операционной системы — крайне сложно. Ядро Linux состоит из 30 миллионов строк кода, и требуется несколько лет, чтобы любое изменение превратилось из идеи в общедоступную версию.

Ведь, во-первых, Linux-сообщество должно согласиться с этим нововведением. Затем оно должно стать частью официального выпуска Linux. Ещё через несколько месяцев его подхватят такие популярные дистрибутивы, как Red Hat и Ubuntu, которые сделают изменение доступным для более широкой аудитории.

Технически, конечно, можно загружать модули прямо в своё ядро ​​и вносить изменения напрямую, но это очень рискованно и требует сложного программирования на уровне ядра, поэтому так практически никто не делает.

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

Высокая безопасность

  • Строгая проверка — прежде чем какую-либо eBPF-программу можно будет загрузить в ядро, она проверяется специальным верификатором, что гарантирует абсолютную безопасность кода. Например, отсутствие жёстких циклов, недопустимого доступа к памяти, небезопасных операций и т.д.
  • Песочница — eBPF-программы запускаются в изолированной памяти ядра, отдельно от других его компонентов. Это предотвращает несанкционированный доступ к памяти, структурам данных и исходному коду ядра.
  • Ограниченные операции — eBPF-программы обычно должны быть написаны на небольшом подмножестве языка C, что подразумевает ограниченный набор инструкций, и, как следствие, ограниченный набор операций, которые смогут выполнять eBPF-программы. Это сильно снижает риск уязвимостей системы безопасности.

Высокая производительность/легкий вес

  • Запуск как собственный машинный код — программы eBPF запускаются как собственные машинные инструкции на процессоре. Это приводит к их ускоренному выполнению и лучшей производительности в целом.
  • Никаких переключений контекста — обычное приложение регулярно переключает контекст между пространством пользователя и пространством ядра, что требует значительных ресурсов. Программы eBPF, работающие на уровне ядра, могут напрямую обращаться к структурам данных и ресурсам ядра, экономя драгоценное время и производительность.
  • Управляемые событиями — программы eBPF обычно запускаются только в ответ на определённые события ядра, а не всегда активны. Это минимизирует сопутствующие расходы ресурсов.
  • Оптимизация для оборудования — eBPF-программы преобразуются в машинный код JIT-компилятором (Just-In-Time) ядра непосредственно перед выполнением, поэтому код оптимизируется для конкретного оборудования, на котором он работает.

Таким образом, eBPF обеспечивает безопасный и эффективный доступ к ядру для программирования. А учитывая, что все процессы проходят через ядро, это открывает некоторые новые возможности, которые были недоступны ранее.

Почему это стало важно только сейчас?

Технология BPF как таковая развивается уже 30 лет, однако за последние 7-8 лет, с появлением eBPF и с его широким распространением — мы понемногу вступаем в эпоху, когда использование eBPF становится массовым явлением.

Краткая история eBPF

  • 1993 год — в статье Национальной лаборатории Лоуренса Беркли исследуется использование агента ядра для фильтрации пакетов. Отсюда и название BPF («Berkeley Packet Filter» или «пакетный фильтр Беркли»).
  • 1997 год — BPF официально представлен как часть ядра Linux (версия 2.1.75).
  • 1997-2014 годы — добавлено несколько функций для улучшения, стабилизации и расширения возможностей BPF.
  • 2014 год — представлено значительное обновление, названное «расширенный пакетный фильтр Беркли» (Extended Berkeley Packet Filter, eBPF). Эта версия внесла большие изменения в технологию BPF и сделала её более широко используемой.

Релиз eBPF был большим и крайне значимым потому, что он упростил расширение функциональности ядра. Теперь программисты могли писать код eBPF-программы примерно так же, как для обычного приложения, а окружающая инфраструктура eBPF сама заботилась о низкоуровневой проверке, безопасности и эффективности. Всё это стало возможно благодаря поддерживающей экосистеме и каркасу вокруг eBPF.

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

Широкое внедрение в производственные системы

Популярность eBPF резко возросла за последние 7-8 лет, когда несколько крупных компаний применили технологию в масштабных производственных системах.

  • 2016 год — Netflix уже широко использовал eBPF в целях отслеживания. Брендан Грегг, реализовавший его, стал широко известен в кругах по инфраструктуре и эксплуатации как специалист по eBPF.
  • 2017 год — Facebook* открыл исходный код Katran, балансировщика нагрузки на основе eBPF. Каждый пакет на «Facebook.com» с 2017 года проходит через eBPF.
  • 2020 год — Google сделала eBPF частью своего проекта Kubernetes. eBPF стал лучше работать с сетью, безопасностью и наблюдаемостью в Google Kubernetes Engine (GKE). К этому же времени eBPF стал активно применяться в компаниях Adobe и Capital One.
  • 2021 год — Facebook, Google, Netflix, Microsoft и Isovalent объединились, чтобы объявить о создании «фонда eBPF» для управления развитием технологии.
  • 2023 год — тысячи компаний используют eBPF, и каждый год появляются сотни eBPF-проектов, исследующих различные варианты использования технологии.

Теперь eBPF является отдельной подсистемой в ядре Linux с широким сообществом для её поддержки. Сама технология значительно расширилась за счет нескольких новых дополнений.

Что же можно сделать с eBPF?

Наиболее распространенные варианты использования eBPF относятся к трём областям:

  1. Сеть
  2. Безопасность
  3. Наблюдаемость

Сеть и безопасность получили более широкое распространение и применение благодаря таким проектам, как Cilum. Когда как решения по наблюдаемости на основе eBPF находятся в более ранней стадии развития и только начинают своё становление.

Безопасность

Безопасность — самый популярный вариант использования eBPF. Используя eBPF, программы могут наблюдать за всем, что происходит на уровне ядра, обрабатывать события с высокой скоростью для проверки неожиданного поведения и гораздо быстрее выдавать предупреждения. Например:

  • Google использует eBPF для масштабируемого обнаружения вторжений;
  • Shopify использует eBPF для обеспечения безопасности контейнеров.

Многие сторонние решения по обеспечению безопасности теперь также используют eBPF для сбора и мониторинга данных.

Сеть

Сеть — еще один широко применяемый вариант использования. Нахождение на уровне eBPF обеспечивает всестороннюю наблюдаемость сети, например, видимость полного сетевого пути, включая все переходы, а также IP-адрес источника и назначения.

С помощью eBPF-программ можно обрабатывать большие объёмы сетевых событий и манипулировать сетевыми пакетами непосредственно в ядре с крайне низкими задержками.

Это позволяет использовать различные функции, такие как балансировка нагрузки, предотвращение DDoS, формирование трафика и оптимизация качества обслуживания (QoS).

Cloudflare, например, использует eBPF для обнаружения и предотвращения DDoS-атак, обрабатывая 10 миллионов пакетов в секунду, практически никак не влияя на производительность сети. А Katran от Meta* на основе eBPF выполняет балансировку нагрузки для всего Facebook.

Наблюдаемость

К настоящему времени должно быть ясно, как eBPF может быть полезен для наблюдения. Всё проходит через ядро. А eBPF обеспечивает высокопроизводительный и безопасный способ наблюдения за всем из ядра. Углубимся же в наблюдаемость и посмотрим на практические применения eBPF в этой сфере.

Как именно eBPF влияет на наблюдаемость?

Любое решение для обеспечения наблюдаемости состоит из 4 основных компонентов:

  1. Сбор данных — получение данных телеметрии из приложений и инфраструктуры.
  2. Обработка данных — фильтрация, индексация и выполнение вычислений по собранным данным.
  3. Хранение данных — краткосрочное и долгосрочное хранение данных.
  4. Пользовательский опыт — определение того, как данные потребляются пользователем.

Из всего этого eBPF на сегодняшний день влияет пока что только на уровень сбора данных — простой сбор данных телеметрии непосредственно из ядра с помощью eBPF.


Итак, когда мы говорим «наблюдаемость eBPF» сегодня, мы имеем в виду использование eBPF в качестве инструментария для сбора данных телеметрии вместо использования других методов инструментирования. Другие компоненты решения для обеспечения наблюдаемости остаются неизменными.

Как работает наблюдаемость eBPF

Чтобы полностью понять механизмы, лежащие в основе наблюдаемости eBPF, необходимо сначала понять концепцию ловушек. Как мы видели ранее, eBPF-программы в основном управляются событиями, т.е. они запускаются каждый раз, когда происходит определённое событие. Например, каждый раз, когда выполняется вызов функции, может быть вызвана eBPF-программа для сбора некоторых данных в целях наблюдения.

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

Четыре различных механизма eBPF позволяют использовать каждый из них:

Статический и динамический eBPF способен подключаться как к пользовательскому пространству, так и к пространству ядра.

  1. «Kernel tracepoint» (точки трассировки ядра) — используются для подключения к событиям, предварительно определённым разработчиками ядра (с помощью макросов TRACE_EVENT).
  2. «USDT» — используется для подключения к предопределённым точкам трассировки, установленным разработчиками в коде приложения.
  3. «Kprobes» (пробы ядра) — используются для динамического подключения к любой части кода ядра во время его выполнения.
  4. «Upprobes» (пользовательские зонды) — используются для динамического подключения к любой части приложения пользовательского пространства во время его выполнения.

В пространстве ядра есть несколько предопределенных ловушек, к которым можно легко присоединить eBPF-программу (например, системные вызовы, вход/выход функции, сетевые события, точки трассировки ядра). Точно так же в пользовательском пространстве многие языковые среды выполнения, системы баз данных и программные стеки предоставляют предопределённые ловушки для инструментов Linux, к которым могут подключаться программы eBPF.

Но что более интересно, так это «kprobes» и «uprobes». Что делать, если что-то ломается в производственной среде, а разработчик не обладает достаточной информацией, но хочет динамически добавлять инструменты прямо во время выполнения? Именно здесь «kprobes» и «upprobes» обеспечивают мощную наблюдаемость.

С помощью «upprobes», например, можно подключиться к определённой функции в приложении без изменения его кода прямо во время выполнения этого приложения. Всякий раз, когда выполняется функция, eBPF-программа может быть запущена для сбора необходимых данных. Это даёт захватывающие возможности, например, отладку в реальном времени.

Теперь, когда мы знаем, как работает наблюдаемость с eBPF, можно рассмотреть и варианты её использования.

Варианты использования наблюдаемости eBPF

Технологию eBPF можно использовать почти для всех распространённых существующих вариантов наблюдаемости. Более того, eBPF также открывает новые возможности.

  1. Мониторинг системы и инфраструктуры: eBPF позволяет осуществлять глубокий мониторинг событий на системном уровне, таких как использование ЦП, выделение памяти, дисковый ввод-вывод и сетевой трафик. Например, LinkedIn использует eBPF для всего своего инфра-мониторинга.
  2. Мониторинг контейнеров и Kubernetes: просмотр специфических для Kubernetes метрик, использования ресурсов и работоспособности отдельных контейнеров и модулей.
  3. Мониторинг производительности приложений (APM): детальное наблюдение за приложениями в пользовательском пространстве и просмотр пропускной способности приложений, частоты ошибок, задержек и трассировок.
  4. Настраиваемая наблюдаемость: видимость пользовательских метрик, характерных для приложений или инфраструктуры, которые не могут быть легко доступны без написания пользовательского кода.
  5. Расширенная наблюдаемость: eBPF также можно использовать для расширенных сценариев, таких как отладка в реальном времени, профилирование приложений с низкими издержками и отслеживание системных вызовов.

Каждый день появляются новые приложения eBPF для наблюдаемости. Что это означает для того, как сегодня осуществляется наблюдаемость? Заменит ли eBPF существующие формы инструментовки? Стоит сравнить его возможности с существующими вариантами.

eBPF по сравнению с существующими методами инструментирования

На сегодняшний день существует два основных способа инструментирования приложений и инфраструктуры для наблюдаемости, помимо eBPF.

  1. Инструментарий на основе агентов. Это независимые программные SDK/библиотеки, интегрированные в код приложения или узлы инфраструктуры для сбора данных телеметрии.
  2. Инструментарий на основе прокси-сервера Sidecar. Sidecars — это лёгкие независимые процессы, которые выполняются вместе с приложением или службой. Они популярны в микросервисах и архитектурах на основе контейнеров, таких как Kubernetes.

Ниже представлено краткое сравнение существующих инструментариев с eBPF:

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

  1. Может охватывать всё за один раз (инфраструктура, приложения).
  2. Менее навязчивый — eBPF не встроен в рабочие нагрузки, такие как агенты кода, которые запускаются при каждом запуске рабочей нагрузки. Сбор данных осуществляется вне диапазона, да ещё и в песочнице, поэтому он никак не влияет на работающую систему.
  3. Низкие затраты на производительность — eBPF работает как машинный код без переключения контекста.
  4. Более безопасный — благодаря встроенным мерам безопасности, таким как верификация.
  5. Простота установки — можно вставить без изменения кода или перезапуска.
  6. Простота обслуживания и обновления — опять же, без изменения кода и перезапуска.
  7. Больше масштабируемости — простота внедрения и обслуживания, а также низкие затраты на производительность.

Что касается минусов, основной пробел в наблюдаемости eBPF сегодня заключается в распределенной трассировке (осуществимо, но сценарии использования всё ещё находятся на ранних стадиях развития).

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

Последствия для наблюдаемости

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

Традиционные игроки, такие как Datadog и NewRelic, уже активно вкладывают средства в создание инструментов на основе eBPF, чтобы расширить свой портфель агентов на основе кода. Между тем, уже есть несколько поставщиков следующего поколения, основанных на eBPF, которые решают как нишевые варианты использования, так и комплексную наблюдаемость.

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

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

Кому и зачем следует использовать наблюдаемость eBPF?

  1. Если вы работаете в современной облачной среде (Kubernetes, микросервисы), то различия между подходами на основе eBPF и агентами наиболее заметны (разница в производительности, безопасности, простоте установки и т.д.).
  2. Если вы работаете в больших масштабах, облегчённые агенты на основе eBPF обеспечат значительные улучшения по сравнению с иными решениями. Вероятно, это одна из причин, по которой внедрение eBPF было самым высоким в технологических компаниях с огромным присутствием, таких как LinkedIn, Netflix и Meta.
  3. Если вам не хватает технических возможностей, и вы ищете решение для наблюдаемости, которое практически не требует усилий для установки и обслуживания, тогда сразу выбирайте решение на основе eBPF.

Итоги

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

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

* Компания Meta и её продукты (Instagram и Facebook) признаны экстремистскими, их деятельность запрещена на территории РФ.