Vagrant CentOS 共享目录挂载问题解决

一直以来都是使用Vagrant与VirtualBox运行CentOS系统来搭建环境,然而有一天突然出现Windows下面的目录无法映射进去了,报错:

D:projectvagrantcentos64php56>vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Clearing any previously set forwarded ports...
==> 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: 80 (guest) => 8080 (host) (adapter 1)
  default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
  default: SSH address: 127.0.0.1:2222
  default: SSH username: vagrant
  default: SSH auth method: private key
  default: Warning: Connection reset. Retrying...
  default: Warning: Connection aborted. Retrying...
  default: Warning: Connection reset. Retrying...
  default: Warning: Remote connection disconnect. Retrying...
==> default: Machine booted and ready!
[default] GuestAdditions versions on your host (5.1.26) and guest (4.3.6) do not matc
Loaded plugins: fastestmirror
Setting up Install Process
Loading mirror speeds from cached hostfile
 * base: mirrors.btte.net
 * epel: repo.fedoralinux.ir
 * extras: mirrors.btte.net
 * updates: mirrors.btte.net
No package kernel-devel-2.6.32-358.23.2.el6.x86_64 available.
Package gcc-4.4.7-18.el6.x86_64 already installed and latest version
Package binutils-2.20.51.0.2-5.47.el6_9.1.x86_64 already installed and latest version
Package 1:make-3.81-23.el6.x86_64 already installed and latest version
Package 4:perl-5.10.1-144.el6.x86_64 already installed and latest version
Package bzip2-1.0.5-7.el6_0.x86_64 already installed and latest version
Nothing to do
Copy iso file C:Program FilesOracleVirtualBoxVBoxGuestAdditions.iso into the box
Installing Virtualbox Guest Additions 5.1.26 - guest version is 4.3.6
Verifying archive integrity... All good.
Uncompressing VirtualBox 5.1.26 Guest Additions for Linux...........
VirtualBox Guest Additions installer
Removing installed version 5.1.26 of VirtualBox Guest Additions...
vboxadd.sh: Stopping VirtualBox Additions.
Copying additional installer modules ...
Installing additional modules ...
vboxadd.sh: Starting the VirtualBox Guest Additions.
Failed to set up service vboxadd, please check the log file
/var/log/VBoxGuestAdditions.log for details.
An error occurred during installation of VirtualBox Guest Additions 5.1.26. Some func
In most cases it is OK that the "Window System drivers" installation failed.
vboxadd.sh: Starting the VirtualBox Guest Additions.
vboxadd.sh: failed: Look at /var/log/vboxadd-install.log to find out what went wrong.
vboxadd.sh: failed: modprobe vboxguest failed.
==> 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.6
  default: VirtualBox Version: 5.1
==> default: Configuring and enabling network interfaces...
  default: SSH address: 127.0.0.1:2222
  default: SSH username: vagrant
  default: SSH auth method: private key
==> default: Mounting shared folders...
  default: /home/rc => D:/project/vagrant/centos64php56
Vagrant was unable to mount VirtualBox shared folders. This is usually
because the filesystem "vboxsf" is not available. This filesystem is
made available via the VirtualBox Guest Additions and kernel module.
Please verify that these guest additions are properly installed in the
guest. This is not a bug in Vagrant and is usually caused by a faulty
Vagrant box. For context, the command attempted was:

mount -t vboxsf -o uid=500,gid=500 home_rc_ /home/rc

The error output from the command was:

/sbin/mount.vboxsf: mounting failed with the error: No such device

这里提示虚拟机里CentOS的VBoxGuestAdditions与VirtualBox的版本匹配,需要升级:

[default] GuestAdditions versions on your host (5.1.26) and guest (4.3.6) do not matc

应该是升级了VirtualBox导致的。然而自动安装新插件失败:

vboxadd.sh: Starting the VirtualBox Guest Additions.
Failed to set up service vboxadd, please check the log file
/var/log/VBoxGuestAdditions.log for details.
An error occurred during installation of VirtualBox Guest Additions 5.1.26. Some func
In most cases it is OK that the "Window System drivers" installation failed.
vboxadd.sh: Starting the VirtualBox Guest Additions.
vboxadd.sh: failed: Look at /var/log/vboxadd-install.log to find out what went wrong.
vboxadd.sh: failed: modprobe vboxguest failed.

导致共享目录无法映射。但是虚拟机仍然是启动成功的,可以ssh进去,或者使用sftp挂载。

