
Amazon Linuxのcloud-initの動きについて調べてみた
この記事は公開されてから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について色々試してみたいと思います。













