Proxmox VEのcloudinitでuserdataを自由に調整する

Posted on 2021/08/10(Tue) 19:30 in technical

Proxmox VEのcliudinitでuserdataを自由に調整する

以前 Proxmox VE 5.2でCloud-Initが使えるようになったので使う話 を書いたのですが、
関連して Proxmox VE 6.0 から "custom Cloudinit configurations" がサポートされるようになりました。
仮想マシンの初回起動時に、任意のaptリポジトリを追加したり、追加のパッケージをインストール出来ると便利なので、実際に使ってこの機能の挙動を確認してみようと思います。
公式ページの Cloud-Init Support は結構サラッと書かれているので、調査ついでにまとめておきます。

前提知識

Proxmox VEで使用可能なcloud-initの設定ファイルは以下の3つです。

  • user-data
  • meda-data
  • network-data

Proxmox VEでcloud-initの設定ファイルを仮想マシン設定に追加するには、設定ファイルを "snippets" が保存可能なStorageのパスにあらかじめ保存しておく必要があります。

Storageに保存するcontentに "snippets" を追加

特に意識せずにStorageを使用している場合、おそらく "snippets" が保存可能な設定になっていると思われます。
今回はProxmox VEをインストール時に大抵追加されている local ストレージに "snippets" を格納できるように設定します。

snippets

コマンドで実施する場合は、以下のようになります。
対象のストレージパスに snippets ディレクトリが出来ていれば良いでしょう。

# pvesm set local --content iso,backup,snippets,vztmpl
# pvesm status -content snippets
Name          Type     Status           Total            Used       Available        %
local          dir     active        29083776        12594948        16488828   43.31%
# ls /var/lib/vz/
dump  images  private  root  snippets  template

現状のcloud-init設定をdumpする

実際にcloud-initの設定を書き始める前に、Proxmox VEが自動生成しているcloud-init設定を取得します。

サンプルの仮想マシン設定

既に、以下のように仮想マシンが設定済みであるとします。

# qm config 2239
boot: c
bootdisk: virtio0
ciuser: dummy
cores: 1
cpu: Skylake-Client
ide2: rdb_vm:vm-2239-cloudinit,media=cdrom
ipconfig0: ip=192.168.1.239/24,gw=192.168.1.1
memory: 1024
name: nginx
nameserver: 192.168.1.1 2001:db8::1
net0: virtio=82:6A:3D:04:05:AB,bridge=vmbr0
onboot: 1
ostype: l26
scsihw: virtio-scsi-pci
searchdomain: example.net
serial0: socket
smbios1: uuid=ec25f72d-0386-4d4d-97ad-6d6e5f83f2cd
vga: serial0
virtio0: rdb_vm:vm-2239-disk-0,size=16G
vmgenid: 968926af-6062-4445-9c56-c6fc90067344

Warning

通常、cloudinit設定は仮想マシンの初回起動時にのみ実行されるので、上記の仮想マシンはまだ一度も起動していないということに注意してください。

サンプルの仮想マシン設定からdumpしたcloudinit設定(user)

このとき qm cloudinit dump 2239 user を実行すると、以下のようにcloud-initの設定を抜き出すことができます。

#cloud-config
hostname: nginx
manage_etc_hosts: true
fqdn: nginx.example.net
user: dummy
chpasswd:
  expire: False
users:
  - default
package_upgrade: true

生成部分のコードは cloudinit_userdata() に書かれていて、YAMLのインデントはハードコーディングな揃え方をしています。
searchdomain が設定されている場合は fqdn がちゃんと "$hostname.$search" になっていることも、上記コードから追いかけられます。

サンプルの仮想マシン設定からdumpしたcloudinit設定(meta)

特に使用しませんが、metaの場合は以下のようになります。

instance-id: 89922b1f51af615ec9079e1ca8651ae5329aefdb

サンプルの仮想マシン設定からdumpしたcloudinit設定(network)

特に使用しませんが、networkの場合は以下のようになります。