Google了下有说是VirtualBox bug的,也有说是Windows问题的,各种折腾不能解决。升级插件也无效:vagrant plugin install vagrant-vbguest。重新安装VirtualBox和Vagrant,并不会影响现有虚拟机及网络配置,但不能解决问题。

直到看到这篇文章,决定从CentOS入手解决。

启动虚拟机后,使用sftp上传VBoxGuestAdditions.iso,ssh进入手动安装:

$ sudo
$ mount VBoxGuestAdditions.iso -o loop /mnt
$ cd /mnt
$ sh VBoxLinuxAdditions.run

安装失败,查看日志:

Building the main Guest Additions module                   [FAILED]
(Look at /var/log/vboxadd-install.log to find out what went wrong)

vboxadd-install.log日志:

/tmp/vbox.0/Makefile.include.header:97: *** Error: unable to find the sources of your current Linux kernel. Specify KERN_DIR=<directory> and run Make again.  Stop.

参照: https://www.centos.org/forums/viewtopic.php?t=45163 ,查看kernel版本

$ rpm -qa kernel* | sort
kernel-2.6.32-358.23.2.el6.x86_64
kernel-devel-2.6.32-696.10.2.el6.x86_64
kernel-firmware-2.6.32-358.10.2.el6.noarch
kernel-headers-2.6.32-696.10.2.el6.x86_64

$ uname -r
2.6.32-358.10.2.el6.x86_64

其实一开始是更多版本不匹配的,尝试更新kernel:

yum update
yum install kernel-headers kernel-devel

结果部分更新失败:

Warning: No matches found for: kernel-devel
No Matches found

参照: https://stackoverflow.com/questions/29396322/warning-no-matches-found-for-kernel-devel 解除版本锁定,设置enabled = 0:

$ vim /etc/yum/pluginconf.d/versionlock.conf

再次运行升级kernel就可以了。安装成功后,重启后,再次运行sh VBoxLinuxAdditions.run 就可以了。事实上Vagrant启动时就会自动安装VBoxGuestAdditions:

[default] GuestAdditions 5.1.26 running --- OK.

Vagrant升级到后发现vagrant up初始化下载box卡住了,那是你的vagrant版本太高与对应的powershell版本对应不上,可以下载最新的powershell安装即可。

如果box下载很慢,可以参照这里的方法自我映射取得url单独下载:

https://app.vagrantup.com/box-cutter/boxes/centos73
==> https://atlas.hashicorp.com/box-cutter/boxes/centos73/versions/2.0.21/providers/virtualbox.box

使用Vagrant和VirtualBox一步步地创建一个Base Box

Vagrant和VirtualBox软件的安装步骤省略,去官网下载最新的版本然后下一步下一步地安装就行了,和正常的安装软件没有什么区别。下面看看利用vagrant和virtualbox如果一步步打造出自己的可复用性强的开发环境。

开始前确保您的计算机支持虚拟化技术,在BIOS中可以开启。

一、在virtualbox中新建一个虚拟机

我这里使用的是CentOS-6.5-x86_64-minimal.iso这个镜像文件来安装的,1G内存,8G虚拟硬盘的配置(后面可以修改)。虚拟机名为centos。

安装好后该虚拟机已经自带了ssh服务,如果没有,需要自己先进行安装。

未分类

开启虚拟机,并登陆root用户。

二、配置虚拟机

创建admin用户组

[root@localhost ~]# groupadd admin

创建vagrant用户并添加到admin用户组

[root@localhost ~]# useradd -g admin vagrant

为vagrant用户设置密码,密码为vagrant(会提示密码太弱,可以不用管它)

[root@localhost ~]# passwd vagrant

修改sudoers文件

[root@localhost ~]# vi /etc/sudoers

在该文件添加下面两行代码,并注释掉requiretty行

Defaults env_keep="SSH_AUTH_SOCK"
%admin ALL=NOPASSWD: ALL

配置网卡:将ONBOOT=no 改为 ONBOOT=yes

