2014年3月21日金曜日

Vagrant とストレージ容量

ストレージ容量が少ない MacBook Air に Vagrant でいくつかサーバーを立てて作業していると、みるみるストレージ容量が枯渇してきたので調査〜対応した。その時のメモ。

2つのディレクトリ

下調べの結果、Vagrant 関連で大きな容量を占めているのは以下の2つだった。
6.3G  ~/.vagrant.d
14G   ~/VirtualBox VMs

vmdk ファイル

さらに、このディレクトリを深堀していくと、両ディレクトリ共に box-disk*.vmdk というファイルがあり、かなりの容量を占めていることがわかった。これは仮想マシンのディスクを構成するファイルのようだ。

ディレクトリごとに生成されるタイミングが異なり、.vagrant.d/ 内の .vmdk ファイルは vagrant box add したタイミングで作られ、VirtualBox VMs/ 内の .vmdk は、初回の vagrant up のタイミングで作られていた。

つまり、vagrant box add しまくると .vagrant.d/ が大きくなり、vagrant init → vagrant up しまくると VirtualBox VMs/ が大きくなる。

vmdk ファイルの肥大化

また VirtualBox VMs/ の .vmdk ファイルは仮想マシーン側のストレージ使用量に併せて肥大化する。しかし仮想マシーン側で使用量が小さくなっても併せて圧縮はされないので、ひとたび肥大化してしまうと手動で圧縮しない限りストレージを確保したまま居座るのでやっかい。

今回は仮想マシン内で大量のデータや画像を保存したり削除したりしていたのでこのケースに相当しそう。

vmdk を手動で圧縮

上のような経緯で VirtualBox VMs/ 内の .vmdk ファイルを手動で圧縮することでストレージの枯渇に対応することにした。

先に結果を言っておくと2台の仮想マシンにこの圧縮をかけて、計5Gくらい圧縮できた。

圧縮手順1


まずゲスト OS 側で空き容量一杯に空のファイルを作成して、削除。
[root@localhost ~]# dd if=/dev/zero of=zero bs=4k
dd: writing `zero': デバイスに空き領域がありません
515280+0 records in
515279+0 records out
2110582784 bytes (2.1 GB) copied, 8.10922 seconds, 260 MB/s
[root@localhost ~]# rm zero
これは「0埋め」と言われている作業でストレージの空き容量を 0 で初期化するための作業。これをやらないと以下の行程で意図したように圧縮できない。

圧縮手順2


今度はホストOS(OSX)側での作業。.vmdk は直接圧縮できないので .vdi に変換してから圧縮して、また .vmdk に戻すという手順を踏む。これらの作業には VBoxManage というコマンドを使う。

作業前に vagrant halt で仮想マシーン を落としておく必要がある。
$ vagrant halt

圧縮手順2−1


VBoxManage コマンドで .vmdk を .vdi に変換。
$ cd ~/VirtualBox\ VMs/server_default_1395298198/
$ VBoxManage clonehd box-disk3.vmdk box-disk3.vdi --format vdi
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Clone hard disk created in format 'vdi'. UUID: fbf1ac71-240c-4422-8f02-5b3bff200e0a

圧縮手順2−2


.vdi を圧縮する。
$ VBoxManage modifyhd box-disk3.vdi compact
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

圧縮手順2−3


圧縮した .vdi を .vmdk に戻す。

まずは既存の .vmdk をリネームしておく。これは後の行程で役に立つのでやっておくといい。
$ mv box-disk3.vmdk box-disk3.vmdk.bak
次は
$ VBoxManage clonehd box-disk3.vdi box-disk3.vmdk --format vmdk
とやればよさそうな気がするが、変換の最後の段階でデバイスの UUID が被ってる的なエラーメッセージが出てしまう。

なので上のコマンドを叩く前に、この仮想マシーンに繋がれている既存のハードドライブ(.vmdk ファイル)を外しておく必要がある。

というか、実は上のコマンドを叩いてエラーが出ても無視して、手順3へと進んでも問題らしい問題は見つからなかったのだが、念のため丁寧なやり方を書いておく。

圧縮手順2−3−1


VirtualBox.app 立ち上げて command + d で仮想メディアマネージャーなるものを立ち上げる。


ハードドライブタブを選択して、一覧から該当のハードドライブを選び解放ボタン、除去ボタンと順に押す。今回は上でリネームした関係で赤いアラートが出ているものを選べばおk。この手順は VBoxManage コマンドでできるかもしれないが、未調査。

圧縮手順2−3−2


やっと本来の目的である .vdi から .vmdk に戻す作業ができる。
$ VBoxManage clonehd box-disk3.vdi box-disk3.vmdk --format vmdk
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Clone hard disk created in format 'vmdk'. UUID: 415c814c-714e-493c-9c11-9ec34939c739
ここは問題なく通るはず。

圧縮手順2−3−3


上で変換した .vmdk ファイルを GUI で接続する。

今度は VirtualBox.app のトップ画面の左側から該当の仮想マシーンを選択して設定ボタンを押す。下のキャプチャは設定ボタン押した後、設定画面が出てきたところ。


設定画面でストレージタブを選ぶ。左側のストレージツリーから SATA Controller を選択して "ハードディスクの追加"ボタンを押す。ダイアログが出るので"既存のディスクを選択"を押して上で変換した .vmdk ファイルを選択する。

これで圧縮済みのハードドライブが仮想マシーンに接続された。ここまでが恐ろしく面倒くさい。細かいキャプチャを撮ろうと思ったけど心が折れたのでキャプチャは省略。

この手順も VBoxManage コマンドでできたかもしれないが未調査。

圧縮手順3


vagrant up して問題のないことを確認して先ほどリネームした .vmdk ファイルと圧縮に使った .vdi ファイルを削除する。

リネームしたファイルは普通に rm コマンドで削除。
$ rm box-disk3.vmdk.bak

.vdi ファイルは先ほどの 仮想メディアマネージャー から削除すると VirtualBox 上にゴミが残らなくていいと思う。気にしない人は rm コマンドで削除すればいいと思う。

参考

https://gist.github.com/t-oginogin/6832937

補足

du コマンド


下調べの過程で du -sh ~/* とやってホームディレクトリ直下の各ディレクトリの使用容量を調べていたが、このコマンドはドットフォルダを表示しないので、.vagrant.d/ の存在に気がつかなかった。

以下のように depth オプションを立てて 1 を指定すればドットフォルダも含む全てのディレクトリを表示してくれる。
$ du -hd 1 ~

CentOS の場合は du -h --max-depth 1だった。

0 件のコメント :

コメントを投稿