ISUCON8予選問題の環境構築

#はじめに
[ISUCON8予選問題をやってみた](https://qiita.com/s_suzaku/items/c2ca2dd7ba217971efd5)ので、環境構築の手順メモ

公式情報

- [予選レギュレーション](http://isucon.net/archives/52445389.html)
- [予選マニュアル](https://github.com/isucon/isucon8-qualify/blob/master/doc/MANUAL.md)
- [コード群](https://github.com/isucon/isucon8-qualify)
- [解説と講評](http://isucon.net/archives/52520045.html)
- [関連エントリまとめ](http://isucon.net/archives/52459762.html)

#前提
・Vagrant, Virtual Box を使ってローカルマシン上にVM(CentOS7)を作成する
・Vagrant, Virtual Box はローカルマシンにインストール済み


# VM構築手順

## VagrantでVM構築

1. CentOS7のBoxファイルをadd

    ``` 
    $ vagrant box add centos/7 
    ```

2. 作業用ディレクトリへ移動

    ```
    $ cd ~/work/isucon8/
    ```
3. Vagrantの初期化（Vagrant ファイルの作成）

    ```
    $ vagrant init
    ```

4. Vagrantfileを以下のように編集   ※IPアドレスやポートは使いたいものを指定してください

    ```
$ vi Vagrantfile
Vagrant.configure("2") do |config|

	config.vm.provider "virtualbox" do |vb|
		vb.cpus = 2
		vb.memory = "1024"                 
	end 

	config.vm.define "webapp1" do |webapp|
		webapp.vm.box = "centos/7"
		webapp.vm.hostname = "webapp1"
		webapp.vm.network :private_network, ip: "192.168.100.1", virtualbox__intnet: "dmz"
		webapp.vm.network :forwarded_port, guest: 22, host: 10221
		webapp.vm.network :forwarded_port, guest: 80, host: 10801
		webapp.vm.network :forwarded_port, guest: 8080, host: 18081
	end

	config.vm.define "webapp2" do |webapp|
		webapp.vm.box = "centos/7"
		webapp.vm.hostname = "webapp2"
		webapp.vm.network :private_network, ip: "192.168.100.2", virtualbox__intnet: "dmz"
		webapp.vm.network :forwarded_port, guest: 22, host: 10222
		webapp.vm.network :forwarded_port, guest: 80, host: 10802
		webapp.vm.network :forwarded_port, guest: 8080, host: 18082
	end

	config.vm.define "webapp3" do |webapp|
		webapp.vm.box = "centos/7"
		webapp.vm.hostname = "webapp3"
		webapp.vm.network :private_network, ip: "192.168.100.3", virtualbox__intnet: "dmz"
		webapp.vm.network :forwarded_port, guest: 22, host: 10223
		webapp.vm.network :forwarded_port, guest: 80, host: 10803
		webapp.vm.network :forwarded_port, guest: 8080, host: 18083
	end

	config.vm.define "bench" do |bench|
		bench.vm.box = "centos/7"
		bench.vm.hostname = "bench"
		bench.vm.network :private_network, ip: "192.168.100.4", virtualbox__intnet: "dmz"
		bench.vm.network :forwarded_port, guest: 22, host: 10224
		bench.vm.network :forwarded_port, guest: 80, host: 10804
	end
end
    ```

5. 全VM（portal, webapp1, webapp2, webapp3, bench）の起動
　※起動するVMを指定したい場合は`vagrant up VM名`を実行

```
$ vagrant up
```

　※ ↓のエラーが出たので、以下のコマンドによりVirtual Boxを再起動して、再度VM起動した

```
エラー内容：
VBoxManage: error: VBoxNetAdpCtl: Error while adding new interface: failed to open /dev/vboxnetctl: No such file or directory
```

```
Virtual Box再起動コマンド：
$ sudo /Library/Application\ Support/VirtualBox/LaunchDaemons/VirtualBoxStartup.sh restart
```

## ansibleでデプロイ
[公式ソースコードのREADME](https://github.com/isucon/isucon8-qualify/tree/master/provisioning)を参照
※bench（ベンチマーク用VM）をansibleコントローラとしてます

#### 事前準備 

0. benchから各VMに鍵でSSHログインできるように設定

1. benchの~/.ssh/configの設定

    ```
    [vagrant@bench ~]$ vi ~/.ssh/config
    Host webapp1
    	HostName webapp1
    	User vagrant
    	Port 22
	IdentityFile SSHの秘密鍵
    Host webapp2
    	HostName webapp2
    	User vagrant
    	Port 22
	IdentityFile SSHの秘密鍵
    Host webapp3
    	HostName webapp3
    	User vagrant
    	Port 22
	IdentityFile SSHの秘密鍵
    Host bench
    	HostName bench
    	User vagrant
    	Port 22
	IdentityFile SSHの秘密鍵
    [vagrant@bench ~]$ chmod 600 ~/.ssh/config 
    [vagrant@bench ~]$ cat /etc/hosts    
    192.168.100.1   webapp1
    192.168.100.2   webapp2
    192.168.100.3   webapp3
    192.168.100.4   bench
    ```

1. benchから各VMへSSHできることを確認
1. 必要なパッケージをインストール

    ```
    [vagrant@bench ~]$ sudo yum install -y ansible git wget go patch gcc
    ```

1. xbuildにより言語をインストール

    ```
    [vagrant@bench ~]$ git clone https://github.com/tagomoris/xbuild.git
    [vagrant@bench ~]$ mkdir local
    [vagrant@bench ~]$ xbuild/go-install     1.10.3  $HOME/local/go
    [vagrant@bench ~]$ export PATH=$HOME/local/go/bin:$HOME/go/bin:$PATH
    [vagrant@bench ~]$ xbuild/perl-install   5.28.0  $HOME/local/perl
    [vagrant@bench ~]$ echo 'export PATH=$HOME/local/go/bin:$HOME/go/bin:$PATH' >> ~/.bash_profile 
    ※perl以外はここでは省略
    ```

1. ソースコードを取得

    ```
    [vagrant@bench ~]$ git clone https://github.com/isucon/isucon8-qualify
    [vagrant@bench ~]$ ls
    isucon8-qualify  local  xbuild
    [vagrant@bench ~]$ cd isucon8-qualify/
    [vagrant@bench isucon8-qualify]$ go get -v github.com/constabulary/gb/...
    [vagrant@bench isucon8-qualify]$ cd provisioning/
    ```

1. プロビジョニング
    ansibleのinventryファイルを修正
      ※ここではwebapp1,2,3,にportal,webappの両方をデプロイ

    ```
    [vagrant@bench provisioning]$ cat development 
    [portal_web]
    # ポータルをデプロイするサーバ
    webapp1
    webapp2
    webapp3
    
    [portal_web:vars]
    ansible_ssh_user=vagrant
    ansible_ssh_port=22
    
    [bench]
    # ベンチマーカをデプロイするサーバ
    bench
    
    [bench:vars]
    ansible_ssh_user=vagrant
    ansible_ssh_port=22
    
    [webapp1]
    # 競技用webappをデプロイするサーバ(1)
    webapp1
    webapp2
    webapp3
    
    [webapp1:vars]
    ansible_ssh_user=vagrant
    ansible_ssh_port=22
    ```

1. ansible playbookを実行
    ※webappに対する言語インストールにより数十分かかりました

    ```
    [vagrant@bench provisioning]$ ansible-playbook -i development site.yml
    ```
    
# アクセス確認
http://192.168.100.1 へアクセスすると、webapp1のVMへ接続できる
![torb.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397685/703b9d15-6f12-9e78-e553-d5d1cdbfab50.jpeg)