前言
最近友人在使用 virt-manager 遇到了問題
大概會像這篇說的
https://www.reddit.com/r/linuxquestions/comments/1d72vie/cant_create_connection_in_qemuvirt_manager/?rdt=35516
dnsmasq: failed to create listening socket for 192.168.122.1: Address already in use
Root Cause
經過詢問後,在同一台機器上面,友人使用 Docker 起了一台 Adguard Home expose port bind 在 0.0.0.0:53
所以 dnsmasq 會報上面的錯誤
dnsmasq 是甚麼
Dnsmasq provides network infrastructure for small networks: DNS, DHCP, router advertisement and network boot
跟官網說明第一行說的一樣,他幫你做了簡單的 network infra,從 DNS, DHCP 到一些我不認識的服務(挖洞某天給自己補)。
dns port 預設會綁定在 53 port 上,所以這時候 dnsmasq 就會跟 docker 的 adguard home 撞。
其實碰撞的原因要講得更多一點會扯到 Linux 中如何判斷 port/addr 可以 bind 成功
https://www.cnblogs.com/schips/p/12553321.html 可以看這篇說明如果不用SO_REUSEADDR的话,如果我们将socketA绑定到0.0.0.0:21,那么任何将本机其他socket绑定到端口21的举动(如绑定到192.168.1.1:21)都会导致EADDRINUSE错误。因为0.0.0.0是一个通配符IP地址,意味着任意一个IP地址,所以任何其他本机上的IP地址都被系统认为已被占用。如果设置了SO_REUSEADDR选项,因为0.0.0.0:21和192.168.1.1:21并不是完全相同的地址端口对(其中一个是通配符IP地址,另一个是一个本机的具体IP地址),所以这样的绑定是可以成功的。需要注意的是,无论socketA和socketB初始化的顺序如何,只要设置了SO_REUSEADDR,绑定都会成功;而只要没有设置SO_REUSEADDR,绑定都不会成功。
Sol
- 向其他的 Hypervisor 學習 不要起 dnsmasq,去建立一個 br0 讓 VM 直接透過 br0 與家用網路直接連線
可能可以解
- 將 adguard home 的 bind address 改成 希望外面可以接觸到的 ip e.g. 192.168.0.X:53
explain : 避免他 bind 在 0.0.0.0 把所有的 53 port 卡住
0.0.0.0 表示電腦上所有的 ip
- 使用 docker 的 macvlan 功能 讓每一台 container 各自擁有自己的 IP
side effect : 好像這樣 host 就不能與 container 通訊