おれさまラボ

実際に手を動かして理解を深めるブログ。

AWS - インスタンスのIPをOSから変更するとどうなるか

はじめに

オンプレの常識とクラウドの常識は違います。

先日以下の記事を読んでいろいろとなるほどなーと思うことがありました。

blog.ipspace.net

その中の以下一文について今回は検証してみました。

Changing an IP or a MAC address in a VM usually results in a disconnected VM.

実験内容

AWS 上で稼働するインスタンスの IP アドレスは AWS が管理します。では、EC2 インスタンス内から IP アドレスを変更するとどうなるでしょうか。

  • 不整合が発生する
  • インスタンスに接続できなくなる
  • 実は AWS 側に IP 変更が反映される

先の記事には、IP が変更されると VM から切断されるとありましたが、果たしてそうでしょうか。

確かめていきます。

ネットワーク設定の確認

まず、本筋とはあまり関係ないのですが、インスタンスのネットワーク設定を確認します。

AWS から管理されているということは、たとえインスタンス起動時に IP アドレスを指定したとしても、インスタンス内の OS に書き込まれるわけではなくて、DHCP で受け取っているのでは無いかなと思いました。

で、確かめてみると予想通りでした。

起動時に自動割当 IP を有効にした場合と起動時に IP を手動で設定した場合で設定ファイルに差分はありませんでした。

起動時に自動割当IPを有効にした場合

$ cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=dhcp
ONBOOT=yes
TYPE=Ethernet
USERCTL=yes
PEERDNS=yes
DHCPV6C=yes
DHCPV6C_OPTIONS=-nw
PERSISTENT_DHCLIENT=yes
RES_OPTIONS="timeout:2 attempts:5"
DHCP_ARP_CHECK=no

起動時にIPを手動で設定した場合

$ cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=dhcp
ONBOOT=yes
TYPE=Ethernet
USERCTL=yes
PEERDNS=yes
DHCPV6C=yes
DHCPV6C_OPTIONS=-nw
PERSISTENT_DHCLIENT=yes
RES_OPTIONS="timeout:2 attempts:5"
DHCP_ARP_CHECK=no

ちなみに、この設定ファイルのパラメータの意味は以下テーブルに記載の通りです。勉強になりました。

パラメーター Value
DEVICE=eth0 物理デバイスNIC)の名前の指定 任意
BOOTPROTO=dhcp 起動プロトコルの指定 none/bootp/dhcp
ONBOOT=yes 起動時に有効化するかどうかの指定 yes/no
TYPE=Ethernet 通信プロトコルの指定 Ethernet / IPsec など
USERCTL=yes yesだとrootユーザー以外もこのデバイスを制御できる yes/no
PEERDNS=yes /etc/resolv.confを見るようにする設定 yes/no
DHCPV6C=yes DHCPv6クライアントの有効化設定 yes/no
DHCPV6C_OPTIONS=-nw DHCPv6クライアントオプションの設定だが詳細不明 オプション値
PERSISTENT_DHCLIENT=yes DHCP-DISCOVERYリクエストに対してDHCP-OFFERがない場合に再送するか否かの指定 yes/no
RES_OPTIONS="timeout:2attempts:5" DNS名前解決オプションの指定 オプション値
DHCP_ARP_CHECK=no 詳細不明。ARPチェックなのだろう。 yes/no

参考1:インターフェース設定ファイル 参考2:11.2. Interface Configuration Files Red Hat Enterprise Linux 6 | Red Hat Customer Portal 参考3:[速報]Amazon Linux AMI 2016.03 がリリースされました! | Developers.IO

OS から IP 変更をかけてみる

ということで本題に入ります。

実験1:割り当てられた IP を変えずに書き込む

まずは、AWS から割り当てられた IP アドレス(今回は 10.255.1.20)をそのまま設定ファイルに記載してみます。

$ sudo cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=none
ONBOOT=yes
NETMASK=255.255.255.0
IPADDR=10.255.1.20
TYPE=Ethernet
USERCTL=yes
PEERDNS=yes
DHCPV6C=yes
DHCPV6C_OPTIONS=-nw
PERSISTENT_DHCLIENT=yes
RES_OPTIONS="timeout:2 attempts:5"
DHCP_ARP_CHECK=no

