開発環境を Vagrant で立てている中で,多くのミドルウェアを1個の仮想環境に押し込めてしまっている関係上,ディスク容量が足りなくてツライという状況があった.
プロセッサーとメモリは Vagrantfile に書くと拡張できるが,ディスクは簡単には拡張できず,VMDK や VDI に手を加えていかなければダメで,1度試したけど面倒で諦めた背景がある.
config.vm.provider 'virtualbox' do |v| v.memory = 1024 v.cpus = 2 end
もし試すなら以下の記事が参考になる.
- Add some way to increase disk space from Vagrantfile · Issue #2339 · hashicorp/vagrant · GitHub
- Resize a Hard Disk for a Virtual Machine provisioned using Vagrant from a Linux base box to run using VirutalBox. · GitHub
- VirtualBox の仮想ディスクのサイズを変更する - Qiita
- Vagrant VMのディスクサイズを後から拡張する方法 | dakatsuka's blog
改善策としての Packer
改善策として Packer を試してみた.
なお,ディスクを拡張する目的だけではなくて,今まで Vagrant 環境を立てるときに毎回 Chef を実行してプロビジョニングする必要もあって,アプリケーション開発者からするとオールインワンの Box を立ち上げるだけの方が圧倒的に効率が良いと考えた.まぁ vagrant package
で Box をエクスポートすることもできるが,Packer で iso から手続き的に Box をビルドできることにメリットがある.
構成
先に構成をまとめておく.
ディレクトリ階層
. ├── http │ └── ks.cfg ├── packer_scripts │ └── vagrant.sh ├── template.json
.gitignore
不要なファイルをコミットしないようにした.
# Packer packer_cache/ *.box
template.json
今回は CentOS 6.7 をベースにしている.
{ "builders": [ { "type": "virtualbox-iso", "boot_command": [ "<tab> text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.cfg<enter><wait>" ], "boot_wait": "10s", "disk_size": 30000, "guest_os_type": "RedHat_64", "http_directory": "http", "iso_checksum": "2ed5ea551dffc3e4b82847b3cee1f6cd748e8071", "iso_checksum_type": "sha1", "iso_url": "http://mirror.hmc.edu/centos/6/isos/x86_64/CentOS-6.7-x86_64-minimal.iso", "ssh_username": "vagrant", "ssh_password": "vagrant", "ssh_port": 22, "ssh_wait_timeout": "10000s", "shutdown_command": "echo '/sbin/halt -h -p' > /tmp/shutdown.sh; echo 'vagrant' | sudo -S sh '/tmp/shutdown.sh'", "virtualbox_version_file": ".vbox_version", "vboxmanage": [ [ "modifyvm", "{{ .Name }}", "--memory", "1024" ], [ "modifyvm", "{{ .Name }}", "--cpus", "2" ] ], "headless": true } ], "provisioners": [ { "type": "shell", "override": { "virtualbox-iso": { "scripts": [ "packer_scripts/vagrant.sh" ] } } }, { "type": "chef-solo", "cookbook_paths": ["./cookbooks", "./site-cookbooks"], "run_list": [ "base", "user", "nginx", "mysql" ] } ], "post-processors": [ { "type": "vagrant", "compression_level": 9, "override": { "virtualbox": { "output": "packer-app.box" } } } ] }
ks.cfg と vagrant.sh
CentOS の kickstart ファイルと vagrant ssh
をできるようにするための vagrant.sh
は,以下のリポジトリで公開されているものをそのまま使った.
構成ポイント
基本的に公式ドキュメントを読みながら template.json
を書いたが,ポイントになりそうな点を残しておこうと思う.
builders
boot_command と http_directory
Linux を自動構築する手順を ks.cfg
に定義して,それを http_directory
に指定すると裏側でウェブサーバが起動して,http でアクセスできるようになる.それを boot_command
から読み込んで実行するような流れになる.
"boot_command": [ "<tab> text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.cfg<enter><wait>" ],
disk_size
disk_size
に MB を指定することで,ディスク容量を初期状態でマウントすることができる.デフォルトだと 40GB になっている.よって,この設定でディスク容量の課題は解消できる.
shutdown_command
プロビジョニングした状態を正常に保存するために graceful に shutdown する必要がある.ドキュメントにも重要な設定だと書かれていた.
It is important to add a shutdown_command. By default Packer halts the virtual machine and the file system may not be sync'd. Thus, changes made in a provisioner might not be saved.
headless
ks.cfg
に従って Linux が自動構築されていくのを眺めるのも楽しいけど,何度も繰り返していると飽きてくるので,headless
でバックグラウンド実行させている.
provisioners
shell
プロビジョニングは全て Chef に任せるとして,vagrant ssh
できるようにするための鍵設定を shell で流している.ドキュメントに the execute_command is puzzling.
と書かれてて笑ったけど,環境によっては sudo でプロンプトが出てしまうため,パスワードをパイプして渡してあげるなどの工夫が必要と書いてあった.今回は特に考慮しなかった.
To many new users, the execute_command is puzzling. However, it provides an important function: customization of how the command is executed. The most common use case for this is dealing with sudo password prompts. You may also need to customize this if you use a non-POSIX shell, such as tcsh on FreeBSD.
chef-solo
run_list
はサンプルだけど,今までの Chef と同様に書くとプロビジョニングできた.
{ "type": "chef-solo", "cookbook_paths": ["./cookbooks", "./site-cookbooks"], "run_list": [ "base", "user", "nginx", "mysql" ] }
post-processors
compression_level
compression_level
で圧縮レベルを指定することができる.デフォルトは 6 になっている.まぁBox サイズは小さくて困ることはないと思うし,今回は最大圧縮レベルの 9 にした.
An integer representing the compression level to use when creating the Vagrant box. Valid values range from 0 to 9, with 0 being no compression and 9 being the best compression. By default, compression is enabled at level 6.
ただし,実際に 0 と 9 で比較してみたけど,今回のケースだとほとんど圧縮されてなかった.
$ ls -l *.box -rw-r--r-- 1 kakakakakku CATK\Domain Users 1368710144 4 19 11:17 packer-app_compression_0.box -rw-r--r-- 1 kakakakakku CATK\Domain Users 1339162491 4 19 10:53 packer-app_compression_9.box
まとめ
Packer の最大のメリットは AWS / DigitalOcean / Docker などと連携してマシンイメージをビルドできる点かもしれないけど,シンプルに Vagrant 連携として使うだけでも,大きなメリットを感じることができた.実際に開発環境構築のコストが極限まで下がったのは嬉しい.
引き続き Packer を使ってくぞ!
Packer を使うアイデアを教えて頂いた @ariarijp に感謝!🎉