メインコンテンツへスキップ
  1. Blogs/

cloud-initでOSの設定

·4291 文字·
Blog VMware VSphere Cloud-Init
hiroki
著者
hiroki
クラウドを作るお仕事をしてます。
目次

はじめに
#

VMをdeployする際にhostnameやuserの作成を実施したいことが多々あると思います。vSphereでは標準でcustomizationというOSのカスタマイズ手法があります。しかしvSphere7.0U3からcloud-initを使用したupdateもサポートされこちらでもOSのカスタマイズができるようになりました。

cloud-initの方がVMware以外(AWS等)でも使われている汎用的なOS初期化手法であり、userの追加や外部libのinstallできるとより複雑なことができる利点がある反面、cloud-init自体について知らないと使えないので今回はcloud-initについて軽く触れつつ、vSphereでの設定方法を紹介したいと思います。

ESXi7.0U3以上、vmware-toolsが11.3.0以上、cloud-init < 23.1がサポート要件です。

1. cloud-init
#

公式HPを見ると、cloud-initは主要クラウド、ベアメタルでサポートされる業界標準のOS初期化scriptと記載されています。実際にサポートされるプラットフォームをdatasourceと呼び、かなりのプラットフォームでサポートされていることがわかります。またcloud-initの良いところはこれらのプラットフォームを自動で判別してくれるので、基本的な使い方を覚えれば様々な場所で使えることも利点になります。

2. cloud-initの使い方
#

今回はubuntu22.04を例にして紹介します。

cloud-initで重要になるのは、deployしたいOS内部の設定であるcloud.cfgと、OSの外からNW情報等の変数を挿入するuserdata.yaml, metadata.yamlになります。

cloud.cfg
#

  • OS側のcloud-init設定を実行するファイルで、userから受け取った情報(NW情報や、新規user作成方法)をどのように設定するか、cloud-initでカスタマイズする・しない項目の選択ができます。
  • これは事前にOS側に配置しておく必要があります。
    • 例えば「VMをcloneする → clone元に」、「ISOからinstallする → ISO内部に」入れておくなど
    • Ubuntuであればdefaultでcloud-initがinstallされているので、最初から存在します。
  • 通常は変更不要で最初から存在するものを使えば良いのですが、vSphereの場合はいくつか変更が必要 + nginx.conf等任意のファイルを編集したい等よりカスタマイズしたい場合はこれを事前に変更しておく必要があります。
# /etc/cloud/cloud.cfg
cloud_init_modules:
 - migrator
 - seed_random
 - bootcmd
 - write-files
 - growpart
 - resizefs
 - disk_setup
 - mounts
 - set_hostname
 - update_hostname
 - update_etc_hosts
 - ca-certs
 - rsyslog
 - users-groups
 - ssh

# The modules that run in the 'config' stage
cloud_config_modules:
 - wireguard
 - snap
 - ubuntu_autoinstall
 - ssh-import-id
 - keyboard
 - locale

userdata.yaml
#

  • userdata.yamlはOSの外部から与える変数情報で、userに関する情報(作成するuser名、ssh公開鍵、所属group、passwd等)を記載することになります。
  • これはOSで統一の設定ではなく、必要に応じて変更したいのでOSの外部から挿入する必要があります。
  • OS外部から挿入する手法は、各プラットフォームが用意しています。もしくはInstall Media(ISO)に埋め込む等もできます。
#cloud-config

users:
  - default
  - name: sampleuser   # 作成するユーザー
    ssh_authorized_keys:
      - ssh-ed25519 <公開鍵> # 登録する公開鍵
    sudo: ALL=(ALL) NOPASSWD:ALL
    groups: sudo, wheel # 所属させるgroup
    shell: /bin/bash
    lock-passwd: false # passwordのロックをするかしないか
    passwd: $6$lXfnasOxmG1k/2lX$bd8lWUdX3mGSr9j2ImUzdGIhv14pmuqPE6W/ocfpx1/GVHjEZbPUJ.rteSvg05Vk6LK40Rtm93H3bViLyfIbx1

「lock_passwd: Defaults to true. Lock the password to disable password login」とdefaultではuserのpasswdはロックされるので注意。

metadata.yaml
#

  • metadata.yamlはOSの外部から与える変数情報で、OSに関する情報(hostname, network等)を設定する形になります。
  • これもOSで統一の設定ではないので、OSの外部から挿入する必要があります。
#cloud-config

