Dockerならではの問題に対処したのでメモを残します。
背景と課題
RHEL / Rocky Linux 9 環境のGPUサーバーにおいて、Dockerビルド(大規模LLMモデルの生成など)を実行した際、ルートパーティション(/)の使用率が100%に達する事象が発生しました。
- 原因: Dockerはデフォルトで
/var/lib/docker(ルート配下)にイメージやビルドキャッシュを保存します。 - 環境: ルート領域は70GB程度ですが、
/home領域には数TBの空きがります。 - 対策: パーティションリサイズ(LVM操作)はリスクが高いため、Dockerのデータ保存先(data-root)を
/home配下へ物理的に移行して解決します。
さっくりとした手順
- 現状を確認し、サービスを停止します。
- Dockerの移行ディレクトリを作成します。
- rsyncを用いて安全にデータを移行します。
- Dockerの設定ファイルを変更します。
- Dockerサービスの再起動を行います。
- 設定変更を確認します。
現状の確認とサービスの停止
まず、現在のDocker設定とディスク使用量を確認し、Dockerサービスを停止します。
- Dockerの保存先確認
docker info | grep "Docker Root Dir"
→ (デフォルトは /var/lib/docker)
- Dockerサービスを停止します。
sudo systemctl stop docker docker.socket
- Dockerサービスの停止を確認します。
systemctl status docker
inactive(dead)を確認します。
移行先ディレクトリを作成します。
大容量領域(今回は /home 配下)に新しい保存用ディレクトリを作成します。
- ディレクトリ作成
sudo mkdir -p /home/docker/data
データの移行(最重要)
既存のイメージやコンテナデータを保持するため、rsync を用いてデータを同期します。
※ cp コマンドよりも、権限やタイムスタンプを正確に保持できる rsync を推奨します。
※ rsyncはRocky9に最初から入っているコマンドです。
/var/lib/dockerの中身を、新ディレクトリへコピー
sudo rsync -aqxP /var/lib/docker/ /home/docker/data/
-a: アーカイブモード(権限等を保持)-x: ファイルシステム境界を越えない
注意: コピー元のパス末尾に/を付けることで、ディレクトリそのものではなく「中身」を転送先に展開します。
設定ファイルの変更 (daemon.json)
- ファイルのバックアップを取ります。(凄く重要)
何かあったときの切り戻しのため。特に、後述するjsonの編集をミスると地獄行きの通過駅無しの特急が待っています。
sudo cp -pi /etc/docker/daemon.json /path/to/backup/directory/daemon.json.$(date +%Y%m%d)
- ファイルのバックアップをdiffで取ります。
sudo diff -u /path/to/backup/directory/daemon.json.$(date +%Y%m%d) /etc/docker/daemon.json
一般ユーザが読み取れないディレクトリ構造も考慮して、念のためsudoをつけます。
→ エラーがなければバックアップ成功。ここでコピー元とコピー先を逆にしているのは編集後のdiffを取るためです。
- Dockerに新しい保存先を認識させるため、
/etc/docker/daemon.jsonを編集します。(エディタは宗教問題のため、自分の教義・信仰に沿ったものを利用してください)
変更例:data-root オプションを追記します。
JSON形式のため、行末のカンマ(,)の有無に注意してください。
{
"runtimes": {
"nvidia": {
"path": "nvidia-container-runtime",
"runtimeArgs": []
}
},
"data-root": "/home/docker/data"
}
- 編集後の差分をdiffで確認します。
sudo diff -u /path/to/backup/directory/daemon.json.$(date +%Y%m%d) /etc/docker/daemon.json
以下のようになっていることを確認します。
- "data-root": "/var/lib/docker"
+ "data-root": "/home/docker/data"
サービスの起動と確認
Dockerを起動し、設定が反映されているか確認します。
- Dockerサービスを起動します。
sudo systemctl start docker
- Dockerサービスの起動を確認します。
systemctl status docker
active(running)を確認します。
- 設定反映の確認
docker info | grep "Docker Root Dir"
=> Docker Root Dir: /home/docker/data となっていれば成功です。
不要データの削除(任意)
動作確認後、元の /var/lib/docker を削除または退避させて、ルートパーティションの空き容量を回復させます。
安全のため、バックアップを取るか慎重に削除してください。この作業を行うときは深呼吸を3回ほど行い、飲み物を飲むなどして落ち着いてから行いましょう。
sudo rm -rf /var/lib/docker
結果
本対応により、ルートパーティションの圧迫が解消されました。
Before:
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/rl-root 70G 70G 20K 100% /
After:
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/rl-root 70G 6.0G 65G 9% /
/dev/mapper/rl-home 6.9T 198G 6.7T 3% /home
トラブルシューティング
- SELinux: 起動に失敗する場合、SELinuxが非標準ディレクトリへのアクセスをブロックしている可能性があります。一時的に
setenforce 0で切り分けを行うか、適切なコンテキストを設定してください。 - JSON構文エラー:
daemon.jsonの記述ミス(カンマ忘れなど)があるとDockerが起動しません。編集後は慎重に確認を行いましょう。