AWS Transit Gateway MulticastのIGMPv2を利用した動的なグループ管理の動作検証をしてみた

    AWS Transit Gateway MulticastのIGMPv2を利用した動的なグループ管理の動作検証をしてみた

    本記事はAsiaQuest Advent Calendarの8日目です。

    目次

      はじめに

      クラウドインテグレーション部の渡邊です。
      今回は、AWS Transit Gateway Multicastの動作検証をします。
      構成は以下の通りです。
      本検証でパブリックサブネットは不要ですが、簡単にSession Managerで接続するために各EC2をパブリックサブネットに配置しています。
      202312_tgw_multicast_01

      AWS Transit Gateway マルチキャストドメインのグループのタイプとして、静的マルチキャストグループおよびIGMPv2マルチキャストグループがあり、本検証では後者を検証します。

      考慮事項は「Transit Gateway でのマルチキャスト」を参考にしてください。

      環境情報

      • Amazon Linux 2 (amzn2-ami-hvm-2.0.20231101.0-x86_64-gp2)

      やってみた

      事前準備

      • Transit Gateway 「マルチキャストサポート」を有効化
      • AWS Transit Gateway マルチキャストドメインの「IGMPv2 のサポート」を有効化
        • AWS Transit Gateway マルチキャストドメインのグループは動的に管理するため、追加設定不要
          202312_tgw_multicast_02
      • ルーティング設定
        • セキュリティグループのアウトバウンドルールとネットワークACLの制限は行っていません
        • 今回はマルチキャストで通信するためUDPポート8123を指定しました
        • 各VPCのCIDRをソースとして指定するためにプレフィックスリストを作成しました
          202312_tgw_multicast_03
      • インスタンスのセットアップ
        • 今回はCloudWatchのネットワークメトリクスを観察するためIperfを各EC2へインストールしました
        • 各インスタンスに設定した、ユーザデータは以下のとおりです
      #!/bin/bash
      echo '# Force IGMPv2 for AWS Transit Gateway' > /etc/sysctl.d/01-multicast.conf
      echo 'net.ipv4.conf.eth0.force_igmp_version = 2' >> /etc/sysctl.d/01-multicast.conf

      cat > /usr/bin/mcast_app_install.sh<< EOF
      #!/bin/bash
      wget -O /usr/bin/mcast_app https://svn.python.org/projects/python/trunk/Demo/sockets/mcast.py
      chmod 755 /usr/bin/mcast_app
      sed -i 's/MYTTL = 1/MYTTL = 32/g' /usr/bin/mcast_app
      sed -i 's/225.0.0.250/239.0.0.100/g' /usr/bin/mcast_app
      yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
      yum-config-manager --enable epel
      yum install -y iperf
      EOF
      chmod 755 /usr/bin/mcast_app_install.sh

      yum update -y
      yum upgrade -y
      yum install -y autoconf automake gcc git
      yum clean all
      rm -rf /var/cache/yum

      git clone https://github.com/troglobit/mcjoin.git /tmp/mcjoin
      cd /tmp/mcjoin
      ./autogen.sh
      ./configure && make
      make install-strip
      cd /tmp
      rm -rf ./*

      /bin/bash /usr/bin/mcast_app_install.sh
      reboot

      AWS Transit Gateway マルチキャストドメインの補足

      グループの設定を静的に設定するためには「静的ソースのサポート」を有効化することで実現できます。
      一方で、本検証対象のIGMPv2を利用した動的なグループ管理はIGMPv2 のサポートを有効化することで実現できます。
      これらの設定は、コンソール画面の「静的ソースのサポート」および「IGMPv2 のサポート」の情報を確認すると、以下の記述がある点から両方設定することはできません。

      静的ソースサポートでは、マルチキャストメンバーをソースとして追加できます。マルチキャストソースのみがマルチキャストデータを送信できます。このフラグを無効にすると、マルチキャストドメインのすべてのメンバーをソースにすることができます。IGMPv2 サポートが有効な場合、このフラグを有効にすることはできません。

      IGMPv2 のサポートにより、マルチキャストドメインの動的なメンバーシップ管理が可能になります。VPC 内の関連付けられたサブネットのホストは、IGMPv2 プロトコルメッセージを使用して、オンデマンドでマルチキャストグループに参加したり離れたりできます。

      202312_tgw_multicast_04
      今回は動的なグループ管理を実現するために静的ソースのサポートを無効化し、IGMPv2 のサポートを有効化します。

       

      マルチキャスト通信をしない場合の動作検証

      以下の流れで検証します。
      ①受信側でlisten
      ②送信側から各インスタンスへデータを送信
      ③CloudWatchメトリクスやAWS Transit Gateway マルチキャストドメインのメンバーを確認

      受信側でUDP8123をlistenします。

      [ssm-user@ip-10-0-1-16 bin]$ iperf -s -p 8123 -u
      ------------------------------------------------------------
      Server listening on UDP port 8123
      Receiving 1470 byte datagrams
      UDP buffer size: 208 KByte (default)
      ------------------------------------------------------------
      [ssm-user@ip-10-1-1-112 bin]$ iperf -s -p 8123 -u
      ------------------------------------------------------------
      Server listening on UDP port 8123
      Receiving 1470 byte datagrams
      UDP buffer size: 208 KByte (default)
      ------------------------------------------------------------

      ソース側から各インスタンスのUDP8123へ1 Mbpsの帯域幅でデータを600秒間送信し続けます。

      [ssm-user@ip-10-0-0-152 bin]$ iperf -c 10.0.1.16 -p 8123 -u -b 1M -t 600 &
      [1] 2323
      [ssm-user@ip-10-0-0-152 bin]$ ------------------------------------------------------------
      Client connecting to 10.0.1.16, UDP port 8123
      Sending 1470 byte datagrams, IPG target: 11215.21 us (kalman adjust)
      UDP buffer size: 208 KByte (default)
      ------------------------------------------------------------
      [ 3] local 10.0.0.152 port 60625 connected with 10.0.1.16 port 8123
      [ ID] Interval Transfer Bandwidth
      [ 3] 0.0-10.0 sec 1.25 MBytes 1.05 Mbits/sec
      [ 3] Sent 892 datagrams
      [ 3] Server Report:
      [ 3] 0.0-10.0 sec 1.25 MBytes 1.05 Mbits/sec 0.023 ms 0/ 892 (0%)


      [ssm-user@ip-10-0-0-152 bin]$ iperf -c 10.1.1.112 -p 8123 -u -b 1M -t 600 &
      [2] 2327
      [ssm-user@ip-10-0-0-152 bin]$ ------------------------------------------------------------
      Client connecting to 10.1.1.112, UDP port 8123
      Sending 1470 byte datagrams, IPG target: 11215.21 us (kalman adjust)
      UDP buffer size: 208 KByte (default)
      ------------------------------------------------------------
      [ 3] local 10.0.0.152 port 57109 connected with 10.1.1.112 port 8123
      [ ID] Interval Transfer Bandwidth
      [ 3] 0.0-10.0 sec 1.25 MBytes 1.05 Mbits/sec
      [ 3] Sent 892 datagrams
      [ 3] Server Report:
      [ 3] 0.0-10.0 sec 1.25 MBytes 1.05 Mbits/sec 0.140 ms 0/ 892 (0%)

      受信者側を確認するとそれぞれデータが受信できています。

      [ssm-user@ip-10-0-1-16 bin]$ iperf -s -p 8123 -u
      ------------------------------------------------------------
      Server listening on UDP port 8123
      Receiving 1470 byte datagrams
      UDP buffer size: 208 KByte (default)
      ------------------------------------------------------------
      [ 3] local 10.0.1.16 port 8123 connected with 10.0.0.152 port 60625
      [ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams
      [ 3] 0.0-10.0 sec 1.25 MBytes 1.05 Mbits/sec 0.141 ms 0/ 892 (0%)
      [ssm-user@ip-10-1-1-112 bin]$ iperf -s -p 8123 -u
      ------------------------------------------------------------
      Server listening on UDP port 8123
      Receiving 1470 byte datagrams
      UDP buffer size: 208 KByte (default)
      ------------------------------------------------------------
      [ 3] local 10.1.1.112 port 8123 connected with 10.0.0.152 port 57109
      [ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams
      [ 3] 0.0-10.0 sec 1.25 MBytes 1.05 Mbits/sec 0.024 ms 0/ 892 (0%)

      実行後にグループのメンバーは追加されていませんでした。
      なぜなら、マルチキャスト通信をせず、各インスタンスにパケットを送信しているからです。

      グラフの色 インスタンス
      オレンジ メンバーインスタンス1のNetworkIn
      メンバーインスタンス2のNetworkIn
      ソースインスタンスのNetworkOut

      CloudWatchメトリクスのNetworkInとNetworkOutを確認すると、重なっているオレンジと緑のグラフ値の合計が赤のグラフの値と動きと、おおよそ一致していることがわかります。
      202312_tgw_multicast_05

      マルチキャスト通信をする場合の動作検証

      マルチキャストアドレス範囲の任意の値を指定して、通信をします。
      手順はマルチキャスト通信をしない場合と同様です。

      送信者側でマルチキャストアドレス239.0.0.100を指定してデータを送信します。

      [ssm-user@ip-10-0-0-152 bin]$ iperf -c 239.0.0.100 -p 8123 -u -b 1M -T 32 -t 600
      ------------------------------------------------------------
      Client connecting to 239.0.0.100, UDP port 8123
      Sending 1470 byte datagrams, IPG target: 11215.21 us (kalman adjust)
      Setting multicast TTL to 32
      UDP buffer size: 208 KByte (default)
      ------------------------------------------------------------
      [ 3] local 10.0.0.152 port 50001 connected with 239.0.0.100 port 8123

      受信側で、送信側で指定したマルチキャストアドレス239.0.0.100をlistenします。

      [ssm-user@ip-10-0-1-16 bin]$ iperf -s -B 239.0.0.100 -p 8123 -u
      ------------------------------------------------------------
      Server listening on UDP port 8123
      Binding to local address 239.0.0.100
      Joining multicast group 239.0.0.100
      Receiving 1470 byte datagrams
      UDP buffer size: 208 KByte (default)
      ------------------------------------------------------------
      [ 3] local 239.0.0.100 port 8123 connected with 10.0.0.152 port 50001
      [ssm-user@ip-10-1-1-112 bin]$ iperf -s -B 239.0.0.100 -p 8123 -u
      ------------------------------------------------------------
      Server listening on UDP port 8123
      Binding to local address 239.0.0.100
      Joining multicast group 239.0.0.100
      Receiving 1470 byte datagrams
      UDP buffer size: 208 KByte (default)
      ------------------------------------------------------------
      [ 3] local 239.0.0.100 port 8123 connected with 10.0.0.152 port 50001

      AWS Transit Gateway マルチキャストドメイングループに4つのメンバーが追加されています。
      202312_tgw_multicast_06

      受信者(今回は2つのEC2)が、IGMPv2 JOIN メッセージを送信することでマルチキャストドメイングループへ参加しています。 一方で、マルチキャストグループから離脱する場合は、IGMPv2 LEAVE メッセージを送信します。

      グループメンバーシップは Transit Gateway からの IGMPv2 JOIN メッセージの受信から始まり、IGMPv2 LEAVE メッセージ の受信で終わります。Transit Gateway は、グループに正常に参加したホストを追跡します。クラウドマルチキャストルーターとして、Transit Gateway は 2 分ごとにメンバー全員に IGMPv2 QUERY メッセージを発行します。各メンバーは 応答中に IGMPv2 JOIN メッセージを送信します。これはメンバーがメンバーシップを更新する方法です。メンバーが 3 つの連続するクエリに応答できない場合、Transit Gateway は、参加したすべてのグループからこのメンバーシップを削除します。ただし、クエリ対象リストからメンバーを完全に削除する前に、12 時間このメンバーにクエリを送信し続けます。明示的な igMPv2 LEAVE メッセージは、それ以降のマルチキャスト処理からホストを即座かつ永続的に削除します。

      引用元:Transit Gateway でのマルチキャスト

      また、グループに正常に参加したホストを追跡するために、TransitGatewayもマルチキャストグループに参加しています。 そのために、IGMPv2 QUERYをすべてのマルチキャストホストを指す224.0.0.1へ送信します。

      Transit Gateway automatically joins the 224.0.0.1 (All Systems) multicast group and sends membership query packets to all the IGMP members so that it can track multicast group membership.

      引用元:Networking Immersion Day

      CloudWatchメトリクスを確認します。
      マルチキャストは、1つのデータを複数の受信側ホストに同時に通信するためのプロトコルであるため、ソースのNetworkOutとすべてのメンバーのNetworkInメトリクスと同じレベルになります。
      202312_tgw_multicast_07

      その他動作検証

      検証1:使用可能なマルチキャストアドレス
      マルチキャストアドレスはクラスDアドレス(224.0.0.0 ~ 239.255.255.255)を使用するため、その範囲内でしたら基本的にメンバーの追加を確認できます。
      特別なマルチキャストアドレスをいくつか検証してみましたが結果は以下の通りになりました。
      送信元からマルチキャスト通信をした際に、メンバーの追加ができているか検証しています。

      マルチキャストアドレス メンバーの追加可否
      224.0.0.0
      224.0.0.1
      224.0.0.2
      239.255.255.255

      送信元の実行結果を見ると接続ができていることがわかります。

      [ssm-user@ip-10-0-1-152 bin]$ iperf -c 239.0.0.0 -p 8123 -u -b 1M -T 32 -t 600
      ------------------------------------------------------------
      Client connecting to 239.0.0.0, UDP port 8123
      Sending 1470 byte datagrams, IPG target: 11215.21 us (kalman adjust)
      Setting multicast TTL to 32
      UDP buffer size: 208 KByte (default)
      ------------------------------------------------------------
      [ 3] local 10.0.1.152 port 36734 connected with 239.0.0.0 port 8123
      [ ID] Interval Transfer Bandwidth
      [ 3] 0.0-54.7 sec 6.84 MBytes 1.05 Mbits/sec
      [ 3] Sent 4881 datagrams

      [ssm-user@ip-10-0-1-152 bin]$ iperf -c 239.0.0.1 -p 8123 -u -b 1M -T 32 -t 600
      ------------------------------------------------------------
      Client connecting to 239.0.0.1, UDP port 8123
      Sending 1470 byte datagrams, IPG target: 11215.21 us (kalman adjust)
      Setting multicast TTL to 32
      UDP buffer size: 208 KByte (default)
      ------------------------------------------------------------
      [ 3] local 10.0.1.152 port 50329 connected with 239.0.0.1 port 8123
      [ ID] Interval Transfer Bandwidth
      [ 3] 0.0-38.2 sec 4.78 MBytes 1.05 Mbits/sec
      [ 3] Sent 3410 datagrams

      [ssm-user@ip-10-0-1-152 bin]$ iperf -c 239.0.0.2 -p 8123 -u -b 1M -T 32 -t 600
      ------------------------------------------------------------
      Client connecting to 239.0.0.2, UDP port 8123
      Sending 1470 byte datagrams, IPG target: 11215.21 us (kalman adjust)
      Setting multicast TTL to 32
      UDP buffer size: 208 KByte (default)
      ------------------------------------------------------------
      [ 3] local 10.0.1.152 port 37416 connected with 239.0.0.2 port 8123
      [ ID] Interval Transfer Bandwidth
      [ 3] 0.0-62.9 sec 7.87 MBytes 1.05 Mbits/sec
      [ 3] Sent 5612 datagrams

      [ssm-user@ip-10-0-1-152 bin]$ iperf -c 239.255.255.255 -p 8123 -u -b 1M -T 32 -t 600
      ------------------------------------------------------------
      Client connecting to 239.255.255.255, UDP port 8123
      Sending 1470 byte datagrams, IPG target: 11215.21 us (kalman adjust)
      Setting multicast TTL to 32
      UDP buffer size: 208 KByte (default)
      ------------------------------------------------------------
      [ 3] local 10.0.1.152 port 49818 connected with 239.255.255.255 port 8123

      検証2:マルチキャスト通信のソースは任意で問題ないか
      静的にソースを決定していないため、関連付けられたネットワーク内の任意のEC2からマルチキャスト通信を行えます。
      はじめに実施したソース(送信側)のEC2およびマルチキャストアドレスとは異なっていても、接続に成功していることがわかります(はじめに実施した際、10.0.1.152から送信してましたが、今回は10.0.1.16から送信しました)。

      [ssm-user@ip-10-0-1-16 bin]$ iperf -c 239.0.1.101 -p 8123 -u -b 1M -T 32 -t 600
      ------------------------------------------------------------
      Client connecting to 239.0.1.101, UDP port 8123
      Sending 1470 byte datagrams, IPG target: 11215.21 us (kalman adjust)
      Setting multicast TTL to 32
      UDP buffer size: 208 KByte (default)
      ------------------------------------------------------------
      [ 3] local 10.0.1.16 port 35892 connected with 239.0.1.101 port 8123
      [ssm-user@ip-10-1-1-112 bin]$ iperf -s -B 239.0.1.101 -p 8123 -u
      ------------------------------------------------------------
      Server listening on UDP port 8123
      Binding to local address 239.0.1.101
      Joining multicast group 239.0.1.101
      Receiving 1470 byte datagrams
      UDP buffer size: 208 KByte (default)
      ------------------------------------------------------------
      [ 3] local 239.0.1.101 port 8123 connected with 10.0.1.16 port 53249
      [ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams
      [ 3] 0.0-25.1 sec 3.14 MBytes 1.05 Mbits/sec 0.038 ms 13937/16179 (86%)
      [ 4] local 239.0.1.101 port 8123 connected with 10.0.1.16 port 35892
      [ssm-user@ip-10-0-0-152 bin]$ iperf -s -B 239.0.1.101 -p 8123 -u
      ------------------------------------------------------------
      Server listening on UDP port 8123
      Binding to local address 239.0.1.101
      Joining multicast group 239.0.1.101
      Receiving 1470 byte datagrams
      UDP buffer size: 208 KByte (default)
      ------------------------------------------------------------
      [ 3] local 239.0.1.101 port 8123 connected with 10.0.1.16 port 53249
      [ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams
      [ 3] 0.0- 1.1 sec 139 KBytes 1.05 Mbits/sec 0.032 ms 16082/16179 (99%)
      [ 4] local 239.0.1.101 port 8123 connected with 10.0.1.16 port 53249
      [ 5] local 239.0.1.101 port 8123 connected with 10.0.1.16 port 35892

      接続確認後、グループメンバーを見ると、受信側のEC2のENIが追加されてました。
      202312_tgw_multicast_08

      まとめ

      • マルチキャストによって、ネットワークで特定のホストに対して、1つのデータを同時に送信できる
      • IGMPv2の特徴
        • 対象ネットワークのいずれのホストもソースになることができる
        • 静的なグループのメンバーを管理する必要がない
        • 以下3つのメッセージによってマルチキャストドメイングループを管理する
          • IGMPv2 JOIN (参加)
          • IGMPv2 LEAVE(離脱)
          • IGMPv2 QUERY(ホストの追跡)

      【参考】

      Multicast IP Address

      Networking Immersion Day

      IPv4 Multicast Address Space Registry

      IGMPv2