【DockerSwarm】30分でDockerクラスターを構築してみる

# なにこれ
ChefSoloでDockerホストをガンガン立てて、DockerSwarmでクラスタリングして
一つのリソースプールにするお話し。趣味で使う数値計算の分散基盤に使う予定。
※chef-soloを使っていますが、今のご時世、chef-localmodeを使うことを推奨します。
参考： https://blog.isao.co.jp/graduated_from_chef-solo/

※Dockerがセットアップできれば、Ansibleでもなんでも大丈夫です。

# 注意
- 決してProduction環境等では使わないでください(セキュリティ対策無しです)

# 前提条件
- わりと真っ白なところから。
- 1台1台手塩をかけてプロビジョニングしたくないのでchef soloを利用する。
- DockerSwarmによるコンテナオーケストレーションを実施
- オーケストレーション部分は手動で行う（後日、レシピ追加でこれも自動化予定)

# 筆者のホスト環境
- 作業用 (192.168.33.10) ubuntu 14.04 Cpus:2 RAM:2GB
- master (192.168.33.11) ubuntu 14.04 Cpus:2 RAM:2GB
- sub-1 (192.168.33.12) ubuntu 14.04 Cpus:2 RAM:2GB
- sub-2 (192.168.33.13) ubuntu 14.04 Cpus:2 RAM:2GB
- sub-3 (192.168.33.14) ubuntu 14.04 Cpus:2 RAM:2GB

# 手順

## ホスト群へのDockerのインストール
この章での作業は、作業用マシンでお願いします。

### 準備
```bash

# gitいれる。rbenvのために
$ sudo apt-get install -y git
$ sudo apt-get install -y libssl-dev libreadline-dev zlib1g-dev

# 新しめのrubyいれとく
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
$ rbenv install 2.3.3
$ rbenv global 2.3.3
$ rbenv rehash

# knife-soloをいれる
$ curl -L https://www.opscode.com/chef/install.sh | sudo bash
$ gem install knife-solo
$ gem i berkshelf --no-ri --no-rdoc

# 作業用chefリポ作成
$ knife solo init chef-repo
$ cd chef-repo
```

### レシピを落としてくる
Dockerをインストールするためのレシピをネットから落としてきます。

```bash
$ vi Berksfile
site :opscode
cookbook 'docker', '~> 2.13.0'
$ berks vendor cookbooks
```

### Dockerインストールするレシピを書く
※ボキャ貧すぎてhelloにしてしまいましたが、お好きな名前をどうぞ

```bash
$ mkdir -p site-cookbooks/hello
$ mkdir -p site-cookbooks/hello/recipes
$ vi site-cookbooks/hello/README.md
これはDockerをインストールするためのレシピです。
```

```bash
$ vi site-cookbooks/hello/metadata.rb
name             'hello'
maintainer       'YOUR_COMPANY_NAME'
maintainer_email 'YOUR_EMAIL'
license          'All rights reserved'
description      'Setup Docker'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version          '0.1.0'
depends          'docker', '~> 2.0'
```

```bash
$ vi site-cookbooks/hello/recipes/default.rb
execute "apt-get-update" do
  command "apt-get update --fix-missing"
  ignore_failure true
end
docker_service 'default' do
  # 0.0.0.0:2376でDockerAPIをEXPOSEしちゃう
  host ["tcp://0.0.0.0:2376", 'unix:///var/run/docker.sock']
  action [:create, :start]
end
# ユーザー名に合わせて編集してください。
execute "set user permission" do
  command "usermod -aG docker vagrant"
end

```

### 対象ホスト達にBootstrapを仕込む
SSHの公開鍵の設定はご自身の環境に合わせてください。やっている事としては、以下の2点です。

- 公開鍵を対象ホスト群へコピーして、鍵でログインできるようにしておく
- chef-soloを対象ホストにインストール

```
$ ssh-copy-id -i ~/.ssh/id_rsa.pub vagrant@192.168.33.11
$ ssh-copy-id -i ~/.ssh/id_rsa.pub vagrant@192.168.33.12
$ ssh-copy-id -i ~/.ssh/id_rsa.pub vagrant@192.168.33.13
$ ssh-copy-id -i ~/.ssh/id_rsa.pub vagrant@192.168.33.14

$ knife solo prepare -i ~/.ssh/id_rsa vagrant@192.168.33.11
$ knife solo prepare -i ~/.ssh/id_rsa vagrant@192.168.33.12
$ knife solo prepare -i ~/.ssh/id_rsa vagrant@192.168.33.13
$ knife solo prepare -i ~/.ssh/id_rsa vagrant@192.168.33.14
```