version: 1
config:
    - type: physical
      name: eth0
      mac_address: '82:6a:3d:04:05:ab'
      subnets:
      - type: static
        address: '192.168.1.239'
        netmask: '255.255.255.0'
        gateway: '192.168.1.1'
    - type: nameserver
      address:
      - '192.168.1.1'
      - '2001:db8::1'
      search:
      - 'example.net'

現状のcloud-init設定を元に追加の設定を書いて、仮想マシン設定を更新

それでは、現状の設定が分かったところで、設定ファイルを吐き出して編集後、そのファイルを cicustom に設定します。

# qm cloudinit dump 2239 user > /var/lib/vz/snippets/2239_cloudinit_userdata.yaml
# vi /var/lib/vz/snippets/2239_cloudinit_userdata.yaml
(中略)
# qm set 2239 --cicustom "user=local:snippets/2239_cloudinit_userdata.yaml"
update VM 2239: -cicustom user=local:snippets/2239_cloudinit_userdata.yaml

Note

Proxmox VE 6.4時点ではGUIで設定できないので、CLIから設定します。

Warning

この設定をすると、Proxmox VEが自動生成しているcloudinitのuser-data設定は使用されなくなります。
(networkとmetaはProxmox VEが生成したものが使われますので、指定したタイプの設定だけが置き換えられるということです)
GUIでは cicustom 設定はサポートされていないので表示されません。
CLIでsnippetsのファイルを参照するように設定変更した後で、GUIでcloudinitのパスワード等を変更しても反映されませんので、混乱しないようにしましょう。

なお、設定を削除するときは以下のようになります。

# qm set 2239 -delete cicustom
update VM 2239: -delete cicustom

(中略) とした設定内容は cloudinit の Modules に沿って書かれていれば何でも良いです。

例えばaptのsourceをppaから追加する場合では、以下のような行を末尾に追記します。

apt:
  sources:
    gns3:
      source: "ppa:gns3/ppa"

起動と確認

設定したVMを起動して、目的のcloudinit設定が処理されているか確認してみます。
今回は先の例で書いたGNS3のppaが追加されているかどうかを確認します。

$ cat /etc/apt/sources.list.d/gns3-ubuntu-ppa-focal.list 
deb http://ppa.launchpad.net/gns3/ppa/ubuntu focal main
# deb-src http://ppa.launchpad.net/gns3/ppa/ubuntu focal main
$ grep "gns3" /var/log/cloud-init.log 
2021-08-10 10:02:17,588 - cc_apt_configure.py[DEBUG]: handling apt config: {'sources': {'gns3': {'source': 'ppa:gns3/ppa'}}}
2021-08-10 10:02:17,713 - cc_apt_configure.py[DEBUG]: adding source/key '{'source': 'ppa:gns3/ppa'}'
2021-08-10 10:02:17,713 - subp.py[DEBUG]: Running command ['add-apt-repository', 'ppa:gns3/ppa'] with allowed return codes [0] (shell=False, capture=True)

GNS3のppaがaptのsources.list.dに追加されていることが確認できました。

APIを使いたい人向けの情報

ここまでの作業をAPIで自動化できると嬉しいかなぁと思って調べていたのですが、今のところ以下の点に課題がありそうです。

  • APIを使用して、Storageにsnippetsをアップロードすることは現在サポートされていません

無理矢理実装することを考えると、sshでログインまたは共有フォルダをマウントしてファイルを置く。ということになるかなと思います。
上記のパッチはサイズや影響範囲も小さく済みそうなので、パッチを当ててAPI経由でsnippetsの格納をサポートするのも悪くはなさそうです。
(今見ると、このパッチは処理部分の問題だけを解消しているので、APIのenumパラメータ周りも修正してあげた方が良いかな?)

参考

終わり

Proxmox VEのGUIで提供されているcloudinit設定だけでは不足する場合、直接ファイルを送り込んで自由にカスタマイズできることが確認できました。

それにしても一番カスタマイズするであろうuser-dataだけでも、ユーザー設定を追加する機能が実装されると嬉しいのですけど、
Bugzillaを"cicustom"で検索 した結果が3件では中々...