提到如何動態追蹤進程中的系統調用,相信你們第一時間都能想到 strace,它的基本用法很是簡單,很是適合用來解決 「爲何這個軟件沒法在這臺機器上運行?」 這類問題。但若是須要分析線上服務 (特別是延遲敏感型)的某些系統調用的延遲時,strace 則不那麼合適,由於它引入的開銷會很是大,從性能分析大師 Brendan Gregg 的測試結果得知,被 strace 追蹤的目標進程的運行速度會下降 100 倍以上,這對生產環境來講將是個災難。前端
那麼是否有比較好用的工具用在生產環境上呢?答案是確定的,下面將介紹兩款工具的經常使用命令,方便你們須要時查閱。api
衆所周知,perf 是 Linux 系統下很是強大的性能工具,由 Linux 內核開發人員在不斷演進和優化。除了能夠分析 PMU (Performance Monitoring Unit) 硬件事件,內核事件等通用功能外,perf 還提供了其餘「子模塊」,好比 sched 分析調度器,timechart 根據負載特徵可視化系統行爲,c2c 分析可能存在的 false sharing (RedHat 在大量 Linux 的應用上,測試過這套 c2c 的開發原型,成功地發現了不少熱點的僞共享緩存行問題。)等, 而 trace 則可用於分析系統調用,其功能很是強大,並保證了能夠接受的開銷—— 運行速度僅放慢 1.36 倍(dd 做爲測試負載) 。咱們一塊兒看下幾個經常使用的場景:緩存
調用 syscall 數量的 top 排行榜數據結構
perf top -F 49 -e raw_syscalls:sys_enter --sort comm,dso --show-nr-samples
從輸出能夠看到在採樣期間,kube-apiserver 的調用 syscall 的次數最多。架構
顯示超過必定延遲的系統調用信息ssh
perf trace --duration 200
從輸出中能夠看到進程名稱、pid ,超過 200 ms 的具體系統調用參數和返回值。工具
統計某個進程一段時間內系統調用的開銷oop
perf trace -p $PID -s
從輸出中能夠看到各系統調用的次數,返回錯誤次數,總延遲,平均延遲等信息。性能
咱們也能夠進一步分析高延遲的調用棧信息測試
perf trace record --call-graph dwarf -p $PID -- sleep 10
對一組任務進行 trace,好比後臺有 2 個 bpf 工具在運行,咱們想看下它們系統調用使用狀況,就能夠先將它們添加到 perf_event 這個 cgroup 下,再執行 perf trace:
mkdir /sys/fs/cgroup/perf_event/bpftools/ echo 22542 >> /sys/fs/cgroup/perf_event/bpftools/tasks echo 20514 >> /sys/fs/cgroup/perf_event/bpftools/tasks perf trace -G bpftools -a -- sleep 10
perf-trace 的使用就介紹到這裏,更多的用法請參考 man 手冊,從上面能夠看到 perf-trace 的功能很是強大,根據 pid 或 tid 就能夠進行過濾。但彷佛沒有對容器和 K8S 環境進行便捷的支持。不用着急,接下來介紹的這個工具就是針對容器和 K8S 環境的。
對於 Traceloop 你們可能有點陌生,但提到 BCC 想必你們就以爲熟悉了。BCC 的前端是 Python/C++,其所屬 iovisor 下還有一個項目叫 gobpf 是 BCC 的 go binding。而 Traceloop 則是基於 gobpf 庫進行開發的,此項目的主要目標應用場景是容器、K8S 環境。其原理比較簡單,其架構如圖所示:
核心步驟以下:
須要注意的是,當前 cgroup id 的獲取方式是經過 bpf helper:bpf_get_current_cgroup_id 來獲取的,這個 id 是 cgroup v2 纔有的。所以只適用於開啓了 cgroup v2 的環境。尚不肯定此項目團隊是否有意向經過讀取 nsproxy 數據結構等方式來對 cgroup v1 進行支持,所以在這裏只作簡單介紹。隨着 K8S 1.19 版本開始支持 cgroup v2,期待 cgroup v2 能儘快普及起來。如下使用 Centos 8 4.18 版本內核進行簡單的演示:在 traceloop 退出時 dump 系統調用信息
sudo -E ./traceloop cgroups --dump-on-exit /sys/fs/cgroup/system.slice/sshd.service
從輸出中能夠看到,其輸出和 strace/perf trace 相似,只是針對 cgroup 進行過濾。須要注意的是 Centos 8 沒有像 Ubuntu 將 cgroup v2 掛載到 /sys/fs/cgroup/unified,而是直接掛載到 /sys/fs/cgroup 下,在使用前建議執行 mount -t cgroup2
來肯定掛載信息。
對於 K8S 平臺,該團隊將 traceloop 集成到 Inspektor Gadget 項目中,經過 kubectl 插件來運行,因爲管網給出詳細的 gif 示例,在這裏就不作過多介紹了,對 cgroup v2 有需求的朋友能夠試一試。
從 benchmark 結果看,strace 的引發的目標程序性能降低最大,perf trace 次之,traceloop 最小。
strace 依然是解決 「爲何這個軟件沒法在這臺機器上運行?」 相關問題的利器,但對於分析系統調用延遲等問題,perf trace 是合適的選擇,其也是基於 BPF 的實現,對於使用 cgroup v2 的容器、K8S 環境,traceloop 會更方便一些。