eBPF Tracing 入門教程與實例

原文鏈接 Learn eBPF Tracing: Tutorial and Examples
譯者 棄餘

在 LPC'18(Linux Plumber's conference) 會議上,至少有24個關於 eBPF 的演講。 eBPF 這一實用技術,將是每個開發者需要掌握的技巧。 也許你的新年目標得再多一個了:學習 eBPF!

eBPF 的名稱源於 extended Berkeley Packet Filter,如果從 eBPF 的功能來說,類似 Virtual Kernel Instruction Set (VKIS) 這樣的名字似乎跟貼切。 eBPF 可以用來做很多事情,比如網絡性能(network performance),防火牆(firewalls),安全(security),程序分析追蹤(tracing) 和 設備驅動(device drivers) 等。其中,諸如 tracing 等功能在網絡上已經有很多資料。這裏的術語 tracing 特指可以生成 per-event 信息的性能分析和觀察工具,例如 tcpdump和strace就是兩個常用的 tracer。

這篇文章將着重於 eBPF tracing 的學習,並分爲 beginner, intermediate, advanced 三個階段,大綱如下:

Beginner: 運行 bcc 工具
Intermediate: 開發 bpftrace 工具
Advanced: 開發 bcc 工具,並貢獻社區
Beginner

  1. eBPF, bcc, bpftrace, iovisor 是什麼
    eBPF 之於 Linux 一定程度上如同 JavaScript 之於 HTML。JavaScript 使得網頁不再是靜態的,它可以讓你編寫程序來監聽鼠標點擊等事件,而且程序運行在瀏覽器的安全虛擬環境中;類似的,有了 eBPF,內核也可以不是固定的(fixed),你可以編寫程序來監聽 disk I/O 事件並執行相關動作,而且程序運行在內核的安全虛擬環境中。實際上,eBPF 更像是運行 JavaScript 的 V8 引擎,而不是像 JavaScript 本身。eBPF 是 Linux Kernel 的一部分。

