Openwrt 在 Docker 下运行并作为旁路由
1.前言
这几天想试着玩一下Openwrt
来作旁路由,但是又没有软路由固件,后来考虑到Openwrt
也是基于 Linux 的,那么在 Docker Hub 上应该有其对应的镜像吧,然后查了下果真有。于是有了后续的操作 … …
推荐的镜像: zzsrv/openwrt
2.准备工作
建议是在虚拟机上安装一个 Linux 系统,我在实体机上(Linux 系统)试了下,是能成功,但是在该电脑上无法访问Openwrt
的 ip
地址,在其它设备(比如手机)能正常访问(需要多做一些配置)。
2.1 虚拟机安装
虚拟机在这里只推荐VirtualBox
。下载地址
还需要下载插件:点这里
或者点图片这里红色方框处的下载连接:
下载完后直接双击下载好后的扩展,就能自动安装到 VirtualBox 中。
2.2 Linux安装
推荐的 Linux 发行版:
- EndeavourOS
- CachyOS,建议下载
Desktop Edition
版本 - LinuxMint,建议下载
Xfce Edition
版本
前两个是Arch
系的发行版,LinuxMint
应该是Debian
系的发行版。我这里用的是CachyOS
,因为正好想尝试下这个发行版,好处是配置有国内的镜像源,下载东西嘎嘎快。
在安装时最好选择有桌面环境,并且桌面选择xfce4
,毕竟轻量嘛,在虚拟机里用着也会更流畅。当然,也可以不需要桌面环境,那么在安装时就必须把语言设置为英语,因为终端界面的中文会是乱码,而且没有图形化界面也不好配置。
2.3 虚拟机的创建
2.4 虚拟机的配置
创建完虚拟机后,需要对其进行配置:
网络配置:
显示配置
镜像挂载
2.5 安装系统
然后就是安装 Linux 系统,网上有很多教程,就不在这里讲了。
3.Docker 配置
3.1 安装 Docker
1 | sudo pamcn -S docker |
可以通过下面指令查看是否安装成功:
1 | sudo docker version |
如果输出类似下面内容就代表安装成功:
1 | Client: |
这里就不把当前用户组添加到docker
了,总之记住,后续 docker
的所有操作,都得用sudo docker
。
3.2 Docker 服务配置
开机自启动:
1
sudo systemctl enable docker
运行
docker
:1
sudo systemctl start docker
4.虚拟机内的网络配置
4.1 查看网络接口信息
查看网络接口:
1
2
3
4ip addr
# 或者(不一定能用,可能没有预装 net-tools)
ifconfig输出结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19~
❯ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:ff:93:f7 brd ff:ff:ff:ff:ff:ff
inet 192.168.2.23/24 brd 192.168.2.255 scope global dynamic noprefixroute enp0s3
valid_lft 85878sec preferred_lft 85878sec
inet6 fe80::d521:edc1:580f:1e00/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:8a:53:e6:cf brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
这里需要着重记下第二个enp0s3
接口,第一个和第三个不用管。从inet 192.168.2.23/24
可以知道虚拟机的ipaddr
是192.168.2.23
。
下面是三个网络接口的详细解释:
lo
(Loopback接口)
- 描述: 这是本地回环接口,用于主机内部的网络通信。它的IP地址是
127.0.0.1
,也被称为localhost
。 - 属性:
- IP 地址:
127.0.0.1/8
和::1/128
- 用途: 允许主机内部进程进行网络通信,而不实际发送数据到网络接口外部。适用于测试和进程间通信。
- 状态: 总是
UP
,表示接口始终可用。
- IP 地址:
enp0s3
(以太网接口)
- 描述: 这是一个物理以太网接口,通常用于连接到网络交换机或路由器。
- 属性:
- MAC 地址:
08:00:27:ff:93:f7
- IP 地址:
192.168.2.23/24
(子网掩码为255.255.255.0),它的广播地址是192.168.2.255
。 - IPv6 地址:
fe80::d521:edc1:580f:1e00/64
- 状态:
UP
,表示接口已激活并连接到网络。 - 用途: 用于连接到局域网或互联网,并提供主机的网络连接。
- MAC 地址:
docker0
(Docker虚拟网桥)
- 描述: 这是Docker默认创建的虚拟网桥,所有未指定其他网络的Docker容器默认连接到这个桥接网络。
- 属性:
- MAC 地址:
02:42:8a:53:e6:cf
- IP 地址:
172.17.0.1/16
,这是Docker的默认子网,用于容器之间的网络通信。 - 状态:
DOWN
,表示虚拟网桥目前没有活动的连接。即使接口状态是DOWN
,Docker可以在需要时自动启用它。 - 用途: 提供一个虚拟的网络环境,使Docker容器能够互相通信并访问网络。
- MAC 地址:
4.2 开启混杂模式(promisc)
开启网卡混杂模式,且虚拟机和docker里都要开启网卡混杂模式,这里网卡标记根据自己的填写:
1 | sudo ip link set enp0s3 promisc on |
注意:在我这里是对enp0s3
,但是每台电脑情况可能不一样,反正肯定是有ipaddr
的这个网络接口名。
4.3 建立 docker 子网
专门建立一个子网,且该网络与家里的局域网在一个网段,网段和网关填自己的:
1 | sudo docker network create -d macvlan --subnet=192.168.2.0/24 --gateway=192.168.2.1 -o parent=enp0s3 macnet |
参数说明:
subnet
是要写你自己路由器所在的那个 网段 。gateway
是要写你自己路由器所在的那个 网关 ,也就是路由器的ipaddr
。parent
是虚拟(子)网卡的真实父级网卡,也就是刚才看的本地网卡(第二个网络接口)。macnet
是子网名。
可以查看网卡是否创建成功:
1 | sudo docker network ls |
输出结果如下:
1 | NETWORK ID NAME DRIVER SCOPE |
解释:
这四个网络接口是在Docker中使用的不同类型的网络驱动程序。每个网络驱动程序具有不同的用途和功能:
bridge
网络
- 驱动程序 :
bridge
- 作用: 默认的网络驱动程序,提供容器之间的网络通信。它创建了一个虚拟网络桥(
docker0
),所有使用bridge
网络的容器都会连接到这个桥上。 - 使用场景 : 当你使用Docker创建容器并不指定自定义网络时,Docker默认会将容器连接到
bridge
网络。容器可以通过这个网络相互通信,也可以访问宿主机的网络。
host
网络
- 驱动程序:
host
- 作用 : 将容器的网络堆栈与宿主机的网络堆栈直接连接。这意味着容器不会获得一个独立的
IP
地址,而是使用宿主机的IP
地址。容器内的网络设置将与宿主机相同。 - 使用场景: 当你需要容器与宿主机之间的网络高度集成,或者需要容器直接使用宿主机的网络接口时,使用
host
网络。常用于性能优化或特殊网络配置需求。
macnet
网络
- 驱动程序:
macvlan
- 作用: 提供MAC地址级别的网络隔离。每个连接到
macvlan
网络的容器可以被分配一个独立的MAC地址,从而在网络中表现为独立的物理设备。 - 使用场景: 当需要在物理网络中隔离不同的容器,并且每个容器需要有一个独立的MAC地址时,使用
macvlan
网络。适用于需要直接与物理网络交换数据的容器,例如在一些网络设备上工作时。
none
网络
- 驱动程序:
null
- 作用: 容器不使用任何网络接口。它会创建一个没有网络连接的容器环境。
- 使用场景: 当你希望容器完全隔离于网络之外,不与任何网络通信时,使用
none
网络。这适用于需要完全网络隔离的容器场景,如某些安全或测试需求。
删除网卡(前提是要停止正在使用该网卡的容器):
1 | sudo docker network rm <网卡名> |
5.搭建 Openwrt
5.1 拉取镜像
可以通过阿里云镜像提升镜像拉取速度:
1 | sudo docker pull registry.cn-hangzhou.aliyuncs.com/zzsrv/openwrt:latest |
5.2 创建容器
1 | sudo docker run --restart always --name opt3 -d --network macnet --ip 192.168.2.3 --privileged registry.cn-hangzhou.aliyuncs.com/zzsrv/openwrt:latest /sbin/init |
参数说明:
run --restart
:设置容器的重启策略为“总是重启”。如果容器停止或Docker
守护进程重启,Docker
将自动重启这个容器。--network macnet
:指定容器连接到名为macnet
(我们刚刚创的那个子网卡)的Docker
网络。--ip 192.168.2.3
:为容器分配一个静态IP地址192.168.2.3
,在macnet
网络范围内。一定要确保该IP
地址在网络的子网中并且未被其他设备占用。/sbin/init
:容器启动时要执行的命令或程序。容器将运行/sbin/init
,这是 Openwrt系统中的初始化进程,通常是启动系统的第一步。
5.3 容器配置
进入容器内部:
1 | sudo docker exec -it opt3 /bin/sh |
配置网络:
1 | vi /etc/config/network |
按i
键进入编辑,esc
键退出编辑,:wq
保存并退出。
需要把ipaddr
设置为在创建容器时设置的IP
,即192.168.2.3
;gateway
和dns
都设置为网关地址(路由器地址),我的是192.168.2.1
。
重置网络使网络配置生效:
1 | /etc/init.d/network restart |
到这一步,整个流程就彻底结束了,回到主机,在浏览器输入地址192.168.2.3
(你自己的容器设置的IP
地址),应该就能进入Openwrt
的登录界面了,默认是没有密码可以直接点击登录的。
后面我先学一下怎么用OpenClash
,然后更新用OpenClash
科学上网的教程。
6.实体机中安装 docker + OpenWrt 的配置
6.1 问题说明
前面的步骤与在虚拟机中的一样,但是在创建并配置好 OpenWrt 的容器后,你会发现在宿主机中无法访问192.168.2.3
(创建的容器的ip addr),但是其它设备(前提是在同一个网关下,比如手机)是能成功访问192.168.2.3
的。
原因:
在Docker
中使用macvlan
网络驱动时,容器和宿主机的网络栈是分离的。这意味着:
- 容器的网络接口
192.168.2.3
是在macvlan
网络上,而宿主机的网络接口不能直接与macvlan
网络中的容器进行通信。 - 因为
macvlan
网络的特性,宿主机的网络接口不会自动知道macvlan
网络中的设备。
6.2 解决办法
6.2.1 创建 maclan 接口
创建一个名为macvlan0
的新虚拟网络接口,它基于物理接口enp0s3
:
1 | sudo ip link add macvlan0 link enp0s3 type macvlan mode bridge |
macvlan
允许在一个物理网络接口上创建多个虚拟网络接口,每个都有自己的 MAC 地址。桥接模式允许 macvlan 接口相互通信。
为这个新接口分配了 IP 地址192.168.2.250
,使其成为192.168.2.0/24
网络的一部分:
1 | sudo ip addr add 192.168.2.250/24 dev macvlan0 |
激活这个新接口,使其能够开始网络通信:
1 | sudo ip link set macvlan0 up |
注意需要把enp0s3
替换为自己实际的网络驱动接口。这个时候在浏览器输入192.168.2.3
就拿正常访问了。
这种配置的主要用途是允许主机直接参与到macvlan
网络中,这对于与 Docker macvlan 网络中的容器通信特别有用。它创建了一个”桥梁”,让主机能够与 macvlan 网络中的设备(如 Docker 容器)进行直接通信,而不需要通过 Docker 的网络栈。
6.2.2 撤销创建的 macvlan 配置
如果要删除创建的macvlan
接口,可以进行以下操作:
- 删除 IP 地址:
1
sudo ip addr del 192.168.2.250/24 dev macvlan0
- 关闭 macvlan 接口:
1
sudo ip link set macvlan0 down
- 删除 macvlan 接口:
1
sudo ip link del macvlan0
解释:
ip addr del
: 删除之前添加的 IP 地址ip link set down
: 关闭网络接口ip link del
: 完全删除网络接口
执行这些命令后,你创建的macvlan
接口及其配置就会被完全移除。
额外提示:
6.2.3 查看当前配置:
在执行这些步骤之前和之后,你可以使用以下命令查看网络配置,以确保更改已经生效:
1 | ip addr show |
保存配置:
如果你经常需要切换这些配置,可以考虑创建脚本来自动化这个过程。例如,创建一个脚本来添加配置,另一个脚本来删除配置。系统重启:
请注意,这些更改在系统重启后不会保持。如果你希望这些更改是永久的,需要将它们添加到网络配置文件中或创建一个系统启动脚本。小心操作:
在执行这些命令时要小心,特别是如果你是通过远程连接(如 SSH)管理系统。错误的网络配置可能会导致你失去对系统的访问。
7.参考教程
- Title: Openwrt 在 Docker 下运行并作为旁路由
- Author: loskyertt
- Created at : 2024-07-30 01:32:03
- Updated at : 2024-11-13 03:07:10
- Link: https://redefine.ohevan.com/2024/07/30/Docker-Openwrt/
- License: This work is licensed under CC BY-NC-SA 4.0.