cloud-initのNoCloudを使ってお試し環境を簡単に構築する
以前cloud-initについて紹介をした。
cloud-initの仕組みはVMを決まったユーザや鍵を使ってセットアップしたり、指定スクリプトを実行したりとクラウドプロバイダ経由でなくても利用したい機能である。
自宅にOpenStackを構築していれば、DatastoreとしてOpenStackが有力な候補となるかもしれないが、「そんなもの自宅にはない」もしくは「もう少しライトにVMを使ってる」という人がほとんどだろう。
そこでNoCloudというDatastoreを使ってqemu/kvmで構築したVMに対してcloud-initを活用してセットアップする。
DatastoreとしてのNocloud
NoCloudはcloud-initのDatastoreとしては少し特殊で、ネットワークを経由せずに起動VMに対してデータを与える役割を担っている。
ではどうやってデータを渡すかというとVFATのローカルディスク経由もしくは、iso9660で外部から与える事ができる。
VM起動確認
まずcloud-initを確認するためのベースイメージを用意する。各ディストリビューションでAWSなどのクラウドプロバイダ上での動作を想定したcloud imageが配布されているが、これを利用すればcloud-initが最初からインストールされているため簡単に利用することができる。
今回はFedoraのcloud imageを利用することにした。 - https://alt.fedoraproject.org/cloud/
NoCloudを利用するためにはuser-data
とmeta-data
をディスクイメージに含める必要がある。
まずmeta-dataを作成する。 ここで指定されている、intance-idについては初回起動かどうかを識別するためのものとドキュメントに記載がある。
Note: that the instance-id provided (iid-local01 above) is what is used to determine if this is “first boot”. So if you are making updates to user-data you will also have to change that, or start the disk fresh.
local-hostanmeはその名の初期ホスト名として利用される。
$ cat << 'EOF' > meta-data instance-id: test-vm local-hostname: test-vm
次にuser-dataを作成する。
ここにはログイン情報などを記載するがせっかくなので、パスワードに加えてsshの公開鍵認証でログインできるように設定する。
今回は最小限のログイン情報を設定したが、様々な設定が可能なのでこちらのドキュメントを参照してほしい。
cat << 'EOF' > user-data #cloud-config users: - name: test groups: users, wheel lock_passwd: False plain_text_passwd: test ssh_pwauth: True ssh_authorized_keys: - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCqg4+5ISX6LuYfF+197BhGLaPGhtpsuIdl0YM26g7b/rt80l6KdccVqmDbv27dD6gfGx2l5DFFIGb1rPLIUnJ8NCsV3zQWivSRac/8thidRzHWLb/fLvmyOA2LqYeKv2SUubbtQVnm972w+gHAukALitmWp251WvCwzj7K2woMWNj63qFtplDnm8LLVZkhbC2iAvr23sNAz8LX+wsaX79A18mo6f7whTXn
この2つのファイルをイメージファイルに固めてvm起動時にcdromとして認識するようにする。
イメージの作成にはgenisoimage
コマンドを利用したが、同じように作成すれば何を使っても問題ない。このときボリュームラベルにcidata
もしくはCIDATA
を設定しなれければいけないことに注意する。
genisoimage -output cloud-init-conf.iso -volid cidata -joliet -rock user-data meta-data
起動する前にダウンロードしてきたFedoraのcloud imageをそのまま使ってもよいが、毎回新しいイメージを用意するのは面倒なので、バッキングファイルとして残しておくことにする。
sudo qemu-img create -b Fedora-Cloud-Base-32-1.6.x86_64.qcow2 -f qcow2 test-vm.qcow2 20G
この状態でcdromに先程生成したisoデータを設定して、virt-installする。
virt-install --name test-vm --ram 16384 --vcpus 4 --arch x86_64 --os-type linux --hvm --virt-type kvm --file ./test-vm.qcow2 --cdrom ./cloud-init-conf.iso --boot hd --graphics bash --serial pty --console pty --autostart
これで設定に間違えがなければ、インストール後に設定したパスワードやssh鍵でログインすることができる。
cdromからは先程設定したデータが確認できた。
$ sudo mkdir /mnt/cdrom $ sudo mount /dev/cdrom /mnt/cdrom/ mount: /mnt/cdrom: WARNING: source write-protected, mounted read-only. $ ls /mnt/cdrom/ meta-data user-data
入力したしたデータやスクリプト、cloud-initの実行結果などはVM内の/var/lib/cloud/
配下で確認することができる。
おまけ
cloud-initではどのdatastoreを利用するのかds-identifyで判定している。
https://github.com/canonical/cloud-init/blob/main/tools/ds-identify#L835-L859
コードを読んでみるとNoCloudの判定のため引数やファイル、ファイルシステムのラベルが最初に設定したcidata
もしくはCIDATA
などかをチェックしていることがわかる。
dscheck_NoCloud() { local fslabel="cidata CIDATA" d="" case " ${DI_KERNEL_CMDLINE} " in *\ ds=nocloud*) return ${DS_FOUND};; esac case " ${DI_DMI_PRODUCT_SERIAL} " in *\ ds=nocloud*) return ${DS_FOUND};; esac for d in nocloud nocloud-net; do check_seed_dir "$d" meta-data user-data && return ${DS_FOUND} check_writable_seed_dir "$d" meta-data user-data && return ${DS_FOUND} done # shellcheck disable=2086 if has_fs_with_label $fslabel; then return ${DS_FOUND} fi # This is a bit hacky, but a NoCloud false positive isn't the end of the world if check_config "NoCloud" && check_config "user-data" && check_config "meta-data"; then return ${DS_FOUND} fi return ${DS_NOT_FOUND} }
cloud-init NoClouda
cloud-init Cloud config examples