AX9000使用docker
步骤/目录:
1.背景介绍
2.准备工作
3.安装与使用docker
(1)portainer
(2)busybox开启SSH
(3)docker-compose
(4)adguardhome
4.收尾及注意事项
(1)docker备份
(2)注意事项
附录:
(1)AX9000上adguardhome开启v6失败
本文首发于个人博客https://lisper517.top/index.php/archives/423/
,转载请注明出处。
本文的目的是在小米AX9000路由器上开启docker。
本文写作日期为2024年1月18日,主要参考了 参考文章一 和 参考文章二 和 小米论坛 。
1.背景介绍
2021年小米出了一款 AX9000旗舰路由器 ,其主要参数如下:
处理器:Qualcomm IPQ8072A 4核 A53 2.2GHz CPU
⽹络加速引擎:双核 1.7GHz NPU
内存:1GB
2.4G Wi-Fi:4×4(最高支持 IEEE 802.11ax协议,理论最高速率可达 1148Mbps)
5.2G Wi-Fi:4×4(最高支持 IEEE 802.11ax协议,理论最高速率可达 4804Mbps)
5.8G Wi-Fi:4×4(最高支持 IEEE 802.11ax协议,理论最高速率可达 2402Mbps)
产品天线:外置高增益天线 + 内置 AIoT天线
产品散热:主动散热
整机接口:1个10/100/1000/2500M 自适应 WAN/LAN口(Auto MDI/MDIX)
1个10/100/1000M 自适应 WAN/LAN口(Auto MDI/MDIX)
3个10/100/1000M 自适应 LAN口(Auto MDI/MDIX)
它有2.4G、5.2G、5.8G三个频段的wifi,网口正常使用时1个2.5G入口,4个千兆出口。这款路由器刚出来时售价¥999,后来涨到¥1299,偶尔有折扣也会卖¥999。另外2023年又出了万兆路由器(¥1799,折扣时¥1599),外观和其它参数差不多,但是网口是2个万兆、4个2.5G。
这款路由器是 4核2.2GHz的CPU + 1G内存 ,性能和可玩性比较强,刚好小米官方提供了能装docker的固件。接下来就展示使用官方固件使用docker、开启ssh。需要说明的是,AX9000有稳定版和开发版固件,其中只有开发版能装docker。目前小米的路由器应该只有AX9000的开发版固件,和万兆路由器的稳定版能装docker,其它厂商不知道有无官固docker。
2.准备工作
首先做一些准备。
(1)小米路由器修复工具:到 小米官网 ,在下面有一个 小米路由器修复工具
。如果出了什么问题,可以尝试用这个工具拯救路由器,但它也不是万能的。另外该工具会报毒,需要允许运行。
(2)开发版固件:点击旁边的ROM(即固件),下载小米路由器AX9000的开发版即可。目前该开发版固件最后一次更新是2021年11月12日,估计以后也不会再更新了。
(3)路由器备份:在路由器后台, 常用设置-系统状态-备份与恢复
里,把当前的路由器的大部分设置备份一下,方便恢复。
(4)U盘准备:准备一个至少64GB的U盘,在windows上用diskgenius(一个windows下管理存储器的强大软件, 官网 的免费版本就能格式化)格式化为ext4,或者在ubuntu下 unmount
并 mkfs.ext4 /dev/xxx
。由于路由器的存储空间、内存不够,所以docker需要装在该u盘中,并且该u盘可以划出虚拟内存(因此最好不要用机械硬盘)。也可以用固态硬盘,稍微有点奢侈,不过最近固态都比较便宜。这个u盘会被挂载到 /mnt/docker_disk
下(同时也在 /extdisks/分区一名称
下)。
该u盘的所有要求如下:有32GB以上的空闲空间;如果有多个分区,需要保证第一个分区为ext4格式,不能用sd卡。
3.安装与使用docker
登录路由器后台,在 常用设置-系统状态-升级检测
里,选择 手动升级
,使用刚才下载的开发版固件。升级过程中切勿断电、重启,可以用UPS保险。升级完成后登录路由器后台,初始设置一下,然后把备份好的设置恢复一下(有些设置无法备份,需要手动恢复)。设置完成后重启,等待重启时可以插上u盘。
重启后到 存储状态
中可以看到u盘已被识别,在 高级设置
下找到Docker,安装并使用docker。值得注意的是 虚拟内存
选项,AX9000的内存为1GB,一般的u盘读取大概在百兆、写入可能在20-100MB/s。如果你要在路由器上运行很多容器的话可以划虚拟内存,但虚拟内存的读写速度比较慢,也可以把u盘换成读写更快的固态硬盘,但是笔者更建议尽量把docker容器放在电脑上。
接下来笔者装一些容器以演示。也可以装其它的容器,只要镜像的tags支持 linux/arm64
即可(最好能支持 linux/aarch64
)。
(1)portainer
一个管理docker容器的容器。只要在路由器后台打开 允许Docker
,并 安装第三方管理
即可。其端口映射为 8001:8000
和 9001:9000
,HTTP网页管理端口在9001,默认用户名密码都是 admin
。
(2)busybox开启SSH
busybox用于开启SSH。需要注意的是,重启路由器后SSH会关闭。这个容器需要在portainer中开启,但是却不需要挂载卷。再portainer网页上( 192.168.31.1:9001
)如下操作:
a.选择 Home - Containers - +Add container
,容器名和镜像名都填 busybox
;
b.下面的 Advanced container settings
中的 Command & logging
的 Console
里把 None
改成 Interactive & TTY (-i -t)
;
c.换到 Volumes
页,添加挂载( + map additional volume
),容器(container)旁边要选 Bind
,宿主机(host)应该是 Writable
,并把宿主机的 /
根目录挂载到容器的 /mnt
下。
d.最后点上面的 Deploy the container
即可部署容器。
busybox容器创建完成后,在 Home - Containers
中点击容器名、进入容器详情页,点击 Container status - Attach
,运行如下命令:
chroot /mnt
也可以用Console而非Attach,在Console中 Use custom command
,命令同样为 chroot /mnt
。
不管Console还是Attach,这里其实已经可以用ash了,如果你只是想用ssh,可以就在portainer里用。如果需要刷其它系统或者备份docker,才有必要进行下面的步骤,以通过portainer以外的客户端连接ssh。
cp /etc/init.d/dropbear /etc/init.d/dropbear_backup
vi /etc/init.d/dropbear
如果不会用vi,可自行查找教程(简单来说,vi中按 /
查找,按 i
更改,按esc并 wq
写入+保存)。总之,该文件有如下几行:
start_service()
{
# .....................ssh......
flg_ssh=`nvram get ssh_en`
channel=`/sbin/uci get /usr/share/xiaoqiang/xiaoqiang_version.version.CHANNEL`
if [ "$flg_ssh" != "1" -o "$channel" = "release" ]; then
return 0
fi
[ -s /etc/dropbear/dropbear_rsa_host_key ] || keygen
. /lib/functions.sh
. /lib/functions/network.sh
注释头几行,完成后如下:
start_service()
{
# .....................ssh......
#flg_ssh=`nvram get ssh_en`
#channel=`/sbin/uci get /usr/share/xiaoqiang/xiaoqiang_version.version.CHANNEL`
#if [ "$flg_ssh" != "1" -o "$channel" = "release" ]; then
# return 0
#fi
[ -s /etc/dropbear/dropbear_rsa_host_key ] || keygen
. /lib/functions.sh
. /lib/functions/network.sh
最后运行 /etc/init.d/dropbear start
即可开启SSH,root的密码可以到 这个网站 ,根据路由器底部的SN码计算得出,或者直接 passwd root
修改密码。打开SSH后,可以用docker-compose来管理容器,见下文。
另外,这里的SSH并未固化,所以重启路由器后还需要手动开启SSH。因为路由器的SSH其实不是很常用,这应该不是什么问题,需要的时候打开就行了,如果怕安全性问题,可以 /etc/init.d/dropbear stop
关闭SSH(后面的备份docker则需要保证SSH常开)。
笔者日常使用时,虽然并未固化SSH,但每次重启后还是能SSH登录,portainer后台看到busybox并没有启动,不知道怎么回事。
(3)docker-compose
用putty或者MobaXterm等软件,或者就在portainer里连接SSH,然后执行以下命令:
docker -v
curl -L https://github.com/docker/compose/releases/download/v2.24.1/docker-compose-`uname -s`-`uname -m` > /mnt/docker_disk/docker-compose
chmod +x /mnt/docker_disk/docker-compose
ln -s /mnt/docker_disk/docker-compose /usr/bin/docker-compose
docker-compose -v
笔者实验时AX9000用的是19.03.15版本docker。国内从github下载docker-compose有点慢,笔者更推荐手动下载,用MobaXterm或者WinSCP上传,网址为 https://github.com/docker/compose/releases/download/v2.24.1/docker-compose-Linux-aarch64
(可以到 https://github.com/docker/compose/releases
看docker-compose最新版本号)。如果用老版本,注意docker-compose从v2.0.1后才支持Linux-aarch64。
(4)adguardhome
一个拦截广告的软件。基本的安装过程与设置见 自建DNS与广告过滤-adguardhome与pihole ,这里提醒yml改成如下(只去掉了53端口映射):
version: '3.8'
services:
adguardhome:
image: 'adguard/adguardhome'
container_name: adguardhome
ports:
- '3000:3000' #网页UI,初始配置端口
- '8500:80' #网页UI,后续配置端口
volumes:
- ./data/adguardhome:/opt/adguardhome/work
- ./conf/adguardhome:/opt/adguardhome/conf
restart: unless-stopped
因为是AX9000上建DNS,自己找自己解析,所以可以不映射53。在portainer的容器管理页中找到adguardhome的 IP Address
这一列(172开头,可能是 172.18.0.2
之类的),到AX9000路由器管理页, 常用设置 - 上网设置
里,把ipv4的DNS1和DNS2都改成该172的ip即可(注意,光改DNS是无法保存的,需要改一下 自动配置
、 手动配置
之类其它的东西)。
另外,AX9000上装的adguardhome不能过滤ipv6广告或做v6的DNS,笔者实践过程及参考资料见附录。
4.收尾及注意事项
(1)docker备份
笔者的习惯是所有docker数据都放在 /mnt/docker_disk/docker
下,备份时只需要在crontab中添加。
mkdir /mnt/docker_disk/backup
/bin/tar -zcf /mnt/docker_disk/backup/docker.tar.gz /mnt/docker_disk/docker
crontab -e
备份的命令确认运行无误后,在crontab中添加一行:
0 23 * * * /bin/tar -zcf /mnt/docker_disk/backup/docker.tar.gz /mnt/docker_disk/docker
然后从你的其它机器上scp到AX9000(或者,由于AX9000可以开samba,你也可以把备份文件放到分享硬盘上,但是默认的SMB是无加密的,请谨慎),或者从AX9000主动scp到其它机器上,备份tar.gz文件。比如后者,那么就在AX9000的crontab中修改:
0 23 * * * /bin/tar -zcf /mnt/docker_disk/backup/docker.tar.gz /mnt/docker_disk/docker && /usr/bin/scp -i 你的密钥 /mnt/docker_disk/backup/docker.tar.gz root@其它机器的ip:/backup/AX9000
这里使用了密钥,要注意openssh的密钥对于dropbear来说太长了,要用dropbear生成的密钥( 参考文章 )放到其它机器上。
如果你是用其它机器连到AX9000,可参考如下命令:
/usr/bin/sshpass -p "AX9000的密码" /usr/bin/scp -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa root@192.168.31.1:/mnt/docker_disk/backup/docker.tar.gz /backup/AX9000
(2)注意事项
摘自前文提到的小米论坛。
a.docker与防火墙:由于docker与防火墙有冲突(经典问题,因为docker和系统都是更改iptables,参考 这个问题 ),建议: 关闭docker -> 修改防火墙 -> 开启docker 。
b.由于docker运行时关机或重启可能导致错误,建议重启前,或者更改一些配置需要重启前,先做好备份,再关闭docker,最后重启。
c.官方建议容器勿超过3个,笔者建议根据内存使用情况来。
d.开启docker时想拔下u盘,应先到 存储状态
页面安全移出硬盘。
附录:
(1)AX9000上adguardhome开启v6失败
和 自建DNS与广告过滤-adguardhome与pihole 中一样,试图通过macvlan为adguardhome开通ipv6:
docker network create -d macvlan \
--subnet=192.168.31.0/24 \
--gateway=192.168.31.1 \
--ipv6 \
--subnet=fe80:7eb5:2afd::/64 \
--gateway=fe80:7eb5:2afd::1 \
-o parent=br-lan \
macvlan_net
在AX9000的SSH中 ifconfig
看到 192.168.31.1
绑定在 br-lan
网卡设备上,在上面的命令中也已进行了修改。yml为:
version: "3"
services:
adguardhome:
image: adguard/adguardhome
container_name: adguardhome
volumes:
- ./data/adguardhome:/opt/adguardhome/work
- ./conf/adguardhome:/opt/adguardhome/conf
restart: unless-stopped
networks:
macvlan_net:
ipv4_address: 192.168.31.50
ipv6_address: fe80:7eb5:2afd::50
networks:
macvlan_net:
external: true
docker-compose up
时输出:
Error response from daemon: failed to create the macvlan port: operation not supported
小米路由器的系统是openwrt改的,上面的报错说明没有装macvlan包。装macvlan:
opkg install kmod-macvlan
#输出 Unknown package 'kmod-macvlan'. ,说明找不到这个包
opkg update
更新一下软件源,出来一堆错误:
Downloading http://downloads.openwrt.org/releases/18.06-SNAPSHOT/targets/ipq/ipq807x_64/packages/Packages.gz
wget: server returned error: HTTP/1.1 404 Not Found
*** Failed to download the package list from http://downloads.openwrt.org/releases/18.06-SNAPSHOT/targets/ipq/ipq807x_64/packages/Packages.gz
...
意思是没有这个网址。浏览器访问一下,果然 http://downloads.openwrt.org/releases/
下没有 18.06-SNAPSHOT
这个版本。到国内的清华镜像源 https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases/
看,也没有这个版本。
再次确认一下版本号:
ubus call system board
输出:
"version": "18.06-SNAPSHOT",
确实是这个版本。
寻找补救方法:
a.更换版本号: 提问一 和 提问二 中也是发现官方源没有 18.06-SNAPSHOT 的包,分别把源改到了 18.06.0 和 18.06.1 版本( vi /etc/opkg/distfeeds.conf
)。或许能运行,但不能保证以后的稳定性。
b.修补: 小米AX1800修复opkg404 中对系统进行修改,但AX1800的方法不一定适用于AX9000,芯片可能不一样。
c.根据 恩山论坛 的说法,在2023-07之后,openwrt官方已删除 18.06-SNAPSHOT 的源,可以 vi /etc/opkg/distfeeds.conf
替换为如下源:
src/gz openwrt_base http://downloads.openwrt.org/releases/packages-18.06/aarch64_cortex-a53/base
src/gz openwrt_packages http://downloads.openwrt.org/releases/packages-18.06/aarch64_cortex-a53/packages/
src/gz openwrt_routing http://downloads.openwrt.org/releases/packages-18.06/aarch64_cortex-a53/routing
可以正常 opkg update
,但是 opkg install kmod-macvlan
仍然显示 Unknown package 'kmod-macvlan'.
,笔者便没有进一步尝试。