直接 eBPF 編碼難於上青天,就好比直接編寫 V8 字節碼。但是沒有人直接寫 V8 字節碼,他們用 JavaScript,或者基於 JavaScript 的框架(jQuery, Angular, React 等)。eBPF 也是一樣,人們通過框架來使用 eBPF。對於 tracing 來說,主要的框架就是 bcc 和 bpftrace,這兩個框架並不在內核代碼中,他們在名爲 iovisor 的 Linux Foundation project 中維護。

  1. eBPF tracing 示例
    tcplife是一個基於 eBPF 的工具,可以顯示完整的 TCP session, 以及對應的進程號(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 做的恰恰是讓這個工具變得實用,tcplife 是高效並且安全的。舉例來說,tcplife 並不會像其他內核技術特性一樣去追蹤每個網絡包(packet),那樣會帶來太多的性能開銷。相反地,tcplife 只追蹤 TCP session 事件,這類事件相對來說頻率較低。這使得tcplife的負載極低,以至於我們可以在生產環境中24小時持續運行這個工具。

  1. 如何使用 eBPF
    對於初學者,嘗試一下 bcc tools。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
這裏我通過運行 opensnoop 來驗證 bcc tools 是否工作,如果你順利到這一步,說明你已經在使用 eBPF 了!

Netflix 和 Facebook 等公司已經在服務器上默認安裝 bcc ,或許你也想這麼做。

  1. 初學者入門教程
    Brendan Gregg 提供了一個 bcc 入門教程,方便初學者很好地開始 eBPF tracing.

作爲初學者,你不必開發 eBPF 代碼。bcc 自帶超過 70 多個工具可以直接使用。bcc 入門教程裏你將接觸 其中 11 個工具:execsnoop, opensnoop, ext4slower (or btrfs, xfs, zfs), biolatency, biosnoop, cachestat, tcpconnect, tcpaccept, tcpretrans, runqlat, and profile.

一旦你開始入門,你需要清楚 bcc tracing 工具還有很多:

eBPF Tracing 入門教程與實例

這些工具都有很詳細的文檔,包括使用手冊和示例。示例文件(xxx_example.txt)展示了屏幕截圖和對應的解釋:比如 biolatency_example.txt. Brendan Gregg 撰寫了許多類似的示例文檔、使用手冊、工具,都在 bcc repo 中。

生產環境中的 bcc tracing 示例沒有提供,Brendan Gregg 在撰寫這篇文檔時,eBPF 剛發展起來並只在測試機器上可用,因此大多數使用示例都是構造的測試用例。之後這個教程裏會提供真實世界的用例,這是初學者可以貢獻的方向:如果你通過 bcc 工具解決了一個實際問題,考慮發佈一個博客文章來共享屏幕截圖,或者添加到 bcc repo 的 examples 文件中。

Intermediate
到這裏,你應該已經可以運行 bcc 並嘗試了上述工具,然後你肯定會想定製開發自己的 bcc 工具。最佳實踐是切換到 bpftrace,bpftrace 提供高級語言可以使得入門開發更簡單。壞處就是 bpftrace 不如 bcc 那麼拓展友好。因此,你最終還是會遇到瓶頸,繼而切換回 bcc。

參考 bpftrace 安裝說明,bpftrace 是不同於 bcc 的另一個項目。此時 bpftrace 還沒有在各個平臺打包發佈。在不久的將來,可以很方便地通過類似 apt-get install bpftrace 的方式來安裝。

  1. bpftrace 教程
    Brendan Gregg 開發一個了 bpftrace 教程,通過一系列命令來學習 bpftrace,一共有 12 個示例循序漸進。

其中一個示例的截圖如下,這裏使用 open syscall tracepoint 來跟蹤 PID 和對應的打開文件路徑。

bpftrace -e 'tracepoint:syscalls:sys_enter_open { printf("%d %s\n", pid, str(args->filename)); }'

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

  1. bpftrace 參考指南
    關於 bpftrace 的更多參考信息,Brendan Gregg 整理了一個 參考指南,提供了關於 bpftrace 的語法、探針、內建等的示例。

這個參考指南的目的很簡單:Brendan Gregg 儘可能地把主題、摘要、截圖都放在一個屏幕上。如果你查找一些東西,需要滾動瀏覽多頁,那就太長了。

  1. bpftrace 示例
    bpftrace repo 中有 20 多個工具,可以通過這些工具來學習開發。例如:

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);br/>delete(@start[arg0]);
}
和 bcc 工具一樣,bpftrace 工具也有完整的使用手冊和示例文檔,例如 biolatency_example.txt。

Advanced

  1. 學習 bcc 開發
    Brendan Gregg 提供了兩個幫助文檔:

bcc Python Developer Tutorial
bcc Reference Guide
在 bcc/tools/*.py 中有很多示例。bcc tools 分爲兩大部分:1)面向內核的 BPF 代碼,用 C 語言開發;2)用戶態工具,用 Python (lua, C++) 等語言開發。開發 bcc tools 一定程度來說是高階的,可能會深入複雜的內核或應用程序的內部。

  1. 貢獻開源
    bcc/bpftrace issues 歡迎大家討論解決:

bcc issues
bpftrace issues
對於 bpftrace, Brendan Gregg 給了 bpftrace internals development guide. 這裏的開發很有挑戰,因爲涉及到 LLVM IR 的知識。

可以貢獻代碼的還有 kernel eBPF (aka BPF) 引擎。如果你瀏覽 bcc/bpftrace issues,你會看到一些相關的優化需求,例如 bpftrace kernel tag 標記的 issues。同時,你還可以關注訂閱 netdev 郵件列表,從而獲得最新的 kernel BPF 開發進展。這些新開發的代碼會進入 net-next 分支,然後合併入 Linux 主分支。

除了開發代碼,你還可以通過測試、打包、博客、演講等方式來貢獻。

Summary
eBPF 可以勝任很多事情。這篇文章介紹如何利用 eBPF 來跟蹤問題和性能分析。總的來說:

Beginner: 運行 bcc tools
Intermediate: 開發 bpftrace tools
Advanced: 開發 bcc tools,給 bcc/bpftrace 社區貢獻代碼。
Brendan Gregg 將上述內容整合到一個頁面中,eBPF Tracing Tools,加油!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章