使用 Vagrantfile 配置虚拟机


configuring-vagrant-virtual-machine

Vagrantflie

在项目的目录下面有个名为 Vagrantfile 的文件,它是执行 vagrant init 命令时创建的一个虚拟机配置文件,这个配置文件包含项目使用的虚拟机的相关配置。

Vagrantfile 文件里的内容大部分都是注释内容,里面介绍了可用的配置选项还有相关的解释。去掉注释内容,实际有效的代码只有三行:

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
end

中间一行代码就是配置的主体内容,上面的这行配置指定了虚拟机使用的 Box 是 centos/7,可以在这个代码块中添加其他自定义的配置:

Vagrant.configure("2") do |config|
  # 配置内容放在这里
end

虚拟机网络配置

把虚拟机作为一台服务器,就需要将主机(电脑)与虚拟机之间通过网络连接在一起,网络中的其他设备也可能要跟虚拟机相连,这就需要配置虚拟的网络,让虚拟机可以被访问。

可以通过 Vagrantfile 去配置虚拟机的网络,Vagrant 提供了以下三种方法:

  • 端口转发 forwarded_port
  • 公有网络 private_network
  • 私有网络 public_network

启动虚拟机后,虚拟机可以使用 nat 方式上网,即如果本机电脑能上网,虚拟机内部也可以上网。

在启动虚拟机返回的日志里,会有如下的相关配置:

==> 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: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)

上述配置意思是从主机使用 SSH 连接虚拟机的时候把主机(host)上的 2222 端口转发到虚拟机(guest)上的 22 端口。

可以通过 vagrant ssh 命令进入虚拟机内容,使用 ping 命令测试一下某个网站的连接。

端口转发 forwarded_port

端口转发就是设置主机与虚拟机之间端口的映射关系,也就是访问主机上的某个端口,把请求转发到虚拟机的某个端口上。

在 Vagrantfile 中的配置端口转发的代码为:

config.vm.network "forwarded_port", guest: 80, host: 8080

重启虚拟机,配置生效,在启动日志中会看到以下代码:

==> default: Forwarding ports...
    default: 80 (guest) => 8080 (host) (adapter 1)
    default: 22 (guest) => 2222 (host) (adapter 1)

安装 web 服务器

为了验证虚拟机的网络配置,需要在虚拟机安装一个 Web 服务器,这里以 NGINX 为例:

连接虚拟机 SSH:

vagrant ssh

安装 epel-release 软件仓库:

sudo yum install epel-release -y

安装 NGINX:

sudo yum install nginx -y

启动 NGINX 服务:

sudo systemctl start nginx

让 NGINX 开机启动:

sudo systemctl enable nginx

查看 NGINX 的运行状态:

sudo systemctl status nginx

如果返回的信息中包含以下语句,就表示 NGINX 已经成功安装并启动运行了。

Active: active (running)

验证端口转发配置

在浏览器中输入以下地址访问:

http://localhost:8080

如果你看到以下 NGINX 的欢迎页面,说明配置成功了!

nginx-start-page

私有网络 private_network

在主机与虚拟机之间创建一个私有网络,或者叫专有网络,通过这个网络主机与虚拟机之间可以相互连接。

在 Vagrantfile 中的配置私有网络的代码为:

config.vm.network "private_network", ip: "192.168.33.10"

重启虚拟机让配置生效,会发现在启动日志中多了个网卡:hostonly

default: Adapter 2: hostonly

通过 SSH 进行虚拟机,可以使用命令 ip addr 查看虚拟机的 IP 地址。

访问网址:http://192.168.33.10,如果配置成功的话,同样会看到一个 NGINX 的欢迎页面。

公有网络 public_network

配置虚拟机的公有类型的网络,可以让虚拟机与主机在同一个局域网内。公有网络的好处是,同一网络的其它的设备可以直接通过虚拟机在公有网络上的 IP 地址访问到这台虚拟机。配置了虚拟机的公有网络,创建这个网络的路由器会为你的虚拟机分配一个 IP 地址。

