CloudStack (IDCFクラウド) で cloud-init を使う
概要
CloudStack で cloud-init を使用する際の構築手順とメモ。
IDCFクラウド標準?(おすすめテンプレート)の CentOS 7.2 では cloud-init インストールしただけでは、正常動作しなかった※ので構築手順を記録しておく。
※cloud-init から META DATA サーバにアクセスできないエラーが発生
原因
CloudStack では VR が dpcp, META DATA サーバの役割も持っており、cloud-init が user_data を取得する際に、 /var/lib/dhclient/dhclient-eth0.leases
ファイルから META DATA サーバのアドレスを取得している。
IDCFクラウド標準の CentOS 7.2 テンプレートでは、NetworkManager が有効になっており、NetworkManager でセットアップされた場合上記ファイルが作成されないため、cloud-init が META DATA サーバの情報取得出来ずにエラーが発生していた。
環境
- CloudStack 4.3.0.3 (IDCFクラウド)
- CentOS 7.2 64-bit
インストール手順
cloud-init インストール
$ sudo yum install cloud-init
cloud-init datasource 設定
以下のファイルを新規作成
/etc/cloud/cloud.cfg.d/99_cloudstack.cfg
datasource:
CloudStack: {}
None: {}
datasource_list:
- CloudStack
cloud-init 有効化
$ sudo systemctl enable cloud-config
$ sudo systemctl enable cloud-init
$ sudo systemctl enable cloud-final
Interface 設定
IF 名の変更
GRUB_CMDLINE_LINUX のオプションに net.ifnames=0 を追記
/etc/default/grub
GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/swap vconsole.font=latarcyrhebsun16 vconsole.keymap=jp106 rd.lvm.lv=centos/root crashkernel=auto net.ifnames=0 rhgb quiet"
grub へ反映
$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg
IF 設定
以下ファイルを新規作成
/etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE="eth0"
BOOTPROTO="dhcp"
IPV6INIT="yes"
MTU="1500"
NM_CONTROLLED="no"
ONBOOT="yes"
TYPE="Ethernet"
NetworkManager 削除
$ sudo yum -y remove NetworkManager
network service 有効化
$ sudo chkconfig network on
再起動
$ sudo reboot
以上
IDCF コミュニティテンプレート
毎回やるのは面倒なのでテンプレート化 + 公開してみた
- テンプレート名: CentOS 7.2 64bit with cloud-init
使用上の注意点
以下の制約があり、user_data へ引き渡すデータサイズは固定になるため、特定の環境下でしか使えない。
(ホスト名とか文字数が変わる環境下では、毎回改行の追加・削除等でバイト数を調整する必要がある。)
Base64エンコード前のデータのバイト数が3の倍数ではない場合、正常に認識できない
IDCFクラウド公式ブログ記事 より。
ちなみに terraform でインスタンス作成しようとしたときは以下のエラーとなる。
Error applying plan:
1 error(s) occurred:
* cloudstack_instance.default: Error creating the new instance test-01: CloudStack API error 400 (CSExceptionErrorCode: 9999): deployVirtualMachine accepts only userdata which size is multiples of 3 bytes before base64 encoding.
user_data を Base64エンコードした際のパディング( ケツに =
が含まれるとダメ)が影響していると思われるが、正直使い物にならないのでなんとかして欲しい。
OKパターン
$ base64 default.yml | tr -d "\n" ;echo ""
I2Nsb3VkLWNvbmZpZwoKd3JpdGVfZmlsZXM6CiAgLSBwYXRoOiAvZXRjL3N5c2NvbmZpZy9tYWNrZXJlbC1hZ2VudAogICAgY29udGVudDogfAogICAgICBPVEhFUl9PUFRTPSItcm9sZT1zaG93cm9vbToke3NoYXJkfSIKICAgICAgQVVUT19SRVRJUkVNRU5UPTEKCgpydW5jbWQ6CiAgLSBzZXJ2aWNlIG1hY2tlcmVsLWFnZW50IHJlc3RhcnQK
NGパターン
$ base64 cloud-config.yml | tr -d "\n" ;echo ""
I2Nsb3VkLWNvbmZpZwoKd3JpdGVfZmlsZXM6CiAgLSBwYXRoOiAvZXRjL3N5c2NvbmZpZy9tYWNrZXJlbC1hZ2VudAogICAgY29udGVudDogfAogICAgICBPVEhFUl9PUFRTPSItcm9sZT1zaG93cm9vbToke3NoYXJkfSIKICAgICAgQVVUT19SRVRJUkVNRU5UPTEKCnJ1bmNtZDoKICAtIHNlcnZpY2UgbWFja2VyZWwtYWdlbnQgcmVzdGFydAo=