明日から使えるかもしれない sysdig
sysdig は多機能なトラブルシューティング向けツールです。 主に Dragos.inc 社が中心となって開発されているオープンソースです。
ざっくり sysdig の多機能っぷりを説明すると、 strace + tcpdump + lsof + htop + iftop + Lua = sysdig って感じです。docker などのコンテナにも対応しており、curses によるグラフィカルなUI出力なども可能です。
sysdig のインストール
Linux では RHEL/CentOS or Debian/Ubuntu 系でも下記コマンドでインストールできます。
curl -s https://s3.amazonaws.com/download.draios.com/stable/install-sysdig | sudo bash
OSX では homebrew でインストールできます。
sysdig は Windows にも対応し、 CoreOS 上でもDockerコンテナから実行可能です。公式のインストレーションガイドでご確認ください。
チゼル(chisels)
sysdig では分析対象となるチゼルを指定する必要があります。チゼルの実体は分析アクション用のスクリプトです。利用可能なチゼルの一覧は sysdig -cl で確認することができます。
(-cl は chisels-list と覚えておくとよいと思います。)
sysdig 0.4.0 系では下記に示すチゼルが利用可能です。
Category: Application
---------------------
httplog HTTP requests log
httptop Top HTTP requests
memcachelog memcached requests log
Category: CPU Usage
-------------------
spectrogram Visualize OS latency in real time.
subsecoffset Visualize subsecond offset execution time.
topcontainers_cpu Top containers by CPU usage
topprocs_cpu Top processes by CPU usage
Category: Errors
----------------
topcontainers_error Top containers by number of errors
topfiles_errors Top files by number of errors
topprocs_errors top processes by number of errors
Category: I/O
-------------
echo_fds Print the data read and written by processes.
fdbytes_by I/O bytes, aggregated by an arbitrary filter field
fdcount_by FD count, aggregated by an arbitrary filter field
fdtime_by FD time group by
iobytes Sum of I/O bytes on any type of FD
iobytes_file Sum of file I/O bytes
spy_file Echo any read/write made by any process to all files. Optionally, you can provide the name of one file to only intercept reads/writes to that file.
stderr Print stderr of processes
stdin Print stdin of processes
stdout Print stdout of processes
topcontainers_file Top containers by R+W disk bytes
topfiles_bytes Top files by R+W bytes
topfiles_time Top files by time
topprocs_file Top processes by R+W disk bytes
Category: Logs
--------------
spy_logs Echo any write made by any process to a log file. Optionally, e
xport the events around each log message to file.
spy_syslog Print every message written to syslog. Optionally, export the events around each syslog message to file.
Category: Misc
--------------
around Export to file the events around the where the given filter matches.
Category: Net
-------------
iobytes_net Show total network I/O bytes
spy_ip Show the data exchanged with the given IP address
spy_port Show the data exchanged using the given IP port number
topconns Top network connections by total bytes
topcontainers_net Top containers by network I/O
topports_server Top TCP/UDP server ports by R+W bytes
topprocs_net Top processes by network I/O
Category: Performance
---------------------
bottlenecks Slowest system calls
fileslower Trace slow file I/O
netlower Trace slow network I/O
proc_exec_time Show process execution time
scallslower Trace slow syscalls
topscalls Top system calls by number of calls
topscalls_time Top system calls by time
Category: Security
------------------
list_login_shells List the login shell IDs
shellshock_detect print shellshock attacks
spy_users Display interactive user activity
Category: System State
----------------------
lscontainers List the running containers
lsof List (and optionally filter) the open file descriptors.
netstat List (and optionally filter) network connections.
ps List (and optionally filter) the machine processes.
さらに各チゼルの情報を知りたい場合は sysdig -i <chisels> を実行します。
(-i は info ですね。)
# sysdig -i spy_users
Category: Security
------------------
spy_users Display interactive user activitylists every command that users launch interactively (e.g. from bash) and every directory users visit
Args:
[int] max_depth - the maximum depth to show in the hierarchy of processes
はい、いきなり覚えきれませんね。
多機能なので学習コスト的に少し取っつきにくく感じますが、そこは 運用で 慣れでカバーです。
sysdig コマンドの最もシンプルな実行方法は sysdig -c <chisels> です。(-c は --chisel です。)
次にいくつかのコマンド例を示します。
CPU使用率の高い稼働中プロセスを上位から出力します。
sysdig -c topprocs_cpu
帯域使用量が多いネットワークコネクションを上位から表示します。
sysdig -c topconns
サーバ全体の帯域使用量を Byte 単位で表示します。
sysdig -c iobytes_net
帯域使用量が多いサーバポートを上位から表示します。
sysdig -c topports_server
帯域使用量が多いプロセスを上位から表示します。
sysdig -c topprocs_net
読み込み/書き込みバイト数が多いファイルを上位から出力します。
sysdig -c topfiles_bytes
I/Oエラーの多いファイルを表示します。
sysdig -c topfiles_errors
システムコールエラーの多いプロセスを表示します
sysdig -c topprocs_errors
処理に比較的時間を要したシステムコールを表示します。
sysdig -c bottlenecks
実行されたコマンドのプロセス実行時間を表示します。
sysdig -c proc_exec_time
呼び出し数の多いシステムコールを上位から出力します。
sysdig -c topscalls
実行時間が多いシステムコールを上位から出力します。
sysdig -c topscalls_time
システム内のすべてのプロセスのオープンファイルを出力します。
sysdig -c lsof
対象IPアドレス間との間で転送される通信データの内容を表示します。
sysdig -c spy_ip 103.245.222.133
対象ポート間との間で転送される通信データの内容を表示します。
sysdig -c spy_port 80
各ユーザーが実行するコマンドの内容を表示します。
sysdig -c spy_users
フィルタ機能
sysdig では膨大な情報量が出力されます。そこで出力を制御するための便利なフィルタ機能があります。
sysdig -l コマンドで、sysdig で利用可能なフィルタ一覧を確認できます。
----------------------
Field Class: fd
fd.num the unique number identifying the file descriptor.
fd.type type of FD. Can be 'file', 'directory', ipv4', 'ipv6', 'unix', 'pipe', 'event', 'signalfd', 'eventpoll', 'inotify' or 'signalfd'.
fd.typechar type of FD as a single character. Can be 'f' for file, 4 for IPv4 socket, 6 for IPv6 socket, 'u' for unix socket, p for pipe, 'e' for eventfd, 's' for signalfd, 'l' for eventpoll, 'i' for inotify, 'o' for uknown.
fd.name FD full name. If the fd is a file, this field contains the full path. If the FD is a socket, this field contain the connection tuple.
fd.directory If the fd is a file, the directory that contains it.
fd.filename If the fd is a file, the filename without the path.
fd.ip matches the ip address (client or server) of the fd.
fd.cip client IP address.
fd.sip server IP address.
fd.port (FILTER ONLY) matches the port (client or server) of the fd.
fd.cport for TCP/UDP FDs, the client port.
fd.sport for TCP/UDP FDs, server port.
fd.l4proto the IP protocol of a socket. Can be 'tcp', 'udp', 'icmp' or 'raw'.
fd.sockfamily the socket family for socket events. Can be 'ip' or 'unix'.
fd.is_server 'true' if the process owning this FD is the server endpointin the connection.----------------------
Field Class: processproc.pid the id of the process generating the event.
proc.exe the full name (including the path) of the executable generating the event.
proc.name the name (excluding the path) of the executable generating the event.
proc.args the arguments passed on the command line when starting the process generating the event.
proc.cmdline full process command line, i.e name + arguments.
proc.cwd the current working directory of the event.
proc.nchilds the number of child threads of that the process generating the event currently has.
proc.ppid the pid of the parent of the process generating the event.
proc.pname the name (excluding the path) of the parent of the process generating the event.
proc.apid the pid of one of the process ancestors. E.g. proc.apid[1] returns the parent pid, proc.apid[2] returns the grandparent pid, and so on. proc.apid[0] is the pid of the current process. proc.apid without arguments can be used in filters only and matches any of the process ancestors, e.g. proc.apid=1234.
proc.aname the name (excluding the path) of one of the process ancesto
rs. E.g. proc.aname[1] returns the parent name, proc.aname[2] returns the grandparent name, and so on. proc.aname[0] is the name of the current process. proc.aname without arguments can be used in filters only and matches any of the process ancestors, e.g. proc.aname=bash.
proc.loginshellid the pid of the oldest shell among the ancestors of the current process, if there is one. This field can be used to separate different user sessions, and is useful in conjunctionwith chisels like spy_user.
proc.duration number of nanoseconds since the process started.
proc.fdopencount number of open FDs for the process
proc.fdlimit maximum number of FDs the process can open.
proc.fdusage the ratio between open FDs and maximum available FDs for the process.
proc.vmsize total virtual memory for the process (as kb).
proc.vmrss resident non-swapped memory for the process (as kb).
proc.vmswap swapped memory for the process (as kb).
thread.pfmajor number of major page faults since thread start.
thread.pfminor number of minor page faults since thread start.
thread.tid the id of the thread generating the event.
thread.ismain 'true' if the thread generating the event is the main one in the process.
thread.exectime CPU time spent by the last scheduled thread, in anoseconds. Exported by switch events only.
thread.totexectime Total CPU time, in nanoseconds since the beginning of the capture, for the current thread. Exported by switch events only.----------------------
Field Class: evtevt.num event number.
evt.time event timestamp as a time string that includes the nanoseco
nd part.
evt.time.s event timestamp as a time string with no nanoseconds.
evt.datetime event timestamp as a time string that includes the date.
evt.rawtime absolute event timestamp, i.e. nanoseconds from epoch.
evt.rawtime.s integer part of the event timestamp (e.g. seconds since po
ch).
evt.rawtime.ns fractional part of the absolute event timestamp.
evt.reltime number of nanoseconds from the beginning of the capture.
evt.reltime.s number of seconds from the beginning of the capture.
evt.reltime.ns fractional part (in ns) of the time from the beginning of the capture.
evt.latency delta between an exit event and the correspondent enter event.
evt.latency.s integer part of the event latency delta.
evt.latency.ns fractional part of the event latency delta.
evt.dir event direction can be either '>' for enter events or '<' for exit events.
evt.type For system call events, this is the name of the system call(e.g. 'open').
evt.cpu number of the CPU where this event happened.
evt.args all the event arguments, aggregated into a single string.
evt.arg (FILTER ONLY) one of the event arguments specified by name or by number. Some events (e.g. return codes or FDs) will be converted into a text representation when possible. E.g.'resarg.fd' or 'resarg[0]'.
evt.rawarg (FILTER ONLY) one of the event arguments specified by name.E.g. 'arg.fd'.
evt.info for most events, this field returns the same value as evt.args. However, for some events (like writes to /dev/log) it provides higher level information coming from decoding the arguments.
evt.buffer the binary data buffer for events that have one, like read(), recvfrom(), etc. Use this field in filters with 'contains' to search into I/O data buffers.
evt.res event return value, as an error code string (e.g. 'ENOENT').
evt.rawres event return value, as a number (e.g. -2). Useful for range comparisons.
evt.failed 'true' for events that returned an error status.
evt.is_io 'true' for events that read or write to FDs, like read(), send, recvfrom(), etc.
evt.is_io_read 'true' for events that read from FDs, like read(), recv(),
recvfrom(), etc.
evt.is_io_write 'true' for events that write to FDs, like write(), send(), etc.
evt.io_dir 'r' for events that read from FDs, like read(); 'w' for events that write to FDs, like write().
evt.is_wait 'true' for events that make the thread wait, e.g. sleep(), select(), poll().
evt.is_syslog 'true' for events that are writes to /dev/log.
evt.count This filter field always returns 1 and can be used to count events from inside chisels.
evt.around (FILTER ONLY) Accepts the event if it's around the specified time interval. The syntax is evt.around[T]=D, where T is the value returned by %evt.rawtime for the event and D is a delta in milliseconds. For example, evt.around[1404996934793590564]=1000 will return the events with timestamp with one second before the timestamp and one second after it, for a total of two seconds of capture.----------------------
Field Class: useruser.uid user ID.
user.name user name.
user.homedir home directory of the user.
user.shell user's shell.----------------------
Field Class: groupgroup.gid group ID.
group.name group name.----------------------
Field Class: syslogsyslog.facility.str facility as a string.
syslog.facility facility as a number (0-23).
syslog.severity.str severity as a string. Can have one of these values: merg, alert, crit, err, warn, notice, info, debug
syslog.severity severity as a number (0-7).
syslog.message message sent to syslog.
フィルタ機能のシンプルな使い方を次に示します。
cat 、または vi コマンドが実行されたときに発生したイベントの trace を表示します。
sysdig proc.name=cat or proc.name=vi
cat が実行されたときに発生した open イベントの trace を表示します。
sysdig proc.name=cat and evt.type=open
Docker Support
sysdig は Docker をサポートしており、コンテナ単位でリソース使用率などを確認することができます。(一応、Rocket などにも対応してた気がします。)
コンテナ一覧を表示します。
sysdig -c lscontainers
各コンテナのCPU使用率を表示します。
sysdig -c topcontainers_cpu
client というコンテナ名を持つコンテナのCPU使用率を表示します。
sysdig -pc -c topprocs_cpu container.name=client
各コンテナの帯域使用量を表示します。
sysdig -pc -c topcontainers_net
mysql というコンテナ名を持つコンテナの ネットワークコネクションを表示します。
sysdig -pc -c topconns container.name=mysql
wordpress というコンテナ名を持つコンテナの 80 番ポートで通信転送されている内容を表示します。
sysdig -A -c echo_fds container.name=wordpress and fd.port=80
各コンテナのディスク I/O を上位から表示します。
sysdig -c topcontainers_file
mysql というコンテナ名を持つコンテナのユーザーの実行コマンドを表示します。
sysdig -pc -c spy_users container.name=mysql
出力フォーマット
-p オプションで出力フォーマットを指定することができます。
sysdig -p"%evt.type %evt.dir %evt.arg.name" evt.type=open
他にも色々と機能が実行されているのではあるのですが、時間の都合により 記載しきれないほど sysdig は多機能です。
ちなみに、dragos.inc 社は sysdig Cloud という多機能な監視系サービスのプロダクトも展開されています。ご興味のある方は参考程度に見てみると良いネタになるかもしれません。
最近は Docker コンテナ向けのモニタリング&セキュリティ系のツールの需要が高まりつつあるのかなと思いますが、sysdig は今のところはおそらく唯一と言っていい(?)コンテナ対応している多機能なトラブルシューティング向けツールなので、今後は少しずつ利用機会が増えていくかもしれません。