instance-id: abcdefgh
local-hostname: abcdefgh
hostname: abcdefgh
network:
  version: 2
  ethernets:
    ens33:
      addresses:
      - 192.168.1.222/24
      routes:
      - to: default
        via: 192.168.1.202
      nameservers:
        addresses:
        - 192.168.1.202
        search: [lab.local]

これらのyamlの書き方は公式ページにも記載されていますが、RedHatのページにユースケース毎に細かく掲載されているのでこちらを参考にするのがおすすめです。

3. vSphere環境でcloud-initを使ってみる。
#

  • 今回はVMをclone後、cloud-initでOSを設定したいと思います。
  • (isoの場合は、他blog参考)

STEP1. clone元でcloud-initの初期設定
#

先ほどの述べたようにcloud.cfgは基本的に変更不要ですが、VMware環境ではいくつか修正が必要なので面倒ですがclone元となるOS内部で以下設定を実施します。ubuntu2204を想定しますが、他OS(linux系)でも同じように使えるはずです。

1. KB59557対策 (競合するcustomizationのOFF)
#
  • vSphereにはOSの設定機能のcustomizationがありcloud-initと競合するので、cloud.cfgにcustomizationを無効するよう記載します。
  • /etc/cloud/cloud.cfgの末尾に以下を追加します。
### 省略 ###
failsafe:
         primary: http://ports.ubuntu.com/ubuntu-ports
         security: http://ports.ubuntu.com/ubuntu-ports
   ssh_svcname: ssh
disable_vmware_customization: false # ←を追加
2. KB80934対策 (Ubuntu20.04以降でNW設定が失敗することの回避)
#
rm -rf /etc/cloud/cloud.cfg.d/subiquity-disable-cloudinit-networking.cfg
rm -rf /etc/cloud/cloud.cfg.d/99-installer.cfg
3. cloud-initの初期化 + shutdown
#
  • cloud-initは基本的にOSを起動した初回のみしか発生しません。
  • 今回修正を入れるためにOSを一度起動してしまったのでcleanを実行して、shutdownしておきます。
cloud-init clean
sudo shutdown

STEP2. VMのclone + userdata.yaml,metadata.yamlをOS外から挿入する
#

STEP1にてOS内部の設定は完了したので、STEP2ではuserdata.yaml, metadata.yamlを用意しOS外部から挿入します。vSphereの場合は「vmの詳細パラメータに追加し、vmware-toolsによって読み込むこと」によって外部からOS内部に挿入することができます。

1. VMのclone, metadata.yaml, userdata.yamlを用意する。
#
  • 前手順で用意したVMをcloneする。
  • 設定したいOS情報であるmetadata.yaml, userdata.yamlを用意する。
2. vmの詳細パラメーター(Advanced Parameters)に用意したyamlを追加する。
#
  • VMの詳細パラメータを開くと(vCenterを開きVMの設定 → 詳細パラメータ)、任意の情報を「key: value」の形で詰めることができます。
  • cloud-init用には決まったkeyがあるのでこれにつめていきます。これらはcloud-init実行時にvmware-toolsを使って読み込まれます。
guestinfo.metadata
guestinfo.metadata.encoding
guestinfo.userdata
guestinfo.userdata.encoding
  • guestinfo.metadata.encoding
    • metadataのデータをどのようなencodingで格納するかを記載します。
    • ただしgzip+base64,base64しか許容されていないので注意ください。今回はgzip+base64を使います。
  • guestinfo.metadata
    • ここにmetadata.yamlをgzip+base64にエンコードしたものを入力します。
    • base64コマンドはdefaultだと改行を入れて見やすくしてしまうので、-w 0を追加しておきます。
cat metadata.yaml | gzip | base64 -w 0
(out)H4sIAAAAAAAAA22QwQ7CIBBE73zFJp6Llhqj/IrxsIVtS0RIWKq/L9XaNOptd95OZrIb4+NoKxND53ohXOCMwVDlrAZsjaWuH4SPBn01RM4Bb7QCf6RA+RHTVQuAOyV2MWhQZaE8UCqQJ1LWwE3zHgHQ2kTMxB+hgvqkZH04yloqpbZqP4MUx7w+y1FDycXR51krsQ712r9TM5qaMqWpll6uf7K/0hc3ABMmM2g4e2zl6yeXJ+Clw6w/AQAAro
  • guestinfo.userdataも同様です。

img001

vCenter7の場合は、「仮想マシンオプション」→「詳細」→「構成パラメータ」→「設定の編集」→「構成パラメータの追加」から追加できます。(要powerOFF)

