VSCodeで一度つないだだけのサーバーが、3週間後にディスク満杯で落ちた話

目次

状況

前のブログ(WordPress)を動かしていたEC2が、ある日から応答しなくなりました。

  • ブラウザで開けない
  • SSHはつながるけど、ログインまでやたら待たされる(20秒くらい)
  • CPU使用率はずっと平常
  • 受信量が1日0.9GBくらいある(何の通信か分からない)

原因の分からない受信があったので、最初は不正アクセスを疑いました。
ただ、AWS側のログイン履歴もAPIの操作履歴もきれいで、SSHのログインも自宅からだけ。
Webの公開ディレクトリに怪しいファイルが置かれた形跡もなかったので、侵入されたわけではなさそうだなと。

原因はディスク満杯

いろいろ調べたあと、df(ディスクの使用状況を見るコマンド)を見たら原因が分かりました。

text
/dev/nvme0n1p1  8.0G  8.0G   20K  100% /

ディスクの残り20KB……。
内訳を調べると、犯人はログではありませんでした。

場所容量
~/.vscode-server4.5GB
/usr(OS本体)2.2GB
/var(ログ・WordPressなど)927MB

8GBのディスクの半分以上をVSCode Serverが使っていました。
~/.vscode-server/cli/servers/の下に、サーバー一式が8世代(1世代200〜700MB)たまっていました。

止まった瞬間もログから分かりました。
VSCodeの新しい版をディスクに展開している途中で空きを使い切って、その巻き添えでApache(httpd)が落ちていました。
php-fpm(PHPを実行するプロセス)とsshdは生き残ったので、「SSHだけはつながる」という状態になっていました。

一度しかつないでいないのに増えていた

Remote-SSHでつなぐとサーバー側にVSCode Serverが置かれる、というのは知っていました。
なので、新しい版が入るのは手元のVSCodeでつないだとき(手元の版が上がったとき)だけだと思っていました。

ところが、たまっていた8世代のうち6世代は、VSCodeでつないでから3週間あまりでできていました。
つないだのはその1回だけです。毎週つないだ覚えはないのに。

調べると、code … agent hostというプロセスがずっと動いていました。
このプロセスは、次のような動きをします。

  • Remote-SSHで接続したときにサーバー側で起動する常駐プロセス
  • 接続を切っても残り続ける
  • 6時間ごとに自分で更新を確認して、新しい版をダウンロードする

つまり、私が何もしなくてもサーバー内で勝手にアップデートを受信し続けていたということです。
知らなかったのはここでした。

(VSCodeのissue microsoft/vscode #338114 にこの挙動が書かれています)

実際、世代が増えた時刻はどれも同じ時・分で、プロセスの起動時刻からきっちり6時間刻みになっていました。
古い世代を消す仕組みもあるはずなのですが、このケースではうまく働かずにたまる一方だったようです。

ディスクが埋まったあとも、このプロセスは1日4回、約220MBをダウンロードしては展開に失敗するのを繰り返していました。
最初に気になっていた1日0.9GBの受信は、この4回分でした。
外から攻撃されていたわけではなく、このプロセスが同じファイルを落とし続けていただけです。

直し方

bash
# 居残っている常駐プロセスを止める(-fを付けてコマンドライン全体から"agent host"を含むプロセスを指定して止める)
pkill -f "agent host"

# VSCode Serverを丸ごと消す(-rfを付けてフォルダの中身ごと確認なしで消す。次につなげば入れ直されるので問題なし)
rm -rf ~/.vscode-server

これでディスク使用率は100%から41%まで下がって、Apacheも起動できました。

ついでに、journald(システムのログ)に上限がなくて地味に大きくなっていたので、上限を付けています。

bash
# SystemMaxUse の行を書き換えて、ログの上限を200MBにする
# 行が無い環境では [Journal] の下に SystemMaxUse=200M を書き足す
sudo sed -i 's/^#\?SystemMaxUse=.*/SystemMaxUse=200M/' /etc/systemd/journald.conf

# 設定を反映する
sudo systemctl restart systemd-journald

再発させないために

  • 使い終わったらVSCode Serverごと消す。 コマンドパレットのRemote-SSH: Uninstall VS Code Server from Host...を使えば、プロセスの停止とディレクトリの削除をまとめてやってくれます。ウィンドウを閉じるだけだと常駐プロセスは残ります。ただ、毎回やるのは面倒なので、私はやらないと思いますが
  • 再起動すればプロセスは消える。 次につなぐまでは増えなくなります。ただ、たまった分は消えないので根本的な解決にはなりませんし、VSCodeのウィンドウを開いたままだとすぐつなぎ直されて復活します
  • ルート8GBのサーバーでVSCode Remoteを使うのは厳しい。 開発でつなぐサーバーなら20〜30GBは欲しいかなと。そもそも、ケチって8GBにしていた私が悪いのですが
  • ディスク使用率を監視しておく。 CPUのアラームは設定していたのですが、ディスクは見ていなかったので気づけませんでした

とりあえず私は、このサーバーにはもうVSCodeで接続しないことにしました。
結局このサーバー自体も廃止して、ブログは静的サイトに移しています。それはまた別の話。

← 前の記事
オープンソースのデータ復元プログラム「testdisk」を使った件
次の記事 →
(最新の記事です)