我正在尝试在我的 Raspberry Pi 上设置 OpenThread 边界路由器 (OTBR)。当按照官方指南中的建议在 Docker 容器中运行 OTBR 时,Google Home 或其他应用程序无法连接到它。
启动 docker 容器时:
docker run --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" -p 8080:80 --dns=127.0.0.1 -it --volume /dev/ttyACM0:/dev/ttyACM0 --privileged openthread/otbr --radio-url spinel+hdlc+uart:///dev/ttyACM0
没有应用程序可以连接到边界路由器。但是,如果我事先在主机上执行这些命令:
sudo sysctl -w net.ipv6.conf.all.disable_ipv6=0
sudo sysctl -w net.ipv4.conf.all.forwarding=1
sudo sysctl -w net.ipv6.conf.all.forwarding=1
然后像这样启动容器
docker run --net=host --dns=127.0.0.1 -it --volume /dev/ttyACM0:/dev/ttyACM0 --privileged openthread/otbr --radio-url spinel+hdlc+uart:///dev/ttyACM0
一切都按预期进行,应用程序可以连接到边界路由器。因为我的主机上已经有一个使用端口 80 的容器,所以我想使用自定义 docker 网络。我不太确定如何做到这一点,因为线程通信至少需要 IPv6 和 UDP 数据包才能进行 DNS 发现。你对此有什么想法吗?
也许你可以使用像 nginx 这样的网关,这样你就可以有尽可能多的容器同时监听端口 80,例如想象一个服务器有多个网站,所有网站同时监听端口 80 和 443时间,实际上 nginx 作为网关监听 80 和 443 并根据请求 url,将请求传递到正确的 web 应用程序,在本地计算机中,您可以修改 /etc/hosts 并添加自定义主机名并执行类似的技巧,所以:
为容器设置主机名,将主机名映射到 /etc/hosts 中的容器 IP 地址,然后设置 nginx
使用
--net=host
运行容器可以解决连接问题。此模式使容器使用主机的网络堆栈,这意味着主机已正确配置为 IPv6。因此,当多个容器需要侦听相同端口(例如 80 和 443)时,您可以尝试解决在 Docker 中设置 OTBR 的要求,重点关注 IPv6 网络,而不是使用 Nginx 作为反向代理来处理端口冲突。
尝试创建一个支持 IPv6 的 Docker 网络,因为 OTBR 需要 IPv6 才能实现正常功能:
docker network create --ipv6 --subnet fd12:3456:789a::/64 my_custom_network
然后在您的自定义网络上启动 OTBR 容器,确保 IPv6 设置正确并转发必要的端口。如果 80 被占用,请将
8080
替换为未使用的端口:
docker run --network my_custom_network \
--sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" \
-p 8080:80 --dns=127.0.0.1 -it \
--volume /dev/ttyACM0:/dev/ttyACM0 --privileged \
openthread/otbr --radio-url spinel+hdlc+uart:///dev/ttyACM0
确保 Raspberry Pi 的防火墙和路由设置允许 IPv6 流量以及必要端口的转发。
并仔细检查 Raspberry Pi 上的 DNS 服务器是否配置为处理来自容器的请求,尤其是在使用
--dns=127.0.0.1
时。