複製したvagrant boxでNICエラーになりssh接続できない

Vagrant環境を作るときにイチから構築するのは面倒なので、すでにローカル環境に構築してあったVagrantゲストマシンを複製することにしました。
Vagrant環境を効率良くつくるには、ChefやAnsibleに頼るのもいいですが、出来上がっているVagrant boxを複製できたほうが楽だと思ったわけです。

ただ、実際にはすんなりとは行かず、複製したVagrant box を up したときに NICエラー「**<Font color="red">Bringing up interface eth1:  Device eth1 does not seem to be present, delaying initialization.</font>**」が発生してしまったのでその対処をしたときのまとめです。

**このノウハウはvagrant環境を複製するときだけでなく、既存VirtualBoxの仮想マシンをVagrant化するときにもつまづくことなので、その辺を検討している方も役立つと思います。**

#Vagrant boxを複製する

###実行環境

**■ホストマシン**

- Macbook Pro 15インチ
- Mac OS X 10.10 Yosemite
- VirtualBox 5.0.14 r105127
- Vagrant 1.7.4 + Landrush + vagrant-vbguest
- Ruby 2.0.0p481 (2014-05-08 revision 45883)

**■ゲストマシン**

- CentOS 7.1  64bit
- GuestAdditions 5.0.14

###実行コマンド

やりたいことは vagrant package で既存ゲストマシンをvagrant packageコマンドでパッケージ化して、vagrant box addコマンドでboxを追加すれば簡単にゲストマシンを複製できるのではないかという思惑です。

```
% cd /Users/[ユーザー名]/Documents/original-site.com/vagrant
% vagrant package
% mkdir /Users/[ユーザー名]/Documents/new-site.com/vagrant
% cp ./package.box /Users/[ユーザー名]/Documents/new-site.com/vagrant
% cd /Users/[ユーザー名]/Documents/new-site.com/vagrant
% vagrant box add new-site.com package.box
% vagrant box list
% vagrant init new-site.com
% vagrant up
```

