VirtualBoxの仮想マシンイメージをVagrant用に変換する

2013年10月10日 09時32分

201310100932VVAW00.png

はじめに

Vagrantのインストールと仮想マシンの作成 では、Vagrantを使った仮想マシンの作成方法について解説しました。 しかし、VagrantではVagrantbox.esで公開されているBoxを起動することはできますが、仮想マシンを新規に作成することはできません。また、Vagrantbox.esで公開されたBoxより、自前のBoxを利用したいと思うこともあるかと思います。
そこで今回は、VirtulBoxで作成した仮想マシンをVagrant用の仮想マシンイメージに変換する方法を解説します。

前提条件

作業の前提条件は、下記のとおりです。

ソフトウエアバージョン
OSWindows 7 Ultimate 32bit
CygwinSetup Version 2.831
VirtualBox4.2.18 r88780
Vagrant1.2.7

仮想マシンの準備

Vagrant Boxへの変換を行うために必要な、仮想マシンの準備を行います。

  1. 仮想マシン名の確認

    VirtualBoxに登録された仮想マシン名を表示し、変換元の仮想マシン名または、UUID(Universal Unified Identifier)を確認します。

    $ VBoxManage list vms
    
    201310100932VVAW01.png

    今回は、CentOS-6.4-i386-minimal(520a517f-b156-4ae2-a196-3f71265b6a8d)を変換します。 なお、この仮想マシンは、CentOSをインストールしたばかりの素の仮想マシンです。

  2. ネットワーク設定の変更

    仮想マシンのネットワークは、デフォルトではNATで作成されるため、ホストマシンと仮想マシン間の通信が行えません。このため、仮想マシンのネットワークをNAT→ブリッジネットワークに変更します。

    $ VBoxManage modifyvm 520a517f-b156-4ae2-a196-3f71265b6a8d --nic1 bridged
    
  3. VirtualBox Guest Add-Inのマウント

    変換元の仮想マシンに、VirtualBox Guest Add-Inをインストールするため、インストールDVDをマウントします。

    DVDのマウントには、Storage Controllerの名前と、空きポートの情報が必要ですので、showvminfoコマンドで確認します。

    $ VBoxManage showvminfo 520a517f-b156-4ae2-a196-3f71265b6a8d | less
    
    Autostart Enabled: off
    Autostart Delay: 0
    Storage Controller Name (0):            SATA
    Storage Controller Type (0):            IntelAhci
    Storage Controller Instance Number (0): 0
    Storage Controller Max Port Count (0):  30
    Storage Controller Port Count (0):      30
    Storage Controller Bootable (0):        on
    SATA (1, 0): F:\VirtualBox\CentOS-6.4-i386-minimal\CentOS-6.4-i386-minimal.vdi (UUID: a04939b2-56e9-4a3f-9fc7-e8b6a23fced1)
    SATA (2, 0): I:\ISO\CentOS\CentOS-6.4-i386-minimal.iso (UUID: 57748687-3714-4b2f-8aed-08d800b0b649) (ejected)
    NIC 1:           MAC: 080027F63828, Attachment: Bridged Interface '', Cable connected: on, Trace: off (file: none), Type: 82540EM, Reported speed: 0 Mbps, Boot priority: 0, Promisc Policy: deny, Bandwidth group: none
    NIC 2:           disabled
    NIC 3:           disabled
    

    Storage Controller名と空きポートが確認できましたので、ISOイメージを割り当てます。

    $ VBoxManage storageattach 520a517f-b156-4ae2-a196-3f71265b6a8d --storagectl SATA --port 2 --type dvddrive --medium I:/ISO/VirtualBox/VBoxGuestAdditions_4.2.18.iso
    

    変更後のメディア割り当て状況を確認すると、ISOイメージが割り当てられています。

    Autostart Enabled: off
    Autostart Delay: 0
    Storage Controller Name (0):            SATA
    Storage Controller Type (0):            IntelAhci
    Storage Controller Instance Number (0): 0
    Storage Controller Max Port Count (0):  30
    Storage Controller Port Count (0):      30
    Storage Controller Bootable (0):        on
    SATA (1, 0): F:\VirtualBox\CentOS-6.4-i386-minimal\CentOS-6.4-i386-minimal.vdi (UUID: a04939b2-56e9-4a3f-9fc7-e8b6a23fced1)
    SATA (2, 0): I:\ISO\VirtualBox\VBoxGuestAdditions_4.2.18.iso (UUID: a3245f31-f7e4-4cda-8259-e8a07445acf4)
    NIC 1:           MAC: 080027F63828, Attachment: Bridged Interface '', Cable connected: on, Trace: off (file: none), Type: 82540EM, Reported speed: 0 Mbps, Boot priority: 0, Promisc Policy: deny, Bandwidth group: none
    NIC 2:           disabled
    NIC 3:           disabled
    
  4. ブート順序の変更

    showvminfoでは、ブート順序も確認できます。

    Number of CPUs:  2
    Synthetic Cpu:   off
    CPUID overrides: None
    Boot menu mode:  message and menu
    Boot Device (1): Not Assigned
    Boot Device (2): HardDisk
    Boot Device (3): DVD
    Boot Device (4): Network
    ACPI:            on
    IOAPIC:          on
    PAE:             on
    

    今回は、HDD→DVDの順序ですので問題ありませんが、DVD→HDDの場合、マウントしたDVDからシステムがブートしてしまうので、ブート順序を変更します。

    $ VBoxManage modifyvm 520a517f-b156-4ae2-a196-3f71265b6a8d --boot1 disk --boot2 dvd --boot3 none --boot4 none
    

    変更後のブート順序は、HDD→DVDの順で起動し、その他は無指定になります。

    Number of CPUs:  2
    Synthetic Cpu:   off
    CPUID overrides: None
    Boot menu mode:  message and menu
    Boot Device (1): HardDisk
    Boot Device (2): DVD
    Boot Device (3): Not Assigned
    Boot Device (4): Not Assigned
    ACPI:            on
    IOAPIC:          on
    PAE:             on
    
  5. 仮想マシンの起動

    変換元の仮想マシンを起動します。

    $ VBoxManage startvm 520a517f-b156-4ae2-a196-3f71265b6a8d
    
    201310100932VVAW02.png
    201310100932VVAW03.png

