docker swarmモードで動かしてみた

manager : workerや他のmanagerに指示を出す。managerでもコンテナ動きます。
worker : managerからの指示でコンテナを動かす。


## managerを準備

1台のみで`docker swarm init`をする。

```rb:init
$ docker swarm init
Swarm initialized: current node (xxxxxxxxxxxxxxxxxxxxxxxxx) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join \
    --token xxxxxx-1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxx \
    64.111.111.111:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
```

ここで表示された`docker swarm join`コマンドを残りのホストで実行する。

```sh:上記メッセージは以下コマンドでも確認ができる
docker swarm join-token manager
docker swarm join-token worker
```

## workerに参加

小規模なら全台managerでいい気がする

```sh:成功時メッセージ
This node joined a swarm as a worker.
```

## ノード一覧表示

```rb:managerで実行
$ docker node ls
ID                           HOSTNAME               STATUS  AVAILABILITY  MANAGER STATUS
0mownxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
0uhp7xxxxxxxxxxxxxxxxxxxx *  localhost.localdomain  Ready   Active        Leader
1rj06xxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
375qoxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
68uiwxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
7t2r6xxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
86e67xxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
8rpajxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
aiyk8xxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
as4kpxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
b6aoxxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
dd58lxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active 
```

workerで実行すると以下エラー

```rb:workerで実行した場合
$ docker node ls
Error response from daemon: This node is not a swarm manager. Worker nodes can't be used to view or modify cluster state. Please run this command on a manager node or promote the current node to a manager.
```

## workerを辞める

```sh:workerで実行
docker swarm leave
```

## manager に参加

`docker swarm manager join-token`のコマンドを実行

```rb:managerに参加
docker swarm join \
 --token xxxxxx-1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxx \
 64.111.111.111:2377
```

## ノード一覧表示

```rb
$ docker node ls
ID                           HOSTNAME               STATUS  AVAILABILITY  MANAGER STATUS
0mowxxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Down    Active        
0uhpxxxxxxxxxxxxxxxxxxxxx *  localhost.localdomain  Ready   Active        Leader
1rj0xxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
375qxxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
3hv0xxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        Reachable
68uixxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
7t2rxxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
86e6xxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
8rpaxxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
aiykxxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
as4kxxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Down    Active        
b6aoxxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        
bakqxxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active        Reachable
dd58xxxxxxxxxxxxxxxxxxxxx    localhost.localdomain  Ready   Active
```


## サービス立ち上げ

* 画面確認方法はswarmクラスタのいずれかのホストのIPアドレスを指定。
    * コンテナが立ち上がっていないクラスタでも代理応答してくれる。

```sh:1台nginx立ち上げ
docker service create --replicas 1 \
 --name web \
 -p 80:80 nginx
```

```sh:3台に増やす
docker service scale web=3
```

```sh:削除する
docker service rm web
```

### ボリューム指定

* [docker service create | Docker Documentation](https://docs.docker.com/engine/reference/commandline/service_create/#add-bind-mounts-volumes-or-memory-filesystems)

```sh:指定例(通常はvolume指定だと思う)
  --mount type=bind,source=/root/html,destination=/var/www/html \
```


## ダウンしたmanagerを登録削除

ノードが一台Downしてしまいました。

```diff
  # docker node ls
  ID                           HOSTNAME               STATUS  AVAILABILITY  MANAGER STATUS
  0uh...................... *  localhost.localdomain  Ready   Active        Reachable
  2bn......................    localhost.localdomain  Ready   Active        Reachable
+ 3hv......................    localhost.localdomain  Down    Active        Unreachable
  51s......................    localhost.localdomain  Ready   Active        Reachable
  8f8......................    localhost.localdomain  Ready   Active        Reachable
  af7......................    localhost.localdomain  Ready   Active        Reachable
  agu......................    localhost.localdomain  Ready   Active        Reachable
  bak......................    localhost.localdomain  Ready   Active        Leader
```

```sh:削除できない
# docker node rm 3hv......................
Error response from daemon: rpc error: code = 9 desc = node 3hv...................... is a cluster manager and is a member of the raft cluster.
It must be demoted to worker before removal
```

```sh:managerからworkerに変更
# docker node demote 3hv0i1fho5wf8bpyh594z4z56
Manager 3hv0i1fho5wf8bpyh594z4z56 demoted in the swarm.
```

```sh:MANAGERではなくなった
  # docker node ls
  ID                           HOSTNAME               STATUS  AVAILABILITY  MANAGER STATUS
  0uh...................... *  localhost.localdomain  Ready   Active        Reachable
  2bn......................    localhost.localdomain  Ready   Active        Reachable
+ 3hv......................    localhost.localdomain  Down    Active        
  51s......................    localhost.localdomain  Ready   Active        Reachable
  8f8......................    localhost.localdomain  Ready   Active        Reachable
  af7......................    localhost.localdomain  Ready   Active        Reachable
  agu......................    localhost.localdomain  Ready   Active        Reachable
  bak......................    localhost.localdomain  Ready   Active        Leader
```

```rb:登録削除
# docker node rm 3hv......................
3hv......................
```

----

## 利用ケース

* フロントエンドをHAproxyにしてバックエンドをswarmクラスタにする
* swarmクラスタを動かすホストをAmazon,googleのようにマルチクラウドベンダーに分ける