はじめに
先日、研究室サーバーで削除されずに残った不要なDockerイメージ・コンテナが、ディスク容量をひっ迫していることに気が付きました。
対策として、SSDを増設しつつDockerのストレージディレクトリ(デフォルトは/var/lib/docker
)を変更する方法を紹介します。
1. SSDの増設
サーバーマシンのOSは、Ubuntu 20.04.6 LTSです。
今回は以下のSSDを増設しました。
また、増設にあたって以下の記事が参考になりました。
まずはサーバーマシンの電源を落とし、電源ケーブルを抜きます。
SSDはネジでマウンタに固定してから挿入します。
SSDを購入した際にはネジは付属していなかったので、ネジのセット(例:https://amzn.asia/d/07dCVfpV)を購入しておくと安心です。今回はM 3*8サイズがピッタリでしたが、SSDやマシンによって異なる可能性があります。
1.1. ディスクのデバイス名を確認
SSDを挿入して電源を入れたら、デバイスがカーネルに認識されているか確認します。
fdiskコマンドは、-l
オプションで指定デバイスのパーティションテーブルを表示しますが、デバイス名を指定しない場合は/proc/partitions
に書かれているデバイスを参照します。
$ fdisk -l ディスク /dev/sda: 3.5 TiB, 3840755982336 バイト, 7501476528 セクタ Disk model: INTEL SSDSC2KB03 単位: セクタ (1 * 512 = 512 バイト) セクタサイズ (論理 / 物理): 512 バイト / 4096 バイト I/O サイズ (最小 / 推奨): 4096 バイト / 4096 バイト ディスクラベルのタイプ: gpt ディスク識別子: ****************-****-****-****-**************** デバイス 開始位置 最後から セクタ サイズ タイプ /dev/sda1 **** ****** ****** *** EFI システム # (省略) ディスク /dev/sdb: 3.65 TiB, 4000787030016 バイト, 7814037168 セクタ Disk model: CT4000MX500SSD1 単位: セクタ (1 * 512 = 512 バイト) セクタサイズ (論理 / 物理): 512 バイト / 4096 バイト I/O サイズ (最小 / 推奨): 4096 バイト / 4096 バイト ディスク /dev/sdc: 16.38 TiB, 18000207937536 バイト, 35156656128 セクタ Disk model: WDC WUH721818AL 単位: セクタ (1 * 512 = 512 バイト) セクタサイズ (論理 / 物理): 512 バイト / 4096 バイト I/O サイズ (最小 / 推奨): 4096 バイト / 4096 バイト ディスクラベルのタイプ: gpt ディスク識別子: ****************-****-****-****-**************** デバイス 開始位置 最後から セクタ サイズ タイプ /dev/sdc1 **** *********** *********** ***** Linux ファイルシステム
今回新しく挿入したSSDはDisk model
や容量などから/dev/sdb
だと分かりました(より詳細な識別情報が欲しい場合はhdparmコマンドの-I
オプションが便利です)。
万が一デバイスが認識されない場合は、電源を落としてからSSDが正しく挿入されているか再確認する必要があります。
1.2. パーティションの作成
先ほどと同じfdiskコマンドを使用して、ディスク上に新しいパーティションを作成します。
最初は、先述の記事に従って以下のように実行してみました。
$ fdisk /dev/sdb fdisk (util-linux 2.34) へようこそ。 ここで設定した内容は、書き込みコマンドを実行するまでメモリのみに保持されます。 書き込みコマンドを使用する際は、注意して実行してください。 デバイスには認識可能なパーティション情報が含まれていません。 このディスクのサイズは 3.7 TiB (4000787030016 バイト) です。DOS パーティションテーブル形式では 2199023255040 バイト以上のドライブには セクタサイズ 512 バイトを使用することができません。GUID パーティションテーブル (GPT) 形式を使用してください。 新しい DOS ディスクラベルを作成しました。識別子は 0x******** です。 コマンド (m でヘルプ): n パーティションタイプ p 基本パーティション (0 プライマリ, 0 拡張, 4 空き) e 拡張領域 (論理パーティションが入ります) 選択 (既定値 p): p パーティション番号 (1-4, 既定値 1): 1 最初のセクタ (2048-4294967295, 既定値 2048): 2048 Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-4294967295, 既定値 4294967295): 新しいパーティション 1 をタイプ Linux、サイズ 2 TiB で作成しました。
残念ながら、ディスクサイズである3.7 TiB
のうち2 TiB
しか使用されずパーティションが作成されてしまいました。よく見ると、DOS パーティションテーブル形式では 2199023255040 バイト以上のドライブには セクタサイズ 512 バイトを使用することができません。GUID パーティションテーブル (GPT) 形式を使用してください。
と説明がありました。
GPTパーティションテーブルを作成するには、gdiskコマンドやpartedコマンドを使用するのが一般的なようですが、util-linux 2.23以降はfdisk
コマンドでもGPTパーティションテーブルがサポートされている*1そうです。
今回はDockerのストレージディレクトリを変更することが目的であり、3.7 TiB
をフル活用したいため、以下のように実行します。
# コマンド (m でヘルプ): d # パーティション 1 を選択 # パーティション 1 を削除しました。 コマンド (m でヘルプ): g 新しい GPT ディスクラベル (GUID: *****************-****-****-****-************) を作成しました。 コマンド (m でヘルプ): n パーティション番号 (1-128, 既定値 1): 最初のセクタ (2048-7814037134, 既定値 2048): Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-7814037134, 既定値 7814037134): 新しいパーティション 1 をタイプ Linux filesystem、サイズ 3.7 TiB で作成しました。 コマンド (m でヘルプ): w パーティション情報が変更されました。 ioctl() を呼び出してパーティション情報を再読み込みします。 ディスクを同期しています。
1.3. ファイルシステムの作成
mkfsコマンドを使用して、作成したパーティション上にファイルシステムを構築します。
ファイルシステムの種類については、以下のドキュメントに簡単にまとめられています。
man filesystems (5): Linux のファイルシステム種別: minix, ext, ext2, ext3, ext4,
今回は、Linuxで最も広く使われているext4を採用しました。
$ cd /sbin $ ls -1 mkfs.* mkfs.bfs mkfs.btrfs mkfs.cramfs mkfs.ext2 mkfs.ext3 mkfs.ext4 mkfs.fat mkfs.minix mkfs.msdos mkfs.ntfs mkfs.vfat mkfs.xfs $ mkfs -t ext4 /dev/sdb1 mke2fs 1.45.5 (07-Jan-2020) Discarding device blocks: done Creating filesystem with 976754385 4k blocks and 244195328 inodes Filesystem UUID: ****-****-****-****-****-******** Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968, 102400000, 214990848, 512000000, 550731776, 644972544 Allocating group tables: done Writing inode tables: done Creating journal (262144 blocks): done Writing superblocks and filesystem accounting information: done
1.4. ファイルシステムのマウント
最後にmountコマンドを使用して、/dev/sdb1
を任意のディレクトリにマウントします。
$ mount /dev/sdb1 /mnt/ssd4tb/ $ df -h Filesystem Size Used Avail Use% Mounted on # (省略) /dev/sdb1 3.6T 89M 3.4T 1% /mnt/ssd4tb
また、リブートしても自動でマウントされるように/etc/fstab
に追記します。ファイルシステムのUUIDはlsblkコマンドで確認できます。
$ lsblk -f NAME FSTYPE LABEL UUID FSAVAIL FSUSE% MOUNTPOINT sda # (省略) sdb └─sdb1 ext4 ********-****-****-****-************ 3.4T 1% /mnt/ssd4tb sdc # (省略) sr0 $ echo "UUID=********-****-****-****-************ /mnt/ssd4tb ext4 defaults 0 2" >> /etc/fstab
パラメータの設定は以下の記事が分かりやすかったです。
An introduction to the Linux /etc/fstab file | Enable Sysadmin
2. Dockerストレージディレクトリの変更
手順は、以下の素晴らしい記事の通りです。
ここでは実行したコマンドとその結果のみ紹介します。
$ cd /mnt/ssd4tb $ sudo cp -ar /var/lib/docker/ . $ docker -v Docker version 26.0.0, build 2ae903e $ sudo vim /lib/systemd/system/docker.service # `ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock`の後に` --data-root /mnt/ssd4tb/docker`を追加 $ sudo systemctl daemon-reload $ sudo systemctl start docker $ sudo systemctl status docker ● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2024-06-20 15:21:42 JST; 20s ago # (省略) $ docker info | grep "Docker Root Dir:" Docker Root Dir: /mnt/ssd4tb/docker $ docker images # (省略) $ docker run -it --rm busybox Unable to find image 'busybox:latest' locally latest: Pulling from library/busybox ec562eabd705: Pull complete Digest: sha256:9ae97d36d26566ff84e8893c64a6dc4fe8ca6d1144bf5b87b2b85a32def253c7 Status: Downloaded newer image for busybox:latest / # echo "Hello World" Hello World / # exit
動作確認まで完了し、無事にDockerのストレージディレクトリを変更できました。
先述した記事でも言及されていますが、docker -v
でバージョンを確認しているのは、Docker Engine v23.0で--graph
オプションが廃止されて--data-root
オプションになった*2ためです。複数のマシンでSSD増設を行いましたが、v23.0以前のDocker Engineも混ざっていたため注意が必要でした。
まとめ
今回は、SSDを増設しつつDockerのストレージディレクトリを変更する方法について紹介しました。
パブリッククラウドを利用すれば簡単にボリュームをアタッチできる時代に、このような経験ができたことは貴重ですし、ストレージに対する理解も深まりました。
これでしばらくは、ストレージ容量が不足して困ることはなさそうです。現状不足しているのは研究の進捗のみです。