こんにちは。斎藤です。
ITインフラの障害は、多くの場合「予期せぬ」タイミングで発生します。特に、CPUリソースを多量に消費したり、Disk I/Oが輻輳している場合、その切り分けは困難な状況に陥りやすいものです。
そこで、本日はITインフラ、特にOS・ミドルウェアを支えるにあたって、問題解決を助けてくれるであろう12個のコマンドを取り上げてみます。「必ず押さえておきたい」5つのものと「更に覚えると便利なコマンド」7つの2節に分けてお話しします。
※CentOS 6.4 (64bit)を前提に取り上げます
必ず押さえておきたいコマンド
もしITインフラ管理者になりたてな方はぜひ
サーバサイドのプログラマをやっていたのだけれど、ある日突然「君、サーバ管理担当ね!」と、バトンを渡される方っていらっしゃると思います。私も以前はそのクチでした...。そうなってしまったとき、まずは覚えておきたい5つのコマンドです。
w
(笑) ではありません!
現在のサーバの状態(uptime, Load Average, ログインユーザ)を簡易的に出力します。
$ w
16:40:10 up 1:26, 1 user, load average: 0.00, 0.01, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
vagrant pts/0 10.0.2.2 15:28 0.00s 0.17s 0.00s w
ここからわかる事は、例えば次の事です。
- 再起動: uptimeが短かすぎる場合
- プロセスの暴走の可能性: Load Average(※1)が論理コア数に比べてあまりに多い
- 不正アクセスの可能性: ログインユーザがやたらと多い
私は、開発に利用するインスタンスに入ると、必ずこのコマンドを実行して異常なCPUリソース消費等が無いかを調べるようにしています。
ps
プロセス一覧を表示します。ご存知の方も多いかと思います。
$ ps auxwwf
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 2 0.0 0.0 0 0 ? S 15:13 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 15:13 0:00 \_ [migration/0]
(※中略)
root 1165 0.0 0.1 64116 1188 ? Ss 15:13 0:00 /usr/sbin/sshd
root 4001 0.0 0.3 97860 3804 ? Ss 15:28 0:00 \_ sshd: vagrant [priv]
vagrant 4003 0.0 0.1 97860 1728 ? S 15:28 0:00 \_ sshd: vagrant@pts/0
vagrant 4004 0.0 0.2 109376 2980 pts/0 Ss 15:28 0:00 \_ -bash
vagrant 15416 0.0 0.1 110348 1104 pts/0 R+ 16:47 0:00 \_ ps auxwwf
オプションに"u"(フォーマット変更), "x"(端末を持たないプロセス), "ww"(出力幅制限無し...プロセス名が全部見える), "f"(プロセスツリーを表示) を付与しています。ここからわかるのは、主に次の事柄です。
- 実行中プロセス(COMMAND)とツリー: 起動しているべきプロセスが動いているか・不正なプロセスが動いていないか
- プロセスの起動時刻・月日(TIME): デーモンの場合は意図しない再起動等が行われていないか
- CPU使用率(%CPU): CPU使用率の把握
- RAM使用率(%RAM): 物理メモリ使用率の把握
- プロセスの状態(STAT): 特にZombie(Z)になっているものは無いか
"f"をつけるとプロセスのツリーまで見えます。もし、子プロセスが暴走していても、親プロセスが子プロセスを監視していると、子プロセスをkillしただけでは問題が解決しない場合があります。そこで、親プロセスが何かを把握しやすいようにしておくと良いでしょう。
暴走中のプロセスを確認する場合は、後述するtopのほうがわかりやすいかと思いますので、あわせて調べます。
なお、暴走しているプロセスをkillする場合は、プロセス番号(PID)をコピペすると、入力の誤りが減らせてよいかと思います。
top
topは、実行中のプロセスを随時更新しながら確認する事ができるコマンドです。
top - 17:09:41 up 28 days, 22 min, 1 user, load average: 0.19, 0.24, 0.24
Tasks: 129 total, 1 running, 128 sleeping, 0 stopped, 0 zombie
Cpu0 : 0.7%us, 0.7%sy, 0.0%ni, 98.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu1 : 0.0%us, 0.7%sy, 0.0%ni, 99.3%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1922564k total, 1788808k used, 133756k free, 163408k buffers
Swap: 4726776k total, 59188k used, 4667588k free, 1221552k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2186 mongod 20 0 1555m 52m 17m S 1.3 2.8 351:58.05 mongod
2054 mysql 20 0 1248m 91m 4348 S 0.7 4.8 351:00.67 mysqld
17402 saito 20 0 67860 43m 772 S 0.7 2.3 7:37.43 tmux
(※以下省略)
psと近いのですが、psと比較して次の点を確認しやすい事が特徴です。
- CPUリソースを消費している順に並ぶ (デフォルトの設定の場合)
- 消費されているCPUコアに偏りがあるかどうかがわかる ("1"キーを押すとCore別の使用率がわかります)
- 使用しているCPUコア番号がわかる (フィールドに"Last used cpu"を追加するとわかります)
なお、メモリの空き容量の確認は、後述するfreeを実行します。
free
メモリの使用・空き容量を調べます。
$ free -m
total used free shared buffers cached
Mem: 1877 1747 130 0 159 1193
-/+ buffers/cache: 394 1482
Swap: 4615 57 4558
オプション"m"はMiB単位表示、という意味です。
物理メモリの空き容量を調べる際に気をつけたいのは、"Mem"の行のFreeではなく、"-/+ buffers/cache"のFreeを見た方が良い、という事です。1行目のfreeだけを見てしまうと、物理メモリ容量不足と誤って判断してしまいかねません。
例えば、ファイルキャッシュを有効に効かせたい場合は余裕を持った方がいいでしょうし、MySQLが動いているサーバで innodb_buffer_pool_size を引き上げる時にはFreeがより小さくなるよう大きく割り当てた方が良いかと思います。
netstat
通信中のセッションを表示します。
$ sudo netstat -natup
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1165/sshd
tcp 0 0 10.0.2.15:22 10.0.2.2:62186 ESTABLISHED 4001/sshd
tcp 0 0 :::22 :::* LISTEN 1165/sshd
udp 0 0 10.0.2.15:123 0.0.0.0:* 3844/ntpd
(※一部省略)
オプションとして"n"(名前を引かない), "a"(全て), "t"(TCPのみ), "u"(UDPのみ), "p"(紐づいているプロセスを出す:root権限が必要)を入れています。ここから、主に次の点が見えてきます。
- どのプロセスが通信しているか: 意図しないプロセスが通信していないかを確認できます
- どこと通信しているか: 意図しない特定のForeign Addressが多い場合は攻撃かもしれません
- 待ち受けているポートは何か: 必要なポートが待ち受け状態になっているかを確認できます
- TCPステータス(State): 待ち行列が増えているか
4つ目のTCPステータスですが、特に高い負荷のサーバでは気をつけてみておきたいポイントです。例えば、SYN_RECEIVEDが多量にある場合、デーモンがリクエストを処理できず待ち行列が発生していることもあれば、DoS(SYN flood攻撃)を受けている可能性もあります。
更に覚えると便利なコマンド
一歩踏み込んだ分析を行う際に
先のコマンドより、さらに分析を進めるために使えるのが、これから紹介するコマンドです。
なお、これから紹介するコマンドはデフォルトでインストールされていない環境があります。その場合は、yumを通じてインストールしてください。
lsof
どのプロセスがファイルを開いているかを調べます。
$ lsof | head
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
(※中略)
mysqld 2054 mysql 9uW REG 253,0 268435456 1445566 /var/lib/mysql/ib_logfile0
mysqld 2054 mysql 10uW REG 253,0 268435456 1445567 /var/lib/mysql/ib_logfile1
mysqld 2054 mysql 11uW REG 253,0 98304 1444494 /var/lib/mysql/cacti/poller_output.ibd
(※以下省略)
上記では、MySQLがデータファイルを開いている状況が確認できます。
例えば、ファイルを削除する際に「ファイルが消えない」「ハードリンクは無くなっているのにディスク容量が解放されない」場合に確認すると、良いかと思います。
vmstat
各種リソースの使用状況を、最短1秒単位で表示します。
$ vmstat 1 3
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 59188 140888 162272 1216520 3 3 6 88 6 7 2 1 94 3 0
0 0 59188 140880 162272 1216548 0 0 0 0 186 366 1 0 99 0 0
0 0 59188 140880 162272 1216548 0 0 0 0 168 362 1 1 99 0 0
例えば、CPUリソースの使われ方を確認する場合に利用すると便利です。特に、定期的にwa(iowait)が上がるのであれば、ディスクのフラッシュ待ちの可能性がある、という事が見えてきます。
注意点として、1行目はマシンが起動してからの統計情報が掲載されている事です。コマンド実行時の1秒あたりのデータではありませんので注意してください。
これに近いコマンドとして"dstat"があります。カラフルでびっくりするかもしれません。
iostat
どのストレージデバイスにどの程度の読み書きが行われているかを、最短1秒単位で表示します。vmstatのディスク版と考えてもいいかと思います。
$ iostat -xmd 1
Linux 2.6.32-358.6.1.el6.x86_64 (saito-hb-vm101) 2013年10月01日 _x86_64_ (2 CPU)
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
scd0 0.00 0.00 0.00 0.00 0.00 0.00 8.00 0.00 1.07 1.07 0.00
vda 1.28 29.76 0.70 17.16 0.01 0.17 21.15 0.12 6.73 3.93 7.01
dm-0 0.00 0.00 0.40 42.84 0.01 0.17 8.18 0.37 8.48 1.62 7.01
dm-1 0.00 0.00 1.58 1.41 0.01 0.01 8.00 0.28 92.68 0.06 0.02
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
vda 0.00 79.00 6.00 158.00 0.04 0.79 10.24 0.92 5.55 5.57 91.40
dm-0 0.00 0.00 6.00 200.00 0.04 0.78 8.12 0.94 4.51 4.44 91.40
dm-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
(以下省略)
"m"(MiB単位), "x"(拡張情報)オプションをつけた方が、読み取りやすくなるかと思います。1つ目のデータは、vmstat同様これまでの統計情報ですので気をつけて読んでください。
上記の例ですが、ディスク"vda"の%util(使用率)が91%となっており、性能限界近くまでioが行われている事がわかります。これ以上のパフォーマンスを求めるなら、よりIOPS(tps)の高いストレージに変えた方が良さそうです。
他にも、ベンチマーク時のスループット・IOPSの確認に利用する事ができます。
iotop
最短1秒間隔で、ディスクを読み書きするプロセスとその内容をモニタリングします。topのDisk I/O版ともいえます。どのプロセスが大きなDisk I/Oを行っているか、簡単に確認する事ができます。
Total DISK READ: 171.89 K/s | Total DISK WRITE: 992.29 K/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
432 be/3 root 0.00 B/s 3.91 K/s 0.00 % 93.09 % [jbd2/dm-0-8]
20068 be/4 apache 156.27 K/s 523.49 K/s 0.00 % 16.06 % rrdtool -
20060 be/4 mysql 7.81 K/s 62.51 K/s 0.00 % 1.53 % mysqld --basedir=/usr --~ql/mysql.sock --port=3306
20063 be/4 mysql 3.91 K/s 66.41 K/s 0.00 % 0.72 % mysqld --basedir=/usr --~ql/mysql.sock --port=3306
22027 be/4 saito 0.00 B/s 0.00 B/s 0.00 % 0.00 % python ./manage.py runserver 0.0.0.0:8888
1 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % init
2 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [kthreadd]
(※以下省略)
なお、実行にはroot権限が必要です。
strace
プログラムのトレースツールの一種です。主に次の事が可能です。
- 参照しているsoオブジェクトをリストアップ
- 指定したプロセスが呼び出したシステムコールの回数・時間を計測
実行方法は大きく2つあります。実行するコマンドに対して計測する方法と、現在実行しているプロセスに対して計測する方法です。多くのトレースツールではトレースのために別途プログラム実行をしなければなりませんが、straceは一部の機能について実行中のプロセスに対してもトレース可能な点が特徴かと思います。
まずは、呼び出しているsoオブジェクトをトレースします。"Hello, world."と表示するだけのC言語で書かれたプログラムをトレースします。
$ strace -e open ./hoge
open("/etc/ld.so.cache", O_RDONLY) = 3
open("/lib64/libc.so.6", O_RDONLY) = 3
hello, world.
利用するシーンとして、複数バージョンのライブラリが入っている場合、どのライブラリをリンクしているかの問題追跡に便利です。また、"-f"オプションを付与すると、fork()先のプロセスもトレースします。
次に、指定したプロセスが呼び出しているシステムコールの回数・時間を計測します。今回はtopを実行しているプロセスに対して実行します。
$ strace -c -p 10878
Process 10878 attached - interrupt to quit
^C
Process 10878 detached
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
40.37 0.000130 0 262 close
33.23 0.000107 0 276 2 read
26.40 0.000085 1 131 stat
0.00 0.000000 0 2 write
0.00 0.000000 0 262 open
0.00 0.000000 0 5 lseek
0.00 0.000000 0 20 rt_sigaction
0.00 0.000000 0 2 ioctl
0.00 0.000000 0 1 1 access
0.00 0.000000 0 1 select
0.00 0.000000 0 30 alarm
0.00 0.000000 0 25 fcntl
0.00 0.000000 0 2 getdents
0.00 0.000000 0 2 gettimeofday
------ ----------- ----------- --------- --------- ----------------
100.00 0.000322 1021 3 total
straceは、プログラムの動作が「遅い」と思ったときや、リンクしているライブラリに問題がある場合等、何が原因かを大まかに把握する際に便利です。さらに詳しい使い方もありますが、ここでは割愛します。
mpstat
CPU使用率をより詳細に最短1秒間隔でモニタリングします。vmstatに近いように見えますが、CPUコア毎に情報を出力できる点が特徴です。例えば、CPUコアを固定して稼働しているプロセスのCPU使用率を計測したり、コア毎の偏りの有無を確認する際に便利です。
$ mpstat -P ALL 1
Linux 2.6.32-358.6.1.el6.x86_64 (saito-hb-vm101) 2013年10月01日 _x86_64_ (2 CPU)
14時54分50秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
14時54分51秒 all 0.50 0.00 0.00 0.00 0.00 0.00 0.00 0.00 99.50
14時54分51秒 0 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 99.00
14時54分51秒 1 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 99.00
14時54分51秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
14時54分52秒 all 57.29 0.00 6.03 9.55 0.00 0.00 0.00 0.00 27.14
14時54分52秒 0 93.00 0.00 7.00 0.00 0.00 0.00 0.00 0.00 0.00
14時54分52秒 1 20.00 0.00 5.00 20.00 0.00 0.00 0.00 0.00 55.00
"-P ALL"で、コア毎のCPU使用率を表示できます。"-P 0"とすれば、0番目のCPUに絞って表示する事が可能です。
sar
各種システムのリソース消費量を、通常10分間隔(※2)、最短1分間隔で表示できます。mpstatとともにsysstatパッケージに同梱されています。取得できるデータはCPU使用率ばかりでなく、NIC, Disk, NFS等様々なデータを取得できます。
以下に、CPU使用率を表示するコマンドを示します。
$ sar -P ALL
Linux 2.6.32-358.6.1.el6.x86_64 (saito-hb-vm101) 2013年10月01日 _x86_64_ (2 CPU)
00時00分01秒 CPU %user %nice %system %iowait %steal %idle
00時10分01秒 all 3.42 0.00 1.16 2.83 0.09 92.50
00時10分01秒 0 3.47 0.00 1.06 0.94 0.07 94.47
00時10分01秒 1 3.38 0.00 1.27 4.72 0.11 90.53
00時20分01秒 all 2.35 0.00 1.10 2.79 0.08 93.67
00時20分01秒 0 2.34 0.00 1.01 1.21 0.06 95.38
00時20分01秒 1 2.36 0.00 1.19 4.38 0.11 91.96
(※以下省略)
なお、昨日以前のデータは、CentOS 6.4では /var/log/sar[日付] というテキストファイルに保存されています。ただ、数百KBあり参照が大変です。その際は kSar を利用するとチャートとして確認できるため便利です。
おわりに
いかがでしたでしょうか。ここまで、「必ず押さえておきたいコマンド」と「更に覚えると便利なコマンド」の2つに分けてお話ししました。
ITインフラの運用、特に障害対応はプログラム開発と違い、当社のようなMSPでも無い限り数多く対応している状況には無いかと思います。そこで、とっさのときに、いわば「懐刀」として知っておくと便利なコマンドの一部をご紹介しました。
プログラム開発の傍ら、ITインフラを支えている方々への参考になりましたら幸いです。
それでは皆様、ごきげんよう。
参考文献
[1] Linux Kernel Updates Vol.2012.12 [Kindle版]
[2] 各コマンドのmanページ
※1: Load Average はCPUの負荷を示す値では必ずしもありません[1]が、ヤマを張るための一つの指標として見るのはいいかと思います。
※2: CentOS 6.4のデフォルトは10分間隔となっています。
追伸
ハートビーツでは、新卒・中途社員を募集しております。ご興味がありましたら、「 採用情報 」のページからご応募ください。