仮想マシンの設定

Vagrant用の仮想マシンイメージに変換するためには、変換元の仮想マシンに、ユーザー名:vagrantを使って、SSHで接続できる必要がありますので、変換元の仮想マシン上で、Vagrant用の設定を行います。

  1. vagrantユーザーの追加

    仮想マシン接続時に必要となる、vagrantユーザーとグルーブを作成します。

    # groupadd vagrant
    # useradd -g vagrant vagrant
    # passwd vagrant
    
    201310100932VVAW04.png
  2. ネットワーク有効化

    仮想マシンのネットワークを有効にして、IPアドレスを確認します。
    ブリッジインターフェースの場合、ホストOS同一セグメントのIPアドレスが割り当てられます。

    # sed -i -e "s|^ONBOOT=.*|ONBOOT=yes|" /etc/sysconfig/network-scripts/ifcfg-eth0
    # service network restart
    # ifconfig eth0
    
    201310100932VVAW05.png
  3. ネットワーク確認

    ホストOS側から、PINGコマンドの応答を確認します。

    $ ping 192.168.0.xx
    
    201310100932VVAW06.png

    ネットワーク接続が確認できたら、ホストOS側から仮想マシンにSSH接続して、 以降の作業を行います。ログインしたら、rootユーザーに移行します。

    $ ssh vagrant@192.168.0.xx
    
    201310100932VVAW07.png
  4. sudo設定

    Vagrantでは、root権限でコマンドを実行できる必要がありますので、/etc/sudoders.dにvagrantユーザー設定を行います。

    # echo 'vagrant ALL=NOPASSWD:ALL' > /etc/sudoers.d/vagrant
    # chmod 0440 /etc/sudoers.d/vagrant
    
  5. sudo設定変更

    vagrantコマンドを使って、仮想マシンに接続できるように/etc/sudoersを編集します。

    # sed -i '/requiretty/s/^/#/' /etc/sudoers
    
  6. SSH認証鍵設定
    # mkdir ~vagrant/.ssh
    # curl -ksLo ~vagrant/.ssh/authorized_keys https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub
    # chmod 0700 ~vagrant/.ssh
    # chmod 0600 ~vagrant/.ssh/authorized_keys
    # chown -R vagrant:vagrant ~vagrant/.ssh
    
  7. SSHサーバー設定変更

    SSH私有鍵を使用した認証を行うように、SSHサーバーの設定を変更します。

    # cp -p /etc/ssh/sshd_config /etc/ssh/sshd_config.orig
    # vi /etc/ssh/sshd_config
    
    #MaxSessions 10
    
    RSAAuthentication yes
    PubkeyAuthentication yes
    #AuthorizedKeysFile     .ssh/authorized_keys
    #AuthorizedKeysCommand none
    #AuthorizedKeysCommandRunAs nobody
    
    # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
    #RhostsRSAAuthentication no
    # similar for protocol version 2
    #HostbasedAuthentication no
    # Change to yes if you don't trust ~/.ssh/known_hosts for
    # RhostsRSAAuthentication and HostbasedAuthentication
    #IgnoreUserKnownHosts no
    # Don't read the user's ~/.rhosts and ~/.shosts files
    #IgnoreRhosts yes
    
    # To disable tunneled clear text passwords, change to no here!
    #PasswordAuthentication no
    #PermitEmptyPasswords no
    PasswordAuthentication no
    
    # Change to no to disable s/key passwords
    #ChallengeResponseAuthentication yes
    ChallengeResponseAuthentication no
    
    # diff /etc/ssh/sshd_config /etc/ssh/sshd_config.orig
    
    47,48c47,48
    < RSAAuthentication yes
    < PubkeyAuthentication yes
    ---
    > #RSAAuthentication yes
    > #PubkeyAuthentication yes
    64c64
    < PasswordAuthentication no
    ---
    > #PasswordAuthentication yes
    

    編集が終了したら、sshdを再起動します。

    # service sshd restart
    
  8. ネットワークルール設定の変更

    Vagrant起動時に、ネットワークインターフェースが常に初期化されるように、70-persistent-net.rulesを変更します。

    # sed -i -e "s|/etc/udev/rules.d/70-persistent-net.rules|/dev/null|" /lib/udev/write_net_rules
    
  9. fastestmirror設定

    yumコマンドで参照するミラーサイトを、日本に限定します。

    # echo "include_only=.jp" >> /etc/yum/pluginconf.d/fastestmirror.conf
    
  10. Firewall、SELinuxの無効化

    開発環境として、Boxを使用するためFirewallおよび、SELinuxを無効化します。

    # chkconfig iptables off
    # chkconfig ip6tables off
    # cp -p /etc/selinux/config /etc/selinux/config.orig
    # sed -i -e "s|^SELINUX=.*|SELINUX=disabled|" /etc/selinux/config
    
    201310100932VVAW08.png
  11. VirtualBpx Guest Add-Inのインストール

    Linux用のVirtualBox Guest Add-Inのインストールを行います。
    Guest Add-Inをインストールすると、共有フォルダやクリップボード共有などの機能をゲストOSで利用できるようになります。

    ビルドに必要なパッケージをインストールし、Add-Inをビルドします。
    X Windows Systemをインストールしていないため、Window System driverのビルドに失敗していますが、問題ありません。

    # yum -y install gcc kernel-devel kernel-headers dkms make bzip2 perl
    # mount -r /dev/cdrom /mnt
    # sh /mnt/VBoxLinuxAdditions.run
    # umount /mnt
    # reboot
    
    201310100932VVAW09.png
  12. 設定スクリプト

    手順4からここまでの手順を、スクリプトにしました。
    手順3のネットワーク確認後、本スクリプトをホストOS側からscpコマンドで転送した後、実行して下さい。

    #!/bin/sh
    
    # SUDO設定
    echo 'vagrant ALL=NOPASSWD:ALL' > /etc/sudoers.d/vagrant
    chmod 0440 /etc/sudoers.d/vagrant
    sed -i '/requiretty/s/^/#/' /etc/sudoers
    
    # SSH設定
    mkdir -p ~vagrant/.ssh
    curl -ksLo ~vagrant/.ssh/authorized_keys https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub
    chmod 0700 ~vagrant/.ssh
    chmod 0600 ~vagrant/.ssh/authorized_keys
    chown -R vagrant:vagrant ~vagrant/.ssh
    
    # SSHD設定
    cp -p /etc/ssh/sshd_config /etc/ssh/sshd_config.orig
    sed -i -e "/^#RSAAuthentication/s/^#//" -e "/^#PubkeyAuthentication/s/^#//" -e "/^PasswordAuthentication/s/yes/no/" /etc/ssh/sshd_config
    service sshd restart
    
    # ネットワークルール設定
    sed -i -e "s|/etc/udev/rules.d/70-persistent-net.rules|/dev/null|" /lib/udev/write_net_rules
    
    # fastestmirror設定
    echo "include_only=.jp" && /etc/yum/pluginconf.d/fastestmirror.conf
    
    # Firewall、SELinux設定
    chkconfig iptables off
    chkconfig ip6tables off
    cp -p /etc/selinux/config /etc/selinux/config.orig
    sed -i -e "s|^SELINUX=.*|SELINUX=disabled|" /etc/selinux/config
    
    # VirtualBox Guest Add-In
    yum -y install gcc kernel-devel kernel-headers dkms make bzip2 perl
    mount -r /dev/cdrom /mnt
    sh /mnt/VBoxLinuxAdditions.run
    umount /mnt
    

