2015-04-29 更新
VMWareをお持ちであれば、Mac上のdockerでVMWareのネイティブフォルダシェアが実現した話をどうぞ。
まえおき
業務で実際に仮想環境としてよく使われるようになったVagrant,Macでのローカルのファイル同期はnfsを使うのが一般的だと思いますが,そのnfsの設定を変更して,Vagrantを爆速にする話.
手元の環境では,大体2倍の速度が出ています.
大体はタイトルの通りasyncを効かせるんですが,日本国内でVagrantに適応している情報がなかったので,書いておきます.
結構単純なのにあまり情報がないのと,計測方法が分からないので,実はプラシーボなのかもしれません.そしたらすみません.
いちおう,コメントかtweet頂ければ,出来る限りお手伝いします.
注意
Vagrantの今の使用層を考えて,黒い画面が不慣れでも分かりやすいようにかなり冗長に書いているので,nfs早くするだけならtl;dr見てください.
nfsについて知識があるわけでなく,海外で見つけた情報を元にした記事です
/etc/を触る比較的コアな設定ですので,自己責任にて.
また,自分はいまDockerのためにしかVagrantを使用していない( Mac -> Vagrant -> boot2docker -> Docker )ので,通常のVagrant運用でどうかは試していません.
気が向いたら.
また、サーバーとかクライアントとか言うと,VagrantでのそれとSSHでのそれとでは意味が少しだけ違ってきて分かりづらくなるので,ここぞという時にしか極力使わないようにします.
併せて,Vagrant記事では基本的にどっちで(Mac側なのかVagrant内のLinux等なのか)コマンド打っているか分かりづらいので,
Macであれば mac$ sudo vi hoge
Vagrantであれば vagrant$ sudo vi hoge
で統一します.
緩募
- Vagrantとのnfs接続速度をbonnie++などで計る方法
- 普通にUbuntuなどをVagrantで立ち上げた時の動作確認
tl;dr
On Mac,
mac$ sudo vi /etc/nfs.conf
nfs.server.async=1
nfs.server.verbose=3
nfs.server.nfsd_threads=512
nfs.server.tcp=1
nfs.server.verbose=3
nfs.server.wg_delay_v3=1
nfs.client.allow_async=1
nfs.client.nfsiod_thread_max=512
nfs.client.mount.options=async,nfsvers=3,mountvers=3,rsize=8192,wsize=8192,acdirmax=3600,soft,intr,tcp
nfs.statd.verbose=1
and, nfs daemon restart
mac$ sudo nfsd restart
check nfsd status,
mac$ sudo nfsd status
nfsd service is enabled
nfsd service is loaded
nfsd is running (pid 43918, 512 threads)
lockd service is enabled
lockd service is loaded
lockd is running (pid 278)
statd.notify service is enabled
statd.notify service is loaded
statd.notify is not running
statd service is loaded
statd is running (pid 279)
rquotad service is loaded
rquotad is running (pid 44194)
Your Vagrantfile,
mac$ vi Vagrantfile
Vagrant.configure("2") do |config|
# ...
config.vm.synced_folder ".", "/vagrant", type: "nfs", mount_options: ["async", "nolock", "nfsvers=3", "vers=3", "tcp", "noatime", "soft", "rsize=8192", "wsize=8192"]
# ...
end
mac$ vagrant up
Done.
実現可能そうな環境
- OS X 10.9 〜
- Vagrant 1.7.2(2015/04/17 最新)
- VirtualBox・Parallels Desktop(VMWareは使える環境ですが試していません)
実際動いてる,手元の環境
Mac (RubyMine etc...) -> Vagrant -> boot2docker -> Docker
- OS X Yosemite 10.10.3
- Vagrant 1.7.2
- Parallels Desktop 10.2.0 (28956)
- boot2docker 1.6(今朝でましたね)
- Docker 1.6(今朝でましたね)
いつものVagrantfile
通常nfs設定を有効にするVagrantfileの設定は,
http://docs.vagrantup.com/v2/synced-folders/nfs.html
Vagrant.configure("2") do |config|
# ...
config.vm.synced_folder ".", "/vagrant", type: "nfs"
# ...
end
type
でnfsを指定することにより,nfsで共有可能になります.
これだけで通常のVirtualbox共有などより早くなるのは周知の事実ですね.Qiitaでもメモされている方がいっぱいいらっしゃいます.
この設定でmac$ vagrant up
すると,Mac側の/etc/exports
に共有するフォルダ情報が書き込まれ,Macをサーバーとして,daemonを立ち上げnfs共有が開始され,Vagrantで立ち上げたOSにマウントされます.(あってる?)
具体的に/etc/exports
を見てみましょう.
mac$ cat /etc/exports
# VAGRANT-BEGIN: 501 5c******-c***-4684-8e21-35289a3c****
"/vagrant" "/path/in/dir" 10.211.55.33 -alldirs -mapall=501:20
# VAGRANT-END: 501 5c******-c***-4684-8e21-35289a3c****
想像で書いたので実際と違うかもしれませんが./path/in/dir
と10.211.55.33
はそれぞれ皆さんの環境によって違い, -alldirs -mapall=501:20
はもしかしたら普通は書いてないかもしれません.
ともかく,Macでnfs daemonを立ち上げているので,Vagrantの裏設定の闇に入らずとも,少しはMac側でカジュアルにいろいろと設定できそうな雰囲気がしてきます.
/etc/nfs.conf
Macでのnfs daemonの設定は./etc/nfs.conf
に記述します.
デフォルトでは,空のファイルだったかコメントがあるのみだったかと思います.
そこに,async(非同期)書き込みを許可する設定をします.
vim
やSublime Text
(いまVagrant触ってるフロントエンドの人はSublime多そうな気がする.そしてThemeはSeti_UIな気がする.作者のctf0はいい人)でnfs.conf
を開きます.
ただ,/etc/
内なので管理者権限が必要ですので,vim
ならsudo
を付け,Sublimeの保存時にMacのパスワードを入れて保存してください.
mac$ sudo vi /etc/nfs.conf
nfs.server.async=1
nfs.server.verbose=3
nfs.server.nfsd_threads=512
nfs.server.tcp=1
nfs.server.verbose=3
nfs.server.wg_delay_v3=1
nfs.client.allow_async=1
nfs.client.nfsiod_thread_max=512
nfs.client.mount.options=async,nfsvers=3,mountvers=3,rsize=8192,wsize=8192,acdirmax=3600,soft,intr,tcp
nfs.statd.verbose=1
大体設定内容は見ればわかりそうな感じです.
詳しくは記事下部にあるリンク,apple manpageを見てください.
nfs.server.async=1
async書き込み許可する.
デフォルトは0(許可しない)
nfs.server.verbose=3
nfsログをDEBUGモードにする.
デフォルトは0.
nfs.server.nfsd_threads=512
nfsスレッドを設定数に変更する
たぶんこれは多すぎます.Redhatのサイトとかだと20指定していました.
Macデフォルトは8.
nfs.server.tcp=1
nfsでのTCPを許可する.
デフォルトでも1.
nfs.server.wg_delay_v3=1
ちょっとよく覚えてませんが,設定するとオーバーヘッドが減るらしいです.
デフォルトは0.
nfs.client.***
nfs.client以下は.Macがserverにあたるのであまり意味がないように思いますが,後述するVagrantfileへの設定を,実は書かなくても自動でやってくれるんじゃないかという期待を胸に一応書いています.
ただ,試していません.
現状動いているので,試すよりRails書いてたいです.
nfsd restart
Macのnfs daemonを再起動して,設定を反映させましょう.
Macの場合は,以下で再起動できます.
mac$ sudo nfsd restart
何も表示されずに終わります.
不安なのでstatusをチェックします.
mac$ sudo nfsd status
nfsd service is enabled
nfsd service is loaded
nfsd is running (pid 43918, 512 threads)
lockd service is enabled
lockd service is loaded
lockd is running (pid 278)
statd.notify service is enabled
statd.notify service is loaded
statd.notify is not running
statd service is loaded
statd is running (pid 279)
rquotad service is loaded
rquotad is running (pid 44194)
指定したスレッド数になっています.
それでも不安であれば,nfs.confのスレッドの数値を変更してrestartしましょう.
nfsd is running
が変化するはずです.
再度Vagrantfile
Mac側でasyncの設定を許可したので,クライアント側でもasyncを設定します.
ついでにprivate_network
も指定しましょう.特にDockerならあとで色々と楽です.
Vagrant自体がbuggyで何度もyakを刈っていたので嫌になり,今はDockerしか使っていないのなんとも言えませんが,原理的には,
Vagrant.configure("2") do |config|
# ...
config.vm.network 'private_network', ip: '192.168.55.33'
config.vm.synced_folder ".", "/vagrant", type: "nfs", mount_options: ["async", "nolock", "nfsvers=3", "vers=3", "tcp", "noatime", "soft", "rsize=8192", "wsize=8192"]
# ...
end
で良さそうな感じです.
動作確認している自分のVagrantfile
Vagrant.configure("2") do |config|
# ...
config.vm.network 'private_network', ip: '192.168.55.33'
config.vm.synced_folder ".", Dir.pwd, type: "nfs", mount_options: ["async", "nolock", "nfsvers=3", "vers=3", "tcp", "noatime", "soft", "rsize=8192", "wsize=8192"]
config.vm.synced_folder "/Users", "/Users", type: "nfs", mount_options: ["async", "nolock", "nfsvers=3", "vers=3", "tcp", "noatime", "soft", "rsize=8192", "wsize=8192"]
# ...
end
最初の設定と違い,かつ/Users
以下すべてを共有する設定になっているのは,この設定がboot2docker用だからです.
お察しください.
ちなみにVagrantのデフォルトmount_optionsは
https://github.com/mitchellh/vagrant/search?utf8=%E2%9C%93&q=mount_options&type=Code
から適当に追ってください
Vagrant up
これでvagrant up
をすれば,幾分普通に起動したときより早いはずです.
ベンチマーク
する方法がよく分からなくて困ってます.教えていただけると嬉しいです.
pythonサーバー建ててwrk
で計測したりしましたが,単純な書き込み速度テストじゃない気がします.
bonnie++
をDocker内で走らせてみましたが,なんか違う感じ.
本来はクライアントからnfsでマウントしてる/mnt
とかにbonnie++する気がするんですが,どこにあるか分からない.
体感
最初にも書きましたが,自分の環境では
Mac -> Vagrant -> boot2docker -> Docker
でnfsを効かせて接続しています.
すごいニッチですが,RubyMineでbundle install
した際にSSHでMac側にgemをsyncするんですが,それが爆速になりました.
あとは,Dockerでdocker pullも早くなってます.
yak shaving
もしかしたら,他のVagrantを起動しようとしたときに/etc/expors
のPermission errorが起きるかもしれない.
その場合,
mac$ sudo rm -rf /etc/exports
mac$ sudo touch /etc/exports
終わりに
次はMacのboot2dockerでnfs使って動作を早くする方法
その後にRubyMineを使ってDocker上でRails開発する方法と,chown問題を書きたいと思います.
参考
nfsd(8)
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man8/nfsd.8.html
nfs.conf(5)
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man5/nfs.conf.5.html
mount(8)
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man8/mount.8.html