曾经使用的软路由是用PVE做底层,虚拟openwrt并直通网卡,然后再虚拟或者用lxc跑一个debian来运行一些docker应用。但是这样openwrt一旦挂掉要访问PVE的话需要把软路由直连电脑,比较麻烦。折腾PVE也会影响网络稳定性。既然现在openwrt已经原生支持了docker和lxc容器的创建和运行,于是打算直接裸跑openwrt,然后在openwrt下运行docker和lxc。
但是在实际使用openwrt上的docker时,遇到了很多问题,例如NAT环回失效(不能在内网用DDNS域名访问内网的服务。已解决)、docker端口直接暴露在路由器WAN口(我测试时,即使luci上没有选择“允许 WAN 访问 Dokcer”,WAN口依然可以访问docker的服务)、docker中无法访问外网,有时候还会莫名其妙无法访问容器的端口。
docker应该是会自动操作iptables,将流量转发到容器内部,但是在路由器上运行docker的话会把容器的端口暴露在WAN口,会有比较大的风险。docker官方似乎有提供解决方案。我初步测试了一下没成功,可能还需要进一步测试。
于是选择另辟蹊径,既然在内网的设备或者虚拟机上跑docker都没有这些问题,那直接在openwrt下先用lxc跑一个debian容器,相当于一台有自己独立IP的内网设备了,然后在debian中安装docker不就可以了。在解决各种问题之后,也算是达成了目标,在此记录一下。
在openwrt的lxc下运行docker,依然会用到openwrt的一些docker相关的内核特性,所以在编译openwrt的时候,最好还是把docker也编译上。我的openwrt云编译仓库: Actions · NagaseKouichi/Actions-OpenWrt (github.com) 。
在openwrt下用lxc运行debian容器的方法可以参考这里: 在 OpenWrt 上玩转 LXC 容器 | 美丽应用 (mlapp.cn) ,不过现在openwrt默认带的lxc4.0基本上各种容器都可以运行,不存在原文中debian高版本无法启动的问题。

debian容器的config文件中,删除这一行前面的注释,打开容器的嵌套功能:
lxc.include = /usr/share/lxc/config/nesting.conf
在最后添加这两行:
lxc.apparmor.profile = unconfined
lxc.cgroup.devices.allow = a
设置好debian容器的网络:
#Network configuration lxc.net.0.type = veth lxc.net.0.flags = up lxc.net.0.link = br-lan lxc.net.0.hwaddr = 26:06:06:94:e6:5b lxc.net.0.ipv4.address = 192.168.10.101/24 lxc.net.0.ipv4.gateway = 192.168.10.1
设置容器开机自动启动:
lxc.start.auto = 1
如果要把openwrt下某个目录映射给debian容器用来保存docker的持久化文件,可以添加映射:
lxc.mount.entry = /opt/docker mnt/docker/ none bind 0 0
然后启动debian容器,按照 Debian Docker 安装 | 菜鸟教程 (runoob.com) 安装docker。
安装的时候发现有报错:

运行/usr/bin/dockerd看看有什么报错:

看到有提示iptables权限问题,应该就是docker企图操作iptables结果失败了,参考 iptables: Operation not supported的解决方案_d3f4ult的博客-CSDN博客 运行:
update-alternatives --config iptables

选择1设置iptables手动模式后,再运行/usr/bin/dockerd试试

看来是可以了,这时重启debian容器就可以正常使用docker了。接下来就是docker的正常使用例如安装portainer之类,就不在此赘述了。
至于性能方面,因为LXC和docker都是通过用户空间来进行环境的隔离,所有的进程实际上还是运行在底层系统上,所以性能上应该和直接在openwrt下运行docker没有什么区别。但是在LXC虚拟的独立linux环境下运行docker,要比在openwrt下直接运行docker更加灵活。
Comments | NOTHING