接続確認

仮想マシンの設定が終了しましたので、SSH接続を確認します。

  1. ユーザー秘密鍵の設定

    Vagrant Boxに接続する際に必要となるSSH私有鍵(秘密鍵)をホストOS側に設定します。
    私有鍵は、デフォルトインストールの場合、C:\USERS\%USERNAME%\.vagrant.dに保存されていますので、insecure_private_keyを$HOME/.sshにコピーします。

    $ cp -p /cygdrive/c/Users/$USERNAME/.vagrant.d/insecure_private_key ~/.ssh/vagrant
    
    201310100932VVAW10.png
  2. SSH設定ファイルの編集

    ホストOSが所属するネットワークのホストに対して、SSH接続するユーザー名と認証鍵を設定します。

    $ vi ~/.ssh/config
    
    Host 192.168.0.*
    IdentityFile ~/.ssh/vagrant
    User vagrant
    
    201310100932VVAW11.png
  3. SSH接続確認

    仮想マシンに接続します。
    パスワードの入力無しで、接続できれば成功です。

    $ ssh 192.168.0.xx
    
    201310100932VVAW12.png

仮想マシンの変換

  1. 仮想マシンのエクスポート

    変換元の仮想マシンのマシン名または、UUIDを指定してイメージをエクスポートします。
    変換元の仮想マシンが起動中の場合は、停止して下さい。

    $ mkdir -p /tmp/box && cd /tmp/box
    $ VBoxManage export 520a517f-b156-4ae2-a196-3f71265b6a8d -o box.ovf
    
  2. MACアドレス確認

    変換元の仮想マシンのMACアドレスを確認します。

    $ VBoxManage showvminfo 520a517f-b156-4ae2-a196-3f71265b6a8d --machinereadable | grep ^macaddress1
    
    201310100932VVAW13.png
  3. Vagrantfileの作成

    Vagrant Boxに必要なVagrantfileを作成します。
    MACアドレスは、先に確認したアドレスを設定します。

    $ vi Vagrantfile
    
    Vagrant::Config.run do |config|
      config.vm.base_mac = "080027F63828"
    end
    
  4. BOXファイル作成

    Vagrant Boxは、tarアーカイブですので、tarコマンドでアーカイブします。

    $ tar cvf /tmp/CentOS-6.4-i386-minimal.box .
    $ rm -f Vagrantfile box.ovf box-disk1.vmdk
    
    201310100932VVAW14.png
  5. 作成スクリプト

    仮想マシン名または、UUIDを指定してVagrant Boxを作成するスクリプトです。

    #!/bin/sh
    #
    # VirtualBoxに登録したVMをVagrant Boxに変換する
    #
    set -e
    
    flag=0
    uuid=
    work=/tmp/box
    dest=/export/vagrant
    
    for i in $@
    do
    	case $i in
    	-v)	flag=1;;
    	*) uuid=$i
    
    cat<<EOF
    mkdir -p ${work}/$i && cd ${work}/$i
    EOF
    [ ${flag} -eq 0 ] && mkdir -p ${work} && cd ${work}
    
    cat<<EOF
    VBoxManage export ${uuid} -o box.ovf
    EOF
    [ ${flag} -eq 0 ] && VBoxManage export ${uuid} -o box.ovf
    
    cat<<EOF
    VBoxManage showvminfo ${uuid} --machinereadable | grep ^macaddress1
    EOF
    [ ${flag} -eq 0 ] && VBoxManage showvminfo ${uuid} --machinereadable | grep ^macaddress1
    
    MAC=`VBoxManage showvminfo ${uuid} --machinereadable | grep ^macaddress1 | sed -e "s|\"||g" -e "s|^.*=||"`
    
    cat<<EOF
    Vagrant::Config.run do |config|
      config.vm.base_mac = "${MAC}"
    end
    EOF
    if [ ${flag} -eq 0 ]; then
    cat <<EOF> Vagrantfile
    Vagrant::Config.run do |config|
      config.vm.base_mac = "${MAC}"
    end
    EOF
    fi
    
    cat<<EOF
    tar cvf $dest/$i.box .
    EOF
    [ ${flag} -eq 0 ] && tar cvf $dest/$i.box .
    
    cat<<EOF
    rm -f *.vmdk box.ovf Vagrantfile
    EOF
    [ ${flag} -eq 0 ] && rm -f *.vmdk box.ovf Vagrantfile
    ;;
    esac
    
    done
    
    cd /tmp
    rm -fr ${work}
    