[root@localhost ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
HWADDR=08:00:27:25:4A:9A
TYPE=Ethernet
UUID=751ae3bb-eb75-4f60-b5c3-7f1afa1dfce1
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=dhcp

配置好网卡后需要重启网络服务:

[root@localhost ~]# service network restart

三、设置端口转发

配置virtualbox端口转发(NAT模式)

未分类

主机ip127.0.0.1

主机端口22(或者其他未被占用端口,最好还是设置成22)

子系统ip可以在虚拟通过ifconfg命令查看到,即eth0网卡的ip地址

子系统端口为22

设置好端口转发规则之后,就能在本地的命令行工具(Xshell,putty..)里通过命令 ssh [email protected] 连接到该虚拟机。

四、添加vagrant公钥,使vagrant用户可以免密码ssh连接该虚拟机

在虚拟机里切换到vagrant用户

[root@localhost ~]# su vagrant
[vagrant@localhost root]$ cd ~
[vagrant@localhost ~]$

然后执行:

[vagrant@localhost ~]$ mkdir ~/.ssh/
[vagrant@localhost ~]$ cd ~/.ssh
[vagrant@localhost .ssh]$ sudo yum -y install wget
[vagrant@localhost .ssh]$ wget http://github.com/mitchellh/vagrant/raw/master/keys/vagrant
[vagrant@localhost .ssh]$ wget http://github.com/mitchellh/vagrant/raw/master/keys/vagrant
[vagrant@localhost .ssh]$ mv vagrant.pub authorized_keys

清理缓存

[vagrant@localhost .ssh]$ sudo yum clean all

然后关闭此虚拟机,通过virtualbox将其电源关闭

五、打包生成box文件

在本地命令行进入该虚拟机目录

cd UsersAdminVirtualBox VMscentos

进行打包

vagrant package --output mycentos.box --base centos

未分类

完成之后你将会在C:UsersAdminVirtualBox VMscentos目录下看到一个mycentos.box文件,我的这个文件有544M。

VirtualBox VMs这个目录可以在virtualbox全局设定-常规里进行修改

到此一个Base Box就制作完成了。

这个box是很干净的,然后可以在这个box的基础上去搭建自己的开发环境,比如lnmp等等。再次进行打包,最后一个带开发环境的box就做好了,可以自己用也可以分发给其他小伙伴使用,不用以后每次都要去搭建一遍环境。

六、附上vagrant常用操作命令

vagrant box list 查看在vagrant里已经安装了哪些box

vagrant box add name boxname.box 添加一个本地的box镜像到vagrant 这个box镜像可以自己制作也可以使用网上的(vagrant box add ubuntu ubuntu/trusty64)

vagrant init name 初始化一个虚拟机,这个name是通过vagrant box list查看

vagrant up 启动虚拟机 在virtualbox中可以看到启动后的虚拟机,第一次启动时时间会长一点

vagrant ssh 连接虚拟机

vagrant reload 重启虚拟机

vagrant status 查看虚拟机当前状态

七、常见问题处理

问题1:

default: in which case you may ignore this message.
==> default: Mounting shared folders...
default: /vagrant => E:/vagrantbox/centos67
Vagrant was unable to mount VirtualBox shared folders. This is usually
because the filesystem "vboxsf" is not available. This filesystem is
made available via the VirtualBox Guest Additions and kernel module.
Please verify that these guest additions are properly installed in the
guest. This is not a bug in Vagrant and is usually caused by a faulty
Vagrant box. For context, the command attempted was:

mount -t vboxsf -o uid=500,gid=500 vagrant /vagrant

The error output from the command was:

mount: unknown filesystem type 'vboxsf'

上面这样的问题可以执行下命令 vagrant plugin install vagrant-vbguest ,然后重启vagrant reload来解决。

问题2:

vagrant up的时候出现 “rsync” could not be found on your PATH. Make sure that rsync is properly installed on your system and available on the PATH. 出现这样的错误

找到C:Usersadmin.vagrant.dboxescentos7virtualbox类似这样的目录下面的Vagrantfile文件

修改type配置项: config.vm.synced_folder “.”, “/vagrant”, type: “virtualbox”

使用Vagrant进行LVS/DR的实验

未分类

LVS/DR模式,数据流来的时候走VS,回去的时候调度到RS上,然后用VIP的作为源地址返回回去。

实验采用Vagrant配置网络和主机信息。Vagrant的用法可参考 Vagrant–快速搭建实验环境利器(http://www.yulongjun.com/linux/20170811-vagrant/)。

Vagrantfile配置文件:

Vagrant.configure("2") do |config|
  # config为全局配置文件
  config.vm.box = "longdream/centos7"     # 这里是我自定义的centos7模板
  config.hostmanager.enabled = true       # 启用hostmanager插件
  config.hostmanager.manage_guest = true  # 允许更新虚拟机上的hosts文件
  config.hostmanager.manage_host = true   # 允许更新主机上的hosts文件
  # 定义Client
  config.vm.define "client" do |client|
    client.vm.network "private_network", ip: "172.16.111.123"
    client.vm.hostname = "client"
    client.vm.provision "shell", inline: "sudo bash /vagrant/client.sh"
  end
  # 定义Router
  config.vm.define "router" do |router|
    router.vm.network "private_network", ip: "172.16.111.222"
    router.vm.network "private_network", ip: "192.168.111.222"
    router.vm.hostname = "router"
    router.vm.provision "shell", inline: "sudo bash /vagrant/router.sh"
  end
  # 定义VS
  config.vm.define "vs" do |vs|
    vs.vm.network "private_network", ip: "192.168.111.100"
    vs.vm.hostname = "vs"
    vs.vm.provision "shell", inline: "sudo bash /vagrant/vs.sh"
  end
  # 定义RS1
  config.vm.define "rs1" do |rs1|
    rs1.vm.network "private_network", ip: "192.168.111.101"
    rs1.vm.hostname = "rs1"
    rs1.vm.provision "shell", inline: "sudo bash /vagrant/rs1.sh"
  end
  # 定义RS2
  config.vm.define "rs2" do |rs2|
    rs2.vm.network "private_network", ip: "192.168.111.102"
    rs2.vm.hostname = "rs2"
    rs2.vm.provision "shell", inline: "sudo bash /vagrant/rs2.sh"
  end
end

Vagrantfile里每一台机器都运行了相应的脚本。

Client:

client.sh

#!/bin/bash
echo "GATEWAY=172.16.111.222" >> /etc/sysconfig/network-scripts/ifcfg-eth1
ifdown eth1 && ifup eth1

Router:

router.sh

#!/bin/bash
echo "net.ipv4.ip_forward=1" >>/etc/sysctl.conf
echo 1 > /proc/sys/net/ipv4/ip_forward

VS:

vs.sh

#!/bin/bash
echo "GATEWAY=192.168.111.222" >> /etc/sysconfig/network-scripts/ifcfg-eth1
ifdown eth1 && ifup eth1
yum install -y ipvsadm
bash /vagrant/vs-dr-wlc.sh start

vs.sh引用的vs-dr-wlc.sh来启动VS。

vs-dr-wlc.sh:

#!/bin/bash
vip=192.168.111.200
mode=g  # m为NAT模式,g为DR模式,i为tun模式
schdule=wlc
rip1=192.168.111.101
rip2=192.168.111.102
dev=lo:1
case $1 in
start)
    ifconfig $dev $vip netmask 255.255.255.255 broadcast $vip up
    ipvsadm -A -t $vip:80 -s $schdule
    ipvsadm -a -t $vip:80 -r $rip1 -$mode -w 3
    ipvsadm -a -t $vip:80 -r $rip2 -$mode -w 1
    ;;
stop)
    ipvsadm -C
    ifconfig $dev down
    ;;
