@uzyexe のノート

ITインフラ運用系のネタを主に書く、つもり・・・

明日から使えるかもしれない sysdig

 sysdig は多機能なトラブルシューティング向けツールです。 主に Dragos.inc 社が中心となって開発されているオープンソースです。

ざっくり sysdig の多機能っぷりを説明すると、 strace + tcpdump + lsof + htop + iftop + Lua = sysdig って感じです。docker などのコンテナにも対応しており、curses によるグラフィカルなUI出力なども可能です。

github.com 

sysdig のインストール

 Linux では RHEL/CentOS or Debian/Ubuntu 系でも下記コマンドでインストールできます。

curl -s https://s3.amazonaws.com/download.draios.com/stable/install-sysdig | sudo bash

OSX では homebrew でインストールできます。

brew update
brew install sysdig

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 activity

lists 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: process

proc.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: evt

evt.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: user

user.uid     user ID.
user.name     user name.
user.homedir     home directory of the user.
user.shell     user's shell.

----------------------
Field Class: group

group.gid     group ID.
group.name     group name.

----------------------
Field Class: syslog

syslog.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 という多機能な監視系サービスのプロダクトも展開されています。ご興味のある方は参考程度に見てみると良いネタになるかもしれません。

sysdig.com

 最近は Docker コンテナ向けのモニタリング&セキュリティ系のツールの需要が高まりつつあるのかなと思いますが、sysdig は今のところはおそらく唯一と言っていい(?)コンテナ対応している多機能なトラブルシューティング向けツールなので、今後は少しずつ利用機会が増えていくかもしれません。