殿堂入り記事

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

2014.02.06

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

ども、大瀧です。みなさん、EC2をバリバリ使ってますか?使いたいときにすぐ使える仮想マシンとして、開発・検証から本番まで幅広く活用されていると思います。
日頃EC2を業務で運用する中で、EC2インスタンスをコピーすると意図しない環境設定に変わってしまうというトラブルが度々あり、cloud-initというツールに拠ることがわかってきました。

「EC2インスタンスのコピーなんて、一旦インスタンスを作成したあとはあまりやらないのでは?」と思われがちですが、EC2独特の制限などもあり、実際の運用では思ったよりも頻繁にインスタンスのコピーが必要になります。インスタンスのバックアップ&リストアなどはイメージしやすいと思いますが、それ以外にも意外なケースとして以下があります *1。インスタンスのコピーは、AMI(Amazon Machine Image:インスタンスのバックアップ)を取得し、新規インスタンスを作成することで実現します。

  1. ネットワーク構成の変更(ClassicからVPCへの移行やPrimary ENIのVPCサブネット変更など)
  2. ディスク(EBS)の拡張(オンプレミスの仮想環境のような、オンライン拡張はできないため)
  3. ELBとの組み合わせでダウンタイム無しでのシステム/アプリのアップデート

cloud-initは、AWS/EC2をはじめとするクラウド環境でLinuxを効率良く管理するための様々な機能を提供します。ただ、cloud-initはインスタンスの初回起動時に割とカジュアルにLinuxの環境設定をいじってしまうので、その既定の動作と変更方法は最低限押さえておくべきです。今回は5つをピックアップし、ご紹介します。

動作確認環境

  • Ubuntu Server 13.10(64-bit) - ami-b945ddb8(東京リージョン)
  • Amazon Linux AMI 2013.09.2(64-bit) - ami-0d13700c(東京リージョン)

※ CentOSについては、AWS MarketplaceのCentOS AMIではcloud-initパッケージが既定ではインストールされないため、必要に応じてインストールしましょう。今回の設定の範囲では、バージョンの近いUbuntuと同様の挙動になると思います。

1. パッケージアップデート

開発環境の整合性維持や本番環境の動作保証の観点から、運用時のパッケージアップデートのタイミングは事前に決めておく必要がありますね。
cloud-initの既定では、インスタンスの初回起動時に自動でセキュリティアップデートを実行します *2。つまり、元のEC2インスタンスで自動アップデートを無効にしたとしても、インスタンスのコピーのタイミングでcloud-initによるセキュリティアップデートが実行されます! *3 cloud-initによるコピー時のアップデート実行を無効にするためには、設定ファイルを以下のように変更します。

/etc/cloud/cloud.cfg

  :
repo_upgrade: none
  :

2. ロケール(言語)

これも、インスタンスのコピー時に、cloud-initによって既定のen_US.UTF8に設定されます。cloud-initの設定ファイルに以下を記述しましょう。

/etc/cloud/cloud.cfg(日本語/UTF8の場合)

  :
locale: ja_JP.UTF-8
  :

3. タイムゾーン

cloud-initのバージョンの差異により、UbuntuとAmazon Linuxで設定が異なります。

Ubuntuの場合

cloud-initの設定ファイルに以下を記述します。設定が無い場合は変更されません。

/etc/cloud/cloud.cfg(Asia/Tokyoの場合)

  :
timezone: Asia/Tokyo
  :

Amazon Linuxの場合

Amazon Linux既定のcloud-initのバージョンではタイムゾーン設定の機能が無いため、cloud-initが直接タイムゾーンを変更することはありません。ただし、上記1のrepo_upgrade: securityによってインスタンスの初回起動時にglibcパッケージが更新されると、パッケージ更新に含まれるスクリプトによりUTCに設定されるため、注意が必要です。これを防ぐためには、/etc/sysconfig/clockファイルを以下のように変更します。

/etc/sysconfig/clock(Asia/Tokyoの場合)

ZONE="Asia/Tokyo"
UTC=False

4. ファイルシステム拡張

これもcloud-initのバージョンの差異により、UbuntuとAmazon Linuxで設定が異なります。

Ubuntuの場合

cloud-initの既定で、インスタンスの初回起動時にルートファイルシステムのサイズが自動で拡張されます。
追加したEBSは拡張の対象にならないことに注意しましょう。

Amazon Linuxの場合

Amazon Linux既定のcloud-initのバージョンでは、ファイルシステムの拡張は自動で実行されません。インスタンスコピー時にEBSのサイズを大きくした場合でも、ファイルシステムサイズはそのままなので注意しましょう。
cloud-initで設定できるruncmd(初回起動時に任意のコマンドを実行する設定)などでresize2fsコマンドを実行すると良いですね。

5. ホスト名

cloud-initのpreserve_hostnameで制御します。既定値が、UbuntuとAmazon Linuxで異なることに注意しましょう。

/etc/cloud/cloud.cfg

  :
preserve_hostname: True
  :

Ubuntuの場合

cloud-initの既定ではpreserve_hostnamefalseのため、インスタンスの初回起動時にip-XX-XX-XX-XXというPrivate IPを元にしたホスト名に変更されます。無効にする場合は、設定をtrueに変更します。

Amazon Linuxの場合

cloud-initの既定ではpreserve_hostnameTrueのためホスト名は変更されません。ただ、cloud-initとは別に/etc/rc.d/rc.sysinitにより、/etc/sysconfig/network内のHOSTNAMEがlocalhostもしくはlocalhost.localdomainの場合のみ、ip-XX-XX-XX-XXが毎回のOS起動時に設定されます *4preserve_hostnamefalseに変更すると、Ubuntuと同様の動作になります。

まとめ

設定によっては便利なものもありますが、ひとまずなるべく手を出さないで欲しい!という場合は、以下の設定にしておきましょう。

/etc/cloud/cloud.cfg

  :
preserve_hostname: true
repo_upgrade: none
locale: ja_JP.UTF-8
  :

EC2のエキスパートの皆さんには、なにを今さらそんな基本的なことを。。。と呆れられるかもしれませんが、正直この記事を書くための検証で初めて気づいた設定もあり、結構目からウロコのところもありました。この辺りは設定漏れのないようにしっかり確認して日々の構築・運用に活かしてください!

おまけ

毎回のインスタンス作成時の指定を忘れないのであれば、ユーザーデータで設定してもOKです。

#cloud-config
repo_upgrade: none
locale: ja_JP.UTF-8

cloud-init-user-data-2-3

参考資料

脚注

  1. ちなみに、インスタンスサイズの変更はインスタンスをStopすれば変更できることを憶えておきましょう。
  2. 実際にはUbuntuであればapt-get、Amazon Linuxではyumユーティリティが内部でトリガーされます。
  3. dpkgコマンドのパッケージロック設定でアップデートを防ぐことは、多分できます(未検証)
  4. 実際には、DNSでPrivate IPの逆引きを問い合わせているので、内部DNSサーバーを構築している場合はこの限りではありません。