初期状態との diff はこの通り。

$ diff /etc/sysconfig/network-scripts/ifcfg-eth0.bef /etc/sysconfig/network-scripts/ifcfg-eth0
2c2
< BOOTPROTO=dhcp
---
> BOOTPROTO=none
3a4,5
> NETMASK=255.255.255.0
> IPADDR=10.255.1.20

この状態でネットワーク再起動をかけると、エラーもなくうまく設定が反映されました。

$ sudo service network restart
Restarting network (via systemctl):                        [  OK  ]

eth0 に指定した IP アドレス(10.255.1.20)がついています。

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 0a:7f:9d:90:3f:b6 brd ff:ff:ff:ff:ff:ff
    inet 10.255.1.20/24 brd 10.255.1.255 scope global dynamic eth0
       valid_lft 3569sec preferred_lft 3569sec
    inet6 fe80::87f:9dff:fe90:3fb6/64 scope link
       valid_lft forever preferred_lft forever

この状態で一度 OS 再起動をかけてみたところ、特に問題なく起動しました。なお、再起動はマネジメントコンソールから行っています。 ※ running → stop → start

インターフェース設定も変わりなく、

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 0a:7f:9d:90:3f:b6 brd ff:ff:ff:ff:ff:ff
    inet 10.255.1.20/24 brd 10.255.1.255 scope global dynamic eth0
       valid_lft 3463sec preferred_lft 3463sec
    inet6 fe80::87f:9dff:fe90:3fb6/64 scope link
       valid_lft forever preferred_lft forever

設定ファイルが書き換えられるというようなこともありませんでした。

$ sudo cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=none
ONBOOT=yes
NETMASK=255.255.255.0
IPADDR=10.255.1.20
TYPE=Ethernet
USERCTL=yes
PEERDNS=yes
DHCPV6C=yes
DHCPV6C_OPTIONS=-nw
PERSISTENT_DHCLIENT=yes
RES_OPTIONS="timeout:2 attempts:5"
DHCP_ARP_CHECK=no

実験2:割り当てられた IP と異なる IP を設定する

次は AWS から割り当てられた 10.255.1.20 ではなく、10.255.1.21 を割り当ててみます。

$ diff /etc/sysconfig/network-scripts/ifcfg-eth0.bef /etc/sysconfig/network-scripts/ifcfg-eth0
2c2
< BOOTPROTO=dhcp
---
> BOOTPROTO=none
3a4,5
> NETMASK=255.255.255.0
> IPADDR=10.255.1.21

ネットワーク再起動をかけると正常に再起動できました。

$ sudo service network restart
Restarting network (via systemctl):                        [  OK  ]

しかし、ネットワークインターフェースには複数の IP アドレスがついてしまっています。ちょっとおかしなことになってきました。

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 0a:7f:9d:90:3f:b6 brd ff:ff:ff:ff:ff:ff
    inet 10.255.1.21/24 brd 10.255.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 10.255.1.20/24 brd 10.255.1.255 scope global secondary dynamic eth0
       valid_lft 3572sec preferred_lft 3572sec
    inet6 fe80::87f:9dff:fe90:3fb6/64 scope link
       valid_lft forever preferred_lft forever

この状態で OS 再起動をかけてみます。ここでも、再起動はマネジメントコンソールから行っています。 ※ running → stop → start

マネジメントコンソールから見える STOP 状態のインスタンスのプライベートIP情報は元の .20 のまま。

起動には問題なく成功し、

2/2 のチェックに合格しました

マネジメントコンソール上の IP にも変化はありません。あくまで、AWS からは 10.255.1.20 と認識しているようです。

ということで、セッションマネージャから接続を試みたところ、接続に失敗しました。

aws ssm start-session --target i-021d495b2216abf94

An error occurred (TargetNotConnected) when calling the StartSession operation: i-021d495b2216abf94 is not connected.

仕方がないので、グローバル IP に対して SSH を試みたところ接続できました。

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-10-255-1-20 ~]$

インターフェース設定は .21 と .20 の 2 つが存在している状態でした。

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 0a:7f:9d:90:3f:b6 brd ff:ff:ff:ff:ff:ff
    inet 10.255.1.21/24 brd 10.255.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 10.255.1.20/24 brd 10.255.1.255 scope global secondary dynamic eth0
       valid_lft 2606sec preferred_lft 2606sec
    inet6 fe80::87f:9dff:fe90:3fb6/64 scope link
       valid_lft forever preferred_lft forever

