第590回で紹介したマルチプラットフォームな仮想マシン管理ツールである
MultipassとPacker
第590回
multipassは特に指定しなければサーバー版のUbuntuをベースイメージとして使います。もし自動的にカスタマイズしたいなら、
そこで今回は自分で仮想マシンイメージを作る方法とそれをmultipassで利用する方法を紹介します。Ubuntu版multipassの標準のバックエンドはQEMUなので、
PackerはUbuntuならパッケージ管理ツールからインストール可能です。しかしながら18.
よって素直にPackerのダウンロードページからバイナリをインストールしましょう。PackerはGo言語で作られたバイナリなので、
$ wget https://releases.hashicorp.com/packer/1.5.4/packer_1.5.4_linux_amd64.zip $ unzip packer_1.5.4_linux_amd64.zip $ sudo cp packer /usr/local/bin/
バイナリひとつ配置すればいいので簡単ですね。また、
$ sudo apt install qemu-system-x86 qemu-utils
これでインストールは完了です
Packer用ファイルとcloud-initデータの作成
PackerはJSONファイルに基づいて、
ベースイメージはUbuntu Cloud Imagesのデータを使うことにします。これは各種クラウドサービスで使用するUbuntuのベースイメージを配布しているサイトです。リリースごとに最新のアップデートを適用したイメージが、
ちなみにこのイメージにはアカウントは設定されていません。ユーザーごとに異なる設定はクラウドサービスごとに合わせたcloud-initで設定する、
Packerでイメージを構築する際、
cloud-initをサポートしたイメージは、
NoCloudでは次のいずれかの方法で、
- ボリュームラベルが
「cidata」 か 「CIDATA」 な、 vfatもしくはiso9660のストレージ - カーネルコマンドラインで指定されたパラメーター
- SMBIOS上のシリアル番号に記載された文字列
後者のふたつに関しては、
Packerのbuilderはhttp_
」
最後に注意が必要なのは、
まとめるとmultipass用のイメージをPackerで構築するために、
- cloud-init用の設定ファイル
( meta-data
とuser-data
) - Packer用の設定ファイル
( ubuntu.
)json
それでは順番に作っていきましょう。
cloud-init用の設定ファイルの作成
cloud-init用の設定ファイルは比較的単純です。要するにPackerのcommunicatorがインスタンス内部にログインできるようにしておけば良いのですから。
$ mkdir cloud-data $ touch cloud-data/meta-data $ openssl passwd -6 ubuntupassword $6$tXF3sTmGEMKhsanM$LyJQLz8lfqQITkNXTiVyAErUXpGkplHX3ftXZCB5/shRGqO7EuOnkRQ5cVjHNmqgAYzMwyOTPkDbZbuj26H6W0 $ cat <<'EOF' > cloud-data/user-data #cloud-config ssh_pwauth: true apt_mirror: http://jp.archive.ubuntu.com/ubuntu/ users: - name: ubuntu sudo: ALL=(ALL) NOPASSWD:ALL passwd: $6$tXF3sTmGEMKhsanM$LyJQLz8lfqQITkNXTiVyAErUXpGkplHX3ftXZCB5/shRGqO7EuOnkRQ5cVjHNmqgAYzMwyOTPkDbZbuj26H6W0 lock_passwd: false EOF
cloud-data/
はcloud-initで使うインスタンスIDやホストネームを指定するために使うファイルですが、
cloud-init本体の設定のポイントは次のとおりです。
ssh_
の設定でパスワードログインを許可しておくpwauth sudo
の設定でパスワード無しのsudo
を許可しておくpasswd
の設定でパスワードを設定しておくlock_
の設定でパスワードログインを許可しておくpasswd
PackerのSSH communicatorはSSHの公開鍵ログインも利用可能です。複数のユーザーで運用するPackerファイルを作るなら公開鍵の設定にしておくべきでしょう。しかしながら今回はPackerファイルにパスワードを直接書いてパスワードログインすることにします。Packerファイルには生のパスワードを直接記述しますが、
また上記では、sudo
コマンドをパスワードなしで実行できるような設定も行っています。
今回はPacker用のアカウントを
Packer用の設定ファイルの作成
次にPacker用の設定ファイルを作成しましょう。
$ cat <<'EOF' > ubuntu.json { "builders": [ { "disk_discard": "unmap", "disk_image": true, "disk_interface": "virtio-scsi", "disk_size": "5120M", "headless": true, "http_directory": "cloud-data", "iso_checksum_type": "sha256", "iso_checksum_url": "http://cloud-images.ubuntu.com/releases/bionic/release/SHA256SUMS", "iso_url": "http://cloud-images.ubuntu.com/releases/bionic/release/ubuntu-18.04-server-cloudimg-amd64.img", "qemuargs": [ [ "-smbios", "type=1,serial=ds=nocloud-net;instance-id=packer;seedfrom=http://{{ .HTTPIP }}:{{ .HTTPPort }}/" ] ], "ssh_password": "ubuntupassword", "ssh_username": "ubuntu", "type": "qemu", } ], "provisioners": [ { "execute_command": "sudo sh -c '{{ .Vars }} {{ .Path }}'", "inline": [ "mv /etc/netplan/50-cloud-init.yaml /root/", "mv /etc/sudoers.d/90-cloud-init-users /root/", "/usr/bin/truncate --size 0 /etc/machine-id", "rm -r /var/lib/cloud /var/lib/dbus/machine-id ", "for i in group gshadow passwd shadow subuid subgid; do mv /etc/$i- /etc/$i; done", "/bin/sync", "/sbin/fstrim -v /" ], "remote_folder": "/tmp", "type": "shell" } ] } EOF
前半はbuildersの設定です。詳細はQEMU用のbuilderを確認してもらうとして、
http_
でcloud-initファイルのディレクトリを指定directory iso_
とurl iso_
でダウンロードするイメージを指定checksum_ XXX qemuargs
でcloud-initのダウンロードもとを指定ssh_
とpassword ssh_
でcommunicatorが使うパスワードとアカウントを指定username type
でQEMUを利用することを指定
iso_
とiso_
はUbuntu Cloud Imagesを参考に、
qemuargs
はPackerがイメージ構築時に利用するQEMUコマンドの引数です。ここにSMBIOSの設定を渡すことで、
「{{ .HTTPIP }}
」{{ .HTTPPort }}
」
後半はprovisionerが実行するコマンドのリストです。Shell Provisionerによって、inline
でリストアップされたコマンドを順番にsudo
で実行しています。
主にbuilderが実行したcloud-initで生成されたファイルのクリーンナップ処理です。これによりmultipassによるcloud-initがキレイに実行されることになります。
/etc/
は初回起動時にsystemd-machine-id-setupで生成される、truncate
コマンドで中身を消しています。
/etc/
他のmv
コマンドの実行はuseradd
などのコマンドは、-
」
今回はPackerとmultipassで同じユーザーではありますが、
fstrim
はファイルの削除等によって消された領域がイメージファイルから確実に削除になるようにするツールです。builderのほうでdisk_
をunmap
に設定しているため、fstrim
がイメージサイズの削減にも繋がります。今回のように削除しているファイルがそうでもない場合はあまり恩恵はありませんが、
イメージのビルドとmultipassでの利用
作成したPackerファイルはvalidateサブコマンドでチェックできます。
$ packer validate ubuntu.json Template validated successfully.
またfixサブコマンドを使うと、
$ packer fix ubuntu.json > new.json
イメージの作成はbuildサブコマンドです。
$ packer build ubuntu.json qemu: output will be in this color. ==> qemu: Retrieving ISO ==> qemu: Trying http://cloud-images.ubuntu.com/releases/bionic/release/ubuntu-18.04-server-cloudimg-amd64.img ==> qemu: Trying http://cloud-images.ubuntu.com/releases/bionic/release/ubuntu-18.04-server-cloudimg-amd64.img?checksum=sha256%3A3c3a67a142572e1f0e524789acefd465751224729cff3a112a7f141ee512e756 ==> qemu: Copying hard drive... ==> qemu: Resizing hard drive... ==> qemu: Starting HTTP server on port 8110 ==> qemu: Found port for communicator (SSH, WinRM, etc): 3636. ==> qemu: Looking for available port between 5900 and 6000 on 127.0.0.1 ==> qemu: Starting VM, booting disk image qemu: The VM will be run headless, without a GUI. If you want to qemu: view the screen of the VM, connect via VNC without a password to qemu: vnc://127.0.0.1:5950 ==> qemu: Overriding defaults Qemu arguments with QemuArgs... ==> qemu: Waiting 10s for boot... ==> qemu: Connecting to VM via VNC (127.0.0.1:5950) ==> qemu: Typing the boot command over VNC... ==> qemu: Using ssh communicator to connect: 127.0.0.1 ==> qemu: Waiting for SSH to become available... ==> qemu: Connected to SSH! ==> qemu: Provisioning with shell script: /tmp/packer-shell037271588 qemu: /: 3.7 GiB (3969331200 bytes) trimmed ==> qemu: Halting the virtual machine... ==> qemu: Converting hard drive... ==> qemu: Error getting file lock for conversion; retrying... Build 'qemu' finished. ==> Builds finished. The artifacts of successful builds are: --> qemu: VM files in directory: output-qemu
作成したイメージはoutput-qemu/
」
$ file output-qemu/packer-qemu output-qemu/packer-qemu: QEMU QCOW2 Image (v3), 5368709120 bytes
あとはこのファイルをmultipassのインスタンス作成時に指定するだけです。
$ multipass launch file://$PWD/output-qemu/packer-qemu \ --disk 5G --name packer Launched: packer
これで任意の