Armadilloフォーラム

podman コンテナでmulticastを受信できない

lmj_iot

2023年2月20日 11時20分

お世話になっています。
Armadillo-IoT A6E 上でpodmanコンテナを作成しています。
コンテナ上でマルチキャスト通信を受信しようとしましたが、他のデバイスからのマルチキャストの受信ができません。
例えば同じLAN上のArmadillo-640から送信したマルチキャストがA6Eのコンテナで受信できません。
A6EのIPアドレス宛のユニキャストのUDP通信はコンテナ上で受信が可能です。

コンテナはpodを使用しても使用しなくてもマルチキャストの受信はできません。
Base OS側あるいはpodmanで何か設定が必要なのでしょうか。
ご教示のほどどうぞよろしくお願いいたします。

ユニキャスト受信可能なことからも podman で -p xxxx/xxxx/udpの様にポートのフォワードは正常に設定できていると思います。
受信プログラムはpython3を使用しています。
podmanを使用しないArmadillo-640ではサンプルプログラムでマルチキャストの受信が可能なことは確認しています。

Base OS およびpodmanのバージョンです。
Alpine Linux v3.16.3
podman version 4.2.1

コメント

at_dominique.m…

2023年2月20日 11時59分

lmj_iotさん

お世話になっています、
アットマークテクノのマルティネです。

> ユニキャスト受信可能なことからも podman で -p xxxx/xxxx/udpの様にポートのフォワードは正常に設定できていると思います。

そうですね。 podman の -p オプションは、Armadillo内にルーターっぽい仕組みでコンテナを NAT に入れて設定した IP をフォーワードしていますが、multicast の場合は「join」のメッセージも対応しないと受信できません。
その対応は残念ですが、podman にはなさそうです。igmpproxy等で頑張れば対応はできるかもしれませんが、今回は直接に Armadillo のネットワークを使えば受信可能となります。

以下のコマンドで確認できました

Armadillo側
# podman run -ti --rm --net=host docker.io/alpine \
    sh -c 'apk add socat && \
        socat UDP4-RECVFROM:1234,ip-add-membership=225.1.1.1:0.0.0.0,fork -'
 
通信側、socat がインストールされている別のパソコン。
ip-multicast-if は Armadillo が接続しているインタフェースの IP アドレスです。
複雑の設定がなければ不要だと思います。
# echo test | socat - UDP-DATAGRAM:225.1.1.1:1234,ip-multicast-if=10.1.1.1

/etc/atmark/containers の場合は、「set_network host」で設定できます。

何か問題があればまた聞いてください。

lmj_iot

2023年2月20日 16時19分

マルティネ様

早速のご回答ありがとうございます。
次の様に理解しました。
- コンテナでhostのネットワークを使用可能にする
- コンテナにsocatをインストールする
- socatでhostに受信したマルチキャストをコンテナへ転送する

自分の環境でテストしてみます。

> /etc/atmark/containers の場合は、「set_network host」で設定できます。
ありがとうございます。
この場合は、socatをインストールしておいたコンテナイメージを使い、
set_network host の後、set_command で socat のコマンドを実行してから、続けてset_command で自分のアプリケーションを起動すればよいのでしょうか。

どうぞよろしくお願いいたします。

at_dominique.m…

2023年2月20日 16時46分

lmj_iotさん

> - コンテナでhostのネットワークを使用可能にする

はい、コンテナは直接に host のネットワークネームスペースを使いますので、podman による NAT を使わずに multicast も利用可能になります。

> - コンテナにsocatをインストールする
> - socatでhostに受信したマルチキャストをコンテナへ転送する

socat はあくまでもこちらの環境でテストするためのツールで、今使ってるアプリケーションが Armadillo-640 で問題なさそうですので host ネットワークを利用すればコンテナでも同じアプリケーションで受信できると思います。

> この場合は、socatをインストールしておいたコンテナイメージを使い、
> set_network host の後、set_command で socat のコマンドを実行してから、続けてset_command で自分のアプリケーションを起動すればよいのでしょうか。

そうですね、テストのためでもコンテナに socat を入れておいた方が連続のテストが楽になりますので、私もそうしていました。

以下のコマンドで socat を podman_start で使えました。

armadillo:~# podman run -ti --name socat docker.io/alpine apk add socat
fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/main/aarch64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/community/aarch64/APKINDEX.tar.gz
(1/4) Installing ncurses-terminfo-base (6.3_p20221119-r0)
(2/4) Installing ncurses-libs (6.3_p20221119-r0)
(3/4) Installing readline (8.2.0-r0)
(4/4) Installing socat (1.7.4.4-r0)
Executing busybox-1.35.0-r29.trigger
OK: 9 MiB in 19 packages
armadillo:~# podman commit socat socat
Getting image source signatures
Copying blob 0a24540c1e5a skipped: already exists  
Copying blob 0bc0f00bdf37 done  
Copying config ba25a453f4 done  
Writing manifest to image destination
Storing signatures
ba25a453f4115549440183bb9735aeff7cb058c78ccd2d8bddc213ffa5b6ce61
armadillo:~# podman rm socat
socat
armadillo:~# cat > /etc/atmark/containers/socat.conf <<EOF
set_image socat
set_network host
set_command socat UDP4-RECVFROM:1234,ip-add-membership=225.1.1.1:0.0.0.0,fork -
EOF
armadillo:~# podman_start socat
Starting 'socat'
bcb17b7701866ab6242b728a026ee937d87ba74a6f9d242955455b1fff883533
armadillo:~# podman logs -f socat
test <-- そこは外部のコマンドから受信したメッセージです
^C <-- ctrl + C で logs コマンドを停止しました

デフォルトの状態は abos-ctrl podman-storage --status が tmpfs 状態になっていますので、再起動の場合はコンテナイメージが消えますが、テストする分には問題ないと思います。
保存したい場合は podman kill -a; abos-ctrl podman-storage --disk (と persist_file -rv /etc/atmark/containers) で永続化してください。

よろしくお願いします。

lmj_iot

2023年2月21日 12時11分

マルティネ様
詳細な回答をありがとうございました。

--net host でhostのネットワークを使用するだけで良いことを理解しました。
テストしてみたところ、マルチキャストをアプリケーションで受信することができました。
また/etc/atmark/container/ とpodman_startでも動作を確認しました。
この度はどうもありがとうございました。大変助かりました。