Linux 監(jiān)控和調(diào)試?yán)?Sysdig 入門教程
Sysdig 簡介
Sysdig 官網(wǎng) 上對自己的介紹是:
Open Source Universal System Visibility With Native Contaier Support.
它的定位是系統(tǒng)監(jiān)控、分析和排障的工具,其實(shí)在 Linux 平臺上,已經(jīng)有很多這方面的工具 strace、tcpdump、htop、iftop、lsof、netstat,它們都能用來分析 Linux 系統(tǒng)的運(yùn)行情況,而且還有很多日志、監(jiān)控工具。為什么還需要 Sysdig 呢?在我看來,Sysdig 的優(yōu)點(diǎn)可以歸納為三個詞語:整合、強(qiáng)大、靈活。
整合
雖然 Linux 有很多系統(tǒng)分析和調(diào)優(yōu)的工具,但是它們一般都負(fù)責(zé)某個特殊的功能,并且使用方式有很大的差異,如果要分析和定位問題,一般都需要熟練掌握需要命令的使用。而且這些工具的數(shù)據(jù)無法進(jìn)行共享,只能相互獨(dú)立工作。Sysdig 一個工具就能實(shí)現(xiàn)上述所有工具的功能,并且提供了統(tǒng)一的使用語法。
強(qiáng)大
Sysdig 能獲取實(shí)時的系統(tǒng)數(shù)據(jù),也能把信息保存到文件中以供后面分析。捕獲的數(shù)據(jù)包含系統(tǒng)的個個方面:
• 全方面的系統(tǒng)參數(shù):CPU、Memory、Disk IO、網(wǎng)絡(luò) IO
• 支持各種 IO 活動:進(jìn)程、文件、網(wǎng)絡(luò)連接等
除了幫你捕獲信息之外,Sysdig 還預(yù)先還有有用的工具來分析這些數(shù)據(jù),從大量的數(shù)據(jù)中找到有用的信息變得非常簡單。比如你能還簡單地做到下面這些事情:
• 按照 CPU 的使用率對進(jìn)程進(jìn)行排序,找到 CPU 使用率最高的那個
• 按照發(fā)送網(wǎng)絡(luò)數(shù)據(jù)報文的多少對進(jìn)程進(jìn)行排序
• 找到打開最多文件描述符的進(jìn)程
• 查看哪些進(jìn)程修改了指定的文件
• 打印出某個進(jìn)程的 HTTP 請求報文
• 找到用時最久的系統(tǒng)調(diào)用
• 查看系統(tǒng)中所有的用戶都執(zhí)行了哪些命令
• ……
基本上自帶的工具就能滿足大部分的分析需求。
靈活
Sysdig 有著類似于 tcpdump 的過濾語法,用戶可以隨意組合自己的過濾邏輯,從茫茫的數(shù)據(jù)中找到關(guān)心的信息。除此之外,用戶還可以自己編寫 Lua 腳本來自定義分析邏輯,基本上不受任何限制。
工作原理
Sysdig 通過在內(nèi)核的 driver 模塊注冊系統(tǒng)調(diào)用的 hook,這樣當(dāng)有系統(tǒng)調(diào)用發(fā)生和完成的時候,它會把系統(tǒng)調(diào)用信息拷貝到特定的 buffer,然后用戶模塊的組件對數(shù)據(jù)信息處理(解壓、解析、過濾等),并最終通過 Sysdig 命令行和用戶進(jìn)行交互。
更多的原理可以參考官方博客
除了 Sysdig 命令之外,還有一個基于終端的 UI 命令 Csysdig,它類似于 top 命令,定時對系統(tǒng)情況進(jìn)行刷新,并且可以讓用戶交互。這篇文章我們只介紹 Sysdig,不會講解 Csysdig 的使用。
安裝
Sysdig 的安裝在官方文檔中有詳細(xì)的說明,這里不再贅述。需要注意的是,Sysdig 對內(nèi)核版本有一定的要求,請保證內(nèi)核不要太舊。
另外,如果使用容器的方式安裝,需要把主機(jī)的很多系統(tǒng)目錄 mount 到容器中:
- $ docker run -i -t --name sysdig --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /dev:/host/dev -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro sysdig/sysdig
Sysdig 基本用法
基本格式
直接在終端輸入 sysdig 就能開始捕獲系統(tǒng)信息,這個命令需要系統(tǒng)管理員權(quán)限,執(zhí)行后你會看到終端有持續(xù)不斷的輸出流。
- $ sudo sysdig
因?yàn)橄到y(tǒng)每時每刻都有大量的系統(tǒng)調(diào)用產(chǎn)生,這樣是沒辦法看清更無法分析輸出信息的,可以先使用 CTRL + c 來退出命令。
在講解如何使用 Sysdig 的參數(shù)之前,我們先來解釋一下它的輸出格式:
- 5352209 11:54:08.853479695 0 ssh-agent (13314) < getrusage
- 5352210 11:54:08.853481094 0 ssh-agent (13314) > clock_gettime
- 5352211 11:54:08.853482049 0 ssh-agent (13314) < clock_gettime
- 5352226 11:54:08.853510313 0 ssh-agent (13314) > getrusage
- 5352228 11:54:08.853511089 0 ssh-agent (13314) < getrusage
- 5352229 11:54:08.853511646 0 ssh-agent (13314) > clock_gettime
- 5352231 11:54:08.853512020 0 ssh-agent (13314) < clock_gettime
- 5352240 11:54:08.853530285 0 ssh-agent (13314) > stat
- 5352241 11:54:08.853532329 0 ssh-agent (13314) < stat res=0 path=/home/cizixs/.ssh
- 5352242 11:54:08.853533065 0 ssh-agent (13314) > stat
- 5352243 11:54:08.853533990 0 ssh-agent (13314) < stat res=0 path=/home/cizixs/.ssh/id_rsa.pub
- 5353954 11:54:08.857382204 0 ssh-agent (13314) > write fd=16 size=280
所有的輸入都是按照行來分割的,每行都是一條記錄,由多個列組成,默認(rèn)的格式是:
- %evt.num %evt.outputtime %evt.cpu %proc.name (%thread.tid) %evt.dir %evt.type %evt.info
各個字段的含義如下:
• evt.num:遞增的事件號。
• evt.time:事件發(fā)生的時間。
• evt.cpu:事件被捕獲時所在的 CPU,也就是系統(tǒng)調(diào)用是在哪個 CPU 執(zhí)行的。比較上面的例子中,值 0 代表機(jī)器的第一個 CPU。
• proc.name:生成事件的進(jìn)程名字,也就是哪個進(jìn)程在運(yùn)行。
• thread.tid:線程的 id,如果是單線程的程序,這也是進(jìn)程的 pid。
• evt.dir:事件的方向(direction),> 代表進(jìn)入事件,< 代表退出事件。
• evt.type:事件的名稱,比如 open、stat等,一般是系統(tǒng)調(diào)用。
• evt.args:事件的參數(shù)。如果是系統(tǒng)調(diào)用,這些對應(yīng)著系統(tǒng)調(diào)用的參數(shù)。
過濾
完整的 Sysdig 使用方法是這樣的:
- sysdig [option]... [filter]
因?yàn)?Sysdig 的輸出內(nèi)容很多,不管是監(jiān)控還是查問題我們要關(guān)注的事件只是其中很小的一部分。這個時候就要用到過濾的功能,找到感興趣的事件。Sysdig 的過濾功能很強(qiáng)大,不僅支持的過濾項(xiàng)很多,而且還能夠自由地進(jìn)行邏輯組合。
Sysdig 的過濾器也是分成不同類別的,比如:
• fd: 對文件描述符(file descriptor)進(jìn)行過濾,比如 fd 標(biāo)號(fd.num)、fd 名字(fd.name)。
• process: 進(jìn)程信息的過濾,比如進(jìn)程 id(proc.id)、進(jìn)程名(proc.name)。
• evt: 事件信息的過濾,比如事件編號、事件名。
• user: 用戶信息的過濾,比如用戶 id、用戶名、用戶 home 目錄、用戶的登錄 shell(user.shell)。
• syslog: 系統(tǒng)日志的過濾,比如日志的嚴(yán)重程度、日志的內(nèi)容。
• fdlist: poll event 的文件描述符的過濾。
完整的過濾器列表可以使用 sysdig -l 來查看,比如可以查看建立 TCP 連接的事件:
- $ sudo sysdig evt.type=accept
過濾器除了直接的相等比較之外,還有其他操作符,包括 =、!=、>=、>、<、<=、contains、in 和 exists,比如:
- $ sysdig fd.name contains /etc
- $ sysdig "evt.type in ( 'select', 'poll' )"
- $ sysdig proc.name exists
更酷的是,多個過濾條件還可以通過 and、or 和 not 進(jìn)行邏輯組合,比如:
- $ sysdig "not (fd.name contains /proc or fd.name contains /dev)"
這些強(qiáng)大的功能綜合到一起,就能讓我們很容易定位到需要的事件,分析和監(jiān)控更有目的性。
自定義輸出格式
標(biāo)準(zhǔn)的輸出已經(jīng)打印出常用的信息,sysdig 還允許你自定義打印出的內(nèi)容,參數(shù) -p 可以加上類似于 C 語言 printf 字符串,比如:
- $ sysdig -p"user:%user.name dir:%evt.arg.path" evt.type=chdir
- user:ubuntu dir:/root
- user:ubuntu dir:/root/tmp
- user:ubuntu dir:/root/Download
上面的信息,可以很容易看到用戶更改當(dāng)前目錄的情況。從上面的例子也可以使用 -p 的使用方法:
• 字段必須用 % 作為前綴,所有在 sysdig -l 中列出來的字段都可以使用
• 你可以在字符串中加入其他可讀性的內(nèi)容,它們會如實(shí)打印出來
• 如果某個字段在時間中不存在,默認(rèn)這個事件會過濾掉,在這個字符串最前面加上 * 符號,會打印出所有的事件,不存在的字段會變成 ,比如:
- $ sysdig -p"*%evt.type %evt.dir %evt.arg.name" evt.type=open
- open > <NA>
- open < /proc/1285/task/1399/stat
- open > <NA>
- open < /proc/1285/task/1400/io
- open > <NA>
- open < /proc/1285/task/1400/statm
- open > <NA>
保存到文件
盡管可以用過濾器減少輸出,直接在終端查看事件流還是沒有辦法讓我們進(jìn)行深入分析。
和 tcpdump 工具類似,Sysdig 也允許你把捕獲的時間保存到本地的文件,然后再讀取文件的內(nèi)容進(jìn)行分析。
保存到文件可以通過 -w 實(shí)現(xiàn),從文件中讀取需要 -r 參數(shù),比如:
- # 捕獲事件,并保存到文件中,這樣在終端是看不到輸出的。
- $ sudo sysdig -w sysdig-trace-file.scap
- # 從文件中讀取 Sysdig 格式的事件進(jìn)行分析。
- $ sudo sysdig -r sysdig-trace-file.scap
另一個有用的功能是,你可以控制捕獲到文件的內(nèi)容。通常情況下,Sysdig 捕獲了系統(tǒng)所有的活動,因此這些數(shù)據(jù)會很大,如果一直捕獲的話,會造成磁盤空間的浪費(fèi),Sysdig 提供了類似于 logrotate 的方式,讓你只保存最新捕獲的文件。
控制捕獲文件大小的一個辦法是在捕獲的使用使用過濾器,之外,你還可以通過 -n 2000 指定捕獲 2000 條事件之后就退出,或者通過 logrotate 的方式來滾動文件:
• sysdig -C 5 -W 10 -w dump.pcap :保證每個文件不超過 5M 大小,并且只保存最近的 10 個文件
• sysdig -G 60 -W 60 -w dump.pcap:每個文件只保存一分鐘內(nèi)的系統(tǒng)活動(-G 60),并且只保存 60 個文件,也就是說捕獲最近一個小時的系統(tǒng)活動,每分鐘的數(shù)據(jù)一個文件
• sysdig -e 1000 -W 5 -w dump.scap:保存 5 個文件,每個文件只有 1000 個事件
當(dāng)使用 -w 保存文件的使用,還可以使用 -z 參數(shù)對保存的內(nèi)容進(jìn)行壓縮,進(jìn)一步減少占用的空間。
讀取的時候也可以使用過濾器,如果我們只關(guān)心 write 系統(tǒng)調(diào)用:
- $ sysdig -r sysdig-trace-nano.scap evt.type=write
而且讀取的時候也可以進(jìn)一步對文件進(jìn)行分割,比如:
- $ sysdig -r dump.scap -G 300 -z -w segments.scap
這個命令,就是讀取 dump.scap 文件的內(nèi)容,并且把它分割成五分鐘(-G 300s)的多個文件。
常用的參數(shù)
除了上面介紹的過濾器參數(shù),Sysdig 還有很多可用的參數(shù),完整的列表和解釋請參考 man sysdig 文檔。這里介紹一下比較常用的:
• -A --print-ascii:把 buffer 中數(shù)據(jù)按照 ASCII 格式打印,方便用戶閱讀
• -x --print-hex:把 buffer 中數(shù)據(jù)按照十六進(jìn)制格式打印
• -X --print-hex-ascii:把 buffer 中數(shù)據(jù)同時按照 ASCII 格式和十六進(jìn)制格式打印
• -s 1024:捕獲 buffer 的數(shù)據(jù)大小,默認(rèn)為 80,如果這個值設(shè)置的過大,會產(chǎn)生很大的文件
• -N:不用把端口號轉(zhuǎn)換成可讀的名字,這個參數(shù)會提高處理的效率
Chisels:實(shí)用的工具箱
雖然有了過濾器和文件的輸入輸出,加上 Sysdig 其他的參數(shù),我們可以按照需求去分析和監(jiān)控系統(tǒng)了,但是很多場景需要更復(fù)雜的數(shù)據(jù)聚合。
Sysdig 提供了另外一個強(qiáng)大的功能:chisels,它們是一組預(yù)定義的功能集合,通過 Lua 腳本實(shí)現(xiàn),用來分析特定的場景。
可以通過 sudo sysdig -cl 列出支持的所有 chisels,我們來解釋一些比較常用的 chisels:
• httplog:輸出所有的 HTTP 請求。
• topprocs_cpu:輸出按照 CPU 使用率排序的進(jìn)程列表。
• echo_fds:輸出進(jìn)程讀寫的數(shù)據(jù)。
• netstat:列出網(wǎng)絡(luò)的連接情況。
• spy_file:輸出文件的讀寫數(shù)據(jù),可以提供某個文件名作為參數(shù),這樣就只輸出該文件的讀寫內(nèi)容。
有些 chisel 可能需要參數(shù)才能正常運(yùn)行,如果要了解某個 chisel 的具體使用說明,可以用 -i 參數(shù),比如要了解 spy_file 的用法:
- $ sudo sysdig -i spy_file
- Category: I/O
- -------------
- spy_file Echo any read/write made by any process to all files. Optionall
- y, you can provide the name of one file to only intercept reads
- /writes to that file.
- This chisel intercepts all reads and writes to all files. Instead of all files,
- you can limit interception to one file.
- Args:
- [string] read_or_write - Specify 'R' to capture only read event
- s; 'W' to capture only write events; 'RW' to capture read and w
- rite events. By default both read and write events are captured
- .
- [string] spy_on_file_name - The name of the file which the chis
- el should spy on for all read and write activity.
文章最開始的時候,我提到過 Sysdig 可以滿足大部分的日常分析,它們主要就是通過 chisel 完成的。比如:
按照網(wǎng)絡(luò)的使用情況對進(jìn)程進(jìn)行排序:
- $ sysdig -c topprocs_net
按照建立連接數(shù)量對進(jìn)程進(jìn)行排序:
- $ sysdig -c fdcount_by fd.sport "evt.type=accept"
查看系統(tǒng)中用戶執(zhí)行的命令:
- $ sysdig -r sysdig.pcap -c spy_users
更多的使用案例,可以參考 Sysdig Example 這篇 wiki。
在 Linux 機(jī)器上,這些 chisel 保存在 /usr/share/sysdig/chisels 文件夾中,每個 chisel 對應(yīng)一個 Lua 腳本文件。如果提供的這些 chisel 還不能滿足需求,用戶也可以根據(jù)需求編寫自己的 chisel。
對容器的支持
Sysdig 另外一個優(yōu)勢是它對容器( Docker 和 Kubernetes )的良好支持,這對于目前采用了容器化的系統(tǒng)管理員來說是很好的福利。
使用 -pc 參數(shù)就能自動在打印的事件中添加上容器的信息(容器名、容器 id 等),比如捕獲 container 名字為 zen_knuth 的所有系統(tǒng)活動:
- $ sysdig -pc container.name=zen_knuth
對容器的分析和原來的一樣,只要通過 container.name=apache 指定要分析的容器名字就行,比如查看某個容器的網(wǎng)絡(luò)連接:
- $ sysdig -pc -c topconns container.name=wordpress1
要集成 Kubernetes 系統(tǒng)監(jiān)控的話,使用 -k http://master_ip:8080 參數(shù),后面是 apiserver 的地址,如果 apiserver 需要認(rèn)證的話,需要指定 -K filename 來說明 apiserver CA 證書的文件地址。關(guān)于 Kubernetes 的監(jiān)控和分析不是這篇文章的重點(diǎn),讀者可以參數(shù) Sysdig 的博客或者其他文檔。
Csysdig:圖形化的 Sysdig
Sysdig 還提供了另外一個圖形化的工具:Csysdig,它的界面和 top/htop 命令相似,并且可以接受用戶的交互。
和 Sysdig 一樣,Csysdig 可以實(shí)時捕獲系統(tǒng)事件,也可以讀取之前保存的文件。
更多文檔
這篇文章介紹的都出入門的、基礎(chǔ)概念性的知識,如果讀者希望進(jìn)一步了解 sysdig,不妨繼續(xù)閱讀下面這些文章:
• sysdig 和傳統(tǒng)的 strace、htop、lsof、tcpdump、iftop命令的比較
• 理解 sysdig 的輸出
• sysdig twitter 賬號 #digoftheday
參考資料
這篇文章主要參考了一下的博客、文章和資料:
• Sysdig User Guide
• Linux Troubleshooting Cheatsheet: strace, htop, lsof, tcpdump, iftop & sysdig
• DigitalOcean: How To Monitor Your Ubuntu 16.04 System with Sysdig
• Sysdig vs DTrace vs Strace: a Technical Discussion•用 Sysdig 監(jiān)控服務(wù)器和 Docker 容器