精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux內核觀測技術eBPF中文入門指南

馬哥Linux運維 ? 來源:coolshell.cn ? 2023-02-08 09:45 ? 次閱讀

1.介紹

eBPF(extened Berkeley Packet Filter)是一種內核技術,它允許開發人員在不修改內核代碼的情況下運行特定的功能。eBPF 的概念源自于 Berkeley Packet Filter(BPF),后者是由貝爾實驗室開發的一種網絡過濾器,可以捕獲和過濾網絡數據包。

出于對更好的 Linux 跟蹤工具的需求,eBPF 從 dtrace中汲取靈感,dtrace 是一種主要用于 Solaris 和 BSD 操作系統的動態跟蹤工具。與 dtrace 不同,Linux 無法全面了解正在運行的系統,因為它僅限于系統調用、庫調用和函數的特定框架。

在 Berkeley Packet Filter(BPF)(一種使用內核 VM 編寫打包過濾代碼的工具)的基礎上,一小群工程師開始擴展 BPF 后端以提供與 dtrace 類似的功能集。eBPF 誕生了。2014 年隨 Linux 3.18 首次限量發布,充分利用 eBPF 至少需要 Linux 4.4 以上版本。

eBPF 比起傳統的 BPF 來說,傳統的 BPF 只能用于網絡過濾,而 eBPF 則可以用于更多的應用場景,包括網絡監控、安全過濾和性能分析等。另外,eBPF 允許常規用戶空間應用程序將要在 Linux 內核中執行的邏輯打包為字節碼,當某些事件(稱為掛鉤)發生時,內核會調用 eBPF 程序。此類掛鉤的示例包括系統調用、網絡事件等。用于編寫和調試 eBPF 程序的最流行的工具鏈稱為 BPF 編譯器集合(BCC),它基于 LLVM 和 CLang。

eBPF 有一些類似的工具。例如,SystemTap 是一種開源工具,可以幫助用戶收集 Linux 內核的運行時數據。它通過動態加載內核模塊來實現這一功能,類似于 eBPF。另外,DTrace 是一種動態跟蹤和分析工具,可以用于收集系統的運行時數據,類似于 eBPF 和 SystemTap。[Ⅰ]

以下是一個簡單的比較表格,可以幫助您更好地了解 eBPF、SystemTap 和 DTrace 這三種工具的不同之處:[Ⅰ]

560f78da-a71f-11ed-bfe3-dac502259ad0.png

從上表可以看出,eBPF、SystemTap 和 DTrace 都是非常強大的工具,可以用于收集和分析系統的運行情況。[Ⅰ]

用途

eBPF 是一種非常靈活和強大的內核技術,可以用于多種應用場景。下面是 eBPF 的一些常見用途:[Ⅰ]

網絡監控:eBPF 可以用于捕獲網絡數據包,并執行特定的邏輯來分析網絡流量。例如,可以使用 eBPF 程序來監控網絡流量,并在發現異常流量時進行警報。[Ⅰ]

安全過濾:eBPF 可以用于對網絡數據包進行安全過濾。例如,可以使用 eBPF 程序來阻止惡意流量的傳播,或者在發現惡意流量時對其進行攔截。[Ⅰ]

性能分析:eBPF 可以用于對內核的性能進行分析。例如,可以使用 eBPF 程序來收集內核的性能指標,并通過特定的接口將其可視化。這樣,可以更好地了解內核的性能瓶頸,并進行優化。[Ⅰ]

虛擬化:eBPF 可以用于虛擬化技術。例如,可以使用 eBPF 程序來收集虛擬機的性能指標,并進行負載均衡。這樣,可以更好地利用虛擬化環境的資源,提高系統的性能和穩定性。[Ⅰ]

總之,eBPF 的常見用途非常廣泛,可以用于網絡監控、安全過濾、性能分析和虛擬化等多種應用場景。[Ⅰ]

2.工作原理

eBPF 的工作原理主要分為三個步驟:加載、編譯和執行。

eBPF 需要在內核中運行。這通常是由用戶態的應用程序完成的,它會通過系統調用來加載 eBPF 程序。在加載過程中,內核會將 eBPF 程序的代碼復制到內核空間。

eBPF 程序需要經過編譯和執行。這通常是由Clang/LLVM的編譯器完成,然后形成字節碼后,將用戶態的字節碼裝載進內核,并通過一個JIT編譯步驟將程序的通用字節碼轉換為機器特定指令集,以優化程序的執行速度。

