ITインフラで起きる「もしも」のための12個のコマンド

こんにちは。斎藤です。

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分間隔となっています。

追伸

ハートビーツでは、新卒・中途社員を募集しております。ご興味がありましたら、「 採用情報 」のページからご応募ください。

株式会社ハートビーツのインフラエンジニアから、ちょっとした情報をお届けします。