步骤/目录:
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下 unmountmkfs.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:80009001: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 & loggingConsole 里把 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'. ,笔者便没有进一步尝试。

标签: docker, AX9000, adguardhome

添加新评论