這個章節脫胎於我早期的blog文章,訂正了一下句法和準確性。html
原始的文字在 VAGRANT 網絡配置node
整個Vagrant系列,已經有四篇文章了:nginx
Vagrant能夠指定三種網絡:端口轉發(Forwarded Ports),私有網絡(Private Network),公有網絡(Public Network)。他們和多數虛擬機提供的網絡是對應的。shell
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的橋接網絡模式。
對於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。
sample-nginx
vagrant init ubuntu/xenial64
進行初始化Vagrantfile
加入必要的聲明 (見後)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
中。
有時候,可能遇到網絡配置失敗的狀況。例如:
$ 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 # 而後從新啓動虛擬機,網絡配置會再次被應用,而且應該會一切正常了
複製代碼