LoginSignup
3
1

More than 3 years have passed since last update.

GCE 仮想マシンの入れ子(Nested Virtualization)を許可して Vagrant box ビルド環境を作る

Posted at

背景・目的

Vagrant box をビルドしてアプリケーション開発環境を作ると便利です。
ビルドした Box をチーム全員で利用することで開発環境を統一することが出来ますし、VM なのでプロジェクトや開発に使う言語やフレームワークごとに Box を変えることができ、Box を最新化すれば開発環境のアップデートも出来ます。

今回、Vagrant box を build する packer を使って Ubuntu 18.04LTS ベースの Vagrant box をビルドすることを目的とします。

GCE の Always free で割り当てられるインスタンスが Nested Virtualization に対応していることが分かったので、GCE 上にビルド環境を作ることにします。

(今回はそこまでやりませんが、Jenkins 等の CI ツールでビルド処理を実行すれば、開発環境も CI できます)

用意した環境

  • ホスト
    • GCE ゾーン us-west1-b, Ubuntu 16.04LTS + Nested Virtualization
    • ゾーンは default CPU が Nested Virtualization 対応の Haswell 以降である必要があります
    • Always free を使いたい場合はゾーン毎の機能を確認してください
  • VirtualBox(6.0.8)
    • Extension Pack(6.0.8)
  • vagrant (2.2.5)
  • packer (1.4.2)

Netsted Virtualization 対応インスタンスを起動する

公式ドキュメントに従って作成すれば簡単に作成できます。

  1. gcloud をインストールする
  2. カスタムイメージを作成する
    • gcloud コマンドを使って下記(※1)のとおりカスタムイメージを作成する
    • Google Cloud Console の「Compute Engine > イメージ」にカスタムイメージ nested-ubuntu-xxxx-vyyyymmdd が作成されたことが確認できる
  3. カスタムイメージを使って Compute Engine の VM インスタンスを作成する
    • Google Cloud Console の GCE VMインスタンス作成画面からインスタンス作成ボタンを押す
    • 作成したカスタムイメージ nested-ubuntu-xxxx-vyyyymmdd を使う
  4. VT-x が有効になっていることを確認する
    • $ grep -cw vmx /proc/cpuinfo が 1 を返せばよい
Ubuntu16.04LTSベースでNestedVirtualization対応イメージを作成する(※1)
$ gcloud compute images create nested-ubuntu-1604-xenial-v20181204 \
--source-image=projects/ubuntu-os-cloud/global/images/ubuntu-1604-xenial-v20181204 \
--licenses "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"
Ubuntu18.04LTSベースでNestedVirtualization対応イメージを作成する
gcloud compute images create nested-ubuntu-1804-bionic-v20190628 \
--source-image=projects/ubuntu-os-cloud/global/images/ubuntu-1804-bionic-v20190628 \
--licenses "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"

VirtualBox をインストールする

以下、カスタムイメージを使ってインストールした VM インスタンス上で作業します。

最新の VirtualBox がよい場合は https://www.virtualbox.org/wiki/Linux_Downloads から URL を確認してコマンドを変更してください。

VirtualBox 5.1.38 の場合

VirtualBoxをインストールする
$ wget https://download.virtualbox.org/virtualbox/5.1.38/virtualbox-5.1_5.1.38-122592~Ubuntu~xenial_amd64.deb
$ sudo apt-get update
$ sudo apt-get install -y ./virtualbox-5.1_5.1.38-122592~Ubuntu~xenial_amd64.deb

VirtualBox 6.0.8 の場合

$ wget https://download.virtualbox.org/virtualbox/6.0.8/virtualbox-6.0_6.0.8-130520~Ubuntu~bionic_amd64.deb
$ sudo apt-get update
$ sudo apt-get install -y ./virtualbox-6.0_6.0.8-130520~Ubuntu~bionic_amd64.deb

Vagrant をインストールする

以下、カスタムイメージを使ってインストールした VM インスタンス上で作業します。

