Vagrant (三) - 网络配置

这个章节脱胎于我早期的blog文章,订正了一下句法和准确性。html

原始的文字在 VAGRANT 网络配置node

整个Vagrant系列,已经有四篇文章了:nginx

  1. Vagrant (一) - 基本知识
  2. Vagrant (二) - 平常操做
  3. Vagrant (三) - 网络配置
  4. Vagrant (四) - Box的用法

网络配置

Vagrant能够指定三种网络:端口转发(Forwarded Ports),私有网络(Private Network),公有网络(Public Network)。他们和多数虚拟机提供的网络是对应的。shell

Vagrant 网络模型

端口转发:

config.vm.network :forwarded_port, guest: 80, host: 8080
复制代码

将虚拟机(被称做guest)的端口80映射为宿主机的端口8080。ubuntu

端口转发隐含着一个provider的NAT网络将被首先建立。 因此,若是你单独定义一条端口转发的配置语句的话,VM将会自动创建NAT网络环境。ruby

私有网络:

config.vm.network :private_network, ip: "192.168.1.104"
复制代码

你能够从宿主机自由访问虚拟机,但LAN网络中的其余人不须要也没法访问虚拟机。bash

值得注意的是,ip地址“192.168.1.104”不是随便指定的。 首先你能够不指定,这表示虚机启动时会DHCP到一个可用的IP地址(例如:192.168.33.101),这是vagrant经过virtualbox私有网络的DHCP机制得到的。 若是你要自行指定明确的IP地址,要保证该地址是在恰当的网段中,例如192.168.33.71。网络

多台虚拟机在私有网络模式下也能够互相访问,只要设置为相同的网段就能够。app

本质上说,这是使用provider的HostOnly模式。less

公有网络:

公有网络其实是表示将虚拟机暴露为LAN(例如你的宿主机所在的办公室网络)中的一台主机。

例如使用LAN的DHCP自动得到IP地址:

config.vm.network :public_network
复制代码

也能够指定LAN网段中的一个可用的地址,但须要注意不要和LAN中已有的主机或者保留的IP地址相冲突。

本质上说,这是使用provider的桥接网络模式。

Provider的网络模式

对于vagrant的provider,例如VirtualBox来讲,网络模式区分的更细,但vagrant并不能使用所有vbox网络模型。

VirtualBox 的典型网络模型:NAT,Hostonly,Bridge以及Internal。

这些模式的细节咱们再也不列举。

借用一张表格来概括:

NAT Bridged Internal Hostonly
vm -> host × ×
host -> vm × × ×
vm -> others hosts × ×
others hosts => vm × × ×
vm <-> vm × same subnet

这张表格描述了virtualbox的网络模型。

实用的网络配置

通常来讲,端口转发足以知足开发须要了。

但对于特殊的须要来讲,你可能须要一台彻底“真实”的虚机,这台虚机能够被稳定地从宿主机访问,而且能够访问LAN中的其余资源。这样的需求实际上能够经过配置多块网卡来解决问题,例如一块配置为私有网络模式,一块配置为公有网络模式。

vagrant经过配置文件可以支持virtualbox的NAT,Bridge以及Hostonly网络模型。

默认状况

默认状况下,咱们已经知道一个最简的流程来启动vagrant:

mkdir /dev
    cd /dev
    vagrant box add ubuntu/trusty64
    vagrant init ubuntu/trusty64
    vagrant up
    vagrant ssh
    vagrant halt
复制代码

这样的步骤,能够获得一台ubuntu 14.04的虚拟机,采用Provider的NAT网络模式,在虚拟机中能够访问宿主机,也可使用宿主机的外网路由上网。

观察它生成的默认的Vagranfile,其网络配置是未指定的。

此时,vagrant创建的vm具备一个NAT网卡。

桥接网络

当采用以下配置语句时,vagrant创建的vm具备一个Bridged网络:

# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
config.vm.network "public_network"
复制代码

