cloud-initのデフォルト挙動を徹底的に調べてまとめてみた -結果ソースコードを読んだ-
コンニチハ、千葉です。
AWSを利用していればcloud-initをご存知の方が多いと思います。ただ、「cloud.cfg上から説明して!」とか言われたら困ると思います。
なにせ、ぐぐってもあまり情報がありません。公式のドキュメントを読んでも設定方法やモジュール名は書いているのですがモジュールがデフォルトでどんな挙動するのか読み取れませんでした。なので、ソースコード(主にコメントw)頑張って読んでまとめました。
初期構築等で設定だけしたいのであれば、このページを見ればいけると思います。
cloud-initの実行タイミング
ふわっと、初回起動みたいに覚えている方もいると思います。実際には初回起動以外にも実行タイミングがあります。
- 一生に?1回だけ実行されるもの
- インスタンスごとに実行されるもの(AMI作成し、そこからインスタンスを作成した時)
- 起動時に毎回実行されるもの
ソースで、「frequency」にPER_INSTANCE, PER_ALWAYS, PER_ONCEのいづれかを指定することで挙動が変わるようでした。
また、cloud.cfgではモジュールを複数指定してあり、それぞれ実行タイミングが違います。デフォルトでは以下の順番で実行されます。
- cloud_init_modules
- cloud_config_modules
- cloud_final_modules
表でまとめてみた
デフォルトでの実行される内容、実行タイミングや、挙動(「-」実行されてみ何も変更しない)、パラメータをまとめてみました。
ただしRHEL6.5のcloud.cfgを元にしてるので、amazon linuxなどの別ディストリビューションでは内容が異なる箇所があると思うのでそこは考慮して参照ください!
各モジュールの実行タイミング(RHEL6.5 デフォルト)
※スマフォだと表が切れますので、画面を横にするか、PCで御覧ください
実行タイミング |
|||||
---|---|---|---|---|---|
No |
項目 |
1回のみ |
インスタンス毎 |
boot毎 |
デフォルト挙動 |
1 |
boot時に指定したコマンドを実行 |
○ |
- |
||
2 |
指定ファイルへの書き込み |
○ |
- |
||
3 |
「/」のファイルシステムを拡張 |
○ |
ファイルシステムを拡張 |
||
4 |
ホスト名の設定(/etc/sysconfig/network) |
○ |
ホスト名を設定 |
||
5 |
ホスト名の設定※モジュールがupdate_hostnameの方(/etc/sysconfig/network) |
○ |
ホスト名を設定 |
||
6 |
「/etc/hosts」の設定 |
○ |
- |
||
7 |
rsyslogの設定 |
○ |
- |
||
8 |
ユーザ・グループ作成 |
○ |
ec2-userを作成する |
||
9 |
sshでのrootでのログイン設定 |
○ |
rootログイン無効 |
||
10 |
sshのパスワードログイン設定 |
○ |
パスワードログイン無効 |
||
11 |
sshキー(/etc/ssh/ssh_host_*key*)の削除 |
○ |
- |
||
12 |
sshdのキータイプを指定 |
○ |
- |
||
13 |
マウントの設定 |
○ |
- |
||
14 |
言語設定 |
○ |
en_US.UTF-8に設定 |
||
15 |
ユーザーパスワードを設定 |
○ |
- |
||
16 |
タイムゾーンの設定 |
○ |
- |
||
17 |
構成管理ツールの設定と起動(puppet) |
○ |
- |
||
18 |
構成管理ツールの設定と起動 (chef) |
○ |
- |
||
19 |
構成管理ツールの設定と起動(salt-minion) |
○ |
- |
||
20 |
構成管理ツールの設定と起動 (mcollective) |
○ |
- |
||
21 |
メタデータアクセス制御 |
○ |
アクセス可能 |
||
22 |
指定コマンドの実行 |
○ |
- |
||
23 |
rightscaleをユーザーデータで設定 |
○ |
- |
||
24 |
1回だけスクリプトを実行(/var/lib/cloud/scripts/per-once) |
○ |
- |
||
25 |
boot毎にスクリプトを実行(/var/lib/cloud/scripts/per-boot) |
○ |
- |
||
26 |
インスタンス毎にスクリプトを実行(/var/lib/cloud/scripts/per-instance) |
○ |
- |
||
27 |
ユーザー定義のスクリプトを実行(/var/lib/cloud/scripts/vendor) |
○ |
- |
||
28 |
sshフィンガープリントをconsole(システムログ)に出力する |
○ |
システムログに出力 |
||
29 |
sshフィンガープリントをconsole(システムログ)の出力フィルタリング |
○ |
- |
||
30 |
boot完了時に指定したURLにリクエストを投げる |
○ |
- |
||
31 |
cloud-init完了ログをconsole(システムログ)に出力する |
○ |
システムログに出力 |
||
32 |
「/var/log/cloud-init.log」のパーミッションを設定 |
○ |
- |
モジュール一覧(RHEL5.6 デフォルト)
No |
項目 |
モジュール |
|
1 |
boot時に指定したコマンドを実行 |
cloud_init_modules |
bootcmd |
2 |
指定ファイルへの書き込み |
write-files |
|
3 |
「/」のファイルシステムを拡張 |
resizefs |
|
4 |
ホスト名の設定(/etc/sysconfig/network) |
set_hostname |
|
5 |
ホスト名の設定(/etc/sysconfig/network) |
update_hostname |
|
6 |
「/etc/hosts」の設定 |
update_etc_hosts |
|
7 |
rsyslogの設定 |
rsyslog |
|
8 |
ユーザ・グループ作成 |
users-groups |
|
9 |
sshでのrootでのログイン設定 |
ssh |
|
10 |
sshのパスワードログイン設定 |
ssh |
|
11 |
sshキー(/etc/ssh/ssh_host_*key*)の削除 |
ssh |
|
12 |
sshdのキータイプを指定 |
ssh |
|
13 |
マウントの設定 |
cloud_config_modules |
mounts |
14 |
言語設定 |
locale |
|
15 |
ユーザーパスワードを設定 |
set-passwords |
|
16 |
タイムゾーンの設定 |
timezone |
|
17 |
構成管理ツールの設定と起動(puppet) |
puppet |
|
18 |
構成管理ツールの設定と起動 (chef) |
chef |
|
19 |
構成管理ツールの設定と起動 (salt-minion) |
salt-minion |
|
20 |
構成管理ツールの設定と起動 (mcollective) |
mcollective |
|
21 |
メタデータアクセス制御 |
disable-ec2-metadata |
|
22 |
指定コマンドの実行 |
runcmd |
|
23 |
rightscaleをユーザーデータで設定 |
cloud_final_modules |
rightscale_userdata |
24 |
1回だけスクリプトを実行(/var/lib/cloud/scripts/per-once) |
scripts-per-once |
|
25 |
boot毎にスクリプトを実行(/var/lib/cloud/scripts/per-boot) |
scripts-per-boot |
|
26 |
インスタンス毎にスクリプトを実行(/var/lib/cloud/scripts/per-instance) |
scripts-per-instance |
|
27 |
ユーザー定義のスクリプトを実行(/var/lib/cloud/scripts/vendor) |
scripts-user |
|
28 |
sshフィンガープリントをconsole(システムログ)に出力する |
ssh-authkey-fingerprints |
|
29 |
sshフィンガープリントをconsole(システムログ)の出力フィルタリング |
keys-to-console |
|
30 |
boot完了時に指定したURLにリクエストを投げる |
phone-home |
|
31 |
cloud-init完了ログをconsole(システムログ)に出力する |
final-message |
|
32 |
「/var/log/cloud-init.log」のパーミッションを設定 |
初期化処理 |
AMIからEC2をリストアするときに何も変更したくない場合はどうすればよいの?
表を見ると、AMIからEC2を作成した場合にデフォルトで変更される箇所は以下となります。
- /etc/sysconfig/networkのホスト名がfqdnに書き換えられる(例:ip-12-34-56-78.us-west-2.compute.internal)
- ec2-userを作成する
- /etc/ssh/sshd_configを書き換え、パスワードログイン無効、rootログイン無効化を行う
- localeを「en_US.UTF-8」に設定する
変更させない場合の対応策としては以下2つあります。
userdataで頑張る
userdataに以下を入力してAMIを作成
#cloud-config preserve_hostname: True # ホスト名を変更させない disable_root: True # rootログインを有効化したい場合はFalse ssh_pwauth: False # パスワードログインを有効化したい場合はTrue locale: ja_JP.UTF-8 # 任意のlocaleを指定
あとは、ec2-userは作成されてしまうので手動で削除を行う
cloud-initの初期化をそもそも実施させない
cloud-initの設定ファイル(/etc/cloud/cloud.cfg)を変更する 以下の個所をコメントアウトする
- set_hostname - update_hostname - sers-groups - ssh - locale
(参考)ソースコードにコメント入れてみた
## (前半)実行モジュールのパラメータを指定する ### defaultで指定したユーザーを作成 users: - default ### sshでのrootでのログインを無効にする disable_root: 1 ### sshのパスワードログインを無効化 ssh_pwauth: 0 ### locale設定ファイルのパスを指定 locale_configfile: /etc/sysconfig/i18n ### mountsを設定(fstabを設定するエントリ)するときのデフォルトの値(指定しないとこの値が設定される) mount_default_fields: [~, ~, 'auto', 'defaults,nofail', '0', '2'] ### /devが存在しない場合、ディレクトリを作成する(ソース読んだのですが自信はないです) resize_rootfs_tmp: /dev ### sshの「/etc/ssh/ssh_host_*key*」を削除※default無効 ssh_deletekeys: 0 ### 「ssh-keygen -t」で利用するキータイプ(rsa,dsa,ecdsa)を指定 ssh_genkeytypes: ~ ### 「/var/log/cloud-init.log」のユーザー:グループを指定 syslog_fix_perms: ~ ## (後半)実行するモジュールを指定する(前半戦) cloud_init_modules: ### ブートプロセス時にコマンドを実行 #### コマンドを指定する場合の指定例 ####bootcmd: ####- echo 192.168.1.130 us.archive.ubuntu.com > /etc/hosts ####- [ cloud-init-per, once, mymkfs, mkfs, /dev/vdb ] - bootcmd ### ファイル書き込み - write-files ### /のファイルシステムを拡張する - resizefs ### ホスト名を設定する(/etc/sysconfig/networkのホスト名を書き換える) - set_hostname ### ホスト名を設定する(/etc/hostnameのホスト名を書き換える)※起動時に毎回実行されるはずだがRHEL6.5では動いてない模様? - update_hostname ### ホスト名を設定する(テンプレートでの指定やlocalhost等の指定が可能) - update_etc_hosts ### rsyslogの設定変更を行う(デフォルトでは何もしない) - rsyslog ### ユーザー・グループの作成を行う(デフォルトではdefaultで指定されているec2-userを作成する) - users-groups ### sshの設定を行う(デフォルトではrootログイン、パスワードログインの無効化) - ssh cloud_config_modules: ### fstabの設定を行う(エフェメラル等やswapの設定を行うがrhelの場合デフォルトでは何もしない) - mounts ### localeの設定を行う(デフォルトはen_US.UTF-8に初期化される) - locale ### ユーザーのパスワードを設定(デフォルトは何も実施しない) - set-passwords ### タイムゾーンの設定(デフォルトでは何も実施しない) - timezone ### 構成管理ツールの設定と起動を行う。デフォルトでは何も実施しない - puppet - chef - salt-minion - mcollective ### メタデータアクセスを拒否ができないように設定する(デフォルトfalseでメタデータにアクセスできる状態) - disable-ec2-metadata ### 指定したコマンドを実行する(デフォルト何もしない) - runcmd cloud_final_modules: ### rightscaleをユーザーデータで設定 - rightscale_userdata ### 一回だけスクリプトを実行(/var/lib/cloud/scripts/per-onceのスクリプト) - scripts-per-once ### 起動毎に実行(/var/lib/cloud/scripts/per-bootのスクリプト) - scripts-per-boot ### AMIからインスタンス作成時の初回起動時だけスクリプトを実行(/var/lib/cloud/scripts/per-instanceのスクリプト) - scripts-per-instance ### AMIからインスタンス作成時の初回起動時だけスクリプトを実行(/var/lib/cloud/scripts/vendorのスクリプト) - scripts-user ### sshフィンガープリントをconsoleに出力する - ssh-authkey-fingerprints ### ssh時のフィンガープリントを出力をする、しないの制御をする(デフォルトでは何もしない) - keys-to-console ### boot完了時に指定したURLにリクエストを投げる※デフォルトでは何もしない - phone-home ### 完了ログをconsoleに出力する - final-message system_info: ### ディストリビューションを指定 distro: rhel ### 初回起動時に作成するユーザーを指定 default_user: name: ec2-user ### cloud-initのディレクトリ設定 paths: cloud_dir: /var/lib/cloud templates_dir: /etc/cloud/templates ### sshdの再起動を行う ssh_svcname: sshd # vim:syntax=yaml ### cloud-iniが利用するデータソースを指定(EC2の場合はmetadataを利用するようになる) datasource: Ec2: timeout: 10 max_wait: 30
まとめ
これで、AMI作成時や起動時に何が設定変更されるのか把握することができました。また、cloud.cfgを理解することでuserdataを利用して初期構築も楽になるのではないかなーと思います。