在 Vagrantfile 中的配置私有网络的代码为:

config.vm.network "public_network"

重启虚拟机让配置生效,启动过程中会让选择网卡,根据实际情况选择即可:

public-network-choose-interface

启动过程中会发现出现了第 3 个网卡:

default: Adapter 3: bridged

这就是配置了虚拟机的公有网络以后生成的。

连接 SSH,使用 ip addr 命令可以查看此时的 IP 地址,这个 IP 地址是根据路由设置自动分配的。

在浏览器中输入虚拟机的 IP 地址,可以验证公有网络是否配置成功。

虚拟机同步目录

为了使本地电脑与虚拟机间建立同步连接,需要为虚拟机配置同步目录, 即编辑本地同步目录中的文件内容,可以同时反馈到虚拟机同步目录中,反之亦然。Vagrant 虚拟机默认的同步目录是 /vagrant

默认情况下,这个共享目录是单向的(主机同步到虚拟机),并且不能实时同步,也就是只能在每次重启虚拟机的时候,才执行一次同步任务。

双向实时同步,要看虚拟机的镜像还有相关的同步目录配置。

禁用默认的同步目录

在配置文件 Vagrantfile 中,添加一行配置代码:

config.vm.synced_folder ".", "/vagrant", disabled: true

代码说明:
config.vm.synced_folder :配置同步目录
".":表示同步目录在当前主机下的位置,一个点表示当前目录,这是一个相对位置(相对的是 Vagrantfile 文件)
"/vagrant":同步目录在虚拟机上的位置
disabled: true:禁用这个同步目录

添加同步目录

在主机项目目录下创建一个名为 com 文件夹,添加同步目录的配置代码:

config.vm.synced_folder "./com", "/www"

这行代码的意思是让主机上项目目录下的 com 跟虚拟机上的 /www 进行同步。

同步目录的类型

  • Virtualbox 类型:Virtualbox 默认的同步类型,需要在虚拟机上安装 virtualbox guest addition。这种类型的同步目录性能低下,并且在 NGINX 环境下,还存在 BUG,不建议使用。
  • SMB 类型:Windows 使用的同步目录类型
  • NFS 类型:macOS 使用的同步目录类型(重点学习此类型,其他两种略过)

NFS 类型同步目录

NFS 类型同步目录配置代码:

config.vm.synced_folder "./com", "/www", type: "nfs"

加了一个 type 属性,值设置成了 nfs,表示这是一个 NFS 类型的共享目录。

重启虚拟机以让配置生效,在启动过程中,会提示输入电脑主机的用户密码。

启动完成后,连接虚拟机 SSH,如果配置成功的话,此时主机与虚拟机之间就可以实现实时的双向同步了。:)

定义多台虚拟机

使用 Vagrantfile 可以在本地项目定义多台虚拟机,每台虚拟机可以独立的配置,也可以单独控制某台虚拟机。

下这个配置定义了两台虚拟机,webdb,并分别为每台虚拟机配置了 IP 地址:

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"

  config.vm.define "web" do |web|
    web.vm.network "private_network", ip: "192.168.33.11"
  end

  config.vm.define "db" do |db|
    db.vm.network "private_network", ip: "192.168.33.12"
  end
end

在 Vagrantfile 里定义一台机器,就是一个代码块:

config.vm.define "web" do |web|
    web.vm.network "private_network", ip: "192.168.33.11"
end

如果你想在之前创建的 awesome-project 里测试多机配置,先把之前创建的虚拟机使用 vagrant destroy 销毁掉,然后添加新的多机配置,再去启动。

多台共用的配置可以放在定义虚拟机的代码块之外:

config.vm.box = "centos/7"

执行 vagrant up 可以同时启动所有的虚拟机,如果单独启动某台虚拟机,在 vagrant 命令最后加上机器的名字就行了:

vagrant reload web

#EOF