软路由与NAS(2) - 软件平台搭建

本文最后更新于:2019 年 02 月 18 日 星期一

这篇文章拖了不知道多久多久(大概3个月),终于把坑填了,顺便再挖一个坑,有空写篇文章讲讲这机子外壳的制作过程。

2018年秋冬之交(双十一前后),用工控主板搭了一个软路由和 NAS 的一个硬件平台,详见这篇文章 软路由与NAS(1) - 硬件平台搭建 。但其实,那只是有了一个机子,真正要实现软路由和 NAS 的功能,还需要一些软件的支持。

所以这篇文章来讲讲这小东西软件平台的搭建历程…

操作系统

首先是使用怎么样的操作系统作为这台机子的主要平台呢?这个问题其实没有多少答案,而且我之前也已经想好了。首先,不像尹大人那样那么会玩,我甚至没法想象去使用什么 Windows Server 来搞事情,也没听过什么 RouterOS 。所以其实,软路由部分肯定需要由 OpenWrt 来承载。 NAS 的话我的要求比较简单,就是能够通过网络访问、读写我那块 1T 硬盘里的数据就可以,性能最好能跟直接插上硬盘传差不多(这是不可能的),所以最简单的,就用 SMB 就行。 OpenWrt 也可以跑 SMB 。

再想想还能有什么应用?其实不管是什么,我能想到的,基本上 OpenWrt 都可以,那么就开始安装 OpenWrt 吧。当然不要!虽然我也不知道为什么,也许只是因为我比较菜,我觉得如果有个图形界面会好很多。而且一个中规中矩的 Linux 系统可能会比较易于使用,而且而且 opkg 实在不如 apt 好用,所以我还是很希望能安装一个 Ubuntu 什么的。但 OpenWrt 肯定是需要的,所以最终方案就是

Ubuntu Desktop 18.04 + VM (OpenWrt)

Ubuntu 就直接官网下载安装就好了,没什么技术含量,不值一提。由于官方编译好的 x86_64 的 OpenWrt 固件完全不能符合我的需求,比如他甚至没有我那块无线网卡(QCA9880)的驱动,所以自己编译一个肯定是逃不了了。为了按照时间顺序记叙,我把这一部分留到后面再讲 (见 OpenWrt 编译

虚拟机

选购(选择)虚拟机也是一个复杂的事情。首先看看大家一般都会有些什么选择吧

  • Oracle VM VirtualBox
  • VMware Workstation Pro
  • VMware Workstation Player
  • Microsoft Hyper-V (on Windows10)

一般来说,虚拟机我都会首先考虑 Oracle VM VirtualBox ,这东西简单易用,开源,免费… 如果这东西能用,我甚至都不会再考虑别的方案

但是大家还记得 VT-d 吧,这东西我在硬件平台搭建那篇文章提到过

英特尔® 定向 I/O 虚拟化技术 (VT-d) 在现有对 IA-32(VT-x)和安腾® 处理器 (VT-i) 虚拟化支持的基础上,还新增了对 I/O 设备虚拟化的支持。英特尔定向 I/O 虚拟化技术能帮助最终用户提高系统的安全性和可靠性,并改善 I/O 设备在虚拟化环境中的性能。

通过 VT-d 我才能将无线网卡穿透进虚拟机,在虚拟机里管理、配置并使能无线网卡。这样做的好处,一个是通过 OpenWrt 可以很方便地设置 WiFi 信道、带宽、功率、密码之类的东西,第二个是这样做 I/O 性能会好很多。

没有 VT-d 的解决方案就是在宿主机配置无线网卡,然后通过虚拟网桥将虚拟机里的虚拟网卡和这块无线网卡桥接。缺点就是没有上面说的两个好处。

那么,既然我花了那么多功夫挑了一块带有支持 VT-d 的 CPU 的主板,这就一定得用上!!

很可惜,我摸索了半天、查了半天,也不知道怎么在 VirtualBox 使用 CPU 的 VT-d 功能,最后我也请教了尹大人一下,貌似的确是不支持的。

VMware Workstation Pro 可能可以,毕竟还是个挺专业的虚拟机软件,但是那是商业软件,跟我的信仰不很相符,而且要付费,而且对于我来说还非常昂贵。随随便便就使用盗版也完全不符合我的信仰,所以暂时不予考虑。VMware Workstation Player 虽然是免费的(非商业使用时),但是功能太少,感觉比 VirtualBox 也不会好到哪里去。

Microsoft Hyper-V 这个东西要在 Windows 系统上才能使用,而且 Windows 10 的话要 Pro 才有这个功能。刚好我有一台 Windows 10 Pro 的机器,稍微尝试过,从微软宣传来看还是很牛的。但是我那台小东西没有 Win 10 Pro 啊,我也完全不想装 Windows , Windows 啥也干不了。而且,按尹大人的说法,要 Windows Server 的 Hyper-V 才支持 VT-d 。还是需要折腾一堆盗版软件,罢了,不折腾了。

那我就走投无路了吗?当然没有。经过尹大人的提点,我想起了大名鼎鼎的 KVM (Kernel-based Virtual Machine) ,开源、免费、强大,而且简单的使用算不上复杂。赶紧 Google 一下,安装…

至于如何使用 VT-d 。稍微 Google 了一下,主要就以下几步

  1. 修改 grub 内核引导参数,设置 intel_iommu=on (对于 Intel® 的 CPU),重启。这一步主要是用于使能某些内核模块,使其支持 IOMMU 功能
  2. 在虚拟机中添加 PCI-E 设备,选择需要直通的设备。这个在图形化界面上操作会容易很多,比如 virt-manager 。开机(开虚拟机)
  3. 第一次开机可能会报错,大意是不能分配所选的硬件。这个的话可以先 virtsh nodedev-detach xxxxxxxx 是要直通的设备的设备号)解除宿主机的占用,要查看设备号的话可以先 virtsh nodedev-list --tree