### 対象ホスト群のrun_listにレシピ追加
つくったレシピが実行されるように全ホストのrun_listにレシピを追加してください
実は、knifeコマンドでうまくやれるがここでは人力で。

```bash
$ vi nodes/192.168.33.11.json
{
  "run_list": [
    "recipe[hello]"
  ],
  "automatic": {
    "ipaddress": "192.168.33.11"
  }
}
```

### 対象ホスト群にDockerインストール実施
たまにコケることがあるので、そのときはリトライしてください。

```bash
$ knife solo cook -i ~/.ssh/id_rsa vagrant@192.168.33.11
$ knife solo cook -i ~/.ssh/id_rsa vagrant@192.168.33.12
$ knife solo cook -i ~/.ssh/id_rsa vagrant@192.168.33.13
$ knife solo cook -i ~/.ssh/id_rsa vagrant@192.168.33.14
```

### 

## オーケストレーション設定と確認
今回構築したDockerホストは、DockerAPI用のポートを外部にEXPOSEしている為、
基本的には外部から作業が可能です。
(ただ、作業マシンにはDockerが入っていて、対象ホスト群と同じネットワーク上にある必要性があります)

### Token生成
ここで生成したトークンは、今後使うのでメモっておいてください。

```bash

vagrant@master:~$ docker -H 192.168.33.11:2376 run --rm swarm create                      
Unable to find image 'swarm:latest' locally latest: Pulling from library/swarm                     
220609e0bc51: Pull complete                     
b54bf338fe2f: Pull complete                     
d53aac5750d5: Pull completeDigest: sha256:c9e1b4d4e399946c0542accf30f9a73500d6b0b075e152ed1c792214d3509d70                 
Status: Downloaded newer image for swarm:latest
d3c063f108135XXXXXXXXXXXXXXXXXXX

```
### スレーブのJOIN

```bash
vagrant@master:~$ docker -H 192.168.33.12:2376 run -d swarm join --addr=192.168.33.12:2376 token://d3c063f108135XXXXXXXXXXXXXXXXXXX
vagrant@master:~$ docker -H 192.168.33.13:2376 run -d swarm join --addr=192.168.33.13:2376 token://d3c063f108135XXXXXXXXXXXXXXXXXXX
vagrant@master:~$ docker -H 192.168.33.14:2376 run -d swarm join --addr=192.168.33.14:2376 token://d3c063f108135XXXXXXXXXXXXXXXXXXX
```

### マネージャーを立ち上げる

```bash
vagrant@master:~$ docker -H 192.168.33.11:2376 run -d -p 12375:2375 swarm manage token://d3c063f108135XXXXXXXXXXXXXXXXXXX
```

### ホスト一覧の確認
JOINしたホストのIPとポート番号が列挙されていれば問題ありません。

```bash
vagrant@master:~$ docker -H 192.168.33.11:2376 run --rm swarm list token://d3c063f108135XXXXXXXXXXXXXXXXXXX
192.168.33.14:2375
192.168.33.13:2375
192.168.33.12:2375
```

### 各Dockerホストの状態
各ホストにpsコマンド投げた感じ。
これらのSwarm管理用のコンテナは削除しないようにしてください。くれぐれも

```bash

vagrant@master:~$ docker -H 192.168.33.11:2376 ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
588ddd969e5a        swarm               "/swarm manage token:"   40 minutes ago      Up 40 minutes       0.0.0.0:12375->2375/tcp   nauseous_hawking
vagrant@master:~$ docker -H 192.168.33.12:2376 ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
f53fd4fc19e3        swarm               "/swarm join --addr=1"   44 minutes ago      Up 44 minutes       2375/tcp            pensive_golick
vagrant@master:~$ docker -H 192.168.33.13:2376 ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
dfae3a02e6a2        swarm               "/swarm join --addr=1"   43 minutes ago      Up 43 minutes       2375/tcp            nostalgic_spence
vagrant@master:~$ docker -H 192.168.33.14:2376 ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
d511dd6b6d17        swarm               "/swarm join --addr=1"   42 minutes ago      Up 42 minutes       2375/tcp            cocky_wozniak
```

