🐧 Linux 総合学習プラットフォーム
プロセス監視/障害対応 ・ 中級

開いているファイル・ポートの確認

Linuxではファイルもソケットも「ファイルディスクリプタ」として扱われ、lsof で誰が何を開いているかを一覧できます。lsof -i で開いているネットワーク接続、lsof でディレクトリ配下のファイルを掴んでいるプロセス、を調べられます。プロセスが開けるファイル数には上限があり、上限に達すると「Too many open files」エラーが出ます。ss はソケット専用の高速ツールで、待ち受けポートや確立中の接続をすばやく確認できます。

Linuxには「すべてはファイルである」という設計思想がある。これが何を意味するか、最初はピンと来ないかもしれない。

普通のテキストファイルや画像はもちろん、ハードウェアへの入り口や、プロセス間の通信路、そしてネットワーク接続までもが、ファイルと同じ仕組みで扱われるのだ。

💡
ポイント「すべてはファイル」だから、ファイルもソケットも同じ道具で調べられる。lsof と ss を使い分けると障害調査の幅が大きく広がる。

プロセスがこうした対象を開くと、それぞれに「ファイルディスクリプタ」という管理番号が割り当てられる。ファイルディスクリプタとは、プロセスが今どのファイルやソケット(通信の出入り口)を開いているかを管理する整理番号のことだ。

この考え方を押さえると、ファイルとネットワークを同じ道具で調べられるようになり、障害調査の幅が大きく広がる。ここでは、開いているものを一覧する lsof と、ソケット専用の高速ツール ss を扱う。

プロセスFD で管理通常ファイル / ログデバイス / ディレクトリソケット(ネットワーク接続)どれも「開いているファイル」として lsof で見える

🔍 誰が何を開いているか、lsof で見る

lsof は list open files の略で、その名のとおり、システム上で開かれているファイルを一覧するコマンドだ。

「すべてはファイル」なので、lsof で見えるのは通常ファイルだけでなく、ディレクトリ、ライブラリ、デバイス、ソケットなど多岐にわたる。

引数なしの lsof は開いているものすべてを出力して膨大になるため、実務では必ず目的を絞って使う。

出力には、COMMAND(プロセス名)、PID(プロセス番号)、USER(所有者)、FD(ファイルディスクリプタ番号と種別)、TYPE(種類)、NAME(対象のパスや接続先)などが並び、「どのプロセスが、何を、どんな形で開いているか」が読み取れる。

よく使う絞り込みを覚えておくと実用的だ。

lsof /var/log/messages ……そのファイルを開いているプロセスが分かる。「削除したのに容量が戻らない」犯人探しに役立つ。

lsof /var/log/messages のようにファイルを指定すると、そのファイルを開いているプロセスが分かる。これは前述のディスク調査で「削除したのに容量が戻らない」ときに、ファイルを掴んでいる犯人を探すのに役立つ。

lsof -u user01 とすればそのユーザが開いているものすべて、lsof -p 1234 とすれば特定のPIDが開いているものすべてを一覧できる。

あるディレクトリ配下のファイルが「使用中で削除・アンマウントできない」ときは、lsof +D /mnt/data のようにすると、その配下を掴んでいるプロセスを突き止められる。

🌐 ネットワーク接続まで lsof で覗ける

ソケットもファイルとして扱われるので、ネットワーク接続も lsof で調べられる。

lsof -i とすると、開いているすべてのネットワーク接続(待ち受け中・通信中の両方)が一覧でき、どのプロセスがどのポートを使っているかが分かる。

lsof -i :8080 ……「ポートが既に使われています(Address already in use)」のとき、そのポートを先に掴むプロセスを特定。

lsof -i :80 のようにポート番号を指定すれば、80番ポートを使っているプロセスだけに絞れる。

「このポートを使っているのは誰だ」を調べるのに直感的で、たとえば新しいサービスを起動しようとして『ポートが既に使われています(Address already in use)』と言われたとき、lsof -i :8080 でそのポートを先に掴んでいるプロセスを特定できる。

🚧 Too many open files、上限を超えると起きること

ファイルディスクリプタにまつわる、実務で頻出のトラブルがある。

