使用lxc搭建openwrt旁路由
最近闲着无聊折腾了下放在客厅里的x86小nas,装了个openwrt作为旁路由用于分流上网。安装openwrt使用的方案既不是格盘重装,也不是exsi或者pve虚拟机安装,而是选择了安装在lxc容器里。本文不是正经教程,仅仅记录折腾时的思考和一些简单的步骤。
为什么不是虚拟机
最大的原因是这台nas已经稳定着omv系统用于nas服务,重装系统是不可能的。虚拟机本身的性能开销也是个大问题,有经验的朋友应该清楚,即使使用了virtio这样的半虚拟化驱动,虚拟机io仍然非常占用cpu。唯一的办法是硬件直通,而即便是硬件直通下,虚拟机的整体开销也比容器大一个数量级。
为什么是lxc
一句话简单科普下的话,lxc就是一个基于cgroup的linux容器技术。有些朋友就要问了,docker也是基于cgroup的,docker也能安装openwrt,为什么不选择鼎鼎有名的docker,而选择没什么人听说过的lxc呢?
一方面是lxc的实现方式。lxc实现了完整的系统容器化,这意味着在lxc容器里有完整的init生命周期和内核信号,完全可以当成一个仅支持linux系统的虚拟机使用。而docker的设计目标则是进程容器化。所谓的进程容器化就是一个容器里只跑一个进程,多进程分别安装在多个容器里。在docker里安装openwrt显然有悖于这一目标,即使可以通过/sbin/init方式来启动容器也会发生很多其他问题。
问题之一是网络支持。docker默认的桥接网络是only-host,不能用于路由。而host模式则直接无法启动openwrt,唯一可选的模式是macvlan。而macvlan有两个问题,其一是实现macvlan需要修改数据包包头并在内核io路径中做了特殊判断,这会带来可见的性能开销。其二是内核里macvlan与主机是单向隔离的,说人话就是容器里可以ping通主机但主机不能ping通容器。解决的办法有二,第一种是通过自定义路由表方式把数据包送出内核,让数据在交换机里转一圈再回来。第二种方式是新建一个macvlan方式的网桥并把主机网卡桥接上去,这样主机与容器处在同一个macvlan网络里,就不存在隔离问题了。这两种方案显然都会造成主机网络性能降低,对性能较低的小主机来说是无法接受的。而lxc则支持最普通的虚拟网桥,可以直接暴露在物理网络上,也可以无隔阂与主机通信。
问题之二是数据持久化问题。docker的设计思路是分层文件系统,容器里发生文件修改实际上是产生了一个新的数据层,这点容器构建来说非常友好,对运行无状态服务来说也没有丝毫问题,但是对openwrt这样时不时更新下软件包、更新下配置文件非常不友好。而lxc则简单粗暴很多,容器直接使用主机的一个文件夹或者块设备,维护与迁移都非常方便。
介于以上几个基本事实,至少在安装openwrt这件事上没有任何选择docker的理由。
如何使用lxc
借助搜索引擎的力量,可以发现openwrt官网上有wiki讲如何在lxc里安装openwrt。但里面的内容有些根本就是错的,建议朋友们不要去看了,浪费时间。
这里简单讲一下操作步骤给朋友们当作参考。首先是创建虚拟网桥。有很多方式可以创建一个虚拟网桥,因为没有绝对标准的方式所以这里不展开讲,只要把物理网卡桥接上了都行。
然后是安装lxc的工具集,同样要根据主机实际情况,debian系统的朋友可以使用apt直接安装。
# apt update && apt install -y lxc
接着在/var/lib/lxc文件夹下创建openwrt文件夹,再在里面创建rootfs文件夹和config文件。一定不能学官网教程上的把文件夹创建在用户文件夹里,那样容器是无法开机自启的。
接着去官网下载主机对应架构的rootfs.tar.gz压缩包,解压到rootfs文件夹里,此时的文件树类似这样。
接着编辑config文件,注释的地方是坑点需要特别注意。
我们还需要在容器启动前编辑容器的网卡配置。新建配置文件/var/lib/lxc/openwrt/etc/config/network,内容大致如下。
最后一步,执行lxc-start -n openwrt启动容器,然后执行lxc-attach -n openwrt进入容器内,使用opkg指令安装管理网页和其他工具。
opkg update && opkg install luci luci-i18n-base-zh-cn
至此局域网内就可以通过浏览器直接访问openwrt的管理网页。如何配制成旁路由分流上网不是本文重点不作赘叙。
![](https://res.smzdm.com/pc/pc_shequ/dist/img/the-end.png)
kyo101
校验提示文案
hehe911
校验提示文案
bbsingao
简单补充下, 最简单方法是lxc launch 官方op, 然后将自己编译的rootfs改了权限替代进去
校验提示文案
maiwst
校验提示文案
cocobolor
校验提示文案
Monkiq
校验提示文案
kylinlau
校验提示文案
天外来鸿
校验提示文案
狂风速想
校验提示文案
lpeody
校验提示文案
KingTam
校验提示文案
值友1240485243
校验提示文案
值友1240485243
校验提示文案
蓝小可
校验提示文案
嗨大帅
校验提示文案
利群无敌好抽
校验提示文案
尼摩船长88
校验提示文案
尼摩船长88
校验提示文案
Monkiq
校验提示文案
利群无敌好抽
校验提示文案
嗨大帅
校验提示文案
cocobolor
校验提示文案
maiwst
校验提示文案
蓝小可
校验提示文案
bbsingao
简单补充下, 最简单方法是lxc launch 官方op, 然后将自己编译的rootfs改了权限替代进去
校验提示文案
值友1240485243
校验提示文案
值友1240485243
校验提示文案
kylinlau
校验提示文案
KingTam
校验提示文案
hehe911
校验提示文案
lpeody
校验提示文案
狂风速想
校验提示文案
天外来鸿
校验提示文案
kyo101
校验提示文案