在內核中運行時,eBPF 程序通常會掛載到一個內核鉤子(hook)上,以便在特定的事件發生時被執行。例如,可以將 eBPF 程序掛載到網絡協議棧的某個位置,以便在收到網絡數據包時被執行。

最后,eBPF 程序還需要經過內核安全機制的檢查。這是為了確保 eBPF 程序不會破壞內核的穩定性和安全性。在檢查過程中,內核會對 eBPF 程序的代碼進行分析,以確保它不會進行惡意操作,如系統調用、內存訪問等。如果 eBPF 程序通過了內核安全機制的檢查,它就可以在內核中正常運行了。在運行過程中,eBPF 程序可以訪問內核的數據結構,并通過內核接口與其他組件進行交互。例如,eBPF 程序可以捕獲網絡數據包,并通過內核接口將它們轉發給用戶態的應用程序。總之,eBPF 的工作原理是通過動態加載、執行和檢查無損編譯過的代碼來實現的。[Ⅰ]

下圖是其架構圖。

5626c56c-a71f-11ed-bfe3-dac502259ad0.jpg

圖片來自:https://www.infoq.com/articles/gentle-linux-ebpf-introduction/

3. 示例

eBPF 可以用于對內核的性能進行分析。下面是一個基于 eBPF 的性能分析的 step-by-step 示例:

第一步:準備工作:首先,需要確保內核已經支持 eBPF 功能。這通常需要在內核配置文件中啟用 eBPF 相關的選項,并重新編譯內核。檢查是否支持 eBPF,你可以用這兩個命令查看 ls /sys/fs/bpf 和 lsmod | grep bpf。

第二步:寫 eBPF 程序:接下來,需要編寫 eBPF 程序,用于收集內核的性能指標。eBPF 程序的語言可以選擇 C 或者 Python,它需要通過特定的接口訪問內核的數據結構,并將收集到的數據保存到指定的位置。

下面是一個 Python 示例:

#!/usr/bin/python3
frombccimportBPF
fromtimeimportsleep
#定義eBPF程序
bpf_text="""
#include
BPF_HASH(stats,u32);
intcount(structpt_regs*ctx){
u32key=0;
u64*val,zero=0;
val=stats.lookup_or_init(&key,&zero);
(*val)++;
return0;
}
"""
#編譯eBPF程序
b=BPF(text=bpf_text,cflags=["-Wno-macro-redefined"])
#加載eBPF程序
b.attach_kprobe(event="tcp_sendmsg",fn_name="count")
name={
0:"tcp_sendmsg"
}
#輸出統計結果
whileTrue:
try:
#print("Totalpackets:%d"%b["stats"][0].value)
fork,vinb["stats"].items():
print("{}:{}".format(name[k.value],v.value))
sleep(1)
exceptKeyboardInterrupt:
exit()

這個 eBPF 程序的功能是統計網絡中傳輸的數據包數量。它通過定義一個 BPF_HASH 數據結構來保存統計結果,并通過捕獲 tcp_sendmsg 事件來實現實時統計。最后,它通過每秒輸出一次統計結果來展示數據。這個 eBPF 程序只是一個簡單的示例,實際應用中可能需要進行更復雜的統計和分析。

第三步:運行 eBPF 程序:接下來,需要使用eBPF編譯器將 eBPF 程序編譯成內核可執行的格式(這個在上面的Python程序里你可以看到——Python引入了一個bcc的包,然后用這個包,把那段 C語言的程序編譯成字節碼加載在內核中并把某個函數attach到某個事件上)。這個過程可以使用 BPF Compiler Collection(BCC)工具來完成。BCC 工具可以通過命令行的方式將 eBPF 程序編譯成內核可執行的格式,并將其加載到內核中。

下面是運行上面的 Python3 程序的步驟:

sudoaptinstallpython3-bpfcc