Vagrant Boxの起動

作成したBoxを起動します。

  1. Vagrantfileの作成

    $ mkdir -p /tmp/test-box && cd /tmp/test-box
    $ vagrant init test-box
    
    201310100932VVAW15.png
  2. Box URLの指定

    作成したVagrantfileに、ダウンロードするBoxのURLを指定します。

    $ vi Vagrantfile
    
    # -*- mode: ruby -*-
    # vi: set ft=ruby :
    
    # Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
    VAGRANTFILE_API_VERSION = "2"
    
    Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
      # All Vagrant configuration is done here. The most common configuration
      # options are documented and commented below. For a complete reference,
      # please see the online documentation at vagrantup.com.
    
      # Every Vagrant virtual environment requires a box to build off of.
      config.vm.box = "test-box"
    
      # The url from where the 'config.vm.box' box will be fetched if it
      # doesn't already exist on the user's system.
      config.vm.box_url = "file://d:/temp/CentOS-6.4-i386-minimal.box"
    
      # Create a forwarded port mapping which allows access to a specific port
      # within the machine from a port on the host machine. In the example below,
      # accessing "localhost:8080" will access port 80 on the guest machine.
      # config.vm.network "forwarded_port", guest: 80, host: 8080
    
  3. 仮想マシンの起動

    $ vagrant up
    
    201310100932VVAW16.png
  4. 仮想マシンに接続

    $ vagrant ssh
    
    201310100932VVAW17.png