By Fco.plj (Own work) [CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons

Vagrantのsynced_folderのtypeを比べてみた

  • このエントリーをはてなブックマークに追加
  • Evernoteに保存

こんにちは。リスペクトの木村です。
今回は、Vagrant の「synced_folder」の話をお送りします。

今回の環境

  • Windows7 Pro 64bit
  • VirtualBox 4.3.26 r98988
  • Vagrant 1.7.2

synced_folder とは

http://docs.vagrantup.com/v2/synced-folders/index.html

簡単に説明すると、ローカルのフォルダを仮想環境の任意のパスにマウントする機能です。
これにより仮想環境側に SCP などでいちいち転送する必要がなくなり、スムーズに直接確認することが出来ます。
デフォルトでは、synced_folder が設定されていなくても Vagrantfile のあるフォルダが /vagrant としてマウントされます。
synced_folder を設定する事で、それとは別に任意でマウントさせる事が可能です。

基本的には次のような記述を Vagrantfile 内に書く事で、vagrant up / vagrant reload 時にマウントされるようになります。

config.vm.synced_folder “ローカルのパス”, “仮想環境上のパス”

ちなみに Windows の場合、ローカルのパスの¥マーク(ディレクトリの区切り文字)を2重にする必要があるので注意が必要です。

C:\hogehoge\hugahuga → C:\\hogehoge\\hugahuga

更に下記のようなオプションが指定でき、権限回りの設定などが変更できます。

オプション名 説明 設定値 デフォルト
create true にすると、マウント先が存在しない場合は作成します。 true / false false
disabled true にするとマウントしません。 true / false false
group マウントするファイル/フォルダの所有グループ名を設定できます。 文字列 SSH接続のユーザー(vagrant)
mount_options mount コマンドのオプションを指定できます。 配列
owner マウントするファイル/フォルダの所有グループ名を設定できます。 文字列 SSH接続のユーザー(vagrant)
type マウントに使用するタイプを指定します。(後述) 文字列 nfs

例えば、disabled を有効にする場合はこんな感じで指定します。

config.vm.synced_folder “ローカルのパス”, “仮想環境上のパス”, disabled: true

synced_folder のタイプ

オプションの一覧表にあった「type」をもう少し詳しく掘り下げたいと思います。

type オプションを指定すると、ファイルのやりとりに使用するタイプを変更できます。
1.7.2 の時点では使用できるタイプが4種類存在しますので、それぞれの特徴を紹介します。
(カッコ内は利用可能なOSです。)

VirtualBox(Windows/Mac/Linux)

http://docs.vagrantup.com/v2/synced-folders/virtualbox.html

VirtualBox の共有フォルダ機能を使用してやりとりを行います。その為、仮想環境側には GuestAddtions が導入されている必要があります。
VirtualBox を provider( =Vagrant から利用する仮想化ソフトの指定 )にしている場合は、この方式がデフォルトで使用されます。

最小限の設定のみで使えるのですが、他に比べて遅いというデメリットがあります。
通常に使っている分には殆ど困りませんが、Apache の DocumentRoot でマウント先を設定している場合など、頻繁に読み書きが発生する環境下ではその影響が現れやすいです。

また、Web サーバ経由でファイルを確認すると更新されていないように見える場合があるため、事前に下記の設定をサーバのコンフィグファイルに記述しておく必要があります。

EnableSendfile(sendfile) は、大まかに言うと「サーバからファイルを送信するときに、ファイルが更新されていなければキャッシュから送信する」機能です。
VirtualBox のファイル共有機能経由でマウントしている先が DOCUMENT_ROOT になっていると、ファイルが更新されたという通知が行き渡らないため、そのままキャッシュの内容を送信してしまう、という現象が発生します。

デフォルトでは有効(on)になっているので、明示的に無効にするよう指定します。
ファイルへ直接読み書きする頻度が増えますが、開発環境であれば気にならないレベルだと思います。

設定例

config.vm.synced_folder “C:\\hogehoge\\hugahuga”, “/hogehoge/hugahuga”

※固有のオプションは存在しません。

NFS(Mac/Linux)

http://docs.vagrantup.com/v2/synced-folders/nfs.html

NFS( http://ja.wikipedia.org/wiki/Network_File_System )の仕組みを利用して通信します。
最初期から実装されていた接続方法のため、VirtualBox が遅いという場合の解決策としてよく取り上げられています。
また、VirtualBox 以外の provider の場合は NFS がデフォルトで使用されます。

ちなみに・・・NFS は Mac / Linux 専用です。Windows の場合は

Windows users: NFS folders do not work on Windows hosts. Vagrant will ignore your request for NFS synced folders on Windows.

と、ドキュメントにありますので利用できません。設定しても無視され、デフォルトのタイプが利用されます。

速度としては高速ですが、NFS についての知識が無いと設定に苦労すると思います。
Mac の場合もデフォルトでは有効になっていないため、nfsdの起動/自動起動の設定や/etc/exportsを作成しておく必要があります。
vagrant up の時に毎回 ROOT のパスワードを聞いてくる現象もありますが、これは仮想環境側の /etc/sudoers にいくつか設定を追加する事で回避できます。
( 詳しくはhttp://docs.vagrantup.com/v2/synced-folders/nfs.html の 「ROOT PRIVILEGE REQUIREMENT」を参照)

設定例

config.vm.synced_folder “hogehoge/hugahuga”, “/hogehoge/hugahuga”, type: “nfs”

NFSの場合、次のオプションが利用できます。

オプション名 説明 設定値 デフォルト
nfs_export false にすると、/etc/exports に設定を書き込みません。 true / false true
nfs_udp true にすると、UDPを使用して通信します。 true / false true
nfs_version NFSのプロトコルバージョンを指定できます。 文字列か数字 3

rsync(Windows/Mac/Linux)

http://docs.vagrantup.com/v2/synced-folders/rsync.html

rsync( http://ja.wikipedia.org/wiki/Rsync )を利用してファイルをやりとりします。
他と違い、基本的には vagrant up / vagrant reload / vagrant provision を実行したタイミングでフォルダの内容が同期されます。vagrant rsync というコマンドでも同期が可能ですし、vagrant rsync-auto というコマンドを実行する事で自動で同期してくれます。設定により、自動同期からファイルやフォルダを除外する事も可能です。

注意する点として、ホスト OS 側から仮想環境への一方向だけの同期であるという所と、rsync-auto を実行していない限り自動的に同期しないという所があります。
synced_folder の設定を解除して再度起動すると、同期先には同期した内容がそのまま残っています。

ローカル・仮想環境の両方に rsync コマンドが必要で、Windows の場合は Cygwin / MinGW での導入が推奨されています。
今回は Cygwin から導入しました。
(Cygwin での rsync 導入は http://qiita.com/daichi87gi/items/6b33349eedce28db430a を参考に)

また、https://github.com/mitchellh/vagrant/issues/4073#issuecomment-62618797 によると、Cygwin の bin フォルダ( C:\cygwin\bin 、64bit の場合は C:\cygwin64\bin )にパスを通したあと、Vagrantfile に次の記述を追記しないとエラーになります。

ENV[“VAGRANT_DETECTED_OS”] = ENV[“VAGRANT_DETECTED_OS”].to_s + ” cygwin”

本来であればVagrantがCygwinの利用を検知してくれるのですが、上手く行かない場合があるため、設定で強制的に「Cygwin を利用している」となるように変更します。

設定例

config.vm.synced_folder “C:\hogehoge\hugahuga”, “/hogehoge/hugahuga”, type: “rsync”, rsync__exclude: “.git/”

rsync の場合、次のオプションが利用できます。他と違ってアンダースコア(_)が2つあります。

オプション名 説明 設定値 デフォルト
rsync__args rsync コマンドに渡すオプションを指定できます。 配列 [“–verbose”, “–archive”, “–delete”, “-z”, “–copy-links”]
rsync__auto false にすると、vagrant rsync-auto の監視対象から除外されます。 true/false true
rsync__chown false にすると、同期の際に自動で実行される chown -R による所有者の変更を行いません。 true / false true
rsync__exclude 同期から除外するファイルやフォルダを指定できます。 文字列か配列

SMB(Windows)

http://docs.vagrantup.com/v2/synced-folders/smb.html

Windows ファイル共有(SMB / http://ja.wikipedia.org/wiki/Server_Message_Block )を利用して通信します。
Windows 限定です。(仮想環境側は Linux でも OK)

NFS と同じように、VirtualBox よりパフォーマンスは良くなります。
追加の設定も Windows のログイン情報だけという手軽さですが、他の方法に比べて通信が不安定という重大な欠点も・・・。

ちなみに上記ドキュメントには記載されていませんが、SMB でマウントするには次の条件が必要です。

  • PowerShell3.0以上
  • コマンドプロンプト/PowerShell が管理者として実行されている

PowerShell で $PSVersionTable と入力し、下記のように「PSVersion」が3.0以上なら大丈夫ですが、そうでない場合は「Windows Management Framework 3.0( http://www.microsoft.com/en-us/download/details.aspx?id=34595 )」を別途インストールする必要があります。

Name                           Value
----                           -----
PSVersion                      4.0
WSManStackVersion              3.0
SerializationVersion           1.1.0.1
CLRVersion                     4.0.30319.18063
BuildVersion                   6.3.9600.16406
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0}
PSRemotingProtocolVersion      2.2

管理者として実行するには、スタートメニューから実行する時に、右クリックから「管理者として実行」を選択して起動します。
管理者ではない状態で起動すると、起動途中で次のようにエラー表示になります。

SMB shared folders require running Vagrant with administrative
privileges. This is a limitation of Windows, since creating new
network shares requires admin privileges. Please try again in a
console with proper permissions or use another synced folder type.

設定例

config.vm.synced_folder “C:\hogehoge\hugahuga”, “/hogehoge/hugahuga”, type: “smb”, smb_username: “Windowsユーザー名”, smb_password: “パスワード”

SMB の場合、次のオプションが利用できます。

オプション名 説明 設定値 デフォルト
smb_host マウントしたいホストの IP アドレスを指定できます。 文字列 Vagrant により自動設定
smb_password マウントに使用するアカウントのパスワードを指定します。 文字列
smb_username マウントに使用するアカウントのユーザー名を指定します。 文字列

smb_password と smb_username のどちらか一方でも指定されていない場合は、起動の度にユーザー名とパスワードを入力する必要があります。
また、ユーザー名にスペースが含まれている場合はちょっとした工夫が必要です。

  • smb_username で設定する場合は、「smb_username: ‘”Toshihiko Kimura”‘」と、シングルクオーテーションで括って更にダブルクオーテーションで括る必要があります。
  • vagrant up 時に入力する場合は、「Username: “Toshihiko Kimura”」のように、ダブルクオーテーションで括るように入力します。

設定(or入力)された値をそのまま mount コマンドに渡しているようなので、スペースが含まれているとエラーになります。
そのため、ダブルクオーテーションで囲って回避する必要があります。

パフォーマンス比較

では、設定する方式によってパフォーマンスにどれぐらい差が出るのか実際に計測してみます。
今回は NFS を除く3種類(VirtualBox/rsync/SMB)で比較します。
(NFS は Windows で使用できないため除外)

今回は以下のような環境で検証しています。

  • マウント先は Apache の DOCUMENT_ROOT
  • 中身は何も設定していない状態の CakePHP
  • 各種バージョンは以下の通り
    • Apache: 2.2.15-29.el6.centos
    • PHP: 5.5.23
    • CakePHP: 2.6.1

負荷テストには siege を利用します。(siege についてはこちら http://qiita.com/inokappa/items/84f42dbd718a8070bd1d )
発行するコマンドは「siege -c 30 -r 5 -t 60s -b http://localhost/」で、同時ユーザー数30・5リクエスト・1分間の連続負荷、という条件です。

実行すると、以下のような結果になりました。
siegeの最後に出力される実行結果を、種別・項目ごとに表にしてまとめました。

VirtualBox rsync SMB
Transactions 724 hits 1649 hits 1211 hits
Availability 100.00% 100.00% 85.89%
Elapsed time 59.27 secs 59.64 secs 59.87 secs
Data transferred 13.54 MB 30.84 MB 21.46 MB
Response time 2.40 secs 1.07 secs 1.44 secs
Transaction rate 12.22 trans/sec 27.65 trans/sec 20.23 trans/sec
Throughput 0.23 MB/sec 0.52 MB/sec 0.36 MB/sec
Concurrency 29.28 29.70 29.07
Successful transactions 724 1649 1094
Failed transactions 0 0 199
Longest transaction 3.99 1.78 18.60
Shortest transaction 0.88 0.35 0.00

(結果の見方はこちら http://qiita.com/inokappa/items/84f42dbd718a8070bd1d#3-3 )

多くの値で rsync>SMB>VirtualBox となっているので、rsync が早いのがよく分かります。
rsync と VirtualBox で比べてみると倍以上の差がありますので圧倒的です。rsyncの場合はローカルを参照しているので早いのは当たり前ですが、予想以上に差が開きました。
SMB はほぼ中間か、rsync に近い値を示しているのでパフォーマンスは良いです。
ただ、Availability が VirtualBox や rsync は100%なのに対し、SMB が86%ほどと不安定さがよく現れています。
SMB で実行している時の siege のログを見てみると、500 / 403 のステータスコードを返していました。

HTTP/1.1 200   1.52 secs:   19610 bytes ==> GET
HTTP/1.1 200   1.77 secs:   19610 bytes ==> GET
HTTP/1.1 200   1.69 secs:   19610 bytes ==> GET
HTTP/1.1 200   1.93 secs:   22860 bytes ==> GET
HTTP/1.0 500   0.21 secs:       0 bytes ==> GET
HTTP/1.0 500   0.04 secs:       0 bytes ==> GET
HTTP/1.0 500   0.42 secs:       0 bytes ==> GET
HTTP/1.1 403   0.01 secs:     289 bytes ==> GET
HTTP/1.1 403   0.01 secs:     277 bytes ==> GET
HTTP/1.1 200   0.38 secs:    1723 bytes ==> GET
HTTP/1.1 200   1.62 secs:   19610 bytes ==> GET
HTTP/1.1 403   0.03 secs:     277 bytes ==> GET
HTTP/1.1 200   1.68 secs:   18205 bytes ==> GET

アクセスするタイミングによって、毎度リソースが読み込めたり読み込めなかったり・・・ということが起こっているようです。より安定して稼働するようになるまでは、SMB は Web アプリケーションのマウント先としてはあまり向かなそうです。

おわりに

rsync の同期はリアルタイムではないのであまり向かないかなと思っていたのですが、一応自動で同期ができるようなので、Windows で使う上で一番現実的な移行先ではないかと思います。導入が若干大変ですが・・・。
その一方、期待株の SMB は不安定さが足を引っ張ってしまい、残念ながら今の所は出番は無さそうです・・・。今後の改善に期待したいと思います。

synced_folder が何か遅いな、と思っている方は自分に最適な type を探し、より快適な環境を目指してみてはいかがでしょうか。
現場からは以上です。

  • このエントリーをはてなブックマークに追加
  • Evernoteに保存