虚拟机之虚拟网络

概述

之前写过关于 Linux 虚拟网卡设备相关的文章,对通过使用 Linux 内核模拟网络设备有了一个比较清晰的认识,该篇是描述虚拟机如何构建虚拟网络环境,如何模拟真实的网络环境;本文是基于 Oracle 的 Virtual Box 来进行描述;

如图,从 Virtual Box 的《User Manual》中可以看到,虚拟机连接宿主机网络主要有 NAT、Bridge、Internal 以及 Host-only 四种方式。下面,就这四种虚拟网络的方式进行一一的描述。

NAT

原理

虚拟机构建了一个虚拟路由器,连接宿主机的网络,凡是从虚拟机发出经过该路由器的 IP 包,均需要通过 NAT 将源地址修改为宿主机的 IP 地址,再通过宿主机的物理网卡将该数据包发送给网关;

如图,virtualbox 模拟了一个虚拟路由器,LAN 口 IP 是 10.0.2.2,WAN 口比较特殊,它直连宿主机的物理网卡 en0,也就是说,可以直接将 en0 看做是该虚拟路由器的 WAN 口。那么数据从虚拟机经过路由器发送到宿主机的过程中,需要通过路由的 NAT 功能,将源 IP 地址从 10.0.2.15 更改成路由器的 WAN 口地址 192.168.202.126;那么数据是如何进行反馈的?VETH-设备中进行过比较详细的描述。

配置

配置比较简单,直接设置为 NAT 即可

注意

NAT 模式只是保证虚拟机可以访问外网,但宿主机无法直接访问宿主机的;因为宿主机的内网 IP 和宿主机的 IP 是隔断的。这个时候,可以借助Host-only来访问。

Bridge

原理

通过 Bridge 桥接虚拟机网卡接口与宿主机的物理网卡接口,打通虚拟机与宿主机的网络链接通路;唯一需要注意的是,因为是模拟通过交换机桥接,所以被桥接的虚拟机网卡接口和宿主机的网卡接口的 IP 地址必须在同一个网段内。

其原理如图所示,

虚拟机 Bridge 相当于一个二层交换机,连接虚拟机虚拟网卡enp0s3和宿主机物理网卡en0,所以数据包可以从enp0s3发出到达en0;注意,该 Bridge 与 Linux Virtual Bridge 不同,Linux Virtual Bridge 是通过 Linux 内核虚拟的,拥有自己的特性,比如,可以设置 IP、屏蔽掉桥接的网卡等,具体参看linux virtual bridge;虚拟机 Bridge 就相当于一个二层交换机,不能设置 IP 也不会屏蔽掉桥接的网卡,更接近与真实的二层交换机,并且虚拟机是在硬件层面进行虚拟化的,所以两者的实现方式也是不同的;且虚拟机网卡的 mac 地址与宿主机物理网卡的 mac 地址不同。

注意

在使用桥接的时候,虚拟机的 IP 地址是通过 DHCP 获取的与主机在同一个网段的 IP 地址,所以,务必保证局域网中有可用的 IP 地址,否则,在初始化虚拟机的时候,会因为没有可用的 IP 而报错。

混乱模式

修改 mac 地址

virtualbox《User Mannual》中提到,因为大多数无线网卡不支持 promiscuous mode,所以,当数据包从虚拟机到达宿主机之前,需要将数据包中的 mac 地址修改为宿主机的 mac 地址;这样做的目的是,在网卡不支持混乱模式的情况下,能够让宿主机收到目的地址为虚拟机 mac 地址数据包,具体参考promiscuous mode;当宿主机收到远程主机反馈给虚拟机的数据包以后,vritual box 应用程序会判断数据包的目的 IP 地址,如果该 IP 地址是虚拟机所对应的 IP 地址,便会将 IP 包中的 MAC 地址修改为目标虚拟机网卡接口对应的 MAC 地址,并将 IP 包发送给对应的虚拟机的网卡接口。

promiscuous mode

这个是网卡接口的一种模式,简称混乱模式;正常情况下,网卡在收到数据包以后,会判断数据包中的 MAC 地址,如果数据包中的 MAC 地址与之不匹配,便会丢弃,注意,网卡只会判断 MAC 地址是否匹配;但是如果开启了混乱模式,网卡接口便无论匹配或者不匹配都会接收该数据包。


