はじめに
以前の記事「Packerを使ってVagrant用の仮想マシンを作成する」では、Vagrant用のBoxイメージ作成ツールの使い方を解説しました。 今回は、2014年7月7日にリソースされたばかりのCentOS 7 for x86_64のVagrant用Boxの作成方法を解説します。 そこで今回は、Packerを使用した仮想マシンの作成方法と、作成した仮想マシンをVagrant用仮想マシンに変換する方法について解説します。
2014年07月29日 20時27分
以前の記事「Packerを使ってVagrant用の仮想マシンを作成する」では、Vagrant用のBoxイメージ作成ツールの使い方を解説しました。 今回は、2014年7月7日にリソースされたばかりのCentOS 7 for x86_64のVagrant用Boxの作成方法を解説します。 そこで今回は、Packerを使用した仮想マシンの作成方法と、作成した仮想マシンをVagrant用仮想マシンに変換する方法について解説します。
作業の前提条件は、下記のとおりです。
| ソフトウエア | バージョン |
|---|---|
| OS | Windows 7 Ultimate 32bit |
| Cygwin | Setup Version 2.831 |
| VirtualBox | 4.3.12 r93733 |
| Vagrant | 1.6.3 |
| Packer | 0.6.1 |
Github上で公開されているPacker Templateをカスタマイズして、Boxを作成します。
box-cutter/centos-vmから、Packer Templateをクローンします。
$ cd /tmp $ git clone git://github.com/box-cutter/centos-vm.git

