はじめに
オンプレの常識とクラウドの常識は違います。
先日以下の記事を読んでいろいろとなるほどなーと思うことがありました。
その中の以下一文について今回は検証してみました。
Changing an IP or a MAC address in a VM usually results in a disconnected VM.
実験内容
AWS 上で稼働するインスタンスの IP アドレスは AWS が管理します。では、EC2 インスタンス内から 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 側から接続できたのだと思います。
ここで、設定ファイルを .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 アドレスを変えるなんて、おバカな考えを起こすのはやめましょう。
以上