AWSとSoftLayerをvxlanで繋いでみる
Japan SoftLayer Summit 2015があり、ちょっとSoftLayerに興味を持ったので、
触って見ました。
いつもならOracle RAC構築に走るのですが、
SoftLayerでのOracle RAC構築は以下のURLで紹介されていますので、今回は個人的にアツイvxlanを使って
AWSとSoftLayerをvxlanで繋いでみます。
Oracle RAC+Softlayerの記事はこちら
http://dba-ha.blogspot.jp/2014/07/softlayer-oracle-rac.html
なお、EC2 with vxlanについては、こちらのエントリで紹介していますので、vxlanについて解説はしません。
http://d.hatena.ne.jp/KNOPP/20141210/1418224473
今回の構成は以下の通りです。
AWS/SoftLayer | ホスト名 | OS(カーネル) | PublicIP | 実インターフェース | vxlan用IP | vxlan用インターフェース |
---|---|---|---|---|---|---|
AWS | A | Amazon linux 2014.09.2.x86_64(3.14.27-25.47.amzn1.x86_64) | 54.200.xx.xx | eth0 | 192.168.1.1 | vxlan0 |
SoftLayer | B | CentOS7(3.10.0-123.20.1.el7.x86_64) | 158.85.xx.xx | eth1 | 192.168.1.2 | vxlan0 |
・事前準備
EC2側、SoftLayer側双方でUDP通信ができるようにしておく。
(ポート番号の指定方法が今のところ不明なので、UDP ALLということで、、、)
・EC2側
###Amazon Linuxにインストールされているiproute2はvxlan(unicast)に対応していないので、 ###最新版をソースから入手しインストール sudo su - yum -y install git bison flex libdb-devel db4-devel gcc git clone git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git cd iproute2 ./configure make make DESTDIR=/usr/share install ###vxlanの構成 #仮装デバイス vxlan0 vlanid 10 使用する物理デバイスはeth0 /usr/share/sbin/ip link add vxlan0 type vxlan id 10 dev eth0 #vxlan0にipアドレスを振る /usr/share/sbin/ip addr add 192.168.1.1/24 broadcast 192.168.1.255 dev vxlan0 #vxlanインターフェースをアップさせる。 /usr/share/sbin/ip link set vxlan0 up #ホストBを登録 /usr/share/sbin/bridge fdb append 00:00:00:00:00:00 dev vxlan0 dst 158.85.xx.xx
SoftLayer側
###CentOS7ではiproute2がvxlan(unicast)に対応しているので、iproute2のインストールの必要はありません。 ###ただし、kernel 3.10.0-123.20.1.el7未満だとvxlanをunicastで使おうとするとKernelパニックが起きるので注意(kernel updateが必要) ###softlayerのCentOS7は2/14現在kernelは3.10.0-123.20.1.el7なので、問題無し。 ###vxlanの構成 #仮装デバイス vxlan0 vlanid 10 使用する物理デバイスはeth1(public) ip link add vxlan0 type vxlan id 10 dev eth1 #vxlan0にipアドレスを振る ip addr add 192.168.1.2/24 broadcast 192.168.1.255 dev vxlan0 #vxlanインターフェースをアップさせる。 ip link set vxlan0 up #ホストAを登録 bridge fdb append 00:00:00:00:00:00 dev vxlan0 dst 54.200.xx.xx
動作確認 ping ホストB→A
[root@centos ~]# ping 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=44.1 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=21.7 ms 64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=21.6 ms 64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=21.7 ms 64 bytes from 192.168.1.1: icmp_seq=5 ttl=64 time=21.8 ms
動作確認 ping ホストA→B
[root@ip-172-31-39-175 iproute2]# ping 192.168.1.2 PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data. 64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=22.0 ms 64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=21.8 ms 64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=21.9 ms 64 bytes from 192.168.1.2: icmp_seq=4 ttl=64 time=21.9 ms 64 bytes from 192.168.1.2: icmp_seq=5 ttl=64 time=21.9 ms
動作確認 ホストBへ追加でIP(192.168.1.3/24)付与
[root@centos ~]#ip addr add 192.168.1.3/24 broadcast 192.168.1.255 dev vxlan0
動作確認 ping ホストA→B (追加したIP)
[root@ip-172-31-39-175 iproute2]# ping 192.168.1.3 PING 192.168.1.3 (192.168.1.3) 56(84) bytes of data. 64 bytes from 192.168.1.3: icmp_seq=1 ttl=64 time=45.3 ms 64 bytes from 192.168.1.3: icmp_seq=2 ttl=64 time=22.6 ms 64 bytes from 192.168.1.3: icmp_seq=3 ttl=64 time=22.7 ms 64 bytes from 192.168.1.3: icmp_seq=4 ttl=64 time=22.6 ms 64 bytes from 192.168.1.3: icmp_seq=5 ttl=64 time=22.7 ms
こんな感じでSoftLayer、AWS間で仮想L2ができました。
なお、SoftLayer、AWS間の通信は暗号化されていませんので、ご利用は計画的に。
RHEL7/CentOS7/OEL7でvxlanを使うときの注意点
ここらへんの記事でvxlanを紹介していますが、
RHEL7/CentOS7/OEL7で使用する場合は注意点があります。
kernel 3.10.0-123.20.1.el7未満ですと、以下の不具合に該当し、ユニキャストモードでvxlanを使おうとするとカーネルパニックが発生するようです。
If the vxlan interface is created without explicit group definition,there are corner cases which may cause kernel panic.
https://lkml.org/lkml/2014/4/18/172 *
RHEL7/CentOS7/OEL7でvxlanを使いたい場合は最新のカーネルまでアップデートして使うのが無難です。
*kernel 3.12となっていますが、RHEL7/CentOS7/OEL7ではkernel 3.10にバックポートされており該当します。
また自分でハマりそうなので、ここに記録しておきます。
EC2 with vxlan (Oracle RAC on EC2)
JPOUG Advent Calender 2014(http://jpoug.doorkeeper.jp/events/17313) の11日目
AWS Advent Calendar 2014 (http://qiita.com/advent-calendar/2014/aws) の11日目
のクロスエントリです。
AWSはとても便利ですごく好きなのですが、一つだけ不満な点があります。
それが、VPC上でmulticast/broadcastがサポートされていない点です。
multicast/broadcastをなんとか実現する為に、GREやOpenVPN、tinc等のトンネリング技術が使われたり
するのですが、ここで紹介するvxlanもまた、そのトンネリング技術のひとつです。
vxlanについて、詳細は以下の@ITの記事を参照ください。
VXLANが登場した理由、他の実装との違い、特徴を整理しよう (1/3)
http://www.atmarkit.co.jp/ait/articles/1412/03/news009.html
Linuxでvxlanが実装された当初はマルチキャストが必要だったのですが、
kernel 3.10ではユニキャストでノード間の接続ができます(Allow setting destination to unicast address)。(それ以前はマルチキャストが必要)
なんと、 このユニキャストで接続できるモードは、kernel 2.6.32-431(RHEL/CentOS/OEL 6.5)以降バックポートされているのです!!このvxlan、個人で確認するかぎりでは、物理インターフェースよりも若干スループットが落ちる程度で非常にパフォーマンスが良いです。(OpenVPNやtincよりもスループットがでます!)
これはEC2で使わない手はありませんね。
というわけで、RHEL/CentOS/OEL 6.5でのEC2 with vxlanの使い方をさらっとここで説明します。
(たぶん、kernel 3.10以降でも手順は同じハズ、、、、、)
○準備
RHEL/CentOS/OEL 6.5のkernel(2.6.32-431 否uek)はvxlanに対応していますが、ipコマンド(iproute2)が対応していませんので、
最新版を取得し、インストールします。
なお、従来のバージョンはそのまま残しておいて、最新バージョンを別ディレクトリ(/usr/share)にインストールします。
yum -y install git bison flex db4-devel git clone git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git cd iproute2 ./configure make make DESTDIR=/usr/share install
○使い方
以下の構成とします
ホスト名 | 実IP | vxlan0 |
---|---|---|
ホストA | 172.31.10.100 | 172.16.1.1 |
ホストB | 172.31.10.101 | 172.16.1.2 |
ホストC | 172.31.10.102 | 172.16.1.3 |
仮装ネットワークは 172.16.0.0/20 vxlan0はvxlanid 10
以下のコマンドを実行します。
ホストA
#仮装デバイス vxlan0 vlanid 10 使用する物理デバイスはeth0 /usr/share/sbin/ip link add vxlan0 type vxlan id 10 dev eth0 #vxlan0にipアドレスを振る( 172.16.1.1/20 broadcast 172.16.15.255) /usr/share/sbin/ip addr add 172.16.1.1/20 broadcast 172.16.15.255 dev vxlan0 #vxlanインターフェースをアップさせる。 /usr/share/sbin/ip link set vxlan0 up #ホストB、Cを登録 bridge fdb append 00:00:00:00:00:00 dev vxlan0 dst 172.31.10.101 bridge fdb append 00:00:00:00:00:00 dev vxlan0 dst 172.31.10.101
ホストB
#仮装デバイス vxlan0 vlanid 10 使用する物理デバイスはeth0 /usr/share/sbin/ip link add vxlan0 type vxlan id 10 dev eth0 #vxlan0にipアドレスを振る( 172.16.1.2/20 broadcast 172.16.15.255) /usr/share/sbin/ip addr add 172.16.1.2/20 broadcast 172.16.15.255 dev vxlan0 #vxlanインターフェースをアップさせる。 /usr/share/sbin/ip link set vxlan0 up #ホストA、Cを登録 bridge fdb append 00:00:00:00:00:00 dev vxlan0 dst 172.31.10.100 bridge fdb append 00:00:00:00:00:00 dev vxlan0 dst 172.31.10.102
ホストC
#仮装デバイス vxlan0 vlanid 10 使用する物理デバイスはeth0 /usr/share/sbin/ip link add vxlan0 type vxlan id 10 dev eth0 #vxlan0にipアドレスを振る( 172.16.1.3/20 broadcast 172.16.15.255) /usr/share/sbin/ip addr add 172.16.1.3/20 broadcast 172.16.15.255 dev vxlan0 #vxlanインターフェースをアップさせる。 /usr/share/sbin/ip link set vxlan0 up #ホストA、Bを登録 bridge fdb append 00:00:00:00:00:00 dev vxlan0 dst 172.31.10.100 bridge fdb append 00:00:00:00:00:00 dev vxlan0 dst 172.31.10.101
スループットの確認
(検証の都合上、実IPは上記IPとは異なりますので雰囲気だけ。 SR-IOVを有効にしています。)
m3.medium 実IP [root@db002 ~]# iperf -c 172.31.14.159 ------------------------------------------------------------ Client connecting to 172.31.14.159, TCP port 5001 TCP window size: 92.6 KByte (default) ------------------------------------------------------------ [ 3] local 172.31.6.190 port 60109 connected with 172.31.14.159 port 5001 [ ID] Interval Transfer Bandwidth [ 3] 0.0-10.0 sec 463 MBytes 388 Mbits/sec vxlan [root@db002 ~]# iperf -c 172.16.1.1 ------------------------------------------------------------ Client connecting to 172.16.1.1, TCP port 5001 TCP window size: 92.1 KByte (default) ------------------------------------------------------------ [ 3] local 172.16.1.2 port 48250 connected with 172.16.1.1 port 5001 [ ID] Interval Transfer Bandwidth [ 3] 0.0-10.0 sec 460 MBytes 386 Mbits/sec m3.large 実IP [root@db002 ~]# iperf -c 172.31.11.88 ------------------------------------------------------------ Client connecting to 172.31.11.88, TCP port 5001 TCP window size: 92.6 KByte (default) ------------------------------------------------------------ [ 3] local 172.31.15.237 port 20624 connected with 172.31.11.88 port 5001 [ ID] Interval Transfer Bandwidth [ 3] 0.0-10.0 sec 853 MBytes 715 Mbits/sec vxlan [root@db002 ~]# iperf -c 172.16.1.1 ------------------------------------------------------------ Client connecting to 172.16.1.1, TCP port 5001 TCP window size: 92.1 KByte (default) ------------------------------------------------------------ [ 3] local 172.16.1.2 port 62692 connected with 172.16.1.1 port 5001 [ ID] Interval Transfer Bandwidth [ 3] 0.0-10.0 sec 848 MBytes 711 Mbits/sec
→物理インターフェースよりも若干スループットが落ちる程度です。
最後にvxlanを使うとこんなことができる一例です
Oracle Linux 6.5(HVM SRIOV有効化済み) Oracle Database oracle 12.1.0.1 での64ノードクラスタ
参考文献
http://diary.atzm.org/20140416.html
http://www.atmarkit.co.jp/ait/articles/1412/03/news009.html
追記:
vxlanを使う場合に、OS起動と同時にvxlanインターフェース有効化する方法ないですかね?
( ifcfg-xxxx を使うイメージで )
みつからないんで、今回はinit script書いちゃいましたけど。
openvswitch on EC2 その2
まずは、宣伝から
まだ席に余裕がありますので、興味ある方は是非
JPOUG> SET EVNETS 20140907
詳細は、こちら
JPOUG> SET EVNETS 20140907
前回公開したエントリでは、以下の問題がありました
・通信が不安定になることがある
→ブリッジインターフェースを二つに分ける必要がある
・EC2メタデータ(169.254.169.254)にアクセスできない
→br0から169.254.169.254にアクセスするrouteを低メトリックで登録
・インターネットにアクセスできない
→デフォルトゲートウェイの指定が必要
前回分も含めて設定をやってくれるスクリプトを作成しましたので、公開します。
https://gist.github.com/s4ragent/c73655fbf6b75096c250
CentOS/RHEL限定です。(Oracle LinuxはUEKだと動かないと思います)
使い方
OVSのダウンロード/インストール
sh ec2openvswitch ovsinstall
ブリッジインターフェイスの作成/初期化
sh ec2openvswitch ovsinit
トンネルの作成
sh ec2openvswitch ovssetgre リモートIP1 リモートIP2 ・・・・
内部インターフェースの作成
sh ec2openvswitch ovscreateint 作成するデバイス名 IPアドレス NETMASK
*デバイス名は 英字+数字(0以外) 数字は vlan-idになります
例 sh ec2openvswitch ovscreateint vlan10 192.168.0.11 255.255.255.0
openvswitch on EC2
タイトルと話がズレますが、まずは、宣伝から
JPOUG> SET EVNETS 20140907
IIJさんの新しいオフィスが会場となります。みなさま奮ってご参加ください。
詳細は、こちら
JPOUG> SET EVNETS 20140907
さて、本題に入ります。
openvswtich をEC2で使う方法がどこ探しても見つからなかったので、真面目に調べてみました。
一応使えるところ(パフォーマンスは別として)までいったので軽くメモします。
ポイントは
・ブリッジのMACをeh0と同じにする
・ブリッジを固定IPにする。
です。
なお、Amazon Linuxでは動きません。
また、eth0にブリッジしているので、手順を誤ると接続不能になりますので、試す際には十分注意してください
環境
AMI ami-4c85ee7c(CentOS 6.5 HVM SRIOV) ・・・・ @understeer さんの公開しているCent OS 6.5(HVM) oregonリージョン(東京だったら ami-7fa6fe7e)
openvswtich 1.10(RDOから入るもの)
openvswtich間はgreで接続
tap0/tap1はvlanで分離
構成
ホスト名 | 実IP | tap0 | tap1 |
---|---|---|---|
ホストA | 172.31.10.220 | 192.168.0.11 | 192.168.1.11 |
ホストB | 172.31.10.221 | 192.168.0.12 | 192.168.1.12 |
ホストC | 172.31.10.222 | 192.168.0.13 | 192.168.1.13 |
インストール(各ホスト共通)
yum -y install https://repos.fedorapeople.org/repos/openstack/openstack-icehouse/rdo-release-icehouse-4.noarch.rpm yum -y install openvswitch service openvswitch start chkconfig openvswitch on
ブリッジの設定(各ホスト共通)
LANG=C #NETMASKの取得 MyMASK=`ifconfig eth0 | grep 'inet addr' | awk -F '[: ]' '{print $19}'` #eth0 IPの取得 MyIP=`ifconfig eth0 | grep 'inet addr' | awk -F '[: ]' '{print $13}'` #eth0のMACアドレスの取得 MyHWADDR=`ifconfig eth0 | grep 'Link encap' | awk '{print $5}'` ovs-vsctl add-br br0 cat > /etc/sysconfig/network-scripts/ifcfg-br0 <<EOF DEVICE=br0 TYPE=Ethernet ONBOOT=yes BOOTPROTO=none IPADDR=$MyIP NETMASK=$MyMASK EOF sed -i 's/BOOTPROTO/#BOOTPROTO/' /etc/sysconfig/network-scripts/ifcfg-eth0 echo "MTU=1546" >> /etc/sysconfig/network-scripts/ifcfg-eth0 ovs-vsctl set bridge br0 other-config:hwaddr=$MyHWADDR ovs-vsctl add-port br0 eth0 && service network restart
最後のnetwork restartで一瞬接続が切れます。
openvswtich間接続(ホストA)
ovs-vsctl add-port br0 gre0 -- set interface gre0 type=gre options:remote_ip=172.31.10.221 ovs-vsctl add-port br0 gre1 -- set interface gre1 type=gre options:remote_ip=172.31.10.222 ovs-vsctl set bridge br0 stp_enable=true
最後のovs-vsctl set bridge br0 stp_enable=trueで応答が10秒ほど途絶えます。
openvswtich間接続(ホストB)
ovs-vsctl add-port br0 gre0 -- set interface gre0 type=gre options:remote_ip=172.31.10.220 ovs-vsctl add-port br0 gre1 -- set interface gre1 type=gre options:remote_ip=172.31.10.222 ovs-vsctl set bridge br0 stp_enable=true
最後のovs-vsctl set bridge br0 stp_enable=trueで応答が10秒ほど途絶えます。
openvswtich間接続(ホストC)
ovs-vsctl add-port br0 gre0 -- set interface gre0 type=gre options:remote_ip=172.31.10.220 ovs-vsctl add-port br0 gre1 -- set interface gre1 type=gre options:remote_ip=172.31.10.221 ovs-vsctl set bridge br0 stp_enable=true
最後のovs-vsctl set bridge br0 stp_enable=trueで応答が10秒ほど途絶えます。
tap設定(ホストA)
cat > /etc/sysconfig/network-scripts/ifcfg-tap0 <<EOF DEVICE=tap0 TYPE=Ethernet ONBOOT=yes BOOTPROTO=none IPADDR=192.168.0.11 NETMASK=255.255.255.0 EOF cat > /etc/sysconfig/network-scripts/ifcfg-tap1 <<EOF DEVICE=tap1 TYPE=Ethernet ONBOOT=yes BOOTPROTO=none IPADDR=192.168.1.11 NETMASK=255.255.255.0 EOF ovs-vsctl add-port br0 tap0 tag=1 -- set Interface tap0 type=internal ovs-vsctl add-port br0 tap1 tag=2 -- set Interface tap1 type=internal ifconfig tap0 192.168.0.11 ifconfig tap1 192.168.1.11
tap設定(ホストB)
cat > /etc/sysconfig/network-scripts/ifcfg-tap0 <<EOF DEVICE=tap0 TYPE=Ethernet ONBOOT=yes BOOTPROTO=none IPADDR=192.168.0.12 NETMASK=255.255.255.0 EOF cat > /etc/sysconfig/network-scripts/ifcfg-tap1 <<EOF DEVICE=tap1 TYPE=Ethernet ONBOOT=yes BOOTPROTO=none IPADDR=192.168.1.12 NETMASK=255.255.255.0 EOF ovs-vsctl add-port br0 tap0 tag=1 -- set Interface tap0 type=internal ovs-vsctl add-port br0 tap1 tag=2 -- set Interface tap1 type=internal ifconfig tap0 192.168.0.12 ifconfig tap1 192.168.1.12
tap設定(ホストC)
cat > /etc/sysconfig/network-scripts/ifcfg-tap0 <<EOF DEVICE=tap0 TYPE=Ethernet ONBOOT=yes BOOTPROTO=none IPADDR=192.168.0.13 NETMASK=255.255.255.0 EOF cat > /etc/sysconfig/network-scripts/ifcfg-tap1 <<EOF DEVICE=tap1 TYPE=Ethernet ONBOOT=yes BOOTPROTO=none IPADDR=192.168.1.13 NETMASK=255.255.255.0 EOF ovs-vsctl add-port br0 tap0 tag=1 -- set Interface tap0 type=internal ovs-vsctl add-port br0 tap1 tag=2 -- set Interface tap1 type=internal ifconfig tap0 192.168.0.13 ifconfig tap1 192.168.1.13
EC2で仮想IPにチャレンジ(現時点では諦め)
http://d.hatena.ne.jp/KNOPP/20140728/1406562348
の続き。
プログラムが異常終了するのは、ARPに対応していなかったようです。
(ARPパケットだとframe.ip_headerがNILになるので、異常終了してた)
そこで、ARPパケットでも対応したのが以下スクリプトになります。
#!/usr/bin/ruby require 'rubygems' require 'packetfu' dev = ARGV[0] mac=`ip link show #{dev} | awk '/ether/ {print $2}'`.chomp ARGV.shift dests = ARGV cap = PacketFu::Capture.new( :timeout => 4000, :iface => dev, :start => true, :filter => "ether src #{mac} and ether[0] & 1 = 1") loop do cap.stream.each do |pkt| frame = PacketFu::IPPacket.parse(pkt) i = 0 dests.each do |dest| frame.eth_daddr = dest if frame.proto[1].to_s == "IP" then frame.ip_header.ip_id = frame.ip_header.ip_id + i frame.ip_header.ip_sum = frame.ip_header.ip_calc_sum() i = i + 1 end frame.to_w(dev) end end end
これで大丈夫。。。。。
と思いきや。残念なことにVPC側ではブロードキャストだけでなく、ARPパケットもいじっているようで、
multi-unicastしたARPパケットは、VPC側でmanageしているIPアドレスの解決要求以外は届きません。
(tcpdumpで確認した結果)
なので、現時点では、multi-unicastを使ってもVIPを使うのは難しいということになります。
諦めてtincで頑張るしかないか。。。。
EC2で仮想IPにチャレンジ(未完)
twitterでは、度々呟いていますが、tincで30ノードRACを越えるべく頑張りつつ、
限界を感じる今日この頃です。
(30ノードを越えると、仮想L2ネットワークが不安定になり、config.shやroot.shが失敗したり、
node evictionが頻発する。。。。。)
そんな中、非常に面白いエントリがあったので、
RAC on EC2に応用できないかと少し検証してみました。
EC2-VPCでIPマルチキャスト/ブロードキャストを実現する(後編)
http://moomindani.wordpress.com/2014/07/22/ec2-vpc_multicast_broadcast_2/
→これで仮想IP扱うことができれば、tincに比べてオーバーヘッドが少ない(はず)なので、
なんとか、ノード数を増やせるかも。。。
環境
ホストA IP 172.31.1.159 (MAC 0a:30:35:58:2e:4d)
ホストB IP 172.31.1.160 (MAC 0a:96:80:90:16:ee)
※ともにAmazon Linux(amzn-ami-hvm-2014.03.2.x86_64-ebs) t2.micro使用
○セットアップ
ほぼそのまま以下のURLの手順で実行しています。
http://moomindani.wordpress.com/2014/07/22/ec2-vpc_multicast_broadcast_2/
○検証内容
・ホストB に仮想IPを割り当てて、使用できるか確認
具体的には、ホストBで ifconfig eth0:0 172.31.1.161 を実行し、
ホストAから ping 172.31.1.161 を実行するだけです。
ホストB
#ruby mcast.rb eth0 0a:30:35:58:2e:4d 0a:96:80:90:16:ee &
#ifconfig eth0:0 172.31.1.161
ホストA
#ruby mcast.rb eth0 0a:30:35:58:2e:4d 0a:96:80:90:16:ee &
#ping 172.31.1.161
○結果
PING 172.31.1.161 (172.31.1.161) 56(84) bytes of data. /usr/local/rvm/gems/ruby-1.9.3-p484/gems/packetfu-1.1.10/lib/packetfu/packet.rb:508:in `method_missing': undefined method `ip_header' for nil:NilClass (NoMethodError) from mcast.rb:21:in `block (3 levels) in <main>' from mcast.rb:19:in `each' from mcast.rb:19:in `block (2 levels) in <main>' from mcast.rb:15:in `each' from mcast.rb:15:in `block in <main>' from mcast.rb:14:in `loop' from mcast.rb:14:in `<main>' From 172.31.1.160 icmp_seq=1 Destination Host Unreachable From 172.31.1.160 icmp_seq=2 Destination Host Unreachable
プログラムが異常終了してしまいました。
なんとなくarpっぽい気がするので、
ホストBからホストAのarpエントリを削除後、ホストBへのpingで再現しました。
ホストB
#arp -a
ip-172-31-1-161.us-west-2.compute.internal (172.31.1.161) at <incomplete> on eth0 ip-172-31-0-2.us-west-2.compute.internal (172.31.0.2) at 0a:99:3b:60:39:13 [ether] on eth0 ip-172-31-0-1.us-west-2.compute.internal (172.31.0.1) at 0a:99:3b:60:39:13 [ether] on eth0 ip-172-31-1-159.us-west-2.compute.internal (172.31.1.159) at 0a:30:35:58:2e:4d [ether] on eth0 ip-172-31-1-255.us-west-2.compute.internal (172.31.1.255) at <incomplete> on eth0 instance-data.us-west-2.compute.internal (169.254.169.254) at 0a:99:3b:60:39:13 [ether] on eth0 ip-172-31-0-255.us-west-2.compute.internal (172.31.0.255) at <incomplete> on eth0
#arp -d ip-172-31-1-159.us-west-2.compute.internal
#ruby mcast.rb eth0 0a:30:35:58:2e:4d 0a:96:80:90:16:ee &
# ping 172.31.1.159
PING 172.31.1.159 (172.31.1.159) 56(84) bytes of data. 64 bytes from 172.31.1.159: icmp_seq=1 ttl=64 time=0.615 ms /usr/local/rvm/gems/ruby-1.9.3-p484/gems/packetfu-1.1.10/lib/packetfu/packet.rb:508:in `method_missing': undefined method `ip_header' for nil:NilClass (NoMethodError) from mcast.rb:21:in `block (3 levels) in <main>' from mcast.rb:19:in `each' from mcast.rb:19:in `block (2 levels) in <main>' from mcast.rb:15:in `each' from mcast.rb:15:in `block in <main>' from mcast.rb:14:in `loop' from mcast.rb:14:in `<main>' 64 bytes from 172.31.1.159: icmp_seq=2 ttl=64 time=0.599 ms 64 bytes from 172.31.1.159: icmp_seq=3 ttl=64 time=0.523 ms
arpエントリがある状態で再度プログラムを実行しても異常終了しません。
#ruby mcast.rb eth0 0a:30:35:58:2e:4d 0a:96:80:90:16:ee &
#ping 172.31.1.159
PING 172.31.1.159 (172.31.1.159) 56(84) bytes of data. 64 bytes from 172.31.1.159: icmp_seq=1 ttl=64 time=0.632 ms 64 bytes from 172.31.1.159: icmp_seq=2 ttl=64 time=0.589 ms 64 bytes from 172.31.1.159: icmp_seq=3 ttl=64 time=0.631 ms 64 bytes from 172.31.1.159: icmp_seq=4 ttl=64 time=0.597 ms 64 bytes from 172.31.1.159: icmp_seq=5 ttl=64 time=0.476 ms 64 bytes from 172.31.1.159: icmp_seq=6 ttl=64 time=0.621 ms 64 bytes from 172.31.1.159: icmp_seq=7 ttl=64 time=0.522 ms 64 bytes from 172.31.1.159: icmp_seq=8 ttl=64 time=0.544 ms 64 bytes from 172.31.1.159: icmp_seq=9 ttl=64 time=0.584 ms
なんとなく発生条件は分かりましたが、どうしたものか。。。。
ネットワークの知識は薄く、packetfuも初めて使ったくらいなので、
これ以上頑張るのはしんどいかも。
P.S.
今回、初めてt2.micro使ってみましたが、パフォーマンスの良さに感激です。
rvm/ruby-1.9.3のコンパイルがt1.microに比べ、体感で3倍以上早く感じました。