*)
    echo "Usage: `basename $0` start|stop"
    exit 1
    ;;
esac

RS1

rs1.sh:

#!/bin/bash
echo "GATEWAY=192.168.111.222" >> /etc/sysconfig/network-scripts/ifcfg-eth1
ifdown eth1 && ifup eth1
yum install -y httpd
cat >/var/www/html/index.html<<EOF
Real Server 1
EOF
systemctl enable httpd
systemctl start httpd
bash /vagrant/rs-config.sh start

RS2

rs2.sh:

#!/bin/bash
echo "GATEWAY=192.168.111.222" >> /etc/sysconfig/network-scripts/ifcfg-eth1
ifdown eth1 && ifup eth1
yum install -y httpd
cat >/var/www/html/index.html<<EOF
Real Server 2
EOF
systemctl enable httpd
systemctl start httpd
bash /vagrant/rs-config.sh start

两个RS都调用的一个脚本

rs-config.sh

#!/bin/bash
vip=192.168.111.200
dev=lo:1
case $1 in
start)
    echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
    echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
    echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
    ifconfig $dev $vip netmask 255.255.255.255 broadcast $vip up
    echo "VS Server is Ready!"
    ;;
stop)
    ifconfig $dev down
    echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
    echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
    echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
    echo "VS Server is Cancel!"
    ;;
*)
    echo "Usage `basename $0` start|stop"
    exit 1
    ;;
esac

vagrant up启动所有机器后,在Virtualbox里关掉所有虚机的eth0(vagrant创建虚机时候,默认的一个NAT网络,默认在eth0上,关闭它以防止对实验造成影响):

ifdown eth0

然后从Client虚机里运行:

bash /vagrant/client-test.sh进行测试:

#!/bin.bash
# 测试LVS
vip=192.168.111.200
for i in `seq 100`;do
    curl --connect-timeout 1 $vip
    sleep 1
done