もちろん設定ファイルも書き換わっていない。

$ cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=none
ONBOOT=yes
NETMASK=255.255.255.0
IPADDR=10.255.1.21
TYPE=Ethernet
USERCTL=yes
PEERDNS=yes
DHCPV6C=yes
DHCPV6C_OPTIONS=-nw
PERSISTENT_DHCLIENT=yes
RES_OPTIONS="timeout:2 attempts:5"
DHCP_ARP_CHECK=no

ここからは推測ですが、OS 上は .21 がプライマリに見えていて、VPC では .20 とインスタンスマッピングされているので、セッションマネージャでの接続は不整合に終わったのだと思います。

ただ、グローバル IP とプライベート IP である .20 は Internet Gateway 側で NAT テーブルが保持されていることで、グローバル IP 側から接続できたのだと思います。

f:id:naoto408:20200531225230p:plain

ここで、設定ファイルを .21 から .20 に戻すとネットワーク再起動に失敗しました。これは意図せずセカンダリアドレスがついてしまっているからかなと思います。

$ diff /etc/sysconfig/network-scripts/ifcfg-eth0.bef
/etc/sysconfig/network-scripts/ifcfg-eth0
[ec2-user@ip-10-255-1-20 ~]$ sudo service network restart
Restarting network (via systemctl):  Job for network.service failed because the control process exited with error code. See "systemctl status network.service" and "journalctl -xe" for details.
                                                           [FAILED]

失敗したときのログはこちら。

$ sudo systemctl status network.service
● network.service - LSB: Bring up/down networking
   Loaded: loaded (/etc/rc.d/init.d/network; bad; vendor preset: disabled)
   Active: failed (Result: exit-code) since Sun 2020-05-17 04:52:53 UTC; 41s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 3423 ExecStop=/etc/rc.d/init.d/network stop (code=exited, status=0/SUCCESS)
  Process: 4114 ExecStart=/etc/rc.d/init.d/network start (code=exited, status=1/FAILURE)
   CGroup: /system.slice/network.service
           tq3789 /sbin/dhclient -q -lf /var/lib/dhclient/dhclient--eth0.lease -pf /var/run/dhclient-eth0.pid -H ip-10-255-1-20 eth0
           mq3919 /sbin/dhclient -6 -nw -lf /var/lib/dhclient/dhclient6--eth0.lease -pf /var/run/dhclient6-eth0.pid eth0 -H ip-10-255-1-20

May 17 04:52:53 ip-10-255-1-20.ap-northeast-1.compute.internal network[4114]: RTNETLINK answers: File exists
May 17 04:52:53 ip-10-255-1-20.ap-northeast-1.compute.internal network[4114]: RTNETLINK answers: File exists
May 17 04:52:53 ip-10-255-1-20.ap-northeast-1.compute.internal network[4114]: RTNETLINK answers: File exists
May 17 04:52:53 ip-10-255-1-20.ap-northeast-1.compute.internal network[4114]: RTNETLINK answers: File exists
May 17 04:52:53 ip-10-255-1-20.ap-northeast-1.compute.internal network[4114]: RTNETLINK answers: File exists
May 17 04:52:53 ip-10-255-1-20.ap-northeast-1.compute.internal systemd[1]: network.service: control process exited, code=exited status=1
May 17 04:52:53 ip-10-255-1-20.ap-northeast-1.compute.internal systemd[1]: Failed to start LSB: Bring up/down networking.
May 17 04:52:53 ip-10-255-1-20.ap-northeast-1.compute.internal systemd[1]: Unit network.service entered failed state.
May 17 04:52:53 ip-10-255-1-20.ap-northeast-1.compute.internal systemd[1]: network.service failed.
May 17 04:53:13 ip-10-255-1-20.ap-northeast-1.compute.internal dhclient[3919]: XMT: Solicit on eth0, interval 117280ms.

仕方がないので OS 再起動してみると無事 .20 に戻り、SSM セッションマネージャからも接続できました。

おわりに

OS 側から IP アドレスを変えるなんて、おバカな考えを起こすのはやめましょう。

以上