### Swarm Manegerにつないでみる
ちゃんとクラスタとして認識されていると思います。
CPU2コア　RAM2GMのマシンを3台束ねているので、合計6CPU RAM6GBに
なっていることも確認できます。いったん、ここまででゴール。

```bash

vagrant@master:~$ docker -H 192.168.33.11:12375 info                                                                                                                                               
Containers: 3                                                                                                                                                                                      
 Running: 3                                                                                                                                                                                        
 Paused: 0                                                                                                                                                                                         
 Stopped: 0                                                                                                                                                                                        
Images: 3                                                                                                                                                                                          
Server Version: swarm/1.2.5                                                                                                                                                                        
Role: primary                                                                                                                                                                                      
Strategy: spread                                                                                                                                                                                   
Filters: health, port, containerslots, dependency, affinity, constraint                                                                                                                            
Nodes: 3                                                                                                                                                                                           
 slave-1: 192.168.33.12:2376                                                                                                                                                                       
  └ ID: EEZI:UKFK:G2F2:SNWF:C3R6:2NWN:PBJV:XO5R:XB34:I5TL:MMNE:ETXN                                                                                                                               
  └ Status: Healthy                                                                                                                                                                               
  └ Containers: 1 (1 Running, 0 Paused, 0 Stopped)                                                                                                                                                
  └ Reserved CPUs: 0 / 2                                                                                                                                                                          
  └ Reserved Memory: 0 B / 2.053 GiB                                                                                                                                                              
  └ Labels: kernelversion=3.13.0-103-generic, operatingsystem=Ubuntu 14.04.5 LTS, storagedriver=aufs                                                                                              
  └ UpdatedAt: 2016-12-06T15:13:17Z                                                                                                                                                               
  └ ServerVersion: 1.12.3                                                                                                                                                                         
 slave-2: 192.168.33.13:2376                                                                                                                                                                       
  └ ID: O53J:5CP5:D2SL:JR3G:B7KG:E2B6:OWEF:WY36:NWPQ:25FZ:6PVT:DQOW                                                                                                                               
  └ Status: Healthy                                                                                                                                                                               
  └ Containers: 1 (1 Running, 0 Paused, 0 Stopped)                                                                                                                                                
  └ Reserved CPUs: 0 / 2                                                                                                                                                                          
  └ Reserved Memory: 0 B / 2.053 GiB                                                                                                                                                              
  └ Labels: kernelversion=3.13.0-103-generic, operatingsystem=Ubuntu 14.04.5 LTS, storagedriver=aufs                                                                                              
  └ UpdatedAt: 2016-12-06T15:13:18Z                                                                                                                                                               
  └ ServerVersion: 1.12.3                                                                                                                                                                         
 slave-3: 192.168.33.14:2376                                                                                                                                                                       
  └ ID: IB4U:UUJB:RCTB:R7NZ:LBYR:3ZB2:WOR6:2IPA:MLYM:IAMA:T45L:FKGZ                                                                                                                               
  └ Status: Healthy                                                                                                                                                                               
  └ Containers: 1 (1 Running, 0 Paused, 0 Stopped)                                                                                                                                                
  └ Reserved CPUs: 0 / 2                                                                                                                                                                          
  └ Reserved Memory: 0 B / 2.053 GiB                                                                                                                                                              
  └ Labels: kernelversion=3.13.0-103-generic, operatingsystem=Ubuntu 14.04.5 LTS, storagedriver=aufs                                                                                              
  └ UpdatedAt: 2016-12-06T15:14:01Z                                                                                                                                                               
  └ ServerVersion: 1.12.3
Plugins:                                                                                                                                                                                           
 Volume:                                                                                                                                                                                           
 Network:                                                                                                                                                                                          
Swarm:                                                                                                                                                                                             
 NodeID:                                                                                                                                                                                           
 Is Manager: false                                                                                                                                                                                 
 Node Address:                                                                                                                                                                                     
Security Options:                                                                                                                                                                                  
Kernel Version: 3.13.0-103-generic                                                                                                                                                                 
Operating System: linux                                                                                                                                                                            
Architecture: amd64                                                                                                                                                                                
CPUs: 6                                                                                                                                                                                            
Total Memory: 6.158 GiB                                                                                                                                                                            
Name: f8e6c11a239c                                                                                                                                                                                 
Docker Root Dir:                                                                                                                                                                                   
Debug Mode (client): false                                                                                                                                                                         
Debug Mode (server): false                                                                                                                                                                         
WARNING: No kernel memory limit support
```