如何在Docker中使用mDNS(mDNS系列1)
起因
为了方便在自家局域网中发布自己由Docker启动的服务,故有了本文中所叙的解决方案,以作记录。
分析
该问题有两种解决方案:
Docker采用
macvlan
网络发布服务,此时容器中拿到的是独立的IP,可以通过在容器内起完整的mDNS服务来发布地址。但是我的NAS及开发板等是使用WiFi联网的,而WiFi网络是不支持macvlan
的,故此方案不可行。通过宿主机的IP发布服务,此时因已与宿主机耦合,故进一步可以利用宿主机上本来就在运行的
avahi-daemon
来降低容器的资源消耗,经测试该方案可行。
在方案2中,有以下几点需要注意:
- 在
host
网络模式下,可以通过获取默认路由对应的IP来拿到宿主机的出口IP。 - 在使用avahi的
avahi-publish
命令发布时注意添加-R
参数,否则会报Failed to add address: Local name collision
错误,这是由于avahi默认一个IP只能绑定一个域名,需要添加-R
参数来允许同一个IP绑定多个域名。关于这个参数,还有个插曲可参见后文描述。 - 在通过dbus与宿主机上的
avahi-daemon
通信时注意权限问题,因是本人在自家使用,故直接给了privileged
的权限,此处可以进一步研究一下,给予更低的使用权限。
处理
Docker容器内执行的run.sh
如下:
1 |
|
Dockerfile文件内容如下:
1 | FROM alpine:latest |
使用的Docker-Compose文件示例内容如下:
1 | version: "3" |
插曲
查询avahi-publish
命令的-R
参数说明时,发现使用avahi-publish -h
命令时有说明,但是想通过man avahi-publish
命令查看详细说明时,却发现没有-R
参数的说明。在查阅了avahi最新的源码后,发现确实存在该问题,故于2022年9月17日向github上的项目提交了PR以期待向开源项目做出自己的贡献。该问题同样在2022年10月28日由其他人提的PR中被修复,且由于他的PR被工作人员先接受,故我的这个PR被关闭。详情可以参见参考1中的链接。在进一步了解及后续跟踪的过程中,还了解了这个项目经历的一系列人员变更及里面发生的故事,比如Issues388、[avahi] Commit and issue editing rights to Avahi repositories,发现即使是如此出名的开源项目背后,也存在一些值得探讨的问题。