Docker用のVagrant box(CentOS 7.2)の作成 & 公開

# 目的
Vagrantで立ち上げたCentOS上にDockerを立ち上げようとしたけど、Kernelのバージョンやらdevicemapperやらでなかなか手こずったので、そこらへんを解決したVagrant boxを自作することにした.
流れ的にはVagran up -> Ansible provisionにしたいのでboxに含めるのは再起動が必要なkernelのバージョンアップのみ
[作成したBox](https://atlas.hashicorp.com/winky/boxes/centos7.2-docker)

# 環境
MacBookPro OSX El Capitan
Vagrant 1.9.1
VirtualBox 5.1.10

# 手順
## 1. CentOS 7.2をダウンロード
[Download CentOS](https://www.centos.org/download/)から最新版のMinimal ISOをダウンロード
記事執筆時点ではCentOS-7-x86_64-Minimal-1611.isoが最新
Vagrant box用なのでMinimalを選択した

## 2. 仮想マシンを作成
 - Name: CentOS-7.2-1611（好きな名前でよい）
 - Memory size: 1024MB（割り当てすぎないようにデフォルトを選択）
 - Hard disk: `Create a virtual hard disk now`を選択
 - Hard disk file type: VDI
 - Storage on physical hard disk: Dynamically allocated
 - File location and size: 8.0GB
 
 上記の設定で仮想マシンを作成
 続いて下記3つの不要な周辺機器を無効化しておく

 - フロッピー
 - オーディオ
 - USB
 
 Macの場合ホストオンリーネットワークを追加する
 `Network->Adapter2`から`Enable Network Adapter`にチェックをいれ`Host-only Adapter`を選択
 `VirtualBox->Preferences..->Network->Host-only Adapter`から`vboxnet0`のIP
アドレスを確認
 
 最後にCentOSをインストールできるように読み込むISOを設定
 `Storage->Controller:IDE->Empty`の`Optical Drive`で先程ダウンロードしたISOファイルを選択

## 3. CentOSをインストール
 1. 仮想マシンを立ち上げる
 2. GUI画面が立ち上げるので`Install CentOS Linux 7`を選択
 3. セットアップ画面が出てくるので各項目ごとに設定
    - LANGUAGE SUPPORT: English
    - DATE&TIME: Asia/Tokyo
    - INSTALLATION DESTINATION: ATA VBOX HARDDISK
 4. 設定を終えたらインストールを開始
 5. インストールが終わったらrootユーザーのパスワードを設定します。
 6. パスワードを設定したら設定を反映させて再起動

## 4. ネットワーク設定
 1. `nmtui`を実行しNetworkManagerを起動
 2. `Edit a connection`を選択
 3. enp0s3 (NAT に対応)
    - [IPv4 CONFIGURATION] 
    - [IPv6 CONFIGURATION] 
    - [X] Automatically connect
    - [X] Available to all users
 4. enp0s8 (ホストオンリーアダプターに対応)
    - [IPv4 CONFIGURATION] 
    - [IPv6 CONFIGURATION] 
    - [X] Automatically connect
    - [X] Available to all users
 5. `Quit`を選択し設定画面を抜ける
 6. `systemctl restart NetworkManager`を実行し設定を反映

## 5. yumをアップデート
 yumをアップデートするとBoxの容量は大きくなるので軽量のBoxを作る場合は飛ばす
 今回はDestroy&Upを気軽にやりたかったので実行
 `yum -y update`を実行

## 6. Vagrantユーザーの作成とSSHの設定
### 6-1. Vagrantユーザーの作成
```
useradd vagrant
passwd vagrant
```
上記のコマンドを実行
Vagrant用なのでパスワードもvagrantにすること

### 6-2. SSHのインストールと自動起動設定を確認
```
systemctl status sshd.service
systemctl list-unit-files -t service | grep sshd.service
```

ちゃんと設定されていれば

```
sshd.service  enabled
```
となっているはず

### 6-3. Vagrantのデフォルトに含まれているinsecure private keyを使ってSSHの鍵認証を行うように設定
```
su - vagrant
mkdir ~/.ssh
chmod 700 ~/.ssh
curl -L -o ~/.ssh/authorized_keys  https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub
chmod 600 ~/.ssh/authorized_keys
chown -R vagrant ~/.ssh
```

### 6-4. sudoの設定
`visudo`を実行しsudo設定を開く

```
Defaults    requiretty
↓
# Defaults    requiretty
 
root    ALL=(ALL)   ALL
vagrant ALL=(ALL)   NOPASSWD:ALL
```

### 6-5. SSHの設定
DNSを使わないように設定
``` /etc/ssh/sshd_config
UseDNS no
```

### 6-6. SELinux 停止
開発環境用なのでSELinuxを停止させておく

```
vi /etc/selinux/config
SELINUX=enforcing
↓
SELINUX=disabled

reboot
```

## 7. VitrualBox GuestAdditionsをインストール
### 7-1. インストールの準備
カーネルのアップデートとコンパイラを導入

```
yum update
yum install bzip2 gcc kernel-devel
```

インストールしたカーネルのバージョンを確認

```
uname -r
3.10.0-514.el7.x86_64
```

普通にBox化する場合はこの状態でOK

今回はDocker用にカーネルのバージョンあげたいのでelrepoからkernelを追加し設定する

```
# repolistにelrepoを追加
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org 
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm

# elrepo-kernel の有効化
vi /etc/yum.repos.d/elrepo.repo

[elrepo-kernel]
name=ELRepo.org Community Enterprise Linux Kernel Repository - el7
baseurl=http://elrepo.org/linux/kernel/el7/$basearch/
        http://mirrors.coreix.net/elrepo/kernel/el7/$basearch/
        http://jur-linux.org/download/elrepo/kernel/el7/$basearch/
        http://repos.lax-noc.com/elrepo/kernel/el7/$basearch/
        http://mirror.ventraip.net.au/elrepo/kernel/el7/$basearch/
mirrorlist=http://mirrors.elrepo.org/mirrors-elrepo-kernel.el7
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-elrepo.org
protect=0
↓
[elrepo-kernel]
name=ELRepo.org Community Enterprise Linux Kernel Repository - el7
baseurl=http://elrepo.org/linux/kernel/el7/$basearch/
        http://mirrors.coreix.net/elrepo/kernel/el7/$basearch/
        http://jur-linux.org/download/elrepo/kernel/el7/$basearch/
        http://repos.lax-noc.com/elrepo/kernel/el7/$basearch/
        http://mirror.ventraip.net.au/elrepo/kernel/el7/$basearch/
mirrorlist=http://mirrors.elrepo.org/mirrors-elrepo-kernel.el7
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-elrepo.org
protect=0

# 既存のkernelの確認と削除
yum list installed | grep kernel
yum -y remove kernel*

# elrepoからkernelをインストール
yum -y install kernel-ml* bzip2 dkms gcc gcc-c++

# grub 設定確認
awk -F\' '$1=="menuentry " {print $2}' /etc/grub2.cfg
  CentOS Linux (4.9.0-1.el7.elrepo.x86_64) 7 (Core) ←一番上に今回インストールしたバージョンのkernel情報があるはず

# grub 起動設定変更
grub2-set-default 0
grub2-mkconfig -o /boot/grub2/grub.cfg

# kernelを反映させるためにOSを再起動
reboot

# kernelのバージョンを確認
uname -r
 4.9.0-1.el7.elrepo.x86_64
```

### 7-2. GuestAdditionsをマウント&インストール
VirtualBox VMのメニューからDevices->insert Guest Additions CD imageを選択
rootユーザーで下記を実行

```
mount /dev/cdrom /mnt
mount: /dev/sr0 is write-protected, mounting read-only
sh /mnt/VBoxLinuxAdditions.run
```

エラーが出た場合はログファイルでエラー内容を確認
今回はファイルが足りないと言われたので必要なファイルを揃える
```
cp /usr/include/linux/version.h /lib/modules/4.9.0-1.el7.x86_64/build/include/linux/version.h
```

再度実行し、無事完了したらGuestAdditionsをアンマウントします

```
sh /mnt/VBoxLinuxAdditions.run
umount /mnt/
```

## 8. udevルールの削除
ネットワークルールの問題でBoxの読み込みに失敗する場合があるのでpersistent-netルールを削除

```
rm /etc/udev/rules.d/70-persistent-net.rules
```

## 9. Boxの軽量化&ログ削除
不要なファイルの削除

```
yum clean all
rm -rf /tmp/*
rm -rf /var/log/*
rm -rf /var/tmp/*
rm -rf /usr/local/src/*
```

仮想ディスクをゼロ埋め&削除

```
dd if=/dev/zero of=/EMPTY bs=1M
rm -f /EMPTY
```

軽量化が終わったらBox化するためにVMをシャットダウン

```
shutdown -h now
```

## 10. Box化
```
vagrant package --base [Box化したいVM名] --output [Box化したときのBox名]
```

## 11. ATALSで公開（おまけ）
1. ATLASアカウントを下記のURLから作成
2. ログイン後、Create a Vagrant BoxからBOX名、説明などを入力してBOXを作成
3. New Box Versionからバージョンと説明を入力してCreate versionを押して最初のバージョンを作成
4. Create new providerを押して、Prioviderにはvirtualboxを選択し、Boxをアップロード

# 参考
- [【CentOS7 Minimal】VirtualBox Guest Additions のインストールでの試行錯誤の記録](http://oki2a24.com/2016/05/05/trial-and-error-to-virtualbox-guest-additions-in-centos7-minimal/)
- [CentOS kernel version up](http://qiita.com/hihihiroro/items/5759b4ce98a226e6c25b)
- [CentOS7.0をvagrant用にbox化するメモ](http://hao03.github.io/blog/2014/07/12/CentOS7-vagrant/)