Cloning into 'centos-vm'... remote: Counting objects: 230, done. remote: Compressing objects: 100% (117/117), done. remote: Total 230 (delta 148), reused 169 (delta 112) Receiving objects: 100% (230/230), 46.11 KiB, done. Resolving deltas: 100% (148/148), done.
クローンした設定ファイルをそのままビルドしても良いのですが、ターゲットとなるcentos70.jsonでは、インストール用のISOイメージが、Desktop版になっており 、Minimal版のISOイメージを指定すると、ビルドエラーになってしまったため、下記の3ファイルを編集します。
| ファイル名 | 概要 |
|---|---|
| centos70.json | PackerでBoxイメージを作成するための設定ファイル |
| ks7.cfg | CentOSでお馴染みのKickStart用設定ファイル |
| vagrant.sh | Vagrant用の設定を行うスクリプトファイル |
$ cd centos-vm $ cp -p centos70.json centos70.json.orig $ cp -p http/ks7.cfg http/ks7.cfg.orig $ cp -p script/vagrant.sh script/vagrant.sh.orig
7,9c7,31
< "iso_http": "http://ftp.riken.go.jp/Linux/centos/7.0.1406/isos/x86_64/CentOS-7.0-1406-x86_64-Minimal.iso",
< "iso_file": "file:///i:/ISO/CentOS/CentOS-7.0-1406-x86_64-Minimal.iso",
< "iso_checksum": "e3afe3f1121d69c40cc23f0bafa05e5d"
---
> "iso_url": "http://mirrors.sonic.net/centos/7.0.1406/isos/x86_64/CentOS-7.0-1406-x86_64-DVD.iso",
> "iso_checksum": "154ba47b7a37e52e0100310c3aeb8f9d9daf4806"
> },
> "builders": [{
> "vm_name": "centos70",
> "type": "vmware-iso",
> "guest_os_type": "centos-64",
> "http_directory": "http",
> "iso_url": "{{ user `iso_url` }}",
> "iso_checksum": "{{ user `iso_checksum` }}",
> "iso_checksum_type": "sha1",
> "ssh_username": "vagrant",
> "ssh_password": "vagrant",
> "ssh_wait_timeout": "10000s",
> "tools_upload_flavor": "linux",
> "boot_command": [
> "<tab> text ks=http://{{ .HTTPIP }}:{{ .HTTPPort}}/ks7.cfg<enter>"
> ],
> "shutdown_command": "echo 'vagrant'|sudo -S shutdown -P now",
> "disk_size": 10140,
> "vmx_data": {
> "memsize": "512",
> "numvcpus": "1",
> "cpuid.coresPerSocket": "1"
> }
11d32
< "builders": [
16c37
< "iso_url": "{{ user `iso_file` }}",
---
> "iso_url": "{{ user `iso_url` }}",
18c39
< "iso_checksum_type": "md5",
---
> "iso_checksum_type": "sha1",
29c50
< "disk_size": 8192,
---
> "disk_size": 10140,
32,33c53
< ["modifyvm", "{{.Name}}", "--cpus", "2"],
< ["modifyvm", "{{.Name}}", "--ioapic", "on"]
---
> ["modifyvm", "{{.Name}}", "--cpus", "1"]
49a70
> "script/cmtool.sh",
{
"variables": {
"cm": "nocm",
"cm_version": "",
"cm_set_path": "",
"cleanup_pause": "",
"iso_http": "http://ftp.riken.go.jp/Linux/centos/7.0.1406/isos/x86_64/CentOS-7.0-1406-x86_64-Minimal.iso",
"iso_file": "file:///i:/ISO/CentOS/CentOS-7.0-1406-x86_64-Minimal.iso",
"iso_checksum": "e3afe3f1121d69c40cc23f0bafa05e5d"
},
"builders": [
{
"vm_name": "centos70",
"type": "virtualbox-iso",
"http_directory": "http",
"iso_url": "{{ user `iso_file` }}",
"iso_checksum": "{{ user `iso_checksum` }}",
"iso_checksum_type": "md5",
"guest_os_type": "RedHat_64",
"guest_additions_path": "VBoxGuestAdditions_{{.Version}}.iso",
"virtualbox_version_file": ".vbox_version",
"ssh_username": "vagrant",
"ssh_password": "vagrant",
"ssh_wait_timeout": "10000s",
"boot_command": [
"<tab> text ks=http://{{ .HTTPIP }}:{{ .HTTPPort}}/ks7.cfg<enter>"
],
"shutdown_command": "echo 'vagrant'|sudo -S shutdown -P now",
"disk_size": 8192,
"vboxmanage": [
["modifyvm", "{{.Name}}", "--memory", "512"],
["modifyvm", "{{.Name}}", "--cpus", "2"],
["modifyvm", "{{.Name}}", "--ioapic", "on"]
]
}],
"provisioners": [{
"type": "shell",
"environment_vars": [
"CM={{user `cm`}}",
"CM_VERSION={{user `cm_version`}}",
"CM_SET_PATH={{user `cm_set_path`}}",
"CLEANUP_PAUSE={{user `cleanup_pause`}}"
],
"execute_command": "echo 'vagrant' | {{.Vars}} sudo -E -S bash '{{.Path}}'",
"scripts": [
"script/fix-slow-dns.sh",
"script/sshd.sh",
"script/vagrant.sh",
"script/vmtool.sh",
"script/cleanup.sh"
]
}],
"post-processors": [{
"type": "vagrant",
"keep_input_artifact": false,
"vagrantfile_template": "tpl/vagrantfile-centos70-no-hgfs.tpl",
"output": "box/{{.Provider}}/centos70-{{user `cm`}}{{user `cm_version`}}.box"
}]
}
centos70.jsonの7~8行目では、CentOS 7 Minimal ISOイメージのダウンロードサイトを指定しています。
今回は、事前にISOイメージをローカルにダウンロードしていますので、16行目ではファイルを指定しています。
また、7行目のダウンロードサイトは、ミラーサイトからネットワーク的に近いサイトに変更すると良いでしょう。
0a1,16 > # CentOS 6.x kickstart file - ks6.cfg > # > # For more information on kickstart syntax and commands, refer to the > # CentOS Installation Guide: > # https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Installation_Guide/s1-kickstart2-options.html > # > # For testing, you can fire up a local http server temporarily. > # cd to the directory where this ks.cfg file resides and run the following: > # $ python -m SimpleHTTPServer > # You don't have to restart the server every time you make changes. Python > # will reload the file from disk every time. As long as you save your changes > # they will be reflected in the next HTTP download. Then to test with > # a PXE boot server, enter the following on the PXE boot prompt: > # > linux text ks=http://<your_ip>:8000/ks.cfg > > # Required settings 2c18 < keyboard jp106 --- > keyboard us 5c21 < timezone Asia/Tokyo --- > timezone UTC 6a23 > # Optional settings 20c37 < firstboot --enabled --- > firstboot --disabled 23,25c40,64 < %packages --nobase < @core < openssh-server --- > %packages --nobase --ignoremissing --excludedocs > # vagrant needs this to copy initial files via scp > openssh-clients > # Prerequisites for installing VMware Tools or VirtualBox guest additions. > # Put in kickstart to ensure first version installed is from install disk, > # not latest from a mirror. > kernel-headers > kernel-devel > gcc > make > perl > curl > wget > bzip2 > dkms > patch > net-tools > git > # Other stuff > sudo > nfs-utils > -fprintd-pam > -intltool > > # unnecessary firmware 27,32c66,71 < -iwl6000g2b-firmware < -iwl7260-firmware < -iwl6000g2a-firmware < -libertas-sd8787-firmware < -iwl2030-firmware < -iwl6050-firmware --- > -atmel-firmware > -b43-openfwwf > -bfa-firmware > -ipw2100-firmware > -ipw2200-firmware > -ivtv-firmware 35,41c74 < -iwl135-firmware < -iwl6000-firmware < -iwl105-firmware < -iwl2000-firmware < -libertas-sd8686-firmware < -iwl5150-firmware < -ivtv-firmware --- > -iwl3945-firmware 43,44d75 < -libertas-usb8388-firmware < -iwl3160-firmware 46c77,90 < -iwl3945-firmware --- > -iwl5150-firmware > -iwl6000-firmware > -iwl6000g2a-firmware > -iwl6050-firmware > -libertas-usb8388-firmware > -ql2100-firmware > -ql2200-firmware > -ql23xx-firmware > -ql2400-firmware > -ql2500-firmware > -rt61pci-firmware > -rt73usb-firmware > -xorg-x11-drv-ati-firmware > -zd1211-firmware 50,62d93 < # fastestmirror < echo 'include_only=.jp' >> /etc/yum/pluginconf.d/fastestmirror.conf < < # package < yum -y update < yum -y install kernel-devel kernel-headers dkms gcc git make curl sudo wget perl bzip2 patch net-tools < < # vagrant in sudoers < echo "vagrant ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/vagrant < chmod 0440 /etc/sudoers.d/vagrant < cp -p /etc/sudoers /etc/sudoers.orig < sed -i "s/^.*requiretty/#Defaults requiretty/" /etc/sudoers < 64c95,99 < wget -qO /etc/pki/tls/certs/ca-bundle.crt http://curl.haxx.se/ca/cacert.pem --- > wget -O/etc/pki/tls/certs/ca-bundle.crt http://curl.haxx.se/ca/cacert.pem > # configure vagrant user in sudoers > echo "%vagrant ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/vagrant > cp /etc/sudoers /etc/sudoers.orig > sed -i "s/^.*requiretty/#Defaults requiretty/" /etc/sudoers
lang en_US.UTF-8 keyboard jp106 rootpw vagrant authconfig --enableshadow --enablemd5 timezone Asia/Tokyo install cdrom user --name=vagrant --plaintext --password vagrant unsupported_hardware network --bootproto=dhcp firewall --disabled selinux --disabled bootloader --location=mbr text skipx zerombr clearpart --all --initlabel autopart firstboot --enabled reboot %packages --nobase @core openssh-server -aic94xx-firmware -iwl6000g2b-firmware -iwl7260-firmware -iwl6000g2a-firmware -libertas-sd8787-firmware -iwl2030-firmware -iwl6050-firmware -iwl100-firmware -iwl1000-firmware -iwl135-firmware -iwl6000-firmware -iwl105-firmware -iwl2000-firmware -libertas-sd8686-firmware -iwl5150-firmware -ivtv-firmware -iwl4965-firmware -libertas-usb8388-firmware -iwl3160-firmware -iwl5000-firmware -iwl3945-firmware %end %post # fastestmirror echo 'include_only=.jp' >> /etc/yum/pluginconf.d/fastestmirror.conf # package yum -y update yum -y install kernel-devel kernel-headers dkms gcc git make curl sudo wget perl bzip2 patch net-tools # vagrant in sudoers echo "vagrant ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/vagrant chmod 0440 /etc/sudoers.d/vagrant cp -p /etc/sudoers /etc/sudoers.orig sed -i "s/^.*requiretty/#Defaults requiretty/" /etc/sudoers # update root certs otherwise Chef Client won't install wget -qO /etc/pki/tls/certs/ca-bundle.crt http://curl.haxx.se/ca/cacert.pem %end
ks7.cfgでは、見つからないパッケージを無視するignoremissingオプションを23行目で削除しています。
また、26~46行目でインストールしないパッケージを指定していますので、使用する環境に合わせて修正する必要があると思います。
54,55行目は、fastestmirrorの検索先をJPのみに限定して、システムのアップデートおよび、VirtualBox Guest Addinのビルドに必要なパッケージをインストールしています。
3,6d2 < OSLANG=ja_JP.UTF-8 < echo '==> Configuring locale settings to $OSLANG' < localectl set-locale LANG=$OSLANG <
#!/bin/bash -eux
OSLANG=ja_JP.UTF-8
echo '==> Configuring locale settings to $OSLANG'
localectl set-locale LANG=$OSLANG
echo '==> Configuring settings for vagrant'
VAGRANT_USER=${VAGRANT_USER:-vagrant}
VAGRANT_HOME=${VAGRANT_HOME:-/home/${VAGRANT_USER}}
VAGRANT_SSH_KEY_URL=${VAGRANT_SSH_KEY_URL:-https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub}
# Add vagrant user (if it doesn't already exist)
if ! id -u $VAGRANT_USER >/dev/null 2>&1; then
echo '==> Creating Vagrant user'
/usr/sbin/groupadd $VAGRANT_USER
/usr/sbin/useradd $VAGRANT_USER -g $VAGRANT_USER -G wheel
echo "${VAGRANT_USER}"|passwd --stdin $VAGRANT_USER
echo "${VAGRANT_USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
fi
echo '==> Installing Vagrant SSH key'
mkdir -pm 700 ${VAGRANT_HOME}/.ssh
echo "==> Downloading SSH key from ${VAGRANT_SSH_KEY_URL}"
echo "==> Saving to ${VAGRANT_HOME}/.ssh/autorized_keys"
wget --no-check-certificate "${VAGRANT_SSH_KEY_URL}" -O ${VAGRANT_HOME}/.ssh/authorized_keys
chmod 0600 ${VAGRANT_HOME}/.ssh/authorized_keys
chown -R ${VAGRANT_USER}:${VAGRANT_USER} ${VAGRANT_HOME}/.ssh
echo '==> Recording box config date'
date > /etc/vagrant_box_build_time
echo '==> Customizing message of the day'
echo 'Welcome to your Packer-built virtual machine.' > /etc/motd
vagrant.shでは、システムロケールの指定方法が、CentOS 7で変更されたため、5行目で指定しています。もし、デフォルトのen_US.UTF-8でも構わないのであれば、この行をコメントアウトして下さい。
設定ファイルの編集が終了したら、Boxを作成します。
$ packer validate centos70.json $ packer build centos70.json
コマンドを実行すると、ターミナル上にメッセージが表示され、VitualBoxの仮想マシンが起動されて、自動インストールが実行されます。

OSがインストールされ、システムが再起動すると、ターミナル上にSSH接続が表示され、指定したスクリプトを実行します。
virtualbox-iso output will be in this color.
==> virtualbox-iso: Downloading or copying Guest additions
virtualbox-iso: Downloading or copying: file:///C:/Program%20Files/Oracle/VirtualBox/VBoxGuestAdditions.iso
==> virtualbox-iso: Downloading or copying ISO
virtualbox-iso: Downloading or copying: file:///I:/ISO/CentOS/CentOS-7.0-1406-x86_64-Minimal.iso
==> virtualbox-iso: Starting HTTP server on port 8081
==> virtualbox-iso: Creating virtual machine...
==> virtualbox-iso: Creating hard drive...
==> virtualbox-iso: Creating forwarded port mapping for SSH (host port 3213)
==> virtualbox-iso: Executing custom VBoxManage commands...
virtualbox-iso: Executing: modifyvm centos70 --memory 512
virtualbox-iso: Executing: modifyvm centos70 --cpus 2
virtualbox-iso: Executing: modifyvm centos70 --ioapic on
==> virtualbox-iso: Starting the virtual machine...
==> virtualbox-iso: Waiting 10s for boot...
==> virtualbox-iso: Typing the boot command...
==> virtualbox-iso: Waiting for SSH to become available...
==> virtualbox-iso: Connected to SSH!
==> virtualbox-iso: Uploading VirtualBox version info (4.3.12)
==> virtualbox-iso: Uploading VirtualBox guest additions ISO...
==> virtualbox-iso: Provisioning with shell script: script/fix-slow-dns.sh
virtualbox-iso: ==> Applying slow DNS fix
virtualbox-iso: Restarting network (via systemctl): [ OK ]
virtualbox-iso: ==> Slow DNS fix applied (single-request-reopen)
==> virtualbox-iso: Provisioning with shell script: script/sshd.sh
virtualbox-iso: ==> Configuring sshd_config options
virtualbox-iso: ==> Turning off sshd DNS lookup to prevent timeout delay
virtualbox-iso: ==> Disablng GSSAPI authentication to prevent timeout delay
virtualbox-iso:
virtualbox-iso:
virtualbox-iso:
virtualbox-iso:
virtualbox-iso:
virtualbox-iso:
virtualbox-iso:
==> virtualbox-iso: Provisioning with shell script: script/vagrant.sh
virtualbox-iso: ==> Configuring locale settings to $OSLANG
virtualbox-iso: ==> Configuring settings for vagrant
virtualbox-iso: ==> Installing Vagrant SSH key
virtualbox-iso: ==> Downloading SSH key from https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub
virtualbox-iso: ==> Saving to /home/vagrant/.ssh/autorized_keys
virtualbox-iso: --2014-07-29 19:33:43-- https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub
virtualbox-iso: Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 103.245.222.133
virtualbox-iso: Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|103.245.222.133|:443... connected.
virtualbox-iso: HTTP request sent, awaiting response... 200 OK
virtualbox-iso: Length: 409 [text/plain]
virtualbox-iso: Saving to: ‘/home/vagrant/.ssh/authorized_keys’
virtualbox-iso:
virtualbox-iso: 100% 409 --.-K/s in 0s
virtualbox-iso:
virtualbox-iso: 2014-07-29 19:33:43 (3.32 MB/s) - ‘/home/vagrant/.ssh/authorized_keys’ saved [409/409]
virtualbox-iso:
virtualbox-iso: ==> Recording box config date
==> virtualbox-iso: Provisioning with shell script: script/vmtool.sh
virtualbox-iso: ==> Installing VirtualBox guest additions
virtualbox-iso: mount: /dev/loop0 is write-protected, mounting read-only
virtualbox-iso: Creating directory install
virtualbox-iso: Verifying archive integrity... All good.
virtualbox-iso: Uncompressing VirtualBox 4.3.12 Guest Additions for Linux............
virtualbox-iso: patching file src/vboxguest-4.3.12/vboxguest/r0drv/linux/memobj-r0drv-linux.c
virtualbox-iso: VirtualBox Guest Additions installer
virtualbox-iso: Copying additional installer modules ...
virtualbox-iso: Installing additional modules ...
virtualbox-iso: Removing existing VirtualBox non-DKMS k[ OK ]dules
virtualbox-iso: Building the VirtualBox Guest Additions kernel modules
virtualbox-iso: Building the main Guest Additions modul[ OK ]
virtualbox-iso: Building the shared folder support modu[ OK ]
virtualbox-iso: Building the OpenGL support module [ OK ]
virtualbox-iso: Doing non-kernel setup of the Guest Add[ OK ]
virtualbox-iso: Starting the VirtualBox Guest Additions[ OK ]
virtualbox-iso: Installing the Window System drivers
virtualbox-iso: Could not find the X.Org or XFree86 Window System, skipping.
==> virtualbox-iso: Provisioning with shell script: script/cleanup.sh
virtualbox-iso: ==> Cleaning up temporary network addresses
virtualbox-iso: ==> Cleaning up yum cache of metadata and packages to save space
virtualbox-iso: 読み込んだプラグイン:fastestmirror
virtualbox-iso: リポジトリーを清掃しています: base
virtualbox-iso: ...: extras updates
virtualbox-iso: Cleaning up everything
virtualbox-iso: Cleaning up list of fastest mirrors
virtualbox-iso: ==> Removing temporary files used to build box
virtualbox-iso: ==> Zeroing out empty area to save space in the final image
virtualbox-iso: dd: `/EMPTY' の書き込みエラー: デバイスに空き領域がありません
virtualbox-iso: 5682+0 レコード入力
virtualbox-iso: 5681+0 レコード出力
virtualbox-iso: 5957189632 バイト (6.0 GB) コピーされました、 82.2385 秒、 72.4 MB/秒
==> virtualbox-iso: Gracefully halting virtual machine...
==> virtualbox-iso: Preparing to export machine...
virtualbox-iso: Deleting forwarded port mapping for SSH (host port 3213)
==> virtualbox-iso: Exporting virtual machine...
virtualbox-iso: Executing: export centos70 --output output-virtualbox-iso\centos70.ovf
==> virtualbox-iso: Unregistering and deleting virtual machine...
==> virtualbox-iso: Running post-processor: vagrant
==> virtualbox-iso (vagrant): Creating Vagrant box for 'virtualbox' provider
virtualbox-iso (vagrant): Copying from artifact: output-virtualbox-iso\centos70-disk1.vmdk
virtualbox-iso (vagrant): Copying from artifact: output-virtualbox-iso\centos70.ovf
virtualbox-iso (vagrant): Renaming the OVF to box.ovf...
virtualbox-iso (vagrant): Using custom Vagrantfile: tpl/vagrantfile-centos70-no-hgfs.tpl
virtualbox-iso (vagrant): Compressing: Vagrantfile
virtualbox-iso (vagrant): Compressing: box.ovf
virtualbox-iso (vagrant): Compressing: centos70-disk1.vmdk
virtualbox-iso (vagrant): Compressing: metadata.json
Build 'virtualbox-iso' finished.
==> Builds finished. The artifacts of successful builds are:
--> virtualbox-iso: 'virtualbox' provider box: box/virtualbox/centos70-nocm.box
ビルドが終了すると、box/virtualbox下にBoxイメージが作成されます。
作成されたBoxは、Vagrantで起動できるBoxイメージですので、Boxを起動します。
$ vagrant init centos7 box/virtualbox/centos70-nocm.box

A `Vagrantfile` has been placed in this directory. You are now ready to `vagrant up` your first virtual environment! Please read the comments in the Vagrantfile as well as documentation on `vagrantup.com` for more information on using Vagrant.
$ vagrant up

Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'centos7' could not be found. Attempting to find and install...
default: Box Provider: virtualbox
default: Box Version: >= 0
==> default: Adding box 'centos7' (v0) for provider: virtualbox
default: Downloading: file://D:/TEMP/centos-vm/box/virtualbox/centos70-nocm.box
default:
==> default: Successfully added box 'centos7' (v0) for 'virtualbox'!
==> default: Importing base box 'centos7'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: centos-vm_default_1406688727674_48809
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
default: Adapter 1: nat
==> default: Forwarding ports...
default: 22 => 2222 (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
default: SSH address: 127.0.0.1:2222
default: SSH username: vagrant
default: SSH auth method: private key
default: Warning: Connection timeout. Retrying...
default: Warning: Connection timeout. Retrying...
default: Warning: Remote connection disconnect. Retrying...
==> default: Machine booted and ready!
GuestAdditions 4.3.12 running --- OK.
==> default: Checking for guest additions in VM...
$ vagrant ssh
