Amazon Linux2のVagrant Boxを作成する
仕事でちょっとした設定をAmazon Linux 2で試したい時、AWSでEC2インスタンスを立ち上げると、お金がかかったり、消し忘れたり、うっかり作業ミスしたりする可能性があるので、簡単な設定を試すのであれば、ローカルマシン上で済ませたくなります。そこで、個人でAmazon Linux2のVagrant Boxイメージを作ってみることにしました。Amazon Linux 2のVirtualBoxのVDIファイルはAWSから公式で配布されているので、このVDIファイルを利用してVagrantイメージを作成出来ます。
AWSのドキュメントでも、Amazon Linux 2を仮想化プラットフォーム上で起動する方法を説明しています。Running Amazon Linux 2 as a Virtual Machine On-Premises - Amazon Elastic Compute Cloud
今回、Vagrant Boxを作成するにあたって、Vagrantのドキュメントを読んでいたら知らなかったことがいくつかあったので記載しておきます。Boxes - Vagrant by HashiCorp
- Vagrantを開発しているHashicorpが推薦しているBoxイメージは、hashicorp(https://app.vagrantup.com/hashicorp)とBento(https://app.vagrantup.com/bento)の2個のみ。
- Ubuntuを開発しているCanonicalでもubuntuというネームスペースでBoxイメージを出しているけれど、HashicorpはBentoのほうのUbuntuイメージを勧めている。
- Bentoは、Amazon Linux 2のBoxイメージも出している。https://app.vagrantup.com/bento/boxes/amazonlinux-2
ということで、bento/amazonlinux-2でもAmazon Linux2をVagrantで動かすことが出来そうですが、今回は手作りでAmazon Linux2のVagrant Boxを作成してみようと思います。
seed.isoの起動イメージ作成
まず、isoファイルを作成します。isoファイルは、CD/DVD/DBなどのデータ形式を完全に再現したファイルです。ISOファイルは、ディスクのコンテンツを丸々、一つのファイルで表現することが出来ます。今回は、seed.isoというファイル名の起動イメージを作ります。seed.iso起動イメージには、meta-data, user-dataの2個のファイルデータを焼き付けてあげます。Amazon Linux2のディスクイメージには、cloud-initパッケージがインストールされていて、起動時にmeta-data, user-dataのデータを参照してOS内に設定を追加することが出来るためです。What is 'cloud-init' and when would you use it? - Quora
meta-dataでは、ホスト名やネットワーク設定を記述します。user-dataでは、ユーザアカウントやパスワードの設定、認証鍵の配置、ロケール・時刻の設定などを記述します。user-dataの書き方については、このドキュメントが参考になります。
cloudinit.readthedocs.io
mkdir seedconfig cd seedconfig cat > meta-data << EOF local-hostname: machine EOF cat > user-data <<- EOF #cloud-config #vim:syntax=yaml users: - default - name: vagrant groups: wheel sudo: ['ALL=(ALL) NOPASSWD:ALL'] plain_text_passwd: vagrant ssh-authorized-keys: - ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key lock_passwd: false locale: ja_JP.UTF-8 timezone: Asia/Tokyo write_files: - path: /etc/environment permissions: '0644' owner: root:root content: | LANG="ja_JP.UTF-8" LC_CTYPE="ja_JP.UTF-8" # https://cloudinit.readthedocs.io/en/latest/topics/network-config.html - path: /etc/cloud/cloud.cfg.d/80_disable_network_after_firstboot.cfg content: | # Disable network configuration after first boot network: config: disabled EOF
user-dataファイルとmeta-dataファイルを作ったので、seed.isoの起動イメージファイルを作成します。hdiutilはディスクイメージを操作するコマンドです。makehybridで、複数のファイルシステムが共存した状態の読み込み専用のディスクイメージを作ります。
# create seed.iso boot image hdiutil makehybrid -o seed.iso -hfs -joliet -iso -default-volume-name cidata ./
- hfsオプションは、HFS+ファイルシステムを作成するために指定します。
- isoオプションは、ISO9660ファイルシステムを作成するために指定します。
- jolietオプションは、ISO9660ファイルシステムを拡張したJolietファイルシステムで作成するために指定します。
- oオプションで起動イメージファイルのファイル名を指定しています。
- -hfs, -iso, -jolietというように複数のファイルシステムをオプションで指定しているとハイブリッドイメージとして起動イメージファイルが作成されます。
- default-volume-nameでファイルシステムのデフォルトのボリューム名を指定しています。amazon linux 2のイメージが起動するとき、user-dataはnocloudという方法で読み込まれます。nocloudでuser-dataファイルをディスクから読み込むときは、cidataというボリュームラベルが付与されていなくてはいけません。NoCloud — Cloud-Init 18.5 documentation
- ./と指定することで、./以下のファイルとディレクトリがディスクイメージのコンテンツとして焼き付けられます。
仮想マシンの起動
AWSのサイトからVDIファイルを取得してきます。
cdn.amazonlinux.com
amazon linux 2のvirtualbox用の仮想ディスク(amzn2-virtualbox-2.0.20190313-x86_64.xfs.gpt.vdi)と、起動イメージ(seed.iso)が用意出来たので、これらを使ってamazon linux 2の仮想マシンをvirtualbox上に作成します。
# create vm VM=vagrant-amznlinux2 VDI=amzn2-virtualbox-2.0.20190313-x86_64.xfs.gpt.vdi VBoxManage createvm --name "$VM" --ostype "RedHat_64" --register VBoxManage storagectl "$VM" --name "SATA Controller" --add "sata" --controller "IntelAHCI" VBoxManage storagectl "$VM" --name "IDE Controller" --add "ide" VBoxManage storageattach "$VM" --storagectl "SATA Controller" --port 0 --device 0 --type hdd --medium $VDI VBoxManage storageattach "$VM" --storagectl "IDE Controller" --port 0 --device 0 --type dvddrive --medium seed.iso VBoxManage modifyvm "$VM" --natpf1 "ssh,tcp,127.0.0.1,2222,,22" --memory 1024 --vram 8 --audio none --usb off
- 仮想マシン(vagrant-amznlinux2)のためにSATA controllerとIDE controllerを作成
- SATAには仮想ディスク(amzn2-virtualbox-2.0.20190313-x86_64.xfs.gpt.vdi)
- IDEには起動イメージファイル(seed.iso)をセット
- ホストマシンの2222ポートのアクセスを仮想マシンの22ポートに転送するように設定
- RAMを1024MB
- グラフィックカードのRAMを8MB
- audioサポートをオフ
- USB仮想コントローラ機能をオフ
仮想マシン(vagrant-amznlinux2)を起動します。--type headlessを指定することで、仮想マシンをコマンドから起動する際、VirtualBoxのGUIツールが一緒に立ち上がらないようになります。Headless Mode for Virtual Machines of VirtualBox - Thomas-Krenn-Wiki
# boot amazon linux2 VBoxManage startvm "$VM" --type headless
仮想マシンが立ち上がったら、以下の手順で公開鍵を取得して、SSH経由でvagrantユーザとしてログインすることが出来ます。
# login amazon linux2 curl -sL https://raw.githubusercontent.com/hashicorp/vagrant/master/keys/vagrant -o vagrant.pem chmod 600 vagrant.pem ssh -p 2222 vagrant@localhost -i vagrant.pem
これで、amazon linux2をVirtualBox上で利用できるようになりました。
vagrant box化
VirtualBox上で動いている仮想マシンをbox化します。ボックス化した時のサイズを小さくするために不要な物を削除します。ddコマンドを使って、0で埋めてしまうのは、仮想マシンイメージの圧縮時に効果的だからのようです。Making smaller base boxes · Issue #343 · hashicorp/vagrant · GitHub 0で埋める処理は、bentoでもboxを作成する際にやっているみたいです。bento/minimize.sh at master · chef/bento · GitHub
sudo rm -rf /var/cache/yum sudo dd if=/dev/zero of=/0 bs=4k sudo rm -f /0 history -c
仮想マシンをシャットダウンします。
sudo shutdown -h now
baseオプションで、box化したいVirtualBoxで動いている仮想マシンを指定しています。このコマンドを実行すると、デフォルトではpackage.boxという名前のファイルが作成されます。
vagrant package --base "$VM"
package.boxのboxファイルを、amzn2-2.0.20190313-x86_64という名前でvagrantに登録します。
vagrant box add --name "amzn2-2.0.20190313-x86_64" package.box
vagrantに登録されたので、vagrantから仮想マシンを起動してSSHログインしてみます。
mkdir amzn2 && cd amzn2 vagrant init amzn2-2.0.20190313-x86_64 vagrant up vagrant ssh