此时,vm在宿主机所在的LAN中等价于一台物理机器。假如你具备LAN Router的管理权的话,这是很简单的一种开发模型:经过路由器的mac绑定为vm保留一个固定的dhcp地址,这样vm不管什么时候启动都会获取到相同的IP地址,你的开发和调试将会很顺利很简单。

私有网络

当采用以下配置语句时,vagrant创建的vm具备两个hostonly网络:

config.vm.network "private_network", ip: "192.168.9.10"
config.vm.network "private_network", ip: "192.168.33.10"
复制代码

标识符“private_network”老是被映射为virtualbox的hostonly模型。

私有网络模型是容许宿主机访问的,为了便于宿主机访问,咱们也能够明确指定一个适当网段的地址。要知道适当的网段是多少,能够这样查证:

  • 经过进入虚机显示网卡信息和IP地址来了解网段。
  • 打开 VirtualBox 的网络配置,检查HostOnly网络的DHCP网段。

混合网络

当采用以下配置语句时,vagrant创建的vm具备一个NAT和一个hostonly网络:

config.vm.network "private_network", ip: "192.168.33.10"
复制代码

标识符“private_network”老是被映射为virtualbox的hostonly模型。

注意 NAT 网络将被隐含地建立。 vagrant在建立网卡时,若是配置文件仅配置了一个private_network,则vagrant自动建立NAT网卡,而后在建立配置文件所描述的网络;而若是配置文件指定了两个以上的private_network的话,vagrant再也不自动建立 NAT 网卡了。

混合网络很是适合开发和测试环境,你能够经过NAT和Internet相通,而后多个vm之间也能相互通讯。

内外网络

内外网络 只是我随便命名的,也就是从vm的角度出发既有内网(VM的私有网络),又有外网(宿主机所在的局域网)。

当采用以下配置语句时,vagrant创建的vm具备一个bridged和一个hostonly网络:

config.vm.network "public_network"
config.vm.network "private_network", ip: "192.168.33.10"
复制代码

这是比较通用的配置模式,vm既有host主机所在局域网的ip,又有一个私有网络的ip地址,所以这些vm之间具备全连通性。

不过,通常来讲开发和测试使用较为封闭的网络模型是比较好的方式,一般不建议vm配置有 public_network 的网卡。

小结

任何

config.vm.network "private_network", ip: "192.168.33.10"
复制代码

语句均可以改成:

config.vm.network "private_network", type: "dhcp"
复制代码

这时virtualbox的网关负责dhcp应答和分配IP。

实例

nginx服务

  1. 创建一个新的工做目录 sample-nginx
  2. 使用 vagrant init ubuntu/xenial64 进行初始化
  3. 修改 Vagrantfile 加入必要的声明 (见后)
  4. 使用 vagrant up 启动该虚拟机,而后能够SSH进入或者 curl -i http://localhost:8080/ 来尝试访问它

完整的 Vagrantfile 以下:

# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
  # The most common configuration options are documented and commented below.
  # For a complete reference, please see the online documentation at
  # https://docs.vagrantup.com.

  # Every Vagrant development environment requires a box. You can search for
  # boxes at https://vagrantcloud.com/search.
  config.vm.box = "ubuntu/xenial64"
  
  # Disable automatic box update checking. If you disable this, then
  # boxes will only be checked for updates when the user runs
  # `vagrant box outdated`. This is not recommended.
  # config.vm.box_check_update = false

  # Create a forwarded port mapping which allows access to a specific port
  # within the machine from a port on the host machine. In the example below,
  # accessing "localhost:8080" will access port 80 on the guest machine.
  # NOTE: This will enable public access to the opened port
  config.vm.network "forwarded_port", guest: 80, host: 8080

  # Create a forwarded port mapping which allows access to a specific port
  # within the machine from a port on the host machine and only allow access
  # via 127.0.0.1 to disable public access
  # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"

  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
  # config.vm.network "private_network", ip: "192.168.33.10"

  # Create a public network, which generally matched to bridged network.
  # Bridged networks make the machine appear as another physical device on
  # your network.
  # config.vm.network "public_network"

  # Share an additional folder to the guest VM. The first argument is
  # the path on the host to the actual folder. The second argument is
  # the path on the guest to mount the folder. And the optional third
  # argument is a set of non-required options.
  # config.vm.synced_folder "../data", "/vagrant_data"

  # Provider-specific configuration so you can fine-tune various
  # backing providers for Vagrant. These expose provider-specific options.
  # Example for VirtualBox:
  #
  # config.vm.provider "virtualbox" do |vb|
  # # Display the VirtualBox GUI when booting the machine
  # vb.gui = true
  #
  # # Customize the amount of memory on the VM:
  # vb.memory = "1024"
  # end
  #
  # View the documentation for the provider you are using for more
  # information on available options.

  # Enable provisioning with a shell script. Additional provisioners such as
  # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
  # documentation for more information about their specific syntax and use.
  config.vm.provision "shell", inline: <<-SHELL apt-get update apt-get install -y nginx SHELL