STEP3. vmの起動
#

  • ここまでできたら後は起動するだけで、cloud-initが実行されてVMの設定が開始されます。

おまけ
#

  • せっかくcloud-initという自動初期化scriptを使っているのに、手動でこれらを設定しているとあまり意味はないので、CLIで設定する方法をいくつか紹介します。
govc
#
  • ぱぱっと詰めれるので便利です。特にansibleのinventoryで管理するまでもない検証用にVMが欲しいけど、DHCPが使えない場合や識別のためにhost名はつけたい、proxyの設定が必要等の場合によく使います。
export GOVC_USERNAME=<vcenterのuser>
export GOVC_PASSWORD=<vcenterのpass>
export GOVC_URL=<vcenterのfqdn,ip>/sdk
export GOVC_INSECURE=true

METADATA=$(cat metadata.yaml | gzip | base64 -w 0)  
USERDATA=$(cat userdata.yaml | gzip | base64 -w 0)

govc vm.change \
 -vm "/Datacenter/vm/cloud-init-01" \
  -e guestinfo.metadata="${METADATA}" \
  -e guestinfo.metadata.encoding="gzip+base64" \
  -e guestinfo.userdata="${USERDATA}" \
  -e guestinfo.userdata.encoding="gzip+base64"
ansible
#

<後で追記するかも>

4. deep dive
#

cloud-initを調べるうちにいくつか気になったことがあったので調べて見ました。

vmの詳細パラメータの情報をどうやってOSで参照するか?
#

vmtoolsd --cmd "info-get guestinfo.vmtools.description"
(out)open-vm-tools 12.1.5 build 20735119
vmware-rpctool "info-get guestinfo.vmtools.description"
(out)open-vm-tools 12.1.5 build 20735119
vmware-rpctool "info-get guestinfo.metadata"
(out)H4sIAAAAAAAAA22QwQ7CIBBE73zFJp6Llhqj/IrxsIVtS0RIWKq/L9XaNOptd95OZrIb4+NoKxND53ohXOCMwVDlrAZsjaWuH4SPBn01RM4Bb7QCf6RA+RHTVQuAOyV2MWhQZaE8UCqQJ1LWwE3zHgHQ2kTMxB+hgvqkZH04yloqpbZqP4MUx7w+y1FDycXR51krsQ712r9TM5qaMqWpll6uf7K/0hc3ABMmM2g4e2zl6yeXJ+Clw6w/AQAA
vmware-rpctool "info-get guestinfo.metadata.encoding"
(out)gzip+base64

cloud-initはどうやってdatasource=vmwareを認識しているか?
#

dscheck_VMware() {
    # Checks to see if there is valid data for the VMware datasource.
    # The data transports are checked in the following order:
    #
    #   * envvars
    #   * guestinfo
    #   * imc (VMware Guest Customization)
    #
    # Please note when updating this function with support for new data
    # transports, the order should match the order in the _get_data
    # function from the file DataSourceVMware.py.

--- 省略 ---
# Activate the VMware datasource only if any of the fields used
    # by the datasource are present in the guestinfo table.
    if { vmware_guestinfo_metadata || \
         vmware_guestinfo_userdata || \
         vmware_guestinfo_vendordata; } >/dev/null 2>&1; then
        return "${DS_FOUND}"
    fi

--- 省略 ---

vmware_vmtoolsd_guestinfo() {
    vmtoolsd --cmd "info-get guestinfo.${1}" 2>/dev/null | grep "[[:alnum:]]"
}

vmware_vmtoolsd_guestinfo_err() {
    vmtoolsd --cmd "info-get guestinfo.${1}" 2>&1 | grep "[[:alnum:]]"
}

vmware_guestinfo() {
    vmware_rpctool_guestinfo "${1}" || vmware_vmtoolsd_guestinfo "${1}"
}

vmware_guestinfo_err() {
    vmware_rpctool_guestinfo_err "${1}" || vmware_vmtoolsd_guestinfo_err "${1}"
}

vmware_guestinfo_ovfenv_err() {
    vmware_guestinfo_err "ovfEnv"
}

vmware_guestinfo_metadata() {
    vmware_guestinfo "metadata"
}

Related

ESXiを自動でインストール
·3901 文字
Blog VMware VSphere RedfishAPI Python Kickstart Ansible
MINISFORUM UM580 review
·1923 文字
Blog Review Homelab