はじめに
お家kubernetesなど、複数台のRaspberry Piを使って通信をする際に、DHCPによって割り当てられるIPアドレスを調べるのはかなり手間です。
解決方法として、netplanなどで各Raspberry Piに対して固定のIPアドレスを割り当て、それぞれの /etc/hosts
に名前とIPを記述して名前解決をするという方法があると思いますが、mDNSを使ってみたら結構便利だったのでまとめます。
mDNSとは
mDNSはMulticast DNSの略で、ローカルネットワーク内でDNSサーバーなしでホスト名解決を行うための仕組みです。
mDNSを有効にすると、各デバイスを<hostname>.local
の形式で参照することができ、DHCPによってIPアドレスが変わっても常に名前でアクセスができます。
例えば、特定のRaspberry Piにraspi1
というホスト名を設定しておけば、同一ネットワーク内の他のホストからはraspi1.local
で名前解決して通信することが可能です。
mDNSによる名前解決の仕組み
https://datatracker.ietf.org/doc/html/rfc6762#section-2
When this document uses the term "Multicast DNS", it should be taken to mean: "Clients performing DNS-like queries for DNS-like resource records by sending DNS-like UDP query and response messages over IP Multicast to UDP port 5353".
とあるように、
マルチキャストでUDPクエリと応答メッセージを5353番ポートでやり取りします。
実際に<hostname>.local
で名前解決しようとしたとき、tcpdumpなどでパケットをキャプチャしてみると、マルチキャストアドレス(mDNSの場合は224.0.0.251
)のUDP 5353番ポートにクエリが送信されることを確認できます。
以下は、hostnameがraspberrypi5-1
の名前をmDNSで解決しようとした際の通信例です。
$ sudo tcpdump -n -t -i any ip
eth0 M IP 192.168.151.154.5353 > 224.0.0.251.5353: 0 A (QM)? raspberrypi5-1.local. (38)
eth0 Out IP 192.168.151.70.5353 > 224.0.0.251.5353: 0*- [0q] 2/0/0 (Cache flush) A 192.168.151.70, (Cache flush)
macOSにおけるmDNS
macOSでは標準でmDNSResponderが動作しています。
- https://github.com/apple-oss-distributions/mDNSResponder
- https://www.unix.com/man_page/osx/8/mdnsresponder/
$ sudo lsof -Pi:5353
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mDNSRespo 424 _mdnsresponder 6u IPv4 0x1a1d408af2c7bdb6 0t0 UDP *:5353
mDNSRespo 424 _mdnsresponder 7u IPv6 0x3dc0e3186f188777 0t0 UDP *:5353
LinuxにおけるmDNS
Linuxでは、ディストリビューションによって異なると思いますが、Avahiが使われていることが多そうです。
$ sudo lsof -Pi:5353
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
avahi-dae 993 avahi 12u IPv4 12678 0t0 UDP *:5353
avahi-dae 993 avahi 13u IPv6 12679 0t0 UDP *:5353
mDNSを使って名前解決してみる
hostnameを設定してmDNSを動かすだけです。
hostnameは元のままで問題なければ、hostnameの設定も必要ないです。
以下は、2台のRaspberry Pi(Debian GNU/Linux 12 (bookworm)
)を使ってmDNSで名前解決ができるようにする例です。
hostnameを設定する
$ hostname
で、現在のhostnameを確認ができ、
$ sudo hostnamectl set-hostname <new_hostname>
で、hostnameの変更ができます。
2台のRaspberry Piをそれぞれraspberrypi5-1
, raspberrypi5-2
に設定します。
$ sudo hostnamectl set-hostname raspberrypi5-1
$ sudo hostnamectl set-hostname raspberrypi5-2
Avahiを動かす
$ sudo apt update && sudo apt install -y avahi-daemon
$ sudo systemctl start avahi-daemon
$ sudo systemctl status avahi-daemon # Activeになっていれば完了です
hostname.localで通信する
$ ping -c 3 raspberrypi5-2.local
PING raspberrypi5-2.local (192.168.151.153) 56(84) bytes of data.
64 bytes from 192.168.151.153 (192.168.151.153): icmp_seq=1 ttl=64 time=0.331 ms
64 bytes from 192.168.151.153 (192.168.151.153): icmp_seq=2 ttl=64 time=0.167 ms
64 bytes from 192.168.151.153 (192.168.151.153): icmp_seq=3 ttl=64 time=0.166 ms
--- raspberrypi5-2.local ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 0.166/0.221/0.331/0.077 ms
参考