eBPF Tracing 入門教程與實例

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

eBPF 的名稱源於 extended Berkeley Packet Filter,若是從 eBPF 的功能來講,相似 Virtual Kernel Instruction Set (VKIS) 這樣的名字彷佛跟貼切。 eBPF 能夠用來作不少事情,好比網絡性能(network performance),防火牆(firewalls),安全(security),程序分析追蹤(tracing) 和 設備驅動(device drivers) 等。其中,諸如 tracing 等功能在網絡上已經有不少資料。這裏的術語 tracing 特指能夠生成 per-event 信息的性能分析和觀察工具,例如 tcpdumpstrace就是兩個經常使用的 tracerpython

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

  • 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 的一部分。ios

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

2. eBPF tracing 示例

tcplife是一個基於 eBPF 的工具,能夠顯示完整的 TCP session, 以及對應的進程號(PID) ,命令(COMM),收發字節數(TX_KB, RX_KB),以及時長(MS):github

# 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小時持續運行這個工具。redis

3. 如何使用 eBPF

對於初學者,嘗試一下 bcc tools。bcc 的安裝很簡單,並有詳細的說明文檔,例如在 Ubuntu 上,效果以下shell

# 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 ,或許你也想這麼作。安全

4. 初學者入門教程

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 工具還有不少:

這些工具都有很詳細的文檔,包括使用手冊和示例。示例文件(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

2. bpftrace 參考指南

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

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

3. 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);
    delete(@start[arg0]);
}

和 bcc 工具同樣,bpftrace 工具也有完整的使用手冊和示例文檔,例如 biolatency_example.txt

Advanced

1. 學習 bcc 開發

Brendan Gregg 提供了兩個幫助文檔:

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

2. 貢獻開源

bcc/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,加油!


原文連接 本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索