ESXi上のVMをboxファイルにする方法

264
NO IMAGE

ESXi+Vagrantで仮想サーバーを作成する場合、通常であれば、VMイメージ(以下、boxファイル)はVagrant Cloud[^1]で取得すれば事足ります。
しかし、既存のboxファイルでは、既に作られているパーティションやvagrant sshでログインする為のユーザーを変更できません。
今回の記事は、そのような問題を解決するために、ESXi上のVMから目的のboxファイルを作成した時の内容をもとにしています。

環境

VMware ESXi 6.7.0
Vagrant 2.2.6

// Vagrantサーバーのファイル構成

|-- box-build (box作成用のディレクトリ)
|   |-- .vagrant/machines/test-vm/vmware_esxi/id
|   `-- Vagrantfile
`-- box-run (boxの動作確認用のディレクトリ)
    `-- Vagrantfile

作成方法

boxファイルにするVMの作成

  1. ESXi上にboxにするためのVMを作成してください。
    今回は、VM名をtest-vmとします。

  2. ユーザーを作成します。
    このユーザーは、vagrant sshやプロビジョンに用いられます。
    ユーザー名はどのようなものでも構いませんが、vagrantという名前でない場合は、VMを起動するためのVagrantfileに特別に設定をする必要があります。
    今回はVagrant Cloudに置かれているboxファイルにならい、ユーザー名、パスワードは共にvagrantとします。
    次のコマンドでユーザーを追加します。
    $ adduser vagrant

  3. vagrantがパスワードなしでsudoを行えるようにします。
    $ sudo visudo
    以下をファイル内に追記します。
    vagrant ALL=NOPASSWD: ALL
    ※パスワードありのままだと、プロビジョン時に要求されるパスワードを返すことができないので、プロビジョンが終了しません。

  4. vagrantユーザーのホームディレクトリにvagrantサーバーから接続するための公開鍵を置きます。
    こちらの公開鍵の内容を/home/vagrant/.ssh/authorized_keysに記述してください。
    この公開鍵が使われるのは、初回ssh接続の時になります。
    それ以降は、初回アクセス時に自動で挿入されたVM固有のsshキーが用いられます。

  5. 公開鍵のパーミッションを変更します。
    $ chmod 700 /home/test/.ssh/
    $ chmod 600 /home/test/.ssh/authorized_keys

  6. VMのマシンIDを削除します。
    次のコマンドで/etc/machine-idを削除します。
    $ rm /etc/machine-id
    このファイルを削除しないと、同じboxファイルから複数のVMを作成した際にプロビジョンがそれぞれのVMに行われる不整合がおきます。
    なお、machine-idファイルは、VM起動時に自動で追加されます。

  7. その他のカスタマイズは自由です。

  8. VMを停止させます。
    次のコマンドを実行します。
    $ shutdown now

VMからboxファイルを作成

  1. VMのマシンIDを取得します。
    ESXiサーバーへログインし、box化したいVMのマシンIDを取得します。
    サーバー上で次のコマンドを実行します。
    $ vim-cmd vmsvc/getallvms
    ※このコマンドで表示されたテーブルのVMidがマシンID、NameがVM名になります。

  2. Vagrantサーバーでbox作成用のVagrantfileを作成します。
    Vagrantfileを記事上部の「Vagrantサーバーのファイル構成」となるようにbox-buildディレクトリに置きます。
    また、Vagrantfileの内容は次の通りです。

# box作成用のVagrantfile

# -*- mode: ruby -*-
Vagrant.configure("2") do |config|

  config.vm.define  "test-vm" do |node|
    node.vm.hostname = "test-vm"
  end

  config.vm.provider :vmware_esxi do |esxi|
    esxi.guest_name = "test-vm"
    esxi.esxi_hostname = "ESXiのIPアドレスorドメイン名"
    esxi.esxi_username = "ルート権限のあるESXiのユーザー"
    esxi.esxi_password = 'prompt:'
  end
end

3.マシンIDを記述します。
 取得したマシンIDを以下のファイルに記述します。
 box-build/.vagrant/machines/{VM名}/vmware_esxi/id
 今回の内容では、パスは次のようになります。
 box-build/.vagrant/machines/test-vm/vmware_esxi/id

4.VMをbox化します。
 box-buildディレクトリ上で以下のコマンドを実行します。
 $ vagrant package
 ※オプションでboxファイル名を指定しない場合、package.boxというboxファイルがbox-buildディレクトリ上に作成されます。
 記事内では、boxファイル名をpackage.boxとして扱います。

VMの起動

  1. boxファイルをvagrantへ適用します。
    次のコマンドでboxファイルをvagrantへ適用します。
    box名は、test-boxとします。
    $ vagrant box add package.box --name test-box
    boxファイルが適用されているかは、次のコマンドで確認できます。
    $ vagrant box list
    ここでtest-boxが表示されていれば、成功です。

  2. VM起動用のVagrantfileを作成します。
    box-runディレクトリにVagrantfileを以下の内容を作成します。

#box起動用のVagrantfile

# -*- mode: ruby -*-
Vagrant.configure("2") do |config|
  config.vm.box = "test-box"

  config.vm.define "新しいVM名" do |node|
    node.vm.hostname = "新しいVM名"
  end

  config.vm.provider :vmware_esxi do |esxi|
    esxi.esxi_hostname = "ESXiのIPアドレスorドメイン名"
    esxi.esxi_username = "root"
    esxi.esxi_password = "esxiサーバーのパスワード"
    esxi.guest_memsize = 16384
    esxi.guest_numvcpus = 1
  end
end

3.VMを起動します。
 box-runディレクトリ上で以下のコマンドを実行します。
 $ vagrant up
 少し待つとVMが作成され、起動します。

まとめ

ネット上にboxファイルを作成する方法を記している記事は多くヒットしますが、プロバイダーにESXiを用いている方法は少なかったので、記事にしました。
box化やVMの起動には、かなり時間がかかる場合があります。(20分くらいかかったこともありました。)お使いの際は、他の作業の合間にすることをお勧めします。

参考文献

  1. 「sudo のパスワードを入力なしで使うには」,
    https://qiita.com/RyodoTanaka/items/e9b15d579d17651650b7 ,
    2020年2月24日アクセス

[^1]: Vagrant Cloudは、boxファイルのリポジトリです。