はじめに
本稿は、cloud-init
に関して、ふわ
っとしたイメージしか持っていなかった私が、自身の記録用にまとめたノートを投稿しているだけですので、エキスパートの方は参考にしないでください。初学者の方にとっては、比較的わかりやすい内容にまとめているつもりです。
cloud-initとは
cloud-initは、cloud instanceの初期化メソッドで、様々なクラウドベンダーをサポートしています。
元々、EC2用に作成されたもので、ec2-init
というパッケージ名だったそうです。
ドキュメントは、こちらです。
インスタンスの初期設定に必要な、アカウント、リポジトリ設定、パッケージのインストールなど様々な機能もありますし、任意のスクリプトを実行する事も可能です。(CA証明書インストール作業とか、結構楽かも。)
cloud-initは #cloud-config
で始まる、ユーザーデータ
などを受け取り、初期セットアップを行います。
cloud-configは、YAML形式で記述します。
例えば、以下でユーザーを作成します。
#cloud-config
users:
- default
- name: foobar
gecos: Foo B. Bar
primary_group: foobar
groups: users
selinux_user: staff_u
expiredate: 2012-09-01
ssh_import_id: foobar
lock_passwd: false
passwd: $6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYC
使い分け
構成管理ツールとして、ChefやAnsible、puppetなどがありますが、それらの使い分けに関してまとめてみました。
以下の画像がわかりやすいと思います。
AnsibleやChefなどと被るところがありますが、初期セットアップ
という観点で使う場合は、 cloud-init
を利用すればいいのではないかと考えています。
terraformで、新たにインスタンスをプロビジョニング、cloud-initで初期セットアップ、Ansibleで構成管理といった連携など考えられます。
Boot Stage
cloud-initのboot stageは以下、5つに分かれています。
- Generator
- Local
- Network
- Config
- Final
Generator
では、cloud-initを実行するか否かの決定をします。実行する場合、Local
ではメタデータに格納されているネットワーク情報を適用します。Network
ではdisk_setupを実行しmodulesをマウントします。Config
では、config_moduleのみをrunします。Final
は一番最後に実行されます。ユーザーログイン後にRunする必要のあるスクリプトはここに記述する必要があります。
それぞれのステージは、以下のコマンドで確認できます。
$ cloud-init status --long
status: running
time: Fri, 26 Jan 2018 21:39:43 +0000
detail:
Running in stage: init-local
モジュール郡はそれぞれが上記のStageに紐づいています。例えば、Bootcmd
は、cloud_init_modules
に属しており、boot毎に実行されます。
scripts-per-boot
では、cloud_final_modules
に属しており、こちらもboot毎に実行されます。これらは実行のタイミングが異なるので、それを意識した上での記述が必要です。
ドキュメントには、
ブートプロセスの後半で実行できない処理にのみ使用してください。
と書いてあったので、上記でない限りは、 cloud_init_modules
内で処理をした方が良いみたいです。
注意としては、再起動プロセスは runcmd
で記述の記述がおすすめ。(runcmdは、config_modulesですが、Final Stageで実行されます。)
デバッグ
まず、cloud-initのディレクトリ情報は以下の通りになっていました。
$ tree --charset=x /var/lib/cloud/ -L 2
/var/lib/cloud/
|-- data
| |-- instance-id
| |-- previous-datasource
| |-- previous-instance-id
| |-- result.json
| |-- set-hostname
| `-- status.json
|-- handlers
|-- instance -> /var/lib/cloud/instances/ocid1.instance.oc1.iad.***********
|-- instances
| `-- ocid1.instance.oc1.iad.***********
|-- scripts
| |-- per-boot
| |-- per-instance
| |-- per-once
| `-- vendor
|-- seed
`-- sem
instanceのcloud-config.txtには、cloud-configの情報が格納されていました。
(これってプロビジョニング後からruncmdなどの記述を変更をしていいのかな。)
$ cat cloud-config.txt
#cloud-config
# from 1 files
# part-001
---
cloud_final_modules:
- - scripts-user
- always
locale: ja_JP.utf8
package_upgrade: true
packages:
- man-pages-ja
- multitail
- nmap
- nc
- tmux
- tree
runcmd:
- - sh
- -c
- echo $(date) >> /tmp/testfile.txt
timezone: Asia/Tokyo
また実行ログは、/var/log/cloud-init.log
に格納されます。基本的に実行確認などは、ここを見ればOKだと思います。
$ cat /var/log/cloud-init.log | grep config-timezone
2020-05-17 16:28:37,630 - handlers.py[DEBUG]: start: modules-config/config-timezone: running config-timezone with frequency once-per-instance
2020-05-17 16:28:37,635 - helpers.py[DEBUG]: Running config-timezone using lock (<FileLock using file '/var/lib/cloud/instances/ocid1.instance.oc1.iad.anuwcljrejk3llyct26xrjijj74qh5i6cgtd33i7575zupmk5g74hk4o7cqa/sem/config_timezone'>)
2020-05-17 16:28:37,636 - handlers.py[DEBUG]: finish: modules-config/config-timezone: SUCCESS: config-timezone ran successfully
もしくは以下のような形で、ログ情報を出力する事も可能です。
runcmd:
- - sh
- -c
- echo $(date) >> /tmp/testfile.txt
$ cat /tmp/testfile.txt
Mon May 18 01:28:38 JST 2020
2020年 5月 18日 月曜日 01:36:08 JST
最後に
初学者としてのcloud-initの私なりの理解をまとめました。
windowsOSをサポートしているcloudbase-initに関してのドキュメントは充実していないようなので、今後そのあたりのまとめ記事など投稿したいなと考えています。
参考情報
Amazon Linuxのcloud-initの実行順番を確認する
cloud-initを使ったLinux OSの初期設定
cloud-initをデバッグする Part 1