読者です 読者をやめる 読者になる 読者になる

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倍以上早く感じました。