Amazon Linux 2でカスタムAMIからの起動時にホスト名を固定する方法

Amazon Linux 2でカスタムAMIを作成して別インスタンスを作成する際に、ホスト名を固定する方法をまとめてみました。hostnamectlコマンドでホスト名を設定するのに加えcloud-initの設定も行いましょう。
2020.01.31

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

清水です。先日、Amazon Linux 2でもろもろ設定をしたカスタムAMIを作成、そのAMIからEC2インスタンスを起動する、という場面がありました。その際、カスタムAMI作成時のベースとなるEC2インスタンス側でホスト名を設定していたにも関わらず、AMIからEC2インスタンス起動時にはこれが初期化されデフォルトのip-XX-XX-XX-XX形式のホスト名に戻ってしまう、ということがあり、この対応をしたので備忘録としてまとめておきたいと思います。

先に結論をまとめてしまいますと、hostnamectlコマンドを使用してホスト名を設定するのに加え、cloud-initのpreserve_hostnameの値をtrueに設定する必要がありました。

Amazon Linux 2でAMIからの起動時にホスト名を固定する

それでは実際の手順についてまとめていきます。

hostnamectlコマンドでホスト名の設定

まずはhostnamectlコマンドを使用してホスト名を設定します。こちらは下記のAWSドキュメントにも記載がある方法ですね。

