<br />
<br />
docker中运行openwrt作主路由(wan口pppoe拨号、动态地址获取等)
前言:
虚拟机中跑openwrt存在性能损失,docker中使用openwrt性能损失较小,由于Docker容器共享宿主机的操作系统内核,因此资源利用率相对较高,容器可以直接访问宿主机的网络接口,并且可以非常高效地进行网络通信。建议通过docker使用openwrt作为主路由,参考:
Docker与虚拟机性能比较 - v魂之挽歌 - 博客园
Docker与虚拟机:性能比较
Docker 容器与虚拟机在网络性能方面的差异_docker与虚拟机性能比较-CSDN博客
———part1 在docker中运行openwrt作主路由设置———
准备工作:
请开启无线路由器AP的dhcp功能,默认网关设置为docker主路由地址,dns设置为主路由地址,nas主路由lan口通过交换机接无线路由器lan口,方便docker主路由更新、维护时连接nas。
ps:若由docker主路由开启dhcp功能,一旦主路由更新、维护,会导致无法连接nas,无法设置docker
获取超级用户(SU)权限:
sudo -i
输入用户密码,回车
查看网口情况:
ifconfig
输出以下内容
enp2s0: flags=4419<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.4 netmask 255.255.255.0 broadcast 192.168.1.255
ether xx:xx:xx:xx:xx:xx txqueuelen 1000 (Ethernet)
RX packets 835394 bytes 1122074499 (1.0 GiB)
RX errors 0 dropped 4720 overruns 0 frame 0
TX packets 289472 bytes 85663961 (81.6 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device memory 0x80800000-808fffff
enp3s0: flags=4419<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.6.111 netmask 255.255.255.0 broadcast 192.168.6.255
inet6 fe80::xxxx:xxxx:xxxx:xxxx prefixlen 64 scopeid 0x20<link>
ether xx:xx:xx:xx:xx:xx txqueuelen 1000 (Ethernet)
RX packets 216925 bytes 79441155 (75.7 MiB)
RX errors 0 dropped 1754 overruns 0 frame 0
TX packets 44369 bytes 6535667 (6.2 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device memory 0x80500000-805fffff
确定wan和lan与物理网卡的对应关系:
我这里设置enp2s0为wan,enp3s0为lan,若不同请自行更换对应命令
设置飞牛中的网络环境,将相关命令通过服务的方式加入开机启动
sudo nano /etc/systemd/system/me_to_op.service
[Unit]
Description=MACVLAN Configuration for me_to_op
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c "ip link set enp2s0 promisc on; ip link set enp3s0 promisc on; ip link del me_to_op || true; ip link add me_to_op link enp3s0 type macvlan mode bridge; ip addr add 192.168.6.6 dev me_to_op; ip link set me_to_op up; ip route add 192.168.6.1 dev me_to_op; route add default gw 192.168.6.1 me_to_op; echo 'nameserver 192.168.6.1' > /etc/resolv.conf"
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
上述服务中的命令解释(不需要输入以下命令)
sudo ip link set enp2s0 promisc on #设置网口混杂
sudo ip link set enp3s0 promisc on #设置网口混杂
因为 macvlan 的安全机制,宿主机与容器内不能通过 macvlan 数据互通,但是 macvlan 之间可以互通,增加macvlan接口
sudo ip link del me_to_op #删除之前残留设置
sudo ip link add me_to_op link enp3s0 type macvlan mode bridge #新建me_to_op接口(类型macvlan)注意网卡对应关系,这里使用lan口的物理网卡作为macvlan的对应接口
sudo ip addr add 192.168.6.6 dev me_to_op #设置本机在me_to_op接口的ip地址
sudo ip link set me_to_op up #启动me_to_op接口
sudo ip route add 192.168.6.1 dev me_to_op #修改路由,通过me_to_op接口访问openwrt,避免宿主机与容器之间无法访问的问题
sudo route add default gw 192.168.6.1 me_to_op #修改默认路由
sudo sh -c 'echo "nameserver 192.168.6.1" > /etc/resolv.conf' #修改dns服务器地址
#重新加载 Systemd 以使更改生效
sudo systemctl daemon-reload
#启用服务
sudo systemctl enable me_to_op.service
#启动服务
sudo systemctl start me_to_op.service
#检查服务状态
sudo systemctl status me_to_op.service
创建docker网络
注意物理网卡对应关系op_lan在openwrt中作为lan口使用,op_wan在openwrt中作为wan口使用
docker network create -d macvlan --subnet=192.168.6.0/24 --gateway=192.168.6.1 -o parent=enp3s0 op_lan
docker network create -d macvlan -o parent=enp2s0 op_wan
导入docker镜像、创建并启动容器
(网口是顺序连接的,不能同时连接,同时连接可能造成openwrt中的网口不能对应的正确分配)
docker run --restart always --name immortalwrt -d \
--network op_lan \
--privileged \
jessekool/immortalwrt_multiple_ethports:latest /sbin/init
docker network connect op_wan immortalwrt
进入openwrt内部修改网口设置
# 进入openwrt镜像内部
docker exec -it openwrt bash
vim /etc/config/network
修改 lan 口ip地址(option ipaddr)
config interface 'lan'
option type 'bridge'
option ifname 'eth0'
option proto 'static'
option netmask '255.255.255.0'
option ip6assign '60'
option ipaddr '192.168.6.1'
#重启openwrt网络
/etc/init.d/network restart
然后浏览器输入192.168.6.1即可进入 openwrt 的后台管理页面(用户名root,密码root,不同openwrt不同,根据自己选择的openwrt进行输入,一般来说密码为password或root)
参考
N100双网口小主机使用docker版openwrt做主路由(PPPoE拨号)超详细!!!!-CSDN博客
————part2 自编译immortalwrt docker容器更新————
请勿尝试通过docker管理界面镜像管理更新容器(将造成数据丢失恢复出厂设置),请务必使用脚本更新
++++++++++请勿自行逐条输入ssh命令更新,将导致连接中断无法操作++++++++++
新建并编辑一个脚本
nano update_immortalwrt.sh
复制并粘贴以下代码
请根据实际情况设置BACKUP_DIRBACKUP_DIR将作为备份文件储存目录
#!/bin/bash
# 设置变量,请根据实际情况设置 BACKUP_DIR
BACKUP_DIR="/vol1/1000/docker"
BACKUP_FILE="$BACKUP_DIR/immortalwrt_backup.tar.gz"
IMAGE_NAME="jessekool/immortalwrt_multiple_ethports:latest"
# 检查并创建 BACKUP_DIR 目录(如果不存在)
if [ ! -d "$BACKUP_DIR" ]; then
echo "目录 $BACKUP_DIR 不存在,正在创建..."
mkdir -p "$BACKUP_DIR"
fi
# 在旧容器运行期间拉取最新镜像(此时网络正常)
echo "正在拉取最新镜像 $IMAGE_NAME..."
if ! docker pull "$IMAGE_NAME"; then
echo "错误:拉取镜像失败,请检查网络连接!"
exit 1
fi
# 检查原容器是否存在
if docker ps -a --format '{{.Names}}' | grep -q "^immortalwrt$"; then
echo "原容器 immortalwrt 存在,正在备份配置..."
# 在原容器中使用 sysupgrade -b 备份配置到 /root/backup.tar.gz
docker exec immortalwrt sysupgrade -b /root/backup.tar.gz
# 检查备份文件是否生成
if docker exec immortalwrt ls /root/backup.tar.gz > /dev/null 2>&1; then
echo "备份文件已生成,正在复制到主机..."
docker cp immortalwrt:/root/backup.tar.gz "$BACKUP_FILE"
# 检查 /etc/AdGuardHome.yaml 是否存在
if docker exec immortalwrt ls /etc/AdGuardHome.yaml > /dev/null 2>&1; then
echo "/etc/AdGuardHome.yaml 存在,正在备份..."
docker exec immortalwrt tar -czf /root/backup_adguard.tar.gz -C / etc/AdGuardHome.yaml
docker cp immortalwrt:/root/backup_adguard.tar.gz "$BACKUP_DIR/backup_adguard.tar.gz"
# 合并备份文件
echo "正在合并备份文件..."
mkdir -p "$BACKUP_DIR/tmp"
tar -xf "$BACKUP_FILE" -C "$BACKUP_DIR/tmp"
tar -xf "$BACKUP_DIR/backup_adguard.tar.gz" -C "$BACKUP_DIR/tmp"
tar -czf "$BACKUP_FILE" -C "$BACKUP_DIR/tmp" .
# 清理临时文件
rm -rf "$BACKUP_DIR/tmp" "$BACKUP_DIR/backup_adguard.tar.gz"
else
echo "/etc/AdGuardHome.yaml 不存在,跳过备份该文件。"
fi
echo "配置已备份到 $BACKUP_FILE"
else
echo "备份文件未生成,请检查容器日志。"
exit 1
fi
else
echo "原容器 immortalwrt 不存在,跳过备份配置。"
fi
# 停止并移除旧的容器(如果存在)
if docker ps -a --format '{{.Names}}' | grep -q "^immortalwrt$"; then
echo "正在停止并移除旧容器 immortalwrt..."
docker stop immortalwrt
sleep 10
docker rm -f immortalwrt
fi
# 运行新的容器
echo "正在启动新容器 immortalwrt..."
docker run --restart always \
--name immortalwrt \
-d --network op_lan --privileged \
"$IMAGE_NAME" /sbin/init
# 将容器连接到指定网络
echo "正在将容器连接到 op_wan 网络..."
docker network connect op_wan immortalwrt
# 等待容器完全启动
echo "等待容器完全启动..."
sleep 20 # 根据实际情况调整等待时间
# 将备份文件复制到新容器中
if [ -f "$BACKUP_FILE" ]; then
echo "正在将备份文件复制到新容器中..."
docker cp "$BACKUP_FILE" immortalwrt:/root/backup.tar.gz
# 在新容器中恢复备份
echo "正在新容器中恢复备份..."
docker exec immortalwrt tar -xzf /root/backup.tar.gz -C / --overwrite
docker exec immortalwrt rm /root/backup.tar.gz
echo "备份已恢复到新容器中。"
# 重启容器以确保配置生效
echo "正在重启容器以应用配置..."
docker restart immortalwrt
sleep 10 # 等待容器重启完成
else
echo "未找到备份文件,跳过恢复步骤。"
fi
# 清理旧镜像
echo "清理未使用的旧镜像..."
docker image prune -f
echo "脚本执行完成。"
ctrl+X
输入“y”,回车
设置脚本权限
chmod +x update_immortalwrt.sh
通过nohup执行脚本,避免网络变化导致执行中断
nohup ./update_immortalwrt.sh &