電子の密林を開拓する

2013年03月

前回作成した「VPC EC2 + ENI + 複数EIP」を破棄します。


・EC2の破棄

$ ec2-stop-instances i-4fce234d
INSTANCE        i-4fce234d      running stopping

$ ec2-terminate-instances i-4fce234d
INSTANCE        i-4fce234d      stopped terminated

$ ec2-describe-instances i-4fce234d
RESERVATION     r-9e32769d      488224276535
INSTANCE        i-4fce234d      ami-20ad1221                    terminated      innerkey        0               t1.micro        2013-03-29T09:56:02+0000 ap-northeast-1a aki-ec5df7ed                    monitoring-disabled                                     ebs                                      paravirtual     xen                     default false


・ENI、PrivateIP、EIP の破棄
まず ENI の状況を確認します。
$ ec2-describe-network-interfaces eni-b7b0b6de
NETWORKINTERFACE        eni-b7b0b6de    ENI-01 for standalone   subnet-8dabade4 vpc-baabadd3    ap-northeast-1a 488224276535     false   available       06:16:62:3a:1c:a1       192.168.1.100           true
GROUP   sg-fbd3cd97     vpc_standalone
ASSOCIATION     54.249.94.148   488224276535    eipassoc-9e2b2bf7       192.168.1.100
ASSOCIATION     54.249.94.173   488224276535    eipassoc-7f2c2c16       192.168.1.101
PRIVATEIPADDRESS        192.168.1.100
PRIVATEIPADDRESS        192.168.1.101
まず、ENIに結び付けられている EIP を割り当て解除します。
$ ec2-disassociate-address  --association-id eipassoc-7f2c2c16
ADDRESS                         eipassoc-7f2c2c16

$ ec2-disassociate-address  --association-id eipassoc-9e2b2bf7
ADDRESS                         eipassoc-e1292a88

$ ec2-describe-network-interfaces eni-b7b0b6de
NETWORKINTERFACE        eni-b7b0b6de    ENI-01 for standalone   subnet-8dabade4 vpc-baabadd3    ap-northeast-1a 488224276535     false   available       06:16:62:0d:2c:9d       192.168.1.100           true
GROUP   sg-fbd3cd97     vpc_standalone
PRIVATEIPADDRESS        192.168.1.100
PRIVATEIPADDRESS        192.168.1.101
EIPの割り当てが解除されました。

次に、セカンダリの Private IP を割り当て解除します。
$ ec2-unassign-private-ip-addresses \
     --network-interface eni-b7b0b6de  \
     --secondary-private-ip-address 192.168.1.101

RETURN  true

