分享自己在家搭建 Linux 虚拟机的经验。
基础知识
在开始搭设虚拟机前,要求实验者掌握一些基础的知识。
遇到问题会 Google, 百度一下的能力也是很重要的,学会抓住关键词搜索。
概要
本文分享在家用环境搭建 Linux 虚拟机环境的过程,并且介绍几个虚拟化软件的用法。适合小白入门
Linux 内核的常用操作系统有:
- Ubuntu https://ubuntu.com/
- CentOS https://www.centos.org/
新手玩家,强烈推荐 Ubuntu 桌面版,有 UI 界面,上手难度没有那么的大。 桌面版下载地址
准备过程
不管你自己的电脑是什么操作, 首先需要你下载官方镜像到自己的电脑上。
访问 https://ubuntu.com/download/desktop 下载镜像, 文件名为 ubuntu-20.04.2.0-desktop-amd64.iso
按操作系统
日常我们家用的电脑一般就是 Windows 系统或者 macOS 苹果系统。请根据自己电脑的系统,下载相迎的虚拟化软件。
- VMware Workstation 适合 Windows,适合新人,推荐
- VMware Fusion 适合 mac
- VirtualBox 适合 mac
Windows
Windows 系统下面,推荐虚拟化软件 VMware Workstation , 官网地址
安装的过程中,需要输入激活码, VMware Workstation 激活码网上随便搜索一下就可以用了
在安装虚拟机之前,我们先看一下 VMware 的网络设置,打开虚拟网络编辑器
这里将桥接模式的网络,桥接到自己电脑的网卡,我这里是台式机,其网卡是 Intel(R) Ethernet Connection(7) I219-V , 这里每个人的情况不同,笔记本电脑的话是 wireless 无线网卡。
同时,我们还需要注意到 VMware 创建了三种网络,他们各自的网络地址。 需要注意的是桥接模式的地址,是根据你自己的电脑所在网络的路由器设置的,一般家用路由器都是 192.168.1.0/24
如果是校园 WiFi, 那估计网络规模会大很多。在 windows 查看自己的网络地址, 打开命令提示符 CMD,运行 ipconfig
如上图所示,这里我自己的家用台式机,网络地址就是 IPv4: 192.168.1.77
name | mode | CIDR |
---|---|---|
VMnet0 | 桥接 | 192.168.1.0/24 |
VMnet1 | 仅主机 | 192.168.230.0/24 |
VMnet8 | NAT | 192.168.64.0/24 |
当 VMware Workstation 安装好了之后,我们就可以用 VMware Workstation 提供的快速安装功能,安装 Ubuntu 桌面版虚拟机。
我这里是 Ubuntu 18, 如果你下载的是最新版本 ubuntu-20.04.2.0-desktop-amd64.iso , 选择的镜像不同
这里设置好虚拟机的名称,还有登录的账号和密码
输入你自己设置的账号密码,登录 Ubuntu
这里可以安装VMware tools, 插件是为了更好使用,比如窗口的缩放,还有拖拽文件进入虚拟机等
检查一下 Ubuntu 虚拟机的 IP 地址,因为我的虚拟机是双网卡: ens33 是 NAT 网络的地址, ens38 是桥接网络的地址
到此,你已经成功安装了虚拟机,在你探索之前,可以看一看快照 部分,学会备份,随便折腾
新手可以跳过。如果你需要双网卡,可以再额外添加一张网卡,我因为第一次初始化设置的网卡是 NAT, 第二次添加的桥接网卡,双网卡的机器一般是拿来当跳板机(堡垒机用)可以看看这篇介绍 ssh 通过跳板机直连跳板机内网服务器
macOS
苹果系统下面,我尝试了 2 种虚拟化软件
VirtualBox 免费的,偶尔程序会崩溃,下图是如何新建一个 NAT 网络
Configure Additional NAT in VMware Fusion
VirtualBox 开源免费的,但桌面窗口的支持没有 VMware Fusion 做的好。VMware Fusion 可以在淘宝很便宜的买到序列码, 我踩坑了:好像淘宝的序列码不支持自建 NAT 网络(因为是非商业版本) non-commercial use only,很坑。 还不如这个公众号里面分享的三个注册码
按网络环境
虚拟机三种网络模式, 这篇文章已经讲得比较详细。
在家用练习环境中,如果选择自己的网络环境。 以下是我的一些建议
- 桥接模式 Bridged:1. 要安装对外提供的服务,自己的实体机想访问虚拟机的服务。2. 只安装一台虚拟机, 新手推荐,快速省事
- 网络地址转换模式 NAT:1. 自己的电脑安装几个虚拟机,搭建集群。 2. 虚拟机没有对外开放的服务,不需要端口转发
桥接模式 Bridged
网络地址转换模式 NAT
这里我们用 mtr 命令测试一下连通性,并且看沿途经过的节点。
1 | root@ubuntu20:~# ip -4 a |
必备技能
学会快照 snapshot
快照 snapshot 就是虚拟机的某一时刻的状态备份。当我们在完成一个重大改变的前后,我们都应该快照。 比如在安装一个软件之前,如果我们不确定担心安装后搞崩了环境,那么我们可以快照一下。大吉大利
ansible 关机
因为一共有 6 台虚拟机了,手动关机还有有点 laborious,所以用 ansible 批量关机方便。
如果不知道的 ansible 的小白同学,可以先看看 Ansible系列 奥哥的 Ansible 学习路径
SSH config 别名,方便记忆,快速登录。 还有跳板机的设置
1 | feiyang@MAC ~ % cat .ssh/config |
1 | # file name: hosts |
1 | # file name: shutdown.yml |
每次如果觉得输入 ansible-playbook 命令还是很麻烦,那就用 alias ,真是懒人促进发展,哈哈哈
1 | vim ~/.zshrc |
打通任督二脉
从上面的家庭网络架构图得知,我们有两个网络:
- 192.168.1.0/24 家庭路由器网络
- 192.168.64.0/24 WIN10 台式机上,Vmware 创建的虚拟 NAT 网络
接下来,我们要做的就是,打通两个网络。Ubuntu18.04 双网卡实现转发,相当于扮演了一个路由器的角色。先来看一眼架构图,今天的主角就是身负双武魂
(斗罗大陆看多了,哈哈)双网卡的 ubuntu18-108
, 它的两个网卡 Network interface controller 上的 IP 分别是 ens33
网卡是 192.168.64.3
and ens38
网卡是 192.168.1.108
网卡名称和 IP 地址非常重要,请牢记,不要混淆了。
1 | root@ubuntu18-108:/home/feiyang# ip -4 a |
NAT Server
其实我的另外一篇 blog 有介绍 NAT server 设置,但这次实验,我们采用的是临时命令行操作,因此有一点不同。在临时命令行后,我们也补充了持久化的文档链接,亲测有效
参考了:
- FORWARD AND NAT RULES
- NAT - Network Address Translation
- linux – 添加、修改、删除路由
- Adding a Static Route to macOS
1 | cat /proc/sys/net/ipv4/ip_forward |
client server
其他的机器,只需要设置一下路由,添加一条路由规则即可。
mac
macbook pro 苹果电脑的 IP 是 192.168.1.125
添加一条路由, 指定双网卡机器 192.168.1.108 为 gateway
1 | sudo route -n add -net 192.168.64.0/24 192.168.1.108 |
linux
centos IP 是 192.168.64.4 , ubuntu20 IP 是 192.168.64.5 。 它们两台都需要设置,添加一条路由, 指定双网卡机器 192.168.64.3 为 gateway
1 | route add -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.64.3 dev ens33 |
- (CentOS7的路由配置持久化)[https://blog.csdn.net/beeworkshop/article/details/102952759]
1
2vim /etc/sysconfig/network-scripts/route-ens33
192.168.1.0/24 via 192.168.64.3 dev ens33 - add static route with netplan on Ubuntu 20.04
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16vim /etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
ethernets:
ens33:
addresses: [192.168.64.5/24]
optional: true
dhcp4: no
gateway4: 192.168.64.2
nameservers:
addresses: [1.1.1.1,8.8.8.8]
routes:
- to: 192.168.1.0/24
via: 192.168.64.3
version: 2
renderer: networkd
测试
mac -> ubuntu20 , ubuntu20 开 2 个 terminal, 一个启动 server, 一个 tcpdump 抓包分析,mac telnet 测试
1
2
3
4
5
6
7# terminal1: start simple http server
python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
# terminal2: tcpdump listen port 8000
tcpdump -i any port 8000 -nnn然后就是 mac telnet 192.168.64.5 8000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17# 方法一: 用 Telnet 测试
telnet 192.168.64.5 8000
Trying 192.168.64.5...
Connected to 192.168.64.5.
Escape character is '^]'.
^]
telnet> q
Connection closed.
# 方法二: 用 mtr 测试
➜ ~ sudo mtr -n -c 3 -r --tcp --port 8000 192.168.64.5
Password:
Start: 2021-06-20T20:07:35+0800
HOST: FEIYANG-MAC Loss% Snt Last Avg Best Wrst StDev
1.|-- 192.168.1.108 0.0% 3 6.2 11.2 3.3 24.3 11.4
2.|-- 192.168.64.5 0.0% 3 10.9 7.7 2.6 10.9 4.5检查 ubuntu20 tcpdump 的结果
1
2
3
4
5
6
7
8
9
10tcpdump -i any port 8000 -nnn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
10:49:42.301949 IP 192.168.64.3.55989 > 192.168.64.5.8000: Flags [S], seq 2641736153, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 283128122 ecr 0,sackOK,eol], length 0
10:49:42.301991 IP 192.168.64.5.8000 > 192.168.64.3.55989: Flags [S.], seq 1529903079, ack 2641736154, win 65160, options [mss 1460,sackOK,TS val 3145755328 ecr 283128122,nop,wscale 7], length 0
10:49:42.303721 IP 192.168.64.3.55989 > 192.168.64.5.8000: Flags [.], ack 1, win 2058, options [nop,nop,TS val 283128124 ecr 3145755328], length 0
10:49:46.519038 IP 192.168.64.3.55989 > 192.168.64.5.8000: Flags [F.], seq 1, ack 1, win 2058, options [nop,nop,TS val 283132312 ecr 3145755328], length 0
10:49:46.519205 IP 192.168.64.5.8000 > 192.168.64.3.55989: Flags [F.], seq 1, ack 2, win 510, options [nop,nop,TS val 3145759545 ecr 283132312], length 0
10:49:46.521868 IP 192.168.64.3.55989 > 192.168.64.5.8000: Flags [.], ack 2, win 2058, options [nop,nop,TS val 283132315 ecr 3145759545], length 0整个过程是
192.168.1.125
->192.168.1.108
->192.168.64.3
->192.168.64.5
centos7 -> mac , mac 开 2 个 terminal, 一个启动 server, 一个 tcpdump 抓包分析,centos7 telnet 测试
1
2
3
4
5
6
7# terminal1: start simple http server
python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
# terminal2: tcpdump listen port 8000
tcpdump -i any port 8000 -nnn然后就是 centos telnet 192.168.1.125 8000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# 方法一: 用 Telnet 测试
telnet 192.168.1.125 8000
Trying 192.168.1.125...
Connected to 192.168.1.125.
Escape character is '^]'.
^]
telnet> q
Connection closed.
# 方法二: 用 mtr 测试
sudo mtr -n -c 3 -r --tcp --port 8000 192.168.1.125
Start: Sun Jun 20 08:16:37 2021
HOST: centos7 Loss% Snt Last Avg Best Wrst StDev
1.|-- 192.168.64.3 0.0% 3 0.4 0.4 0.4 0.5 0.0
2.|-- 192.168.1.125 0.0% 3 1002. 902.3 201.3 1502. 656.6检查 mac tcpdump 的结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17➜ ~ sudo tcpdump -i any port 8000 -nnn
Password:
tcpdump: data link type PKTAP
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type PKTAP (Apple DLT_PKTAP), capture size 262144 bytes
18:44:00.166899 IP 192.168.1.108.54120 > 192.168.1.125.8000: Flags [S], seq 3298177179, win 29200, options [mss 1460,sackOK,TS val 4138980 ecr 0,nop,wscale 7], length 0
18:44:00.166996 IP 192.168.1.125.8000 > 192.168.1.108.54120: Flags [S.], seq 3788626158, ack 3298177180, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 282788376 ecr 4138980,sackOK,eol], length 0
18:44:00.169945 IP 192.168.1.108.54120 > 192.168.1.125.8000: Flags [.], ack 1, win 229, options [nop,nop,TS val 4138982 ecr 282788376], length 0
18:44:00.169966 IP 192.168.1.125.8000 > 192.168.1.108.54120: Flags [.], ack 1, win 2058, options [nop,nop,TS val 282788379 ecr 4138982], length 0
18:44:12.790139 IP 192.168.1.108.54120 > 192.168.1.125.8000: Flags [F.], seq 1, ack 1, win 229, options [nop,nop,TS val 4151601 ecr 282788379], length 0
18:44:12.790165 IP 192.168.1.125.8000 > 192.168.1.108.54120: Flags [.], ack 2, win 2058, options [nop,nop,TS val 282800870 ecr 4151601], length 0
18:44:12.790246 IP 192.168.1.125.8000 > 192.168.1.108.54120: Flags [F.], seq 1, ack 2, win 2058, options [nop,nop,TS val 282800870 ecr 4151601], length 0
18:44:12.792923 IP 192.168.1.108.54120 > 192.168.1.125.8000: Flags [.], ack 2, win 229, options [nop,nop,TS val 4151606 ecr 282800870], length 0
^C
8 packets captured
2158 packets received by filter
0 packets dropped by kernel整个过程是
192.168.64.4
->192.168.64.3
->192.168.1.108
->192.168.1.125
总结
这下,两个网络之间就实现了互通。让我联想到了 AWS VPC peering ,又联动上了。 如今 SSH 就不需要跳板机 ProxyJump 了, vault UI 192.168.64.3:8200 也不需要 Nginx 代理了。
我们如今只是将 Windows10 VMware 自定义的 NAT 内网和家庭网络连通了起来。 如果家里的其他电脑也创建了 NAT 内网, 那么最终我们可以在家里本地环境,模拟出多个网络,就像 AWS 多个VPC 一样,最终都连通起来。