ここで、vagrant up中にeth1が見つからないという旨のエラーが表示されてしまいました。
じつはこのエラーが発生する前に[rubyの文字エンコーディングエラー「Encoding::UndefinedConversionError」](http://qiita.com/J_Sugar__/items/fd55d99003262ad68412)が表示されてしまい、先にそちらを解消済みです。


#Vagrant up時にエラー発生「Device eth1 does not seem」

vagrant upを叩いて途中まではうまく行っているように見えましたが、最後の方で「**<Font color="red">Bringing up interface eth1:  Device eth1 does not seem to be present, delaying initialization.</font>**」というエラーが表示されてしまいました。

```
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Removing hosts
==> default: Clearing any previously set forwarded ports...
==> default: Fixed port collision for 22 => 2222. Now on port 2200.
==> default: Clearing any previously set network interfaces...
==> default: [landrush] Host DNS resolver config looks good.
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 22 => 2200 (adapter 1)
==> default: Checking for host entries
==> default: adding to (/etc/hosts) : 192.168.33.13  new-site.com  # VAGRANT: 5bf133289f45efcba785af6f72acfd17 (default) / b07f4a7b-4843-44b9-a661-84bc3d537b63
Password:
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2200
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Connection timeout. Retrying...
==> default: Machine booted and ready!
GuestAdditions 5.0.14 running --- OK.
==> default: Checking for guest additions in VM...
  5
==> default: Setting hostname...
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

service network restart

Stdout from the command:

Shutting down interface eth0:  [  OK  ]
Shutting down loopback interface:  [  OK  ]
Bringing up loopback interface:  [  OK  ]
Bringing up interface eth0:
Determining IP information for eth0... done.
[  OK  ]
Bringing up interface eth1:  Device eth1 does not seem to be present, delaying initialization.
[FAILED]
```

vagrant boxコマンドでパッケージ化した package.box を他人に配布する分にはなにも問題はありませんが、同一ホストマシン上で box add した場合は事情が変わってきます。

同一ホストマシン上でゲストマシンを複製すると、複製元と複製先のゲスト環境とでLANカードのMACアドレスが競合してしまうようです。

この状態でも一応 Vagrant環境は起動しますが vagrant ssh コマンドを叩いても接続できません。

#対処方法

vagrantの特徴として、vagrant up時に毎回NICの設定が自動更新されます。
この自動更新は後々悪さをするので無効化します。

Vagrantfileファイルを開いて、private_network の auto_config を false に設定しておけばOKです。

```
% vim Vagrantfile

config.vm.network "private_network", ip: "192.168.33.13", auto_config:false
```

さきほど vagrant up したときに VirtualBox にゲストマシンが登録されたはずなので、VirtualBox設定からネットワークを開きます。

![スクリーンショット 2016-02-11 20.49.19.png](https://qiita-image-store.s3.amazonaws.com/0/39468/14cb1628-13cc-e539-1882-7c1e630999bb.png)


複製元ゲストマシンのMACアドレスのままなので更新ボタンを押して新しいMACアドレスを割り当てます。
これを「アダプター1」「アダプター2」のどちらも行います。

このときに割り当てられたMACアドレスはメモしておいてください。後ほどゲストマシン上でNICを修正するときに必要になります。

［OK］ボタンをクリックして設定内容を保存したらもう一度 vagrant up します。

```
% vagrant up
```

この時点ではまだゲストマシンのNICは更新されておらずSSH接続はできません。
なので VirtualBox のコンソールからログインして操作することになります。

##ネットワークスクリプトを修正する

vimエディタでifcfg-ethファイルを開いて新しいMACアドレスを指定します。

```
# vim /etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE="eth0"
BOOTPROTO="dhcp"
HWADDR="08:00:27:ec:49:42"
IPV6INIT="no"
MTU="1500"
NM_CONTROLLED="yes"
ONBOOT="yes"
TYPE="Ethernet"
```

```
# vim /etc/sysconfig/network-scripts/ifcfg-eth1

DEVICE="eth1"
BOOTPROTO="none"
HWADDR="08:00:27:13:ea:3b"
IPV6INIT="no"
IPADDR=192.168.33.13
MTU="1500"
NM_CONTROLLED="no"
ONBOOT="yes"
TYPE="Ethernet"
```


次に 70-persistent-net.rules ファイルを修正します。

ちなみに 70-persistent-net.rules ファイルとは、NICとethのマッピングを行っており、NICが起動しないときはこのファイルが原因のことが多いですね。

```
# vim /etc/udev/rules.d/70-persistent-net.rules
```

ファイルを開くと古い設定情報が書かれているので、いったん全て削除してしまいます。
そしたら以下の内容を貼り付けます。
（ただし、MACアドレスは自分が割り当てたもので置き換えてください）

```
# PCI device 0x8086:0x100e (e1000) (custom name provided by external tool)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:27:ec:49:42", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

# PCI device 0x8086:0x100e (e1000) (custom name provided by external tool)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:27:13:ea:3b", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"
```

※MACアドレスのアルファベットを大文字で書いたらこの後のネットワーク再起動でデバイスが見つからない旨のエラーが表示されましたが、小文字に書き換えたらうまく行きました。理由は分かりませんが一応書いておきます。


最後にネットワークを再起動します。

```
# service network restart
```

これにて新しいMACアドレスの割り当ては完了です。
ここまでくれば、vagrant up 後に ssh接続できるようになっているはずです。

```
% vagrant halt
% vagrant up
% vagrant ssh
```


一点気をつけることは先ほど Vagrantfileファイルで指定しておいた config.vm.network の **auto_config:false** は消さずにそのままにしておきましょう。
もし消したり true へ変更してしまうと、次に vagrant up したときにせっかく編集したネットワークスクリプトが元に戻ってしまうことがあるのでご注意ください。

どうしても vagrant up 後のNICエラーが解消されないときは、既存VagrantマシンとIPアドレスが競合してしまっている可能性があります。
VagrantfileファイルのIPアドレスを見直してみましょう。