$ ec2-describe-network-interfaces eni-b7b0b6de
NETWORKINTERFACE        eni-b7b0b6de    ENI-01 for standalone   subnet-8dabade4 vpc-baabadd3    ap-northeast-1a 488224276535     false   available       06:16:62:0d:2c:9d       192.168.1.100           true
GROUP   sg-fbd3cd97     vpc_standalone
PRIVATEIPADDRESS        192.168.1.100
センンダリ Private Ip が消えて、プライマリ(192.168.1.100)だけ残っていますね。もしプライマリ Private IP 側も削除する必要があれば、同じ手順ようなで割り当て解除できると思います……試してないですけれど(x_x;

次に、ENI 自身を削除します。
$ ec2-delete-network-interface  eni-b7b0b6de
NETWORKINTERFACE        eni-b7b0b6de

$ ec2-delete-network-interface eni-b7b0b6de
Client.InvalidNetworkInterfaceID.NotFound: The networkInterface ID 'eni-b7b0b6de' does not exist
サックリ消えました。

最後に、EIPを解放します。残したままだと課金されてしまうので…。
$ ec2-describe-addresses
ADDRESS 54.249.94.148           vpc     eipalloc-9d2828f4
ADDRESS 54.249.94.173           vpc     eipalloc-912828f8

$ ec2-release-address 54.249.94.148
Client.InvalidParameterValue: You must specify an allocation id when releasing a VPC elastic IP address
VPC用に確保された EIP は、IPアドレス指定ではなく allocation ID を指定するようです。
$ ec2-release-address --allocation-id eipalloc-9d2828f4
ADDRESS                         eipalloc-9d2828f4

$ ec2-release-address --allocation-id eipalloc-912828f8
ADDRESS                         eipalloc-912828f8

$ ec2-describe-addresses
EIPも解放されました。



VPC環境が残ったままですが、これは残したままでも課金されないので また使うのであれば そのままでも大丈夫でしょう。
もし、キレイにしたいのであれば、以前の記事「AWSでVPCを作る - 破棄編」のようにして削除してください。



今回はここまで。


VPC内のEC2に複数のEIP(Global IP)を付与してみます。
もっとも、VPC内のEC2には 直接EIPを付与することが出来ないため、実際にはENIへEIPを付与し、ENIをEC2へアタッチすることになります。



・ENIコマンドを探す

ENI が必要なことは分かっているので、そのコマンドを確認してみます。
$ ls -1 /opt/aws/bin/*network*interface*
/opt/aws/bin/ec2-attach-network-interface
/opt/aws/bin/ec2-create-network-interface
/opt/aws/bin/ec2-delete-network-interface
/opt/aws/bin/ec2-describe-network-interface-attribute
/opt/aws/bin/ec2-describe-network-interfaces
/opt/aws/bin/ec2-detach-network-interface
/opt/aws/bin/ec2-modify-network-interface-attribute
/opt/aws/bin/ec2-reset-network-interface-attribute
作って、アタッチして…という流れは、他のモノと変わらないようです。
しかし、ec2-create-network-interface --help、ec2-modify-network-interface-attribute --help どちらのの説明を見てみても、後から Private IP address を変更する方法が記載されていません。
きっと、専用のコマンドがあるのでしょう…。
$ ls -1 /opt/aws/bin/*private*address*
/opt/aws/bin/ec2-assign-private-ip-addresses
/opt/aws/bin/ec2-unassign-private-ip-addresses
そのままズバリのものがありますね。
これで複数の Private IP address を ENI に付与できるはずです。



・VPC環境の作成
ENIは VPC環境でしか使えないようなので、先に VPC環境を作成します。
$ ec2-create-vpc 192.168.1.0/24
VPC     vpc-baabadd3    pending 192.168.1.0/24  dopt-ecc9f785   default

$ ec2-create-subnet \
     --vpc vpc-baabadd3  \
     --cidr 192.168.1.0/24

SUBNET  subnet-8dabade4 pending vpc-baabadd3    192.168.1.0/24  251     ap-northeast-1a
前回作ったのと同じように、192.168.1.0/24 (サブネットも同じで1つだけ)のVPC環境になります。



・Internet GateWay の作成
VPC環境が外部と通信するためには Internet GateWay が必要なので、ソレを作成し、VPC環境にアタッチしておきます。
$ ec2-create-internet-gateway
INTERNETGATEWAY igw-d22a2abb

$ ec2-attach-internet-gateway \
     igw-d22a2abb \
     --vpc vpc-baabadd3

ATTACHMENT      vpc-baabadd3    attaching


・Routing Table の作成
VPC作成時にAWSが標準で作成したRoutingTableがあるはずなので、ソレを確認してみます。
$ ec2-describe-route-tables  --filter='vpc-id=vpc-baabadd3'
ROUTETABLE      rtb-bcabadd5    vpc-baabadd3
ROUTE   local           active  192.168.1.0/24          CreateRouteTable
ASSOCIATION     rtbassoc-bfabadd6       main
内向けの経路しか登録されていないようなので、外向けの経路を登録します。
$ ec2-create-route  \
     rtb-bcabadd5  \
     --cidr 0.0.0.0/0  \
     --gateway  igw-d22a2abb

ROUTE   igw-d22a2abb                    0.0.0.0/0

$ ec2-describe-route-tables rtb-bcabadd5
ROUTETABLE      rtb-bcabadd5    vpc-baabadd3
ROUTE   local           active  192.168.1.0/24          CreateRouteTable
ROUTE   igw-d22a2abb            active  0.0.0.0/0               CreateRoute
ASSOCIATION     rtbassoc-bfabadd6       main
外向けのパケットがIGWを通して外部に流れるような経路が出来ました。



・セキュリティグループの作成
httpd(web)、smtpd(mail) 、sshd(ssh) が利用できる EC2インスタンスを起動する前提で、VPC用セキュリティグループを作成します。特に名前に意味があるわけではありませんが、ここでは standalone という名前にしておきます。

$ ec2-create-group \
     vpc_standalone \
     --vpc vpc-baabadd3  \
     --description 'standalone in VPC'

GROUP   sg-fbd3cd97     vpc_standalone  standalone in VPC

$ ec2-authorize  \
     sg-fbd3cd97  \
     --protocol tcp  \
     --port-range 22  \
     --cidr '0.0.0.0/0'

GROUP   sg-fbd3cd97
PERMISSION                      ALLOWS  tcp     22      22      FROM    CIDR    0.0.0.0/0       ingress

$ ec2-authorize sg-fbd3cd97 \
     --protocol tcp  \
     --port-range 25  \
     --cidr '0.0.0.0/0'

GROUP   sg-fbd3cd97
PERMISSION                      ALLOWS  tcp     25      25      FROM    CIDR    0.0.0.0/0       ingress

$ ec2-authorize  \
     sg-fbd3cd97  \
     --protocol tcp  \
     --port-range 80  \
     --cidr '0.0.0.0/0'

GROUP   sg-fbd3cd97
PERMISSION                      ALLOWS  tcp     80      80      FROM    CIDR    0.0.0.0/0       ingress

$ ec2-describe-group sg-fbd3cd97
GROUP   sg-fbd3cd97     488224276535    vpc_standalone  standalone in VPC       vpc-baabadd3
PERMISSION      488224276535    vpc_standalone  ALLOWS  tcp     22      22      FROM    CIDR    0.0.0.0/0       ingress
PERMISSION      488224276535    vpc_standalone  ALLOWS  tcp     25      25      FROM    CIDR    0.0.0.0/0       ingress
PERMISSION      488224276535    vpc_standalone  ALLOWS  tcp     80      80      FROM    CIDR    0.0.0.0/0       ingress
PERMISSION      488224276535    vpc_standalone  ALLOWS  all                     TO      CIDR    0.0.0.0/0       egress


・ENIの作成
EC2インスタンス起動時に ENI を指定する必要があるため、先にENIを作成します。ENIにはセキュリティグループも必要なので、同時に指定しておきます。

$ ec2-create-network-interface \
     --description 'ENI-01 for standalone'  \
     --private-ip-address 192.168.1.100  \
     --group sg-fbd3cd97  \
     subnet-8dabade4
NETWORKINTERFACE        eni-b7b0b6de    ENI-01 for standalone   subnet-8dabade4 vpc-baabadd3    ap-northeast-1a 488224276535     false   pending 06:16:62:3a:1c:a1       192.168.1.100           true
GROUP   sg-fbd3cd97     vpc_standalone
PRIVATEIPADDRESS        192.168.1.100
ENIが作成できたので、セカンダリの Private IP を追加します。
$ ec2-assign-private-ip-addresses  \
     --network-interface eni-b7b0b6de \
     --secondary-private-ip-address 192.168.1.101

RETURN  true
ホントに二つのPrivate IP address が付与されたかどうか、確認してみます。
$ ec2-describe-network-interfaces eni-b7b0b6de
NETWORKINTERFACE        eni-b7b0b6de    ENI-01 for standalone   subnet-8dabade4 vpc-baabadd3    ap-northeast-1a 488224276535     false   available       06:16:62:3a:1c:a1       192.168.1.100           true
GROUP   sg-fbd3cd97     vpc_standalone
PRIVATEIPADDRESS        192.168.1.100
PRIVATEIPADDRESS        192.168.1.101

バッチリですね。



・EIP の確保と、ENIへの割り当て
EIP (Global IP)を確保して、作成済みのENIに割り当てます。
Private IP address 1つごとに1つのEIPを割り当てできるので、2つのEIPが使用できます。

Private IP address でそうしたように、キレイに二つ並んだモノが欲しいのですが…。ec2-allocate-address には そのようなオプションは無いですね…。
仕方ないので、二回取得することにします。
$ ec2-allocate-address --domain vpc
ADDRESS 54.249.94.148           vpc     eipalloc-9d2828f4

$ ec2-allocate-address --domain vpc
ADDRESS 54.249.94.173           vpc     eipalloc-912828f8
確保したEIPを 「192.168.1.100→54.249.94.148」「192.168.1.101→54.249.94.173」の組み合わせでENIに割り当てしてみます。
$ ec2-associate-address \
     --allocation-id eipalloc-9d2828f4  \
     --network-interface eni-b7b0b6de  \
     --private-ip-address 192.168.1.100
ADDRESS                 eipalloc-9d2828f4       eipassoc-9e2b2bf7       eni-b7b0b6de    192.168.1.100

$ ec2-associate-address \
     --allocation-id eipalloc-912828f8 \
     --network-interface eni-b7b0b6de  \
     --private-ip-address 192.168.1.101

ADDRESS                 eipalloc-912828f8       eipassoc-7f2c2c16       eni-b7b0b6de    192.168.1.101

$ ec2-describe-network-interfaces eni-b7b0b6de
NETWORKINTERFACE        eni-b7b0b6de    ENI-01 for standalone   subnet-8dabade4 vpc-baabadd3    ap-northeast-1a 488224276535     false   available       06:16:62:3a:1c:a1       192.168.1.100           true
GROUP   sg-fbd3cd97     vpc_standalone
ASSOCIATION     54.249.94.148   488224276535    eipassoc-9e2b2bf7       192.168.1.100
ASSOCIATION     54.249.94.173   488224276535    eipassoc-7f2c2c16       192.168.1.101

PRIVATEIPADDRESS        192.168.1.100
PRIVATEIPADDRESS        192.168.1.101
期待通りに割り当てられているようです。



・EC2インスタンスの起動
OSはいつも通り Ubuntu12 で、マイクロインスタンスを使用します。
ec2-run-instances で EC2を起動するのですが、その際 ENI を指定する方法が不明です。
公式のWEBページだと --network-interface オプションを利用することになっていますが、--help オプションで表示される説明だと --network-attachment となっています。省略形はどちらも -a になっているので、どちらでも使えるのかもしれませんが…。ちなみに、利用しているEC2コマンドのバージョンは1.6.7.1 (2013-02-01) です(ec2-version コマンドで確かめました)。
$ ec2-run-instances  ami-20ad1221  \
     --key innerkey  \
     --instance-count 1  \
     --instance-type t1.micro  \
     --instance-initiated-shutdown-behavior stop  \
     --group sg-fbd3cd97  \
     --subnet subnet-8dabade4  \
     --network-interface eni-b7b0b6de:0

Unrecognized option: --network-interface (use -h for usage)
げげ! まさかの公式ページが間違っているオチ...。--network-attachment が正解らしいです。
$ ec2-run-instances  ami-20ad1221  \
     --key innerkey  \
     --instance-count 1  \
     --instance-type t1.micro  \
     --instance-initiated-shutdown-behavior stop  \
    --group sg-fbd3cd97  \
    --subnet subnet-8dabade4  \
    --network-attachment eni-b7b0b6de:0
Client.InvalidParameterCombination: Network interfaces and an instance-level subnet ID may not be specified on the same request
--subnet 指定と、--network-attachment は同居できないようです。というか、よく考えたら必要ないですよね…。
$ ec2-run-instances  ami-20ad1221  \
     --key innerkey  \
     --instance-count 1  \
     --instance-type t1.micro  \
     --instance-initiated-shutdown-behavior stop  \
    --group sg-fbd3cd97  \
    --network-attachment eni-b7b0b6de:0
Client.InvalidParameterCombination: Network interfaces and an instance-level security groups may not be specified on the same request
今度はセキュリティグループが指定できない…と。たしかに、既にENIで指定してあるのでセキュリティグループ(--group)も不要ですよね。
$ ec2-run-instances  ami-20ad1221  \
     --key innerkey  \
     --instance-count 1  \
     --instance-type t1.micro  \
     --instance-initiated-shutdown-behavior stop  \
     --network-attachment eni-b7b0b6de:0

RESERVATION     r-9e32769d      488224276535
INSTANCE        i-4fce234d      ami-20ad1221            ip-192-168-1-100.ap-northeast-1.compute.internal        pending innerkey 0               t1.micro        2013-03-28T13:15:11+0000        ap-northeast-1a aki-ec5df7ed                    monitoring-disabled      54.249.94.148   192.168.1.100   vpc-baabadd3    subnet-8dabade4 ebs                                     paravirtual     xen              sg-fbd3cd97     default false
NIC     eni-b7b0b6de    subnet-8dabade4 vpc-baabadd3    488224276535    in-use  192.168.1.100           true
NICATTACHMENT   eni-attach-5e921337     0       attaching       2013-03-28T13:15:11+0000        false
NICASSOCIATION  54.249.94.148   488224276535    192.168.1.100
NICASSOCIATION  54.249.94.173   488224276535    192.168.1.101
GROUP   sg-fbd3cd97
PRIVATEIPADDRESS        192.168.1.100
PRIVATEIPADDRESS        192.168.1.101
ようやくEC2インスタンスが起動できました!



・EC2側でのENI+EIPの認識状態

プライマリ側の EIP を使って ssh で接続してみましょう。
$ ssh -i ~/.ssh/innerkey.pem -l ubuntu 54.249.94.148
なお、セカンダリのEIPでは接続できないので注意してください。
$ ssh -i ~/.ssh/innerkey.pem -l ubuntu 54.249.94.173
ssh: connect to host 54.249.94.173 port 22: Connection timed out
sshログインできたら、ネットワーク設定を確認してみます。
ubuntu$ ifconfig -a
eth0      Link encap:Ethernet  HWaddr 06:16:62:3a:1c:a1
          inet addr:192.168.1.100  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::416:62ff:fe3a:1ca1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:349 errors:0 dropped:0 overruns:0 frame:0
          TX packets:345 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:35751 (35.7 KB)  TX bytes:37538 (37.5 KB)
          Interrupt:25

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
んー。二つ設定したはずの Private IP は、1つだけしか認識されていませんね。つまり、それと結び付けられている セカンダリのEIPも使用できないワケで…。AWS側で設定しても、OS側に自動設定してくれるわけではないようです…。

設定を確認してみましょう…
$ cat /etc/network/interfaces

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet dhcp
まさかのDHCP設定...。static(固定IP)じゃないんだ…。
まぁ、割り当てられたプライマリPrivateIPが変更された場合を考慮すると、DHCPの方が良いのでしょうね。

ちなみに、/etc/network/interfaces の末尾に iface eth0:1 inet dhcp を追記して再起動しても eth0:1 は利用可能になりませんでした。恐らく、eth0 と eth0:1 は物理的に同じNICなので MACアドレスも同一で…そのために DHCP サーバから同じPrivateIPが付与されたので使えなくなっているのかと思われます。iface行の下に hwaddress ether xx:xx:xx:xx:xx~ とか指定して MACアドレスを偽装すれば DHCP から異なる Private IP を貰えるかもしれないですが、クラウド環境下で MACアドレス偽装とか怖すぎるのでやめておきます…(x_x;

他に、ec2-run-instances に --network-attachment :0:subnet-8dabade4:"NewOne":192.168.1.20:"sg-fbd3cd97":true:1」とか指定して、AWS自身に 新しい2つの Private IP を持つENIを自動生成させた場合でも、やはり 二つ目の Private IP はOSに認識されていませんでした…。

結局、プライマリの Private IP 以外は 自力で設定する必要がありそうです。
メンドクサイので自動化する手段が欲しい...(^^;

仕方ないので、/etc/network/interfaces に以下のように追記します。
# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface / eth0
auto eth0
iface eth0 inet dhcp

# The primary network interface / eth0:1
auto eth0:1
iface eth0:1 inet static
address 192.168.1.101
netmask 255.255.255.0

この設定では、metric がすべて1になってしまいますが…。
⇒ ifmetric パッケージを導入して eth0:1 側に metric 2 等の設定を追加しても、反応してくれませんでした。正直、metric の設定方法が良く分からない…。


ちなみに、eth0:1 を追加した直後から sudo を実行すると「sudo: unable to resolve host ip-192-168-1-100」とか怒られてしまうので、/etc/hosts に以下のような行を追記しておきます。
127.0.1.1   localhost.localdomain   ip-192-168-1-100
ホスト名は sudo のエラーと合わせておいてください。IPアドレスは 127.0.1.1 です。
これで名前が解決できるようになって、sudo がエラーを出さなくなります。
⇒ 127.0.1.1 というのは debian 系(Ubuntuもその一派)が勝手に設定するIPアドレスらしいです。今回のサーバだと 192.168.1.100 がプライマリのPrivateIPなのでその値を記載するのが本来の使い方のような気もしますが(x_x;

取りあえず、2つのIPアドレスで通信できるのかどうか、curl で確認してみます。利用する IPアドレス(=リクエスト発行元となるIPアドレス/ネットワークインターフェース)変更するには --interface オプションを使用します。

$ curl \
       --interface eth0 \
       'http://www.axisnetworks.biz/tools/gip/' 2>&1 \
   | egrep --only-matching \
       'name="ip">[^<]*<'

name="ip">54.249.94.148  <

$ curl \
       --interface eth0:1 \
       'http://www.axisnetworks.biz/tools/gip/' 2>&1
   | egrep --only-matching
       'name="ip">[^<]*<'

name="ip">54.249.94.173  <
期待通りに動作していますね。
http://www.axisnetworks.biz/tools/gip/ はブラウザでアクセスした際、利用しているグローバルIPを教えてくれるサービスらしいです。


では外部からの接続はどうでしょうか?

まず、port 80 で待ち受ける設定をします。待ち受けには nc (netcat)コマンドを利用します。
$ sudo nc -l 192.168.1.100 80
この状態で待ち受け(listen)が始まるので、別のサーバから「telnet 54.249.94.148 80」とか「curl 'http://54.249.94.148'」とか入力して、nc 側に接続させます。ちなみに、nc で待ち受けしているサーバでは(ネットワーク設定にもよりますが)自分自身に接続できないので、他のサーバを用意してください。
同じように「sudo nc -l 192.168.1.101 80」として待ち受けた場合には、「telnet 54.249.94.173 80」とか「curl 'http://54.249.94.173'」として接続できます。
もちろん、EIP (54.249.94.148と54.249.94.173)は ご自身で確保したものと置き換えてくださいね。

これで、二つの Global IP Address が利用できることを確認できました☆

⇒ もっとも、このような「同一subnetにIPアドレスを二つ持つ」というのが必要な状況は、あんまりありませんが…。
⇒ 今回は、「メイルサーバ用に複数IPを持ったサーバが欲しかった」のでこのような実験をしています。


文字数が足りなくなったので、今回はここまで。
破棄手順は、次回になります。

今回も AWSとはあんまり関係ない話です。AWSは使いますが…。


Javaアプリケーションをネットワーク越しにリモートデバッグ(remote debugging)するための設定について記載します。

リモートデバッグを利用すれば、例えば「ローカルPCはLAN環境にあり、グローバルIPや そのポート番号を自由に利用できないが、それらを利用するプログラムをデバッグしたい」という要望を叶えることが出来ます。つまり、LAN外のサーバでプログラムを動作させつつ LAN内のローカルPCで IDE を利用することが出来ます。
具体的には、例えばSMTPプログラムのテスト/デバッグに利用します…(しましたw)。



・EC2の準備
EC2インスタンスを起動して、Java (JDK) をインストールします。
Oracle(Sun)の標準JDKでなく OpenJDK でも良いのであれば、AmazonLinux には標準で OpenJDK (1.6) がインストールされているので、ラクチンです。ここでは、AmazonLinux を利用しておきます。

セキュリティグループには、アプリケーションで利用する設定に加えて 22番ポートも追加しておいてください。
VPCを利用する場合、Subnet、Internet GateWay、Routing Table なども設定する必要があります。

OS によっては、SUSE やら iptables 等のファイヤーウォール/セキュリティ保護プログラムの設定も必要です。期待するプログラムが起動できなかったり、パケットが通過できなかったりするので…。
⇒ 例えば AWS にある redhat6.3 って、デフォルトで iptables によるフィルタが設定されてます…。sshd を邪魔しないとは思いますが…。redhat はコレが標準なのでしょうか?[謎]



・sshd の設定
リモートデバッグにはポートを1つ使用しますが、さすがにデバッグ用のポートをインターネットに直接公開するのは怖いので ssh 越しで利用します。
AmazonLinux だと 標準では ssh port forwarding が無効になっているので、有効にしておきます。
具体的には /etc/ssh/sshd_config にあるはずの AllowAgentForwarding のパラメータを yes に変更します。



・ssh 接続
リモートデバッグで使用するポートを1つ決めて、EC2へ ssh port forwarding 接続します。ここでは port 9999 を利用するものとします。
ssh接続元は、デバッガとしての NetBeans を起動するPCになります。
$ ssh \
     -L 9999:localhost:9999 \
     -l ec2-user \
     YOURHOSTNAME.amazonaws.com



・Java プログラムの起動

EC2側で Java プログラムをネットワーク越しにデバッグできるようにオプション付で起動します。
$ java \
     -Xdebug \
     -Xrunjdwp:transport=dt_socket,server=y,address=9999,suspend=y
     ....................

※アプリケーション依存のパラメータ指定などは、必要に応じて適切に指定してください。
-Xdebug は「デバッグモードを有効にする」というオプションです。
-Xrunjdwp:~は、リモートデバッグに使用する Java Debug Wire Protocol というものを設定します。コロン以降のパラメータも「-Xrunjdwpオプションの一部」なので、コンマの前後等に空白を入れないように注意してください。
-Xrunjdwpの各サブパラメータの意味は、以下のようになります。
transport : サーバ側の待ち受けに利用するソケットの名称
server : サーバモードにするか否か (y/n)
address : サーバ側で待ち受けに使用するポート番号
suspend : 起動時にデバッガが接続するまで実行を停止させるか否か (y/n)

ウマク起動出来たら、以下のような表示が見られます。
Listening for transport dt_socket at address: 9999

ちなみに、Javaのリモートデバッグ(JDWP)に関する詳細はコチラで閲覧できます。
http://docs.oracle.com/javase/1.4.2/docs/guide/jpda/conninv.html
http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/conninv.html
http://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-Desktop/html/introduction.html



・NetBeans からサーバ側 Javaプログラムに接続する
ssh接続元となっているローカルPC側で NetBeans を起動したら、デバッグする対象プログラムのソースコードをプロジェクトとしてロードしておきます。
その後、メニューから [デバッグ]→[デバッガのアタッチ] と辿って、サーバ側へ接続します。

netdebug_netbeans











サーバー側での設定に合わせますが、今までのサンプル通り起動しているなら上記のとおりでOKです。
※ ssh の port forwarding を使用しているので、 localhost:9999 が デバッグ対象のJavaプログラムが動作している AWS EC2 側の 9999 に直結されています。



・デバッグ
リモートデバッグが成立すれば、後はふつーにステップ実行などを行うだけです。
当然ですが、NetBeans 側のソースコードは実行中の Java プログラムとバージョンが一致している必要があります。

もしリモートデバッグが成立しない場合は、以下の点を確認ください。他にも確認項目はあるかもしれませんが、少なくとも自分(私!!!)がハマったのは以下のような点でした (^^;

1. Javaプログラムを起動しているサーバー側では ssh port forwarding を受け入れる設定になっているか?
⇒ /etc/ssh/sshd_config にある AllowAgentForwarding が yes になっていることを確認する。
$ sudo cat /etc/ssh/sshd_config  \
     | fgrep -i AllowAgentForwarding
AllowAgentForwarding yes

※これはAmazonLinuxの例です
2. Javaプログラムを起動する際のパラメータで、リモートデバッグ機能を有効にしているか?
$ java \
     -Xdebug \
     -Xrunjdwp:transport=dt_socket,server=y,address=9999,suspend=y
     ....................


※-Xrunjdwp:~ の行にあるコンマで区切られたパラメータの間には空白は入れないでください。
3. ssh の port forwarding が成立しているか?
⇒ NetBeans を起動している側のPCで netstat -avn | grep ':9999' を実行したとき、以下のような二行が表示されるか? (Windows7+cygwin の場合の例)
$ netstat -avn | grep ':9999'
TCP 127.0.0.1:9999 0.0.0.0:0 LISTENING
TCP [::1]:9999 [::]:0 LISTENING




なお、利用後は、EC2インスタンスをTERMINATEするか、STOPするのを忘れずに…。



AWS とは無関係ですが、AWS EC2 の利用例ということで、参考まで…。

AWS EC2 で AmazonLinux を OS として起動し、その上で Java アプリケーションを動作させ、ローカルPCから リモートデバッグをしようとしたのですが…。
ローカルPCからデバッグ用のポートを接続するために ssh の port forwarding を利用したところ、ウマク接続できませんでした。

1時間ほど悩んで、/etc/ssh/sshd_config に port forwarding の設定が無いのではないか…と思い付き、確認してみるとビンゴでした…。

以下のようになれば正解らしいです。
$ sudo cat /etc/ssh/sshd_config  \
     | fgrep -i AllowAgentForwarding

AllowAgentForwarding yes
設定したら、以下のように反映させます。
$ sudo /etc/init.d/sshd restart
Stopping sshd:                                             [  OK  ]
Starting sshd:                                             [  OK  ]
ローカルPCから ssh port forwarding を有効にして ssh 接続するには、以下のようにします。
$ ssh -L 9999:localhost:9999 -l ec2-user  ~.amazonaws.com
この例では ローカルPC の ポート9999 を ssh 接続先サーバから見て localhost:9999 へ接続(port forwarding)します。ウマク設定出来ている場合、ローカルPC側のnetstat で以下のようになるはずです。この例は windows7のcygwin で実行しています。
$ netstat -avn | grep ':9999'
  TCP    127.0.0.1:9999         0.0.0.0:0              LISTENING
  TCP    [::1]:9999             [::]:0                 LISTENING
上側が IPv4 で、下側が IPv6ですね…。

これで、ローカルPCの 9999 が、ssh 接続先の localhost:9999 と同じように利用できます。


なぜ AmazonLinux では ssh portforwarding がデフォルトでOFFなのか分かりませんが…。コレって sshd の標準設定なんでしたっけ???

AWS とはあんまり関係ありませんが、参考まで…。



前回の「AWSでVPCを作る」の続きです。
今回は、作成した VPC 環境を破棄する、後片付けの手順になります。


・消去の順番
消去/破棄する順番に特に意味があるわけではありませんが…。
ルーティングやgateway を破棄してしまうと、VPC内部にアクセスできなくなってしまいます。
そのため、先に、VPC内のインスタンスを破棄し、その後、ルーティングテーブル、Gateway、EIP、VPC…と破棄していくことにします。
インスタンスの shutdown 時に、他のサーバと通信してデータを保存する…とかあったら困るので。



・EC2の破棄
特に何も言うことは無く、EC2インスタンスを shutdown して terminate させます。
# インスタンスをSTOPさせる
$ ec2-stop-instances  i-f3e1f0f0
INSTANCE        i-f3e1f0f0      running stopping

# TerminationProtection を無効にする
$ ec2-modify-instance-attribute \
     i-f3e1f0f0 \
     --disable-api-termination false

disableApiTermination   i-f3e1f0f0      false

# インスタンスをTERMINATEさせる
$ ec2-terminate-instances i-f3e1f0f0
INSTANCE        i-f3e1f0f0      stopped terminated

# インスタンスの状態を確認
$ ec2-describe-instances i-f3e1f0f0
RESERVATION     r-e95723ea      488224276535
INSTANCE        i-f3e1f0f0      ami-20ad1221                    terminated      innerkey        0               t1.micro        2013-03-14T09:13:51+0000 ap-northeast-1a aki-ec5df7ed                    monitoring-disabled                                     ebs                                      paravirtual     xen                     default false


・ルーティングテーブルの破棄
# ルーティングテーブル一覧確認
$ ec2-describe-route-tables
ROUTETABLE      rtb-eac9f783    vpc-e8c9f781
ROUTE   local           active  192.168.1.0/24          CreateRouteTable
ROUTE   igw-7b350c12            active  0.0.0.0/0               CreateRoute
ASSOCIATION     rtbassoc-edc9f784       main

# 0.0.0.0/0 に対するルーティングを削除
$ ec2-delete-route \
     rtb-eac9f783 \
     --cidr 0.0.0.0/0

RETURN  true

# 削除結果の確認
$ ec2-describe-route-tables
ROUTETABLE      rtb-eac9f783    vpc-e8c9f781
ROUTE   local           active  192.168.1.0/24          CreateRouteTable
ASSOCIATION     rtbassoc-edc9f784       main

# ルーティングテーブル自体を削除してみるが…
$ ec2-delete-route-table rtb-eac9f783
Client.DependencyViolation: The routeTable 'rtb-eac9f783' has dependencies and cannot be deleted
どうやら、main として VPC に割り当てられているルーティングテーブルは削除できないようですね…。
割り当てを解除してみましょう。
$ ec2-disassociate-route-table rtbassoc-edc9f784
Client.InvalidParameterValue: cannot disassociate the main route table association rtbassoc-edc9f784
むーん。main として割り当てられているルーティングテーブルは、割り当て解除できないようですね…。これは無視しておきましょう。



・Gateway の削除
# Gateway の確認
$ ec2-describe-internet-gateways
INTERNETGATEWAY igw-7b350c12
ATTACHMENT      vpc-e8c9f781    available

# Gateway と VPC の紐づけ解除
$ ec2-detach-internet-gateway \
     igw-7b350c12 \
     --vpc vpc-e8c9f781

RETURN  true

# Gateway の削除
$ ec2-delete-internet-gateway igw-7b350c12
RETURN  true

# 削除結果確認
$ ec2-describe-internet-gateways igw-7b350c12
Client.InvalidInternetGatewayID.NotFound: The internetGateway ID 'igw-7b350c12' does not
EIPが設定されたままなのに、削除できてしまいましたね…。
恐らく、既に EIPと紐づいていたはずの EC2インスタンスが削除されてしまったので、既にGateway と EIP の紐づけが解除されているのでしょう…。



・EIPの削除
EIPの状態を確認してみます。
$ ec2-describe-addresses
ADDRESS 54.249.84.161           vpc     eipalloc-f728119e
既に gateway や EC2 との紐づけは解除されているので、削除(解放)するだけですね…。
$ ec2-release-address \
     --allocation-id eipalloc-f728119e

ADDRESS                         eipalloc-f728119e

$ ec2-describe-addresses
EIPを削除(解放)できました。



・VPCの削除
まずは、VPC内部のサブネットを破棄します。
# VPC確認
$ ec2-describe-vpcs
VPC     vpc-e8c9f781    available       192.168.1.0/24  dopt-ecc9f785   default

# サブネット確認
$ ec2-describe-subnets
SUBNET  subnet-f0c3fd99 available       vpc-e8c9f781    192.168.1.0/24  251     ap-northeast-1a

# サブネットの削除
$ ec2-delete-subnet subnet-f0c3fd99
SUBNET  subnet-f0c3fd99

# サブネット確認
$ ec2-describe-subnets subnet-f0c3fd99
Client.InvalidSubnetID.NotFound: The subnet ID 'subnet-f0c3fd99' does not exist
最後はエラーになっていますが、削除したものを確認しようとしているので 期待通りのエラー内容になります。


次に VPC 自体を破棄しますが……
$ ec2-delete-vpc  vpc-e8c9f781
Client.DependencyViolation: The vpc 'vpc-e8c9f781' has dependencies and cannot be deleted.
VPCが、何かと依存関係にあって削除できないようですね。何でしょうか???


あああー。VPC専用のセキュリティグループを作成した記憶がありますね…。
$ ec2-describe-group --filter 'group-name=vpc_web'
GROUP   sg-1d1e0071     488224276535    vpc_web web in VPC      vpc-e8c9f781
PERMISSION      488224276535    vpc_web ALLOWS  tcp     22      22      FROM    CIDR    0.0.0.0/0       ingress
PERMISSION      488224276535    vpc_web ALLOWS  tcp     80      80      FROM    CIDR    0.0.0.0/0       ingress
PERMISSION      488224276535    vpc_web ALLOWS  all                     TO      CIDR    0.0.0.0/0       egress
たしかに残っています。これを削除してみましょう。
$ ec2-delete-group vpc_web
Client.InvalidParameterValue: Invalid value 'vpc_web' for groupName. You may not reference Amazon VPC security groups by name. Please use the corresponding id for this operation.

$ ec2-delete-group sg-1d1e0071
RETURN  true
名前指定では削除できなくて、自動付与された識別子でしか指定できないのはメンドクサイですが、一応セキュリティグループは消去できました。
では、VPC自体を削除してみましょう。
$ ec2-delete-vpc  vpc-e8c9f781
VPC     vpc-e8c9f781

$ ec2-describe-vpcs vpc-e8c9f781
Client.InvalidVpcID.NotFound: The vpc ID 'vpc-e8c9f781' does not exist
バッチリ消えましたね。


・最後の確認
念のため、AWS Management Console でインスタンスなどの状態を確認しておきましょう。
削除しないまま放置していると、無駄に課金されてしまうので…。



・まとめ
VPCを破棄する場合、以下の順序で処理する。
  1. EC2等のインスタンス
  2. ルーティングテーブル
  3. Gateway
  4. EIP
  5. セキュリティグループ
  6. VPC
RDSなども利用しているのであれば、(サーバー上のコンテンツプログラムの)依存関係に応じてインスタンスを破棄していく必要があります。



今回はここまで…。















このページのトップヘ