この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
昨日Amazon Linuxのcloud-init Tips集という記事を書きましたが、他にも色々気になることがあって調べてみましたので、記事にしてみます。
調べてみたこと
実行タイミング
まず、cloud-initがいつ実行されるのかを調べてみました。Amazon Linux AMIでLaunchしたEC2のランレベルを確認すると、
$ runlevel
N 3
なので、/etc/rc3.d/配下を確認してみます。
$ ls -alF /etc/rc3.d/ | grep cloud
lrwxrwxrwx 1 root root 26 8月 5 10:58 S50cloud-init-local -> ../init.d/cloud-init-local*
lrwxrwxrwx 1 root root 20 8月 5 10:58 S51cloud-init -> ../init.d/cloud-init*
lrwxrwxrwx 1 root root 22 8月 5 10:58 S52cloud-config -> ../init.d/cloud-config*
lrwxrwxrwx 1 root root 21 6月 12 01:51 S98cloud-final -> ../init.d/cloud-final*
このように、cloud-initの起動スクリプトは4つのファイルに分かれていました。通常sshやhttpdなどのサービスの起動スクリプトはS52よりも後でS98より先にあります。
lrwxrwxrwx 1 root root 14 7月 22 17:24 S55sshd -> ../init.d/sshd*
lrwxrwxrwx 1 root root 17 6月 12 01:53 S57ntpdate -> ../init.d/ntpdate*
lrwxrwxrwx 1 root root 14 6月 12 01:53 S58ntpd -> ../init.d/ntpd*
lrwxrwxrwx 1 root root 18 6月 12 01:51 S80sendmail -> ../init.d/sendmail*
lrwxrwxrwx 1 root root 15 6月 12 01:51 S90crond -> ../init.d/crond*
lrwxrwxrwx 1 root root 13 6月 12 01:52 S95atd -> ../init.d/atd*
このため実行順序としては
- cloud-init-local
- cloud-init
- cloud-config
- 各種サービスの起動
- cloud-final
となります。
それぞれの起動スクリプトがやっていること
この4つの起動スクリプトの内容を確認すると、以下のような違いがありました。
$ diff cloud-init-local cloud-init
70c70
< $cloud_init $CLOUDINITARGS init --local
---
> $cloud_init $CLOUDINITARGS init
$ diff cloud-init-local cloud-config
70c70
< $cloud_init $CLOUDINITARGS init --local
---
> $cloud_init $CLOUDINITARGS modules --mode config
$ diff cloud-init-local cloud-final
70c77
< $cloud_init $CLOUDINITARGS init --local
---
> $cloud_init $CLOUDINITARGS modules --mode final
内容はほぼ同一で、$cloud_init(/usr/bin/cloud-init)への引数が違うだけでした。
この引数による違いは、cloud-initの設定ファイルである/etc/cloud/cloud.cfgと/etc/cloud/cloud.cfg.d/配下のスクリプトで確認できます。
$ cat /etc/cloud/cloud.cfg.d/00_defaults.cfg
# ### DO NOT MODIFY THIS FILE! ###
# This file will be replaced if cloud-init is upgraded.
# Please put your modifications in other files under /etc/cloud/cloud.cfg.d/
#
# Note that cloud-init uses flexible merge strategies for config options
# http://cloudinit.readthedocs.org/en/latest/topics/merging.html
# The top level settings are used as module
# and system configuration.
# A set of users which may be applied and/or used by various modules
# when a 'default' entry is found it will reference the 'default_user'
# from the distro configuration specified below
users:
- default
ssh_pwauth: false
# Example datasource config
# datasource:
# Ec2:
# metadata_urls: [ 'blah.com' ]
# timeout: 5 # (defaults to 50 seconds)
# max_wait: 10 # (defaults to 120 seconds)
locale_configfile: /etc/sysconfig/i18n
mount_default_fields: [~, ~, 'auto', 'defaults,nofail', '0', '2']
resize_rootfs: noblock
resize_rootfs_tmp: /dev
ssh_deletekeys: true
ssh_genkeytypes: [ 'rsa', 'dsa', 'ecdsa' ]
syslog_fix_perms: ~
# The modules that run in the 'init' stage
cloud_init_modules:
- rsyslog
- migrator
- bootcmd
- write-files
- growpart
- resizefs
- set-hostname
- update-hostname
- update-etc-hosts
- users-groups
# The modules that run in the 'config' stage
cloud_config_modules:
- locale
- ssh
- set-passwords
- mounts
- yum-configure
- yum-add-repo
- package-update-upgrade-install
- timezone
- puppet
- disable-ec2-metadata
- runcmd
# The modules that run in the 'final' stage
cloud_final_modules:
- scripts-per-once
- scripts-per-boot
- scripts-per-instance
- scripts-user
- ssh-authkey-fingerprints
- keys-to-console
- phone-home
- final-message
- power-state-change
# System and/or distro specific settings
# (not accessible to handlers/transforms)
system_info:
# This will affect which distro class gets used
distro: amazon
distro_short: amzn
# Default user name + that default users groups (if added/used)
default_user:
name: ec2-user
lock_passwd: true
gecos: EC2 Default User
groups: [ wheel ]
sudo: [ "ALL=(ALL) NOPASSWD:ALL" ]
shell: /bin/bash
# Other config here will be given to the distro class and/or path classes
paths:
cloud_dir: /var/lib/cloud/
templates_dir: /etc/cloud/templates/
upstart_dir: /etc/init/
package_mirrors:
- arches: [ i386, x86_64 ]
search:
regional:
- repo.%(ec2_region)s.%(services_domain)s
- repo.%(ec2_region)s.amazonaws.com
ssh_svcname: sshd
# vim:syntax=yaml expandtab
cloud-init-localとcloud-initではcloud_init_modulesが、cloud-configではcloud_config_modulesが、cloud-finalではcloud_final_modulesが、それぞれ実行されます。
例えばbootcmdやwrite-filesなどはcloud_init_modulesで実行されますので、cloud_config_modulesで実行されるyum-configureやruncmdなどより前に実行されることが分かりますね。
なお、ここに書いてある各モジュールは/usr/lib/python2.6/site-packages/cloudinit/configにあります。Pythonで書かれていますので、読むとどんな動きをしているのかがわかります。
User-Dataの読み込まれるタイミング
/usr/bin/cloud-initを読むと、以下のように記述されていました。
# Cloud-init 'init' stage is broken up into the following sub-stages
# 1. Ensure that the init object fetches its config without errors
# 2. Setup logging/output redirections with resultant config (if any)
# 3. Initialize the cloud-init filesystem
# 4. Check if we can stop early by looking for various files
# 5. Fetch the datasource
# 6. Connect to the current instance location + update the cache
# 7. Consume the userdata (handlers get activated here)
# 8. Construct the modules object
# 9. Adjust any subsequent logging/output redirections using the modules
# objects config as it may be different from init object
# 10. Run the modules for the 'init' stage
# 11. Done!
なので、cloud-initの段階でUser-Dataの内容(/var/lib/cloud/instance/user-data.txt)が読み込まれます。
まとめ
ということで、cloud-initの動きについて少し理解が深まりました。次は各moduleについて色々試してみたいと思います。