让Vagrant在Windwos下支持使用NFS/SMB共享文件夹从而解决目录共享IO缓慢的问题

自己的本是mbp vagrant使用nfs共享文件夹,所以使用一切ok,但是公司的开发环境是windows10。
windows下是有些问题的,就是在windows下默认的虚拟机共享文件夹的方式,磁盘IO效率实在是太低了。
表现情况,vagrant ssh 在/vagrant/project 下敲命令都卡啊卡,表现的和连接美国vps一样!
执行php程序,从调试来看,花费在文件IO上的时间实在是有点长,能达到1-3秒
vagrant在windows共享文件夹实在是太慢了,亏我忍受那么久。
一直在忍啊忍啊,今天实在是受不了,想要解决掉这个问题,想办法让windows支持NFS或者samb的方式共享文件夹给vagrant虚拟机
如果能支持NFS就当然是最好。
找到vagrant-winnfsd这个vagrant的插件
发现新版也支持Windows下SMB的方式了

NFS方式使用vagrant-winnfsd

安装vagrant 插件 vagrant-winnfsd

$ vagrant plugin install vagrant-winnfsd
但是这样安装会出现以下错误

Installing the 'vagrant-winnfsd' plugin. This can take a few minutes...
Bundler, the underlying system Vagrant uses to install plugins,
reported an error. The error is shown below. These errors are usually
caused by misconfigured plugin installations or transient network
issues. The error from Bundler is:

An error occurred while installing childprocess (0.5.8), and Bundler cannot continue.
Make sure that `gem install childprocess -v '0.5.8'` succeeds before bundling.

Warning: this Gemfile contains multiple primary sources. Using `source` more than once without a block is a security risk, and may result in installing unexpected gems. To resolve this warning, use a block to indicate which gems should come from the secondary source. To upgrade this warning to an error, run `bundle config disable_multisource true`.Gem::RemoteFetcher::FetchError: Errno::ECONNABORTED: An established connection was aborted by the software in your host machine. - SSL_connect (https://rubygems.org/gems/childprocess-0.5.8.gem)

看来是缺少childprocess-0.5.8.gem这个东西
索性把需要的包都下载到本地,然后本地安装
https://rubygems.org/gems/childprocess-0.5.8.gem
https://rubygems.org/gems/vagrant-winnfsd-1.1.0.gem
然后

vagrant plugin install childprocess-0.5.8.gem
vagrant plugin install vagrant-winnfsd-1.1.0.gem

看一看安装好的插件

$ vagrant plugin list
childprocess (0.5.8)
  - Version Constraint: 0.5.8
vagrant-share (1.1.4, system)
vagrant-winnfsd (1.1.0)
  - Version Constraint: 1.1.0

配置

编辑项目下的Vagrantfile文件
网络设置为私有,仅宿主机

config.vm.network "private_network", ip: "192.168.33.10"
# config.vm.network "private_network", type: "dhcp"

在Vagrant.configure(‘2’) do |config| 中加入

Vagrant.configure('2') do |config|
  # other config here
  config.vm.network "private_network", ip: "192.168.33.10"

  #winfsd
  config.winnfsd.logging = "on"
  config.winnfsd.uid = 1
  config.winnfsd.gid = 1
  config.vm.synced_folder "./", "/vagrant", type: "nfs"
end

SMB方式Windows共享方式

配置

Vagrant.configure('2') do |config|
  # other config here
  config.vm.network "private_network", ip: "192.168.33.10"

  #SMB
  config.vm.synced_folder "./", "/vagrant", type: "smb",
      smb_username: "母鸡Windows帐号",
      smb_password: "母鸡Windows密码",
      owner: "www",
      group: "www"
      #mount_options: ["dmode=775,fmode=664"]
end

启动vagrant虚拟机, 注意启动过程当中需要输入windwos系统的帐号和密码

d:\projects>vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Fixed port collision for 22 => 2222. Now on port 2200.
==> default: Preparing SMB shared folders...
    default: You will be asked for the username and password to use for the SMB
    default: folders shortly. Please use the proper username/password of your
    default: Windows account.
    default:
    default: Username: administrator
    default: Password (will be hidden):
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 22 => 2200 (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2200
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Connection timeout. Retrying...
    default: Warning: Connection timeout. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
    default: The guest additions on this VM do not match the installed version of
    default: VirtualBox! In most cases this is fine, but in rare cases it can
    default: prevent things such as shared folders from working properly. If you see
    default: shared folder errors, please make sure the guest additions within the
    default: virtual machine match the version of VirtualBox you have installed on
    default: your host and reload your VM.
    default:
    default: Guest Additions Version: 4.3.26
    default: VirtualBox Version: 5.0
==> default: Configuring and enabling network interfaces...
==> default: Mounting SMB shared folders...
    default: D:/projects => /vagrant
==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision`
==> default: flag to force provisioning. Provisioners marked to run always will still run.

d:\projects>

发现vagrant开启了一个名称为c30268623ba3dedeaa9f098b570dca21的共享
这个地方有个安全大坑,共享权限居然是Everyone!所以注意母鸡Windows上是否有其他帐号能访问!
我把c30268623ba3dedeaa9f098b570dca21本共享的权限改了,发现vagrant还是会把权限设置为Everyone
如果有开启其他普通帐号,guest什么的这里有安全隐患

C:\Users\Administrator>net share

共享名       资源                            注解

-------------------------------------------------------------------------------
IPC$                                         远程 IPC
c30268623ba3dedeaa9f098b570dca21
             D:\projects
命令成功完成。

为了防止smb共享剔除不活动的连接需要执行以下命令让系统不要自动踢掉不活动的连接
net config server /autodisconnect:-1

vagrant不会自动删除共享,要删除共享使用命令
net share c30268623ba3dedeaa9f098b570dca21 /delete

参考资料

vagrant-winnfsd项目源码
开启 NFS 文件系统提升 Vagrant 共享目录的性能
NFS for Vagrant on Windows
Vagrant SYNCED FOLDERS
Vagrant 使用 samba 共享文件夹