end
复制代码

这是一个至关简单的实例。更复杂的初始化,能够考虑使用一个独立的脚本文件来完成,而不是直接放在 Vagrantfile 中。

Updates

有时候,可能遇到网络配置失败的状况。例如:

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'ubuntu/bionic64'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'ubuntu/bionic64' is up to date...
==> default: Setting the name of the VM: setup_bionic_default_1511875921207_73707
==> 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 (guest) => 2222 (host) (adapter 1)
==> default: Running 'pre-boot' VM customizations...
==> 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: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: 
    default: Vagrant insecure key detected. Vagrant will automatically replace
    default: this with a newly generated keypair for better security.
    default: 
    default: Inserting generated public key within guest...
    default: Removing insecure key from the guest if it's present... default: Key inserted! Disconnecting and reconnecting using new SSH key... ==> 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: 5.1.28_Ubuntu r117968 default: VirtualBox Version: 5.2 ==> default: Configuring and enabling network interfaces... The following SSH command responded with a non-zero exit status. Vagrant assumes that this means the command failed! /sbin/ifdown 'enp0s8' || true /sbin/ip addr flush dev 'enp0s8' # Remove any previous network modifications from the interfaces file sed -e '/^#VAGRANT-BEGIN/,$ d' /etc/network/interfaces > /tmp/vagrant-network-interfaces.pre
sed -ne '/^#VAGRANT-END/,$ p' /etc/network/interfaces | tac | sed -e '/^#VAGRANT-END/,$ d' | tac > /tmp/vagrant-network-interfaces.post

cat \
  /tmp/vagrant-network-interfaces.pre \
  /tmp/vagrant-network-entry \
  /tmp/vagrant-network-interfaces.post \
  > /etc/network/interfaces

rm -f /tmp/vagrant-network-interfaces.pre
rm -f /tmp/vagrant-network-entry
rm -f /tmp/vagrant-network-interfaces.post

/sbin/ifup 'enp0s8'

Stdout from the command:



Stderr from the command:

bash: line 4: /sbin/ifdown: No such file or directory
sed: can't read /etc/network/interfaces: No such file or directory sed: can't read /etc/network/interfaces: No such file or directory
bash: line 20: /sbin/ifup: No such file or directory
复制代码

这是因为 vagrant 使用 ifupdown 软件包来管理虚拟机的网络配置问题,然而某些新版本的操做系统,例如 Ubuntu 18+ 已经放弃了 ifupdown,于是 vagrant 脚本会失败。

解决的办法是两次启动虚拟机,而且在其间自行安装 ifupdown:

$ vagrant up   # 启动虚拟机,会报错网络配置不成功
$ vagrant ssh  # 不理睬错误直接登陆到虚拟机中
ubuntu@node1$ sudo apt install ifupdown; exit
$ vagrant halt # 关闭虚拟机
$ vargant up && vagrant ssh # 而后从新启动虚拟机,网络配置会再次被应用,而且应该会一切正常了
复制代码

References

相关文章
相关标签/搜索