目标
- 在单台PC机上安装3+台虚拟机[1]
- 这些虚拟机间可以相互访问
- 宿主机[2]与虚拟机可以相互访问
- 虚拟机可以访问公网
本文将采用 NAT + Host-Only 双网卡的方式实现上述目标,因为采用这种组合来实现是很简单的,需要做的配置也非常少。
前置条件
本文仅在以下环境下验证通过,如果您的情况与此有差异,则全文内容仅供参考
- windows11
- virtual box7.0
- ubuntu18.04
另外,需要宿主电脑至少预留40~60G空闲磁盘,用来安装VirtualBox和虚拟机。
搭建流程
主要有以下几步:
- 安装VirtualBox
- 创建虚拟机并安装Ubuntu系统
- 配置Ubuntu网络
安装VirtualBox
下载VirtualBox
VirtualBox的安装比较简单,本文使用的是当前(2023年2月)最新的7.0版本,点击这里直接下载。
安装VirtualBox
下载后,双击安装文件(如果下载的是归档或压缩文件,请先解压),如果不需要特别指定安装目录的话,一直点击〔下一步〕,直到安装结束即可。
如果需要将VirtualBox安装到指定目录,可以在安装向导界面上进行设置。
创建虚拟机并安装系统
下载Ubuntu
可直接点击这里下载ubuntu18.04的种子文件,下面列出ubuntu相关的资源清单
- ubuntu18.04.iso光盘镜像文件
- ubuntu18.04归档目录
- ubuntu所有文件归档目录
- ubuntu官方网站
- ubuntu18.04 版本发布说明文档
- ubuntu的阿里镜像
您也可以选择其它旧的发行版或最新的稳定版本。本文选择了18.04(版本代号为Bionic Beaver)这个版本,一来这是一个LTS版本, 官方宣称会支持10年,
同时它体积小,安装时默认的〔使用整个磁盘〕功能比较符合我们个人学习研究的感观,简而之,这个版本的安装过程和安装后使用都比较省事。
另外,建议下载live版本的ISO文件,相对于非Live版本而言,它的安装向导提供了更多的可配置项,特别是初始的用户名和密码。更多live-server与非live版本的差异,见ubuntu18.04 版本发布说明文档
创建虚拟机
将先创建一个原型虚拟机,再基于它复制其它的虚拟机。原型机的基本信息如下:
属性 | 内容 | 备注 |
---|---|---|
名称 | ubuntu-a | |
CPU核心数 | 2 | 可根据自己宿主机的cpu核心数来调整,笔者的个人笔记本为6核,因此设置为2 |
内存大小 | 1280M | 同理,请根据自己宿主机的物理内存调整,笔者的个人笔记本内存为16G |
SATA磁盘 | 20G | 同理,请根据自己宿主机的空闲磁盘调整,但建议至少10G |
step1. 运行VirtualBox程序,打开程序主窗体界面。
step2. 指定虚拟机名称和操作系统
在主界面上点击【新建(N)】图标,调出虚拟机创建对话框,在对话框中,根据个人宿主机电脑实际情况,依次设置虚拟机名称、虚拟机文件存放目录和操作系统ISO安装文件的路径。如下图所示:
关于图中的第①步,即:Skip Unattended Installation 这一选项,请勾选该选项。VirtualBox识别出了ubuntu-18.04-live-server-amd64.iso文件,表示它内建了对该系统的支持,能够以全自动的、无人值守的方式安装该操作系统。因此,在一下步中,会多出一个主机名称、系统初始用户名称、昵称、密码设置的对话框,这些信息用于VirtualBox之后对ubuntu系统的自动安装任务。
但经过验证,VirtualBox的自动安装(即 Unattached Installation)是不行的。至少针对ubuntu-18.04这个版本,在我的电脑上没有成功。因此要勾选Skip Unattached Installation这个选项,以跳过自动安装。
依次单击菜单栏的
〔控制(M)〕
→新建(N)
,或按下Ctr+N
快捷键也可以调出虚拟机创建对话框。
step3. 分配物理内存和CPU
单击〔下一步〕进入物理内存和CPU的分配设置对话框。根据自己电脑的物理CPU核数和内存进行适当减配即可。如下图所示:
step4. 分配磁盘空间
单击〔下一步〕进入对话框。这个比较简单,为虚拟机指定好磁盘大小即可。
step5. 虚拟机参数确认
单击〔下一步〕,对话框将显示前4步设置的所有内容,确认无误后,单击〔完成〕即可。完成后VirtualBox主界面左侧面板中,会多出一个图标来,其名称为ubuntu-a,它就是我们刚刚新的虚拟机。另外,在磁盘上也会多出一个文件夹来(本文中这个文件夹位置为:E:\Data\VirutalMachine\ubuntu-a)
step6. 为虚拟机安装ubuntu系统
在VirtualBox的主界面,双击刚刚创建的虚拟机机图标,启动虚拟机,进入ubuntu操作系统的安装进程。根据安装向导,一步步输入自己的参数即可。除了初始的主机名称和登录账户信息外,其它的直接使用默认设置就可以了。
Ubuntu系统基本设置(可选)
一般来说,刚安装的系统,里边的软件包大多都过时了,因此需要更新系统的软件包
step1. 更改软件包源
先执行如下命令,备份之前的APT源配置文件。
cd /etc/apt/ # 进入apt源配置目录sudo cp sources.list sources.list.origion # 备份apt源配置
然后使用阿里的ubuntu软件包源,替换掉官方默认的源,即使用以下内容,覆盖source.list文件内容
deb https://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiversedeb-src https://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiversedeb https://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiversedeb-src https://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiversedeb https://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiversedeb-src https://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse# deb https://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse# deb-src https://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiversedeb https://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiversedeb-src https://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
step2. 更新系统软件包
直接执行以下命令即可。该命令的执行时长较长,请耐心等待 ?
sudo apt update && upgrade
其中的apt
命令也可以换成apt-get
,多数情况下,二者是等效的,详细差异见这里。
另外,关于命令update与upgrade的区别,这里有较为详细的讲解。
以上命令需要访问公网。VirtualBox7在创建虚拟机时,会默认配置一个NAT类型的网卡,只要宿主机能访问公网,通过该网卡虚拟机就能访问到公网。
网络设置
终于进入到最重要的网络设置了。目前为止,文章开头的4个目标,只有目标4彻底完成了,可以在虚拟机内输入ping www.bing.com
验证是否可以连接公网。
但我们似乎什么也没做,这是因为VirtualBox在新建虚拟机时,默认添加了一张类型为NAT的网卡。只要宿主机能上网,目标4就已经完成了。
右击VirtualBox主界面上的ubuntu-a虚拟机图标,单击弹出菜单中的〔设置〕项,以打开虚拟机设置面板,选中〔网络〕选项卡。此时,右侧网卡列表中的〔网卡1〕就是默认的NAT网卡,如下图所示:
此时,宿主机还不能连接到虚拟机,在虚拟机中输入ifconfig -a
查看其IP地址,其中的enp03
就是默认的那张NAT网卡,如下所示。本示例中,其IP地址为:10.0.2.15 。 如果在宿主机中ping这个ip是会失败的。
enp0s3: flags=4163 mtu 1500 inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ inet6 fe80::a00:27ff:feb6:1744 prefixlen 64 scopeid 0x20 ether 08:00:27:b6:17:44 txqueuelen 1000 (Ethernet) RX packets 140099 bytes 156313416 (156.3 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 45269 bytes 2765605 (2.7 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0lo: flags=73 mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1000 (Local Loopback) RX packets 132 bytes 12334 (12.3 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 132 bytes 12334 (12.3 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
接下来,我们就要完成目标2和目标3。
添加host-only网卡
依次如下操作:
- 打开ubuntu-a虚拟机的设置面板,切换到〔网络〕选项卡,点击〔网卡2〕。
- 勾选〔启用网络连接(E)〕属性
- 打开〔连接方式(A)〕的下拉列表,选择「仅主机(Host-Only)网络」
- 〔名称(N)〕属性栏,选择 VirtualBox Host-Only Ethernet Network
网络设置中,还有一组高级(advanced)属性,这些采用默认的值即可,无需特别配置
整个设置界面如下图所示:
刚刚已经为ubuntu-a虚拟机新添加了一张Host-Only类型的网卡。现在我们要启动该主机,进入系统查看一下该网卡在运行起来后,获得的ip是多少。
重启后,在虚拟机中输入ifconfig -a
,将得到类似下面这样的输出(略去了回环网卡)
enp0s3: flags=4163 mtu 1500 inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255 inet6 fe80::a00:27ff:feb6:1744 prefixlen 64 scopeid 0x20 ether 08:00:27:b6:17:44 txqueuelen 1000 (Ethernet) RX packets 20 bytes 3630 (3.6 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 47 bytes 4716 (4.7 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0enp0s8: flags=4163 mtu 1500 ether 08:00:27:d6:ec:0e txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
上面的enp0s8
网卡,就是新添加的Host-Only网卡,但不幸的是,相对于enp03
而言,这张网卡是没有分配到IP地址的。那也就不可用了,为什么会这样呢?与NAT网卡不同,Host-Only网卡很特殊,它还需要在操作系统中进行相关的网络设置才能发挥作用。
ubuntu 18.04 引入了netplan来管理网络,其配置文件位于/etc/netplan目录下,其中有个.yml后缀的文件,使用vim编辑该文件[3], 结果如下
network: ethernets: enp0s3: addresses: [] dhcp4: true optional: true enp0s8: # 该节点(包含其子节点的内容)是新添加的 addresses: - 192.168.56.101/24 dhcp4: false optional: true version: 2
其中的enp03
节点是之前的内容,enp08
是本次添加的内容。可以看到,我们手动将网卡2的ip地址设置为了192.168.56.101,并禁用了DHCP
- 也可以将Host-Only网卡的IP配置成DHCP方式动态获取。但配置为静态ip有个好处,就是虚拟机重启后,其IP地址是不会变的,而DHCP方式是有可能会改变,这不利于在多个虚拟机上部署集群软件。
- 这里有一篇关于netplan的快速操作中文博客,可以参考一下
netplan的配置文件编辑好后,执行以下命令验证配置是否正确
sudo netplan try
验证无误后,可以选择直接生效(回车即可),此时再执行ifconfig -a
命令查看,会得到类似下面的结果(略去了回环网卡)
enp0s3: flags=4163 mtu 1500 inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255 inet6 fe80::a00:27ff:feb6:1744 prefixlen 64 scopeid 0x20 ether 08:00:27:b6:17:44 txqueuelen 1000 (Ethernet) RX packets 20 bytes 3630 (3.6 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 47 bytes 4716 (4.7 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0enp0s8: flags=4163 mtu 1500 inet 192.168.56.101 netmask 255.255.255.0 broadcast 192.168.56.255 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ inet6 fe80::a00:27ff:fed6:ec0e prefixlen 64 scopeid 0x20 ether 08:00:27:d6:ec:0e txqueuelen 1000 (Ethernet) RX packets 76 bytes 9568 (9.5 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 59 bytes 11698 (11.6 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
下划线标识出来的部分,就是我们刚刚手动为Host-Only网卡分配的ip,那么宿主机是否可以ping得通这个IP呢?以下是笔者的电脑上执行ping命令的结果
C:\Users\Administrator>ping 192.168.56.101正在 Ping 192.168.56.101 具有 32 字节的数据:来自 192.168.56.101 的回复: 字节=32 时间<1ms TTL=64来自 192.168.56.101 的回复: 字节=32 时间<1ms TTL=64来自 192.168.56.101 的回复: 字节=32 时间<1ms TTL=64来自 192.168.56.101 的回复: 字节=32 时间=1ms TTL=64192.168.56.101 的 Ping 统计信息: 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),往返行程的估计时间(以毫秒为单位): 最短 = 0ms,最长 = 1ms,平均 = 0ms
可以看到,已经能ping得通了。
OK,是时候验证一下,在宿主机上是否可以通ssh方式连接(登录)虚拟机了。选择一款windows上的ssh连接工具(推荐MobaXTerm或XShell),经验证,是可以连接成功的。
现在,你一定有个疑问,为什么手动设置的IP是192.168.56.101,设置成192.168.139.101或者192.170.56.101行不行。答案是不行,因为VirtualBox7在宿主机上创建了一个名为VirtualBox Host-Only Network Adapter的虚拟网卡,如下图所示。这个网卡,就是我们在给虚拟机创建网卡2指定名称时选择的网卡。它默认的网段是192.168.56.0/24,并且该网卡默认开启了dhcp,dhcp的ip为192.168.56.100。因此我们可以手动给虚拟机配置的ip范围是:192.168.56.101 ~ 192.168.56.254。
那么这个默认的网段和dhcp的ip是否可以修改呢?是可以的,详见下一小节的问题一。
相关问题
问题一. host-only网卡的IP地址在哪里设置?
上面我们为host-only网卡设置的静态ip为192.168.56.101,且网段为192.168.56。正如上小节所述,这是因为在安装VirtualBox程序时,就默认在宿主机生成了一张host-only的网卡。我们在为虚拟机添加网卡时,只能选择网络类型,并不能为其单独设置ip和dhcp等。如果要为网卡设置一个不同的网段,比如:192.168.82.0/24,应该在全局的网络管理界面中去操作,因为网卡的创建也是全局的。
点击VirtualBox主界面上左侧面板上的,工具 栏上右侧的菜单列表图标,此后会出现一个下拉菜单,点击其中的网络菜单项,这将使用主界面的右侧面板内容切换到全局的网络设置。如下图所示
全局网络设置界面,默认显示的是Host-Only类型的网卡信息
- 选中列表中的一个网卡(默认只有VirtualBox Host-Only Network Adapter)
- 点击「适配器(Adapter)」TAB选项卡下的〔手动配置网卡〕,就可以设置ip和网段了
- 勾选「DHCP服务器)」TAB选项卡下的〔启用服务器〕,就可以配置DHCP相关参数了
问题二. VirtualBox各种网络模式的都有什么用?
VirtualBox有多种网络模式,非运维人员对这些模拟出来的各种网络功能是搞不清楚的。我们一般也只想在本机建立一个文章开头所描述的那个经典场景。如果你想深入地了解它们,下面是一些可参考的博文
- VirtualBox网络配置官方手册
- VirtualBox网络配置超全详解-中文
- 这是上面那边博文的原始英文版本
问题三. 添加Host-Only网卡时,下拉列表为空怎么办?
这种情况如果出现,基本上是安装VirtualBox时出现了错误。可以尝试在全局的网络管理界面中,点击创建图标新建一张Host-Only类型的网卡,如下图所示
如果创建失败,则表明安装的VirtualBox有问题,建议卸载重新安装,如果还不行,尝试安装其它的版本。
复制虚拟机
目前为止,我们仅创建了一台虚拟机,因此,目标1和目标2还未完成。完成这两个目标,最笨的办法,就是把创建虚拟机和设置网络的步骤,再重复做两遍。但这效率太低,我们可以借助VirtualBox提供的虚拟机复制功能,快速完成另外两台虚拟机的创建和设置。
step1. 复制虚拟机本体
以创建第二台虚拟机为例,按如下步骤操作:
鼠标右击ubuntu-a虚拟机图标,在右键菜单中,选择〔复制〕,如下列图组中的第①项所示
在弹出的虚拟机复制对话框中,依次设置相应属性(如下),示意图为下列图组中的第②项所示。设置完成后,点击〔下一步〕按钮
- 名称栏(Name),设置一个新的虚拟机名,如:ubuntu-b
- 路径栏(Path),与之前的虚拟机保持一致即可
- 网卡地址策略栏(MAC Address Policy),请务必选择「为所有网卡重新生成 MAC 地址」
- 其它选项栏(Other Options),该栏内的所有条目都不要勾选
在副本类型设置对话框中,选中「完全复制」,如下列图组中的第③项所示。然后点击〔完成〕按钮
虚拟机复制操作的所有属性设置就已经完成了,接下来VirtualBox开始正式执行复制,这会花费一些时间,如下列图组中的第④项所示。在复制完成后,在主界面的虚拟机列表栏会多出一个虚拟机图标,如图组中的第⑤项所示
step2. 修改ip和主机名
新复制出来的主机,其主机名、登录账户、ip地址都与第一台虚拟机一样,这在做集群时是不行的,因此,至少需要将IP和主机名改掉。
启动刚刚复制出来的虚拟机
执行以下命令修改主机名
sudo hostnamectl set-hostname ubuntu-b # ubuntu-b是本示例中,要设置的新主机名
修改主机名还有其它一些方法,参见这里
执行命令
sudo vim /etc/netplan/50-cloud-init.yaml
打开网络配置文件[3:1]修改文件中的enp0s8网卡(也就是Hony-Only类型的那张网卡)的ip,如下所示
network: ethernets: enp0s3: addresses: [] dhcp4: true optional: true enp0s8: addresses: - 192.168.56.102/24 # ip由复制前的101改成102 dhcp4: false optional: true version: 2
验证虚拟机间的互访问性
执行sudo reboot
重启虚拟机,并将第一台虚拟机也启动起来。此时一共有两台虚拟机,并且都启动起来了,为方便描述,用ubuntu-a、ubuntu-b来分别代表第一台和第二台虚拟机。它们的ip分别是192.168.56.101和192.168.56.102- 选择一款SSH连接工具分别登录ubuntu-a和ubuntu-b,验证是否可以在宿主以上以SSH方式连接到虚拟机
- 在ubuntu-a上,执行命令
ping 192.168.5.102
, 验证ubuntu-a是否可以访问ubuntu-b - 在ubuntu-b上,执行命令
ping 192.168.5.101
, 验证ubuntu-b是否可以访问ubuntu-a
至此,目标2和目标3已完成?
step3. 创建第3台虚拟机
整篇文章,只差最后一个小目标了,那就是需要创建至少3台虚拟机,即目标1。幸运的是,现在不用再从头开始一步步创建它了,请参考上一小节(即复制虚拟机)部分操作即可。
小结
本文实现了一个在个人电脑上,安装虚拟机进行学习研究的经典场景,即:在宿主机上安装多台虚拟机,并且这些虚拟间可以互通,宿主机也能SSH登录到这些虚拟机。主要难点在网络设置上,简单来说就是NAT网卡负责连接公网,Host-Only网卡负责虚拟机之间以及虚拟机与宿主机之间的连接,当然这两种类型的网卡还有其它功能,但对于我们提到的这个最常见的应用场景,可以用这样的方式来看待这两种类型的网卡。
这里最容易失败的是第2步网络设置。由于NAT网卡设置上去后,什么也不用做,就可以连接公网了,会自然地觉得Host-Only网卡也是这样的。但事实是如果只是为虚拟机添加Host-Only网卡,宿主机并不能访问虚拟机,因为这张网上还没有分配到IP,需要登录到操作系统,修改其网络配置,为该网卡设置静态IP或开启dhcp。
另外,在创建多个虚拟机时,我们利用了VirtualBox的虚拟机复制功能,简化了后续虚拟机的创建。需要注意的是,复制时要为新虚拟机的所有网卡创建全新的MAC地址。
在虚拟化术语中,虚拟机被称作Guest,而不是Virtual Machine。宿主机被称作Host,即主人与客人的关系。 ↩︎
宿主机(Host)即安装VirtualBox程序的操作系统所在的主机,一般来说就是一台物理电脑 ↩︎
netplan的配置文件是YAML格式的,但该配置文件的名称在不同主机上是不一样的 ↩︎ ↩︎