那为什么说,虚拟机 Bridge 模式需要网卡的这种“混乱模式”?因为虚拟机网卡的 MAC 地址与宿主机的 MAC 地址不同,设宿主机物理网卡地址为 mac_1 / ip_1,虚拟机网卡地址为 mac_2 / ip_2,数据包都是从宿主机的物理网卡中发出和接收,当宿主机物理网卡接收发送给虚拟机的数据包以后,发现其目标 MAC 地址 mac_2 与自身 mac_1 不符,便会丢弃,所以导致虚拟机无法接收数据;将其大致描绘一下该过程如下,

  1. 首先,物理交换机会维护这样一个对应关系,ip_1 - mac_1 和 ip_2 - mac_2 -> 某一个交换机 LAN A 口,该口接入的既是该宿主机。
  2. 反馈给虚拟机的数据包的目标地址 ip_2 - mac_2,需要经过物理交换机 LAN A 口
  3. 数据包到达宿主机的物理网卡,这个时候,如果该网卡不是混乱模式,那么会将 ip_2 - mac_2 的数据包丢弃,因为目标地址 mac_2 与宿主机 mac 地址不匹配,那么虚拟机就不能收到该数据包;但如果是混乱模式,那么虚拟机就可以收到该数据包;

这也是为什么,在大多数无线网卡不支持 promiscuous mode 的前提下,virtual box 采取更改 mac 地址的方式来接收数据包;

在网卡不支持混乱模式的前提下,虚拟机将 mac 地址改变后传输,那么交换机便只会维护 ip_1 - mac_1 和 ip_2 - mac_1 与 LAN A 口的映射关系(两个 mac 地址相同),那么发送给虚拟机 ip_2 的数据包便不会被宿主机网卡所丢弃,因为 ip_2 的数据包的源 mac 地址 mac_1 与宿主机匹配;

配置

宿主机上的物理网卡接口是en0,当前的 IP 是 192.168.202.126

1
2
3
4
5
6
7
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 3c:15:c2:dd:9c:da
inet6 fe80::44b:ad90:7a46:df63%en0 prefixlen 64 secured scopeid 0x4
inet 192.168.202.126 netmask 0xffffff00 broadcast 192.168.202.255
nd6 options=201<PERFORMNUD,DAD>
media: autoselect
status: active

VirtualBox 虚拟机设置,桥接宿主机物理网卡 en0

如图,通过交换机生成的网卡接口 enp0s3,IP 地址 192.168.202.173

从宿主机登录虚拟机成功,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
bogon:comedsh.github.io mac$ ssh 192.168.202.173
The authenticity of host '192.168.202.173 (192.168.202.173)' can't be established.
ECDSA key fingerprint is SHA256:3cek5walC5XUI0lJsW+RAZKBK0lHqFLmno9TeMg9Ais.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.202.173' (ECDSA) to the list of known hosts.
mac@192.168.202.173's password:
Welcome to Ubuntu 16.10 (GNU/Linux 4.8.0-30-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

68 packages can be updated.
37 updates are security updates.


Last login: Sat Jan 7 15:26:40 2017
mac@ubuntu:~$

Internal

Host-only

原理

其原理与 linux VETH pair 虚拟设备类似,虚拟机中的 veth 设备可以与宿主机中的 veth 设备进行通讯;两者的区别在于,linux VETH pair 是一对一的关系,而 Host-only 是一对多的关系;

如图,两个虚拟机中的 enp0s3 网卡接口都与 vboxnet0 成为 veth pair 的关系,从宿主机中可以通过网卡接口 vboxnet0 分别于两个虚拟主机的 enp0s3 网卡接口进行通讯,反之亦然;所以 vboxnet0 与多个虚拟机的网卡接口之间是一对多的关系;相关特点描述如下,

  1. vboxnet0 与 宿主机的物理网卡是不通的,也就是说,Host-only 模式只能使虚拟机和宿主机之间的通讯,虚拟机不能连接外网,也不能被外网访问。
  2. 虚拟机之间是可以互访的;如图,virtualbox 1 和 virtualbox 2 是可以互相访问的。

配置

参考设置 host-only 模式

设计与使用

在《User Mannual》中解释得比较清楚,如果我们有一个应用分为两个模块 web 和 database,在一个宿主机上通过两个虚拟机分别部署这两个 web 和 database 模块,我们简称为 web 虚拟机和 database 虚拟机;我们的设计目标是,database 虚拟机不能通过外网访问,但是可以通过宿主机访问便于维护,同时可以被 web 虚拟机访问;web 虚拟机可以通过外网访问;

  1. database 虚拟机设计
    使用 Host-only 模式即可;
  2. web 虚拟机设计
    使用 Host-only 模式,这样,web 虚拟机可以访问 database 虚拟机;
    让外网可以访问,有两种实现方式
    • NAT
      需要在虚拟机的虚拟路由器上设置 DNAT,既是端口转发;当请求经过宿主机后,通过该 DNAT 映射转发给虚拟机中的应用服务。
    • Bridged
      不用在宿主机上做额外的设置,请求从宿主机通过虚拟交换机直接转发给虚拟机的服务即可。