AWSから提供されているAmazon Linux 2のAMIからEC2インスタンスを起動し、下記のようにhostnameコマンドのset-hostname`オプションでホスト名を設定します。

# 変更前の情報の確認
[ec2-user@ip-10-82-21-70 ~]$ hostnamectl
   Static hostname: ip-10-82-21-70.ap-northeast-1.compute.internal
         Icon name: computer-vm
           Chassis: vm
        Machine ID: ec2eb2a972ed3b680c44e70900000000
           Boot ID: 12992af5b90a4b16909b6c4e00000000
    Virtualization: xen
  Operating System: Amazon Linux 2
       CPE OS Name: cpe:2.3:o:amazon:amazon_linux:2
            Kernel: Linux 4.14.158-129.185.amzn2.x86_64
      Architecture: x86-64

# hostnameコマンドでホスト名を設定
[ec2-user@ip-10-82-21-70 ~]$ sudo hostnamectl set-hostname myserver.example.net

# hostsファイルを変更
[ec2-user@ip-10-82-21-70 ~]$ sudo cp -p /etc/hosts /etc/hosts.original
[ec2-user@ip-10-82-21-70 ~]$ sudo vi /etc/hosts
[ec2-user@ip-10-82-21-70 ~]$ cat /etc/hosts
127.0.0.1   myserver.example.net myserver localhost4 localhost4.localdomain4
::1         localhost6 localhost6.localdomain6

インスタンスを再起動して新しいホスト名を確認してみます。

# 再起動
[ec2-user@ip-10-82-21-70 ~]$ sudo reboot
Connection to 54.238.000.000 closed by remote host.
Connection to 54.238.000.000 closed.

# 起動完了したらsshで接続
[shimizu.toshiya@classmethod] [~]
 $ ssh -i ~/.ssh/key.pem ec2-user@54.238.000.000
Last login: Fri Jan 31 01:52:12 2020 from xxx.yyy.zzz.example.ne.jp

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

https://aws.amazon.com/amazon-linux-2/

# hostnamectlコマンドでホスト名を確認(シェルプロンプトでもホスト名を確認できますね)   
[ec2-user@myserver ~]$ hostnamectl
   Static hostname: myserver.example.net
         Icon name: computer-vm
           Chassis: vm
        Machine ID: ec2eb2a972ed3b680c44e70900000000
           Boot ID: 2015cb074e2d4004b3f3934100000000
    Virtualization: xen
  Operating System: Amazon Linux 2
       CPE OS Name: cpe:2.3:o:amazon:amazon_linux:2
            Kernel: Linux 4.14.158-129.185.amzn2.x86_64
      Architecture: x86-64

例えば停止→起動を行ってみてもホスト名は維持されています。

# EC2インスタンスを一度停止
[ec2-user@myserver ~]$ sudo shutdown -h now
Connection to 54.238.000.000 closed by remote host.
Connection to 54.238.000.000 closed.

# マネジメントコンソールでEC2インスタンスを起動しssh接続
[shimizu.toshiya@classmethod] [~]
 $ ssh -i ~/.ssh/key.pem ec2-user@13.231.000.000
The authenticity of host '13.231.000.000 (13.231.000.000)' can't be established.
ECDSA key fingerprint is SHA256:eMibFHsVtkRad1ZgNMabotWCoZhxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '13.231.000.000' (ECDSA) to the list of known hosts.
Last login: Fri Jan 31 02:04:45 2020 from xxx.yyy.zzz.example.ne.jp

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

https://aws.amazon.com/amazon-linux-2/

# hostnamectlコマンドでホスト名を確認(ホスト名は先ほど設定されたままの状態)
[ec2-user@myserver ~]$ hostnamectl
   Static hostname: myserver.example.net
         Icon name: computer-vm
           Chassis: vm
        Machine ID: ec2eb2a972ed3b680c44e70900000000
           Boot ID: 9f181f30d9ca41ddb8f7d7b300000000
    Virtualization: xen
  Operating System: Amazon Linux 2
       CPE OS Name: cpe:2.3:o:amazon:amazon_linux:2
            Kernel: Linux 4.14.158-129.185.amzn2.x86_64
      Architecture: x86-64

ではこのhostnamectrlでホスト名を設定した状態のEC2インスタンスからカスタムAMIを取得、そのAMIからEC2インスタンスを起動してみましょう。以下のように、ホスト名はデフォルトのip-XX-XX-XX-XX.ap-northeast-1.compute.internalに戻ってしまいました。

# カスタムAMIから起動したEC2インスタンスにssh接続
[shimizu.toshiya@classmethod] [~]
 $ ssh -i ~/.ssh/key.pem ec2-user@52.196.000.000
The authenticity of host '52.196.000.000 (52.196.000.000)' can't be established.
ECDSA key fingerprint is SHA256:eMibFHsVtkRad1ZgNMabotWCoZhxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '52.196.000.000' (ECDSA) to the list of known hosts.
Last login: Fri Jan 31 02:11:13 2020 from xxx.yyy.zzz.example.ne.jp

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

https://aws.amazon.com/amazon-linux-2/

# hostnamectlコマンドでホスト名を確認(ホスト名はデフォルトのip-XX-XX-XX-XXに戻ってしまっている)
[ec2-user@ip-10-82-21-190 ~]$ hostnamectl
   Static hostname: ip-10-82-21-190.ap-northeast-1.compute.internal
         Icon name: computer-vm
           Chassis: vm
        Machine ID: ec2eb2a972ed3b680c44e70900000000
           Boot ID: 29b2bad6e64b4144bb9d6de200000000
    Virtualization: xen
  Operating System: Amazon Linux 2
       CPE OS Name: cpe:2.3:o:amazon:amazon_linux:2
            Kernel: Linux 4.14.158-129.185.amzn2.x86_64
      Architecture: x86-64

cloud-initのpreserve_hostnameをtrueに設定

カスタムAMIからEC2を起動時にホスト名がデフォルトに上書かれてしまう……、原因として考えられたのがcloud-initまわりでした。調査しつつ社内でも情報をいただき、cloud-init設定ファイル内のpreserve_hostnameの値をTrueに設定することでこの事象を回避しホスト名を固定できることが確認できました。

参考にしたのは以下のエントリ、「5. ホスト名」の箇所です。こちらのエントリはAmazon Linux(2ではなくて1のほう)を対象に記載されていますが、この設定内容の情報が役に立ちました。

Amazon EC2(Linux)システム管理で知らないとハマる5つの環境設定 | Developers.IO

具体的な設定手順です。hostnamectrlコマンドでホスト名を設定したのち、さらに以下のようにcloud-init設定ファイルを書き換えます。/etc/cloud/cloud.cfgファイルにpreserve_hostname: trueの設定を加えることとなります。

# cloud-initの設定ファイル/etc/cloud.cfgを編集します
[ec2-user@myserver ~]$ sudo cp -p /etc/cloud/cloud.cfg /etc/cloud/cloud.cfg.original
[ec2-user@myserver ~]$ sudo vi /etc/cloud/cloud.cfg

# 編集内容としてはファイルの末尾に「preserve_hostname: true」を追記しました
[ec2-user@myserver ~]$ diff /etc/cloud/cloud.cfg /etc/cloud/cloud.cfg.original
86d85
< preserve_hostname: true
[ec2-user@myserver ~]$

このcloud-initを書き換えた状態でEC2インスタンスからカスタムAMIを取得しましょう。取得できたらこのAMIからEC2インスタンスを起動して起動してみます。以下のように、きちんとホスト名がカスタムAMI取得前のものから固定されていますね!

# カスタムAMIからEC2インスタンスを起動してssh接続
[shimizu.toshiya@classmethod] [~]
 $ ssh -i ~/.ssh/key.pem ec2-user@54.95.000.000
The authenticity of host '54.95.000.000 (54.95.000.000)' can't be established.
ECDSA key fingerprint is SHA256:eMibFHsVtkRad1ZgNMabotWCoZhxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '54.95.000.000' (ECDSA) to the list of known hosts.
Last login: Fri Jan 31 02:18:28 2020 from xxx.yyy.zzz.example.ne.jp

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

https://aws.amazon.com/amazon-linux-2/

# hostnamectlコマンドでホスト名を確認(ホスト名は設定されたまま、固定された状態)
[ec2-user@myserver ~]$ hostnamectl
   Static hostname: myserver.example.net
         Icon name: computer-vm
           Chassis: vm
        Machine ID: ec2eb2a972ed3b680c44e70900000000
           Boot ID: b07ba867efa8401c8762ee1e00000000
    Virtualization: xen
  Operating System: Amazon Linux 2
       CPE OS Name: cpe:2.3:o:amazon:amazon_linux:2
            Kernel: Linux 4.14.158-129.185.amzn2.x86_64
      Architecture: x86-64

まとめ

Amazon Linux 2でカスタムAMIを作成して別インスタンスを作成する際に、ホスト名を固定する方法をまとめてみました。hostnamectlコマンドのset-hostnameオプションを使用してホスト名を設定するのに加え、cloud-initのpreserve_hostnameTrueに設定しておきましょう。なお、デフォルトとなっているホスト名ip-XX-XX-XX-XX形式のものについては、トラブル回避などのためDNS/DHCPと連携してホスト名の重複を避けるような意図もあるかと考えます。とはいえ、アプリケーション要件などによってホスト名を固定する要件もあるかと思います。ホスト名の変更や固定は計画的に行いましょう。