前言
最近友人在使用 virt-manager 遇到了問題
大概會像這篇說的
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 提供小型網路的 DNS、DHCP、路由廣播與網路開機等基礎設施。
dns port 預設會綁定在 53 port 上,所以這時候 dnsmasq 就會跟 docker 的 adguard home 撞。
其實碰撞的原因要講得更多一點會扯到 Linux 中如何判斷 port/addr 可以 bind 成功,這篇有詳細說明。
如果不用 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 並不是完全相同的地址端口對,所以可以同時綁定。
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 通訊