这个具体可以 Google 。

我按着教程设置好了之后还是开不了机,又 Google 了一圈,原因应该是无线网卡和两块有线网卡被分配到同一个 IOMMU 组了。这种情况下只能拆分这个 IOMMU 组,或者解除这个 IOMMU 组中所有设备在宿主机中的占用(既然宿主机用不了了,那我还不如把他们全部分配给虚拟机)。鉴于拆分一个 IOMMU 组的操作对于我来说过于繁琐,所以干脆把那些设备都分配给虚拟机吧。反正虚拟机是软路由,让他管理所有网络设备也挺好。修改完设置就可以开机了。

编译 OpenWrt

OpenWrt 肯定是得自己编译一个,因为官方编译好的版本甚至都没有我那块无线网卡的驱动。编译嘛,也算得上简单,只要照着官方文档做就行(最好能有梯子,不然编译时的一些下载过程能够慢得让你怀疑人生)。配置的话,主要就是加上 Firmware -> ath10k-firmware-qca988x ,这是对我那块无线网卡 QCA9880 的支持。其他的模块可以根据自己喜好选择,一些好玩的小应用也可以随便挑些(比如 啥都扫个死 之类的)。然后 make downloadmake 就行。

第一次我是在那台小东西上编译的,因为编译完就可以立刻安装,看起来很方便。顺便也是测试一下 CPU 性能,还有就是发热量什么的(当时买的散热片还没有到,还记得硬件平台搭建那篇文章里扳手湿纸巾的照片吗)。编译过程超过一个小时,非常慢了,受不了,所以后面都是在 302 的喷气式发动机(一台8核、16G内存的刀片服务器,因其开机自检时风扇发出的强大声浪而得名“喷气式发动机”)上编译的。不过这个编译过程还是让我对这个小东西的发热量有了一定的认识,CPU 100% 时无风扇是能十分勉强地压住的,基本稳定在70摄氏度上下,平时 CPU 跑不满 100% ,就完全没有问题了。

编译完,设置虚拟机,启动。

网络配置

网络配置的难点,其实主要不在那几个真的网卡的配置上。因为都直通给虚拟机了,所以在 OpenWrt 里设置非常简单。难点主要在于配置虚拟机的 OpenWrt 与外面宿主机的 Ubuntu 之间的网络。