注:在Python3下請不要使用 pip3 install bcc (參看:https://github.com/iovisor/bcc/issues/2278#issuecomment-825356087)

如果你是 Ubuntu 20.10 以上的版本,最好通過源碼安裝(否則程序會有編譯問題),參看https://github.com/iovisor/bcc/issues/3993#issuecomment-1228217609:

aptpurgebpfcc-toolslibbpfccpython3-bpfcc
wgethttps://github.com/iovisor/bcc/releases/download/v0.25.0/bcc-src-with-submodule.tar.gz
tarxfbcc-src-with-submodule.tar.gz
cdbcc/
aptinstall-ypython-is-python3
aptinstall-ybisonbuild-essentialcmakeflexgitlibedit-devlibllvm11llvm-11-devlibclang-11-devzlib1g-devlibelf-devlibfl-devpython3-distutils
aptinstall-ycheckinstall
mkdirbuild
cdbuild/
cmake-DCMAKE_INSTALL_PREFIX=/usr-DPYTHON_CMD=python3..
make
checkinstall

接下來,需要將上面的 Python 程序保存到本地,例如保存到文件 netstat.py。運行程序:最后,可以通過執行以下命令來運行 Python 程序:

$chmod+x./netstat.py
$sudo./netstat.py
tcp_sendmsg:29
tcp_sendmsg:216
tcp_sendmsg:277
tcp_sendmsg:379
tcp_sendmsg:419
tcp_sendmsg:468
tcp_sendmsg:574
tcp_sendmsg:645
tcp_sendmsg:29

程序開始運行后,會在控制臺輸出網絡數據包的統計信息。可以通過按 Ctrl+C 組合鍵來結束程序的運行。

下面我們再看一個比較復雜的示例,這個示例會計算 TCP 的發包時間(示例參考于 Github 上這個 issue[1] 里的程序):

#!/usr/bin/python3
frombccimportBPF
importtime
#定義eBPF程序
bpf_text="""
#include
#include
#include
#include
structpacket_t{
u64ts,size;
u32pid;
u32saddr,daddr;
u16sport,dport;
};
BPF_HASH(packets,u64,structpacket_t);
inton_send(structpt_regs*ctx,structsock*sk,structmsghdr*msg,size_tsize)
{
u64id=bpf_get_current_pid_tgid();
u32pid=id;
//記錄數據包的時間戳和信息
structpacket_tpkt={};//結構體一定要初始化,可以使用下面的方法
//__builtin_memset(&pkt,0,sizeof(pkt));
pkt.ts=bpf_ktime_get_ns();
pkt.size=size;
pkt.pid=pid;
pkt.saddr=sk->__sk_common.skc_rcv_saddr;
pkt.daddr=sk->__sk_common.skc_daddr;
structinet_sock*sockp=(structinet_sock*)sk;
pkt.sport=sockp->inet_sport;
pkt.dport=sk->__sk_common.skc_dport;
packets.update(&id,&pkt);
return0;
}
inton_recv(structpt_regs*ctx,structsock*sk)
{
u64id=bpf_get_current_pid_tgid();
u32pid=id;
//獲取數據包的時間戳和編號
structpacket_t*pkt=packets.lookup(&id);
if(!pkt){
return0;
}
//計算傳輸時間
u64delta=bpf_ktime_get_ns()-pkt->ts;
//統計結果
bpf_trace_printk("tcp_time:%llu.%llums,size:%llu\n",
delta/1000,delta%1000%100,pkt->size);
//刪除統計結果
packets.delete(&id);
return0;
}
"""
#編譯eBPF程序
b=BPF(text=bpf_text,cflags=["-Wno-macro-redefined"])
#注冊eBPF程序
b.attach_kprobe(event="tcp_sendmsg",fn_name="on_send")
b.attach_kprobe(event="tcp_v4_do_rcv",fn_name="on_recv")
#輸出統計信息
print("TracingTCPlatency...HitCtrl-Ctoend.")
whileTrue:
try:
(task,pid,cpu,flags,ts,msg)=b.trace_fields()
print("%-18.9f%-16s%-6d%s"%(ts,task,pid,msg))
exceptKeyboardInterrupt:
exit()

上面這個程序通過捕獲每個數據包的時間戳來統計傳輸時間。在捕獲 tcp_sendmsg 事件時,記錄數據包的發送時間;在捕獲 tcp_v4_do_rcv 事件時,記錄數據包的接收時間;最后,通過比較兩個時間戳來計算傳輸時間。

從上面的兩個程序我們可以看到,eBPF 的一個編程的基本方法,這樣的在 Python 里向內核的某些事件掛載一段 “C語言” 的方式就是 eBPF 的編程方式。

實話實說,這樣的代碼很不好寫,而且有很多非常詭異的東西,一般人是很難駕馭的(上面的代碼我也很不是很容易都能寫通的,把 Google 都用了個底兒掉,讀了很多晦澀的文檔……)。好在這樣的代碼已經有人寫了,我們不必再寫了,在 Github 上的 bcc 庫下的 tools 目錄[2]有很多……

BCC(BPF Compiler Collection)是一套開源的工具集,可以在 Linux 系統中使用 BPF(Berkeley Packet Filter)程序進行系統級性能分析和監測。BCC 包含了許多實用工具,如:

bcc-tools:一個包含許多常用的 BCC 工具的軟件包。

bpftrace:一個高級語言,用于編寫和執行 BPF 程序。

tcptop:一個實時監控和分析 TCP 流量的工具。

execsnoop:一個用于監控進程執行情況的工具。

filetop:一個實時監控和分析文件系統流量的工具。

trace:一個用于跟蹤和分析函數調用的工具。

funccount:一個用于統計函數調用次數的工具。

opensnoop:一個用于監控文件打開操作的工具。

pidstat:一個用于監控進程性能的工具。

profile:一個用于分析系統 CPU 使用情況的工具。

下面這張圖你可能見過多次了,你可以看看他可以干多少事,內核里發生什么事一覽無余。

5645e8f2-a71f-11ed-bfe3-dac502259ad0.png

4.延伸閱讀

一些經典的文章和書籍關于 eBPF 包括:

Brendan Gregg 的《BPF Performance Tools: Linux System and Application - Observability[3]》一書是一個全面的指南,涵蓋了 eBPF 的基礎知識和實踐應用。

eBPF 的官網:https://ebpf.io/ 由 Cilium 建立

Cilium’s BPF and XDP Reference Guide:http://docs.cilium.io/en/latest/bpf/

BPF Documentation:https://www.kernel.org/doc/html/latest/bpf/index.html

BPF Design Q&A:https://www.kernel.org/doc/html/latest/bpf/bpf_design_QA.html

還有 Github 上的 Awesome eBPF:https://github.com/zoidbergwill/awesome-ebpf

5. 彩蛋

最后來到彩蛋環節。因為最近 ChatGPT 很火,于是,我想通過 ChatGPT 來幫助我書寫這篇文章,一開始我讓 ChatGPT 幫我列提綱,并根據提綱生成文章內容,并查找相關的資料,非常之順利,包括生成的代碼,我以為我們以很快地完成這篇文章。

但是,到了代碼生成的時候,我發現,ChatGPT 生成的代碼的思路和方法都是對的,但是是比較老的,而且是跑不起來的,出現了好些低級錯誤,如:使用了未聲明的變量,沒有引用完整的C語言的頭文件,沒有正確地初始化變量,錯誤地獲取數據,類型沒有匹配……等等,在程序調試上,挖了很多的坑,C 語言本來就不好搞,挖的很多運行時的坑很難察覺。

所以,耗費了我大量的時間來排除各種各樣的問題,其中有環境上的問題,還有代碼上的問題,這些問題即便是通過 Google 也不容易找到解決方案,我找到的解決方案都放在文章中了,尤其是第二個示例,讓我調試了3個多小時,讀了很多 bcc 上的 issue 和相關的晦澀的手冊和文檔,才讓程序跑通。

到了文章收關的階段,我讓 ChatGPT 給我幾個延伸閱讀,也是很好的,但是沒有給出鏈接,于是我只得人肉 Google 了一下,然后讓我吃驚的是,好多 ChatGPT 給出來的文章是根本不存在的,完全是它偽造的。我連讓它干了兩次都是這樣,這個讓我驚掉大牙。

這讓我開始懷疑它之前生成的內容,于是,我不得我返回仔細 Review 我的文章,尤其是“介紹”、“用途”和“工作原理”這三個章節,基本都是 ChatGPT 生成的,在 Review 完后,我發現了 ChatGPT 給我生造了一個叫 “無損編譯器”的術語,這個術語簡直了,于是我開始重寫我的文章。我把一些段落重寫了,有一些沒有,保留下來的我都標記上了 [Ⅰ],大家讀的時候要小心閱讀。

最后,我的結論是,ChatGPT 只是一個不成熟的玩具,只能回答一些沒有價值的日常聊天的問題,要說能取代 Google,我覺得不可能,因為 Google 會基于基本的事實,而 ChatGPT 會基于內容生成的算法,在造假方面稱得上是高手,可以列為電信詐騙的范疇了,我以后不會再使用 ChatGPT 生成文章內容或是作我的幫手了。StackOverflow 把其 ban 了真是不能太贊了!

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 內核
    +關注

    關注

    3

    文章

    1336

    瀏覽量

    40081
  • Linux
    +關注

    關注

    87

    文章

    11123

    瀏覽量

    207883
  • 開源
    +關注

    關注

    3

    文章

    3123

    瀏覽量

    42065
  • 代碼
    +關注

    關注

    30

    文章

    4668

    瀏覽量

    67753
  • 觀測
    +關注

    關注

    0

    文章

    19

    瀏覽量

    9592

原文標題:Linux 內核觀測技術 eBPF 中文入門指南

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    FreeRTOS實時內核使用指南_中文

    FreeRTOS實時內核使用指南_中文.pdf
    發表于 04-08 17:38

    FreeRTOS實時內核使用指南_中文

    本帖最后由 lee_st 于 2018-2-3 14:18 編輯 FreeRTOS實時內核使用指南_中文
    發表于 02-03 14:17

    關于 eBPF 安全可觀測性,你需要知道的那些事兒

    許慶偉:龍蜥社區eBPF技術探索SIG組 Maintainer & Linux Kernel Security Researcher。本文是作者在 PODS 2022 大會上關于內核
    發表于 09-08 15:31

    openEuler 倡議建立 eBPF 軟件發布標準

    eBPF 是一個能夠在內核運行沙箱程序的技術,提供了一種在內核事件和用戶程序事件發生時安全注入代碼的機制,使得非內核開發人員也可以對
    發表于 12-23 16:21

    Linux內核中文版教程

    Linux內核中文版教程
    發表于 03-28 09:45 ?0次下載

    Linux內核解讀入門

    Linux內核解讀入門關鍵詞:Linux, 內核,源代碼一.核心源程序的文件組織: 1. Linux
    發表于 01-16 14:40 ?103次下載

    淺談Linux內核解讀入門

    針對好多Linux 愛好者對內核很有興趣卻無從下口,本文旨在介紹一種解讀linux內核源碼的入門方法,而不是解說
    發表于 11-08 10:06 ?2次下載

    linux內核入門教材之linux內核設計與實現第二版中文版免費下載

    此書是當今首屈一指的linux內核入門最佳圖書。作者是為2.6內核加入了搶占的人,對調度部分非常精通,而調度是整個系統的核心,因此本書是很權威的。這本書講解淺顯易懂,全書沒有列舉一條匯編語句,但是
    發表于 10-15 18:20 ?0次下載
    <b class='flag-5'>linux</b><b class='flag-5'>內核入門</b>教材之<b class='flag-5'>linux</b><b class='flag-5'>內核</b>設計與實現第二版<b class='flag-5'>中文</b>版免費下載

    教你們如何使用eBPF追蹤LINUX內核

    1. 前言 我們可以使用BPF對Linux內核進行跟蹤,收集我們想要的內核數據,從而對Linux中的程序進行分析和調試。與其它的跟蹤技術相比
    的頭像 發表于 04-20 11:26 ?2239次閱讀
    教你們如何使用<b class='flag-5'>eBPF</b>追蹤<b class='flag-5'>LINUX</b><b class='flag-5'>內核</b>

    介紹eBPF針對可觀測場景的應用

    隨著eBPF推出,由于具有高性能、高擴展、安全性等優勢,目前已經在網絡、安全、可觀察等領域廣泛應用,同時也誕生了許多優秀的開源項目,如Cilium、Pixie等,而iLogtail 作為阿里內外千萬實例可觀測數據的采集器,eBPF
    的頭像 發表于 08-11 09:10 ?1430次閱讀

    eBPF安全可觀測性的前景展望

    本次分享將從監控和可觀測性、eBPF安全可觀測性分析、內核安全可觀測性展望三個方面展開。
    的頭像 發表于 08-17 11:27 ?1428次閱讀

    Linux技術eBPF內核原理及應用

    BCC(BPF Compiler Collection)是一套開源的工具集,可以在 Linux 系統中使用 BPF(Berkeley Packet Filter)程序進行系統級性能分析和監測。
    發表于 01-04 10:31 ?2458次閱讀

    Linux 內核eBPF優勢和eBPF潛力總結

    Express Data Path (XDP):網絡驅動程序是最早可以附加 XDP BPF 鉤子的點。當收到一個數據包時,eBPF 程序就會被觸發運行。
    發表于 01-10 11:37 ?2832次閱讀

    eBPF,何以稱得上是革命性的內核技術

    eBPF 的全稱是 extended Berkeley Packet Filter,它被稱之為 “革命性” 的內核技術,可以在 Linux 內核中運行沙盒程序,而無需更改
    的頭像 發表于 05-08 08:26 ?524次閱讀
    <b class='flag-5'>eBPF</b>,何以稱得上是革命性的<b class='flag-5'>內核技術</b>?

    基于ebpf的性能工具-bpftrace

    在前面我已經分享了關于ebpf入門的文章: 基于ubuntu22.04-深入淺出 eBPF 。 這篇文章介紹一個基于ebpf技術的強大工具-
    的頭像 發表于 09-04 16:02 ?572次閱讀
    基于<b class='flag-5'>ebpf</b>的性能工具-bpftrace