root@kmconner.net:~/www/# cat << TECH
###################################################################################
##                                             TOP  PROFILE  POSTS  TAGS  ABOUT  ##
##                                                                               ##
##                         Welcome to kmconner’s Website                         ##
##                               浅く広く 時に深く                               ##
##                                                                               ##
###################################################################################
TECH
root@kmconner.net:~/www/# cat << TECH
###########################################
##     TOP  PROFILE  POSTS  TAGS  ABOUT  ##
##                                       ##
##     Welcome to kmconner’s Website     ##
##           浅く広く 時に深く           ##
##                                       ##
###########################################
TECH

Hyper-V 上の Linux マシンのディスクを最適化する

はじめに

Windows Server に搭載されている仮想化システムである Hyper-V では、仮想ディスクのフォーマットとして主に VHDX と呼ばれる形式を使用しています。 この形式には

がありますが、今回の記事では可変容量ディスクを使用しています。 可変容量ディスクは固定容量ディスクと比較して、ディスクイメージのサイズを小さくしてディスク容量を節約できるというメリットがありますが、使い方によってはそのメリットがあまり発揮されないことがあります。 この記事では、 Ubuntu をインストールした Hyper-V 上の仮想マシンで使用しているディスクファイルの容量を節約する方法を紹介します。

この記事で紹介する手法はでディスクファイルの最適化を試す場合には、 必ずバックアップを取って行ってください。 データの破損等に関しては自己責任でお願いします。

使用した環境

Windows Server 2016 の Hyper-V 上にほぼデフォルト設定の状態の仮想マシンを作成し、 Ubuntu 18.04 をインストールしました。 デフォルトから異なっている点は、第2世代であること、セキュアブートがオフになっていることです。 (今回の検証内容にはあまり関係ないと思われます)

今回用意したディスクは最大容量が 128 GB の可変容量の VHDX で、その中身はインストール後に、ソフトウェアのアップーデート及び容量の大きなソフト (libreoffice など) を削除した状態です。

まず、ターミナルから df コマンドを使用してディスクの使用状況を見たものがこちらです。

df コマンドの結果

この結果から、ディスクの使用量はおよそ6.8 GB 程度と考えられます。 しかしながら、この仮想ディスクの実際のサイズは 12.9 GB と、使用量よりもかなり大きくなってしまっています。

最適化に使用する手法

今回は以下の手法を用いて、ディスクの最適化をします。

zerofree コマンドの使用

zerofree コマンドとは、ストレージにおいて、使用されていない領域を全て特定の値 (今回は 0) にするコマンドです。 使用されていない領域を 0 で埋める理由として、可変容量の VHDX ファイルの以下のような性質があります。

VHDX のディスクでは、ディスクのデータを特定のサイズごとに区切ってブロックとして管理しています。 そのブロックのデータが全て 0 となった時、そこのブロックを削除してディスクサイズを削減することができます。

これらの方法を実際に試してみます。

まず、通常起動時にルートにマウントされているファイルシステムを確認します。 (先の例では /dev/sda2 であることがわかります。)

次に、 Ubuntu のインストールディスクのイメージを仮想マシンのディスクドライブにアタッチしてそのドライブから起動します。 起動する際には Try Ubuntu without installing を選択してください。 Ubuntu が起動したらターミナルを開きます。 (このような方法が必要なのは、通常起動をしてしまうとファイルシステムが Read-Write でマウントされてしまうためです。)

デフォルトの状態では zerofree はインストールされていないので、 sudo apt-get install zerofree でインストールします。 インストールできたら、次のコマンドを打って未使用な領域を 0 で埋めます。

sudo zerofree /dev/sda2

/dev/sda2 の部分は適宜読み替えてください。 操作終了後はシャットダウンしてください。

仮想マシンの電源が切れたら、管理者権限で起動した Powershell で以下のコマンドを実行してディスクファイルの最適化を行います。 この操作が先ほど説明した、すべてのデータが 0 のブロックを削除する操作に該当します。

Optimize-VHD <path/to/vhdx> -mode Full

ブロックサイズの変更

これは Microsoft のドキュメント の中でも紹介されていた方法です。

先程も述べた通り、 VHDX はディスクを一定のサイズのブロックに分けて管理します。 そのブロックサイズを変更することで、仮想ディスクの容量を節約できる場合があるようです。

VHDX ファイルを作成する際のデフォルトのブロックサイズは 32 MB ですが、以下のコマンドを使用してこれを 1MB に変更します。

Convert-VHD -Path <path/to/source> -DestinationPath <path/to/destination> -BlockSizeBytes 1MB

最適化した結果

これらの方法を使用した結果、ファイルサイズは以下のように変わりました。

最適化前: 12.9 GB zerofree の使用: 11.7 GB ブロックサイズの変更後: 8.5 GB zerofree + ブロックサイズの変更後: 6.1 GB

これらの方法でディスク容量を大幅に削減できました。

多少手間のかかる方法ではありますが、データの損失にはくれぐれも注意して、是非試してみてください!