如果是对虚拟机的有一些了解的人,他们第一反应肯定是 “桥接” 嘛。我们再来回顾一下虚拟机网络的几大经典模式 NAT、Bridged、Host-only、Internal

Mode VM -> Host VM <- Host VM1 <> VM2 VM -> Net/LAN VM <- Net/LAN
Host-only + + + - -
Internal - - + - -
Bridged + + + + +
NAT + Port forward - + Port forward
NAT Service + Port forward + + Port forward

参考 Oracle VM VirtualBox 的文档,的确桥接就能达到要求。但是 VirtualBox 桥接网络的配置应该是建立一个虚拟机虚拟网卡到宿主机真实网卡的一个虚拟网桥。用 KVM 也可以这样配置,但是我已经把仅有的两个以太网卡、一个无线网卡直通给虚拟机了,没有多余的网卡可以用于设置桥接。

不过幸运的是, KVM 可以自己设置虚拟网络,并不需要局限于某几种固定的网络结构。我随便摸索了一下,网通了。大概就是,新建一个虚拟网桥virbr1,虚拟机添加虚拟网络连接到虚拟网桥。然后 Openwrt 里将虚拟网卡桥接到其他几个 LAN 端的网卡上,宿主机设置 virbr1 接口的 ip 地址为 LAN 端网络的一个 ip 地址,设置宿主机路由表,设置 Openwrt 路由表。然后宿主机和 LAN 端其他设备都互通了。其实我完全搞不明白发生了什么,我现在连这一通虚拟设备、虚拟网络这些设置的东西在逻辑上是什么结构都不清楚,不过网络通了。设置虚拟机的虚拟网卡为 virtnet 之后,实测虚拟机和宿主机之间传输速率能达到 10Gbps ,看起来就不会有什么瓶颈了。

有空我得好好理解一下这里面的配置

剩余的工作

网络都设置好之后其实问题就很简单了。安装配置 smb ,设置自动挂载硬盘。但是,非常奇怪的是,通过无线局域网访问 smb 时,传输速率只有不到 30MBps ,也就是 240Mbps ,远没有达到千兆位每秒。用 iperf3 测试了一下,通过 WiFi 连接软路由时,设备与软路由之间只有 300Mbps 左右的传输速率(设备紧贴路由器),那么就怪不得了,估计是无线的配置上、无线网卡的驱动、或者别的什么玄学的地方还有点问题了,有空再研究一下。

但是当我通过以太网连接, smb 的下载速率仍然不过 80MBps ,也就是 640Mbps ,也还是远没有达到千兆位以太网的传输速率。 iperf3 测速没问题, 1000Mbps 上下,那这少了几百兆位每秒的速率是怎么回事呢。硬盘读写速率没问题,本机拷贝的话 200MBps 左右,本机使用 smb 下载也差不多有 200MBps。那就很玄学了,有空再看看瓶颈在哪,看看怎么可以优化一下。


关于OpenWrt

最开始真正接触软路由,是大二的时候,在科协。尹大人在一台老旧的主机上跑个 OpenWrt ,那个机子有四个网卡(两LAN两WAN)。两个WAN一个走翼讯出,一个走校园网出,两个LAN接两个无线AP。效果就是睿思等校内流量走校园网,其他流量走翼讯,两个WiFi中一个是普通的,一个带透明代理。初见很是惊奇,未曾想过竟能如此优雅地配置网络。

那时的我,刚好大一结束的暑假刚看完一本计算机网络的入门教材(也是尹大人推荐的,《计算机网络 自顶向下方法》),对计算机网络充满兴趣。而 OpenWrt 在那时的我看来是一个完美的学习平台,可以检验我对很多计算机网络基础知识的认识,而且事实上也让我认识到自己对书上看的理解得太肤浅。所以从那时起我就慢慢玩起了 OpenWrt ,开始是直接官网下载固件来玩,后来也尝试照着文档自己编译来玩(特别是当发现官方提供的 Raspberry Pi 3B+ 的固件不能正常使用)。

不过其实到今天我也还只是稍微改几个配置然后编译,然后能用就不管的水平。比起尹大人,平均一天一编译,对每个配置项都了如指掌,甚至亲自修改源码,我算是非常肤浅的用户了。