最新の Vagrant がよい場合は
https://www.vagrantup.com/downloads.html から URL を確認してコマンドを変更してください。

Vagrant 1.9.8 の場合

vagrantをインストールする
$ wget https://releases.hashicorp.com/vagrant/1.9.8/vagrant_1.9.8_x86_64.deb
$ sudo apt-get update
$ sudo apt-get -y install ./vagrant_1.9.8_x86_64.deb

Vagrant 2.2.5 の場合

$ wget https://releases.hashicorp.com/vagrant/2.2.5/vagrant_2.2.5_x86_64.deb
$ sudo apt-get update
$ sudo apt-get -y install ./vagrant_2.2.5_x86_64.deb

packer をインストールする

以下、カスタムイメージを使ってインストールした VM インスタンス上で作業します。

Packer 1.4.2 の場合

packerをインストールする
$ sudo apt-get update
$ sudo apt-get install -y unzip
$ wget https://releases.hashicorp.com/packer/1.4.2/packer_1.4.2_linux_amd64.zip
$ unzip packer_1.4.2_linux_amd64.zip
$ sudo chown root:root packer
$ sudo mv -i packer /usr/local/bin/

Vagrant Box をビルドする

packer はビルド方法を記した JSON ファイルを基にしてビルド処理を行います。
OS インストールから実施することが出来るが大変なのでベースとなる OVF を使ってカスタムすることにし、下記のような JSON ファイルを作成します。

ビルドする
$ vagrant box add bento/ubuntu-18.04 # Provider は VirtualBox を選ぶ
$ packer build build.json
  • /home/YOUR_ACCOUNT/.vagrant.d/boxes/bento-VAGRANTSLASH-ubuntu-18.04/201812.27.0/virtualbox/box.ovf は YOUR_ACCOUNT を自身のアカウント名に変更し、日付(201812.27.0)の部分はパスを調べて適宜変更してください
packer用ビルドファイル(build.json)
{
  "variables": {
    "box_basename": "ruby",
    "headless": "true"
  },
  "builders": [
    {
      "type": "virtualbox-ovf",
      "source_path": "/home/YOUR_ACCOUNT/.vagrant.d/boxes/bento-VAGRANTSLASH-ubuntu-18.04/201906.18.0/virtualbox/box.ovf",
      "output_directory": "packer-buildtmp-{{ user `box_basename` }}",
      "vm_name": "{{ user `box_basename` }}",
      "virtualbox_version_file": ".vbox_version",
      "guest_additions_path": "VBoxGuestAdditions_{{.Version}}.iso",
      "headless": "{{ user `headless` }}",
      "ssh_username": "vagrant",
      "ssh_password": "vagrant",
      "shutdown_command": "echo 'vagrant' | sudo -S shutdown -P now"
    }
  ],
  "provisioners": [
    {
      "type": "shell",
      "execute_command": "echo 'vagrant' | {{.Vars}} sudo -S -E -u root -H sh -eux '{{.Path}}'",
      "scripts": [
        "scripts/ubuntu/custom.sh"
      ],
      "expect_disconnect": true
    }
  ],
  "post-processors": [
    [
      {
        "type": "vagrant",
        "output": "builds/{{ user `box_basename` }}.box",
        "keep_input_artifact": true,
        "compression_level": 9
      }
    ]
  ]
}
scripts/ubuntu/custom.sh
echo HELLO WORLD
# apt-get install で BOX にパッケージをインストールする

その他

packer の動作ログを表示する

packer 実行時に環境変数 PACKER_LOG, PACKER_LOG_PATH を設定します。(参考)

packer.logにログを出力する
PACKER_LOG=1 PACKER_LOG_PATH=packer.log packer build dev.build.json

VirtualBox の動作ログを表示する

~/VirtualBox VMs/${SOME_VM_NAME}/Logs/VBox.log に VirtualBox の動作ログが表示されます。
VirtualBox で何か問題が発生した場合は、ここを参照するとよいでしょう。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1