Linuxでは、1つのプロセスが同時に開けるファイル(=ファイルディスクリプタ)の数に上限が設けられている。これは暴走したプログラムが資源を無限に食い潰すのを防ぐための安全装置だ。

だが、多数の接続を捌くWebサーバやデータベースでは、この上限に達してしまうことがある。

つまずきアクセスが増えた途端にサーバがエラーを返し始めたら、Too many open files(FD上限到達)を疑う。安全装置に引っかかっている。

上限を超えてさらに開こうとすると、「Too many open files(開きすぎです)」というエラーが出て、新しい接続やファイルアクセスが失敗する。アクセスが増えた途端にサーバがエラーを返し始めたら、この上限到達を疑う。

ulimit -n と lsof -p PID | wc -l ……上限(ソフトリミット)と、実際に開いている数を突き合わせ、上限に近づいていないか見る。

調査では、まず ulimit -n で現在のプロセスが開けるファイル数の上限(ソフトリミット)を確認する。そのうえで、問題のプロセスが実際にいくつ開いているかを lsof -p PID | wc -l で数え、上限に近づいていないかを見る。

上限に達しているなら、対処は2方向だ。

1つは、本当にそれだけの接続が必要なら上限を引き上げること。これはサービスごとの設定(systemd の LimitNOFILE など)や、システム全体の設定で行う。

もう1つは、そもそも開いたファイルや接続をきちんと閉じていないプログラム側のバグ(ファイルディスクリプタの「リーク」)を疑い、コードを修正することだ。エラーが時間とともにじわじわ増えていく場合は、後者のリークの可能性が高くなる。

コツエラーが時間とともにじわじわ増えるなら、FDの「リーク」(閉じ忘れ)を疑う。上限引き上げではなくコード修正が本筋になる。

⚡ ソケットだけを手早く見るなら ss

lsof は何でも調べられる万能選手だが、ネットワークのソケットだけを手早く確認したいなら、専用ツールの ss のほうが高速で軽快だ。

ss は socket statistics の略で、待ち受けポートや確立中の接続を瞬時に一覧する。

前のトピックでも触れたとおり、ss -tlnp(TCPの待ち受けポートをプロセス付きで表示)が代表的な使い方だ。

ss -tanp ……-a で待ち受けと確立の両方を表示。ss -t state established なら確立中のTCP接続だけに絞れる。

これに加えて、確立済みの接続まで含めて全体を見たいときは ss -tanp のように -a(待ち受けと確立の両方)を使う。

ss は出力をオプションで細かく絞れるのも利点だ。たとえば ss -t state established で確立中のTCP接続だけを抜き出す、といった調査もできる。

大量の接続があるサーバでは、lsof より ss のほうが結果がすぐ返るため、ネットワークまわりの第一手として重宝する。

⚖ lsof と ss、どちらをいつ手に取るか

使い分けの目安はこうだ。ネットワークのソケットだけを素早く見たいなら ss、ファイル・ソケットを横断して「誰が何を開いているか」を幅広く調べたいなら lsof、だ。

コツソケットだけ素早くなら ss、ファイルもソケットも横断して幅広く見たいなら lsof。第一手は ss、深掘りは lsof と覚えておく。

具体的には、待ち受けポートの確認は ss -tlnp、ポートを掴んでいるプロセスの特定は lsof -i :ポート、削除済みファイルや使用中ディレクトリの調査は lsof、「Too many open files」エラーの調査は ulimit -n と lsof -p PID | wc -l の組み合わせ、というように引き出しを持っておくと、ファイルディスクリプタ起因の障害に素早く対応できる。

「すべてはファイル」という発想を軸に、lsof と ss を使い分けられるようになると、一見ばらばらに見えるファイル・プロセス・ネットワークの問題を、ひとつながりの視点で調べられるようになる。

この項目に出てくる用語

ファイルディスクリプタふぁいるでぃすくりぷた
プロセスが開いているファイルやソケットを指す番号。上限がある。
ポートぽーと
通信の宛先を区別する番号。サービスは特定ポートで待ち受ける。

関連コマンド

lsofss

▶ 学習アプリでこの続きを学ぶ・演習する