LoginSignup
3
2

More than 5 years have passed since last update.

Docker swarmモードを試してみた

Last updated at Posted at 2016-12-08

最初に

ホントはRaft Distributed Consensus Alrogithm/Protocolを使っているようなのでマネージャーが3台より多くあると障害にも強いクラスタになるようですが今回はそんなこと考えないです。

気になった方はetcd総選挙を眺めてみるを読むと良いかもしれないです。(すごい参考になりました)

この辺めっちゃ参考にしてます。
https://docs.docker.com/engine/swarm/

実行環境

node 役割
node-01 worker兼マネージャー
node-02 worker

ターミナル1はnode-01のコマンド実行用にする

ターミナル1
$ docker-machine create -d virtualbox node-01
$ eval $(docker-machine env node-01)

ターミナル2はnode-02のコマンド実行用にする

ターミナル2
$ docker-machine create -d virtualbox node-02
$ eval $(docker-machine env node-02)

初期化

まずはマネージャーの初期化

ターミナル1
$ docker swarm init --advertise-addr $(docker-machine ip node-01)
Swarm initialized: current node (61p7kfvmw4m4nbfz3vodgc2y6) is now a manager.

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

    docker swarm join \
    --token SWMTKN-1-0ue65cw4x1k6j2hys2n6hgzpqy0ckv8du7v88e6drkoylh1snm-d7uhyzmofmli2mxa9n93jwepd \
    192.168.99.100:2377

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

上記を実行するとworkerを参加させるためのtoken付きのコマンドが発行される
このコマンドをworkerにしようと思っているnode-02で実行するとクラスタに参加できる

参加する前に現状のクラスタの状態を確認しておく

ターミナル1
$ docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
61p7kfvmw4m4nbfz3vodgc2y6 *  node-01   Ready   Active        Leader

tokenの確認は下記のコマンドでもできる

ターミナル1
$ docker swarm join-token worker
To add a worker to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-0ue65cw4x1k6j2hys2n6hgzpqy0ckv8du7v88e6drkoylh1snm-d7uhyzmofmli2mxa9n93jwepd \
    192.168.99.100:2377

マネージャーとしてクラスタに参加させたい場合は docker swarm join-token manager を実行するとマネージャーとして参加させるためのtokenが見れる

node-02をworkerとして参加させて見る

ターミナル2
$ docker swarm join \
--token SWMTKN-1-0ue65cw4x1k6j2hys2n6hgzpqy0ckv8du7v88e6drkoylh1snm-d7uhyzmofmli2mxa9n93jwepd \
192.168.99.100:2377

This node joined a swarm as a worker.

クラスタの状態を確認する

ターミナル1
$ docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
61p7kfvmw4m4nbfz3vodgc2y6 *  node-01   Ready   Active        Leader
cu9p6rego36d4hhtn2653bacj    node-02   Ready   Active

ちなみにworker側で状態の確認などはできない

ターミナル2
$ 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.

サービスの作成

redisサービスを生成する
(TODO: redisのクラスタが生成できるかもしれないが調査できていないためreplicasは1にしている)

ターミナル1
$docker service create --replicas 1 --name redis -p 6379:6379 redis:3.2.0-alpine
7vurzloshshm2wn5vezxuexku

サービスの確認を連打していたらREPLICASが1/1になるのが確認できる

ターミナル1
$ docker service ls
ID            NAME   REPLICAS  IMAGE               COMMAND
ac3iz5deljd1  redis  0/1       redis:3.2.0-alpine
$ docker service ls
ID            NAME   REPLICAS  IMAGE               COMMAND
ac3iz5deljd1  redis  1/1       redis:3.2.0-alpine
ターミナル1
$ docker service ps redis
ID                         NAME     IMAGE               NODE     DESIRED STATE  CURRENT STATE            ERROR
25g7igyki966vlljtv9lktywx  redis.1  redis:3.2.0-alpine  node-01  Running        Preparing 7 seconds ago

実際にどちらのnodeからでも接続できるか確認する
ついでにnode-01でfooにbarをセットしてnode-02で確認できるかも見ておく

ターミナル1
$ redis-cli -h $(docker-machine ip node-01)
192.168.99.100:6379> set foo bar
OK
192.168.99.100:6379> get foo
"bar"
192.168.99.100:6379> exit

$ redis-cli -h $(docker-machine ip node-02)
192.168.99.101:6379> get foo
"bar"
192.168.99.101:6379> exit

サービスのスケールアップ・スケールダウン、そして自動復旧について

redisのコンテナ数を2つに増やすには下記のscaleコマンドを実行します

ターミナル1
$ docker service scale redis=2
redis scaled to 2

$ docker service ps redis
ID                         NAME     IMAGE               NODE     DESIRED STATE  CURRENT STATE                   ERROR
25g7igyki966vlljtv9lktywx  redis.1  redis:3.2.0-alpine  node-01  Running        Running 27 minutes ago
73f8jbhknsqu2xo4czq3ng7r0  redis.2  redis:3.2.0-alpine  node-02  Running        Running less than a second ago

$ docker service ls
ID            NAME   REPLICAS  IMAGE               COMMAND
ac3iz5deljd1  redis  2/2       redis:3.2.0-alpine

上記のようにかんたんにスケールアップできますが、自動的に負荷分散されるのでredis等の場合にはコンテナ側でクラスタ化しないと値のセットして参照したら見れないことになる可能性があるので1つに戻しておきます。

ターミナル1
$ docker service scale redis=1
redis scaled to 1

$ docker service ps redis
ID                         NAME     IMAGE               NODE     DESIRED STATE  CURRENT STATE           ERROR
25g7igyki966vlljtv9lktywx  redis.1  redis:3.2.0-alpine  node-01  Running        Running 32 minutes ago
73f8jbhknsqu2xo4czq3ng7r0  redis.2  redis:3.2.0-alpine  node-02  Shutdown       Shutdown 3 seconds ago

$ docker service ls
ID            NAME   REPLICAS  IMAGE               COMMAND
ac3iz5deljd1  redis  1/1       redis:3.2.0-alpine

上のreplicasの数を減らした場合コンテナは削除されずただストップする形になるので何度も試してるとゴミが残ることになります。

ターミナル2
$ docker ps -a
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS                          PORTS               NAMES
a18235283c81        redis:3.2.0-alpine   "docker-entrypoint.sh"   6 minutes ago       Exited (0) About a minute ago                       redis.2.73f8jbhknsqu2xo4czq3ng7r0

そして消されるコンテナは古い順ではなくNAMEに書かれてる数値が大きいものから削除されるようです(要検証)

20ぐらいまで増やして1つに絞ってみたらredis.13が生き残ったったのでランダムっぽいです

dcjg438wipqsw6lsi0vw67f5a  redis.11     redis:3.2.0-alpine  node-01  Shutdown       Shutdown about a minute ago
09a4j1fwxb91tkqioz4bti3sz  redis.12     redis:3.2.0-alpine  node-01  Shutdown       Shutdown 3 seconds ago
064hpn2v6jwpy0p8kbpryzwn7  redis.13     redis:3.2.0-alpine  node-01  Running        Running 3 minutes ago
8lu1d4qwtyb1wz050fjccnbtm  redis.14     redis:3.2.0-alpine  node-01  Shutdown       Shutdown about a minute ago
c9740i08ndi7dte16wsri9ev0  redis.15     redis:3.2.0-alpine  node-01  Shutdown       Shutdown about a minute ago
099mt2ha487pafhufc37hiutv  redis.16     redis:3.2.0-alpine  node-02  Shutdown       Shutdown 3 seconds ago

docker stop等によってコンテナが眠ってしまった場合自動的にreplicasの数になるように実行されます。
↑この機能を利用していい感じにコンテナの差し替えができるのでは無いかと思ったりもしている

ローリング・アップデート

下記の設定をするだけでローリングアップデートできます。

  --update-delay
  --update-parallelism

5秒待ち1コンテナずつ更新かける場合は下記のコマンドになる。

ターミナル1
$ docker service update --update-delay 5s --update-parallelism 1 --image redis:3.2.5-alpine redis
redis

scaleをとりあえず20にして試した結果

840x553ujrfghnbqhqi9s0zx5  redis.7       redis:3.2.5-alpine  node-02  Running        Running 55 seconds ago
3qoj8jpmcfj1ji20aa2hgx1by   \_ redis.7   redis:3.2.0-alpine  node-01  Shutdown       Shutdown 58 seconds ago
844vrpbzjs29q9kua2b3n9r3p   \_ redis.7   redis:3.2.0-alpine  node-01  Shutdown       Shutdown 17 minutes ago
db6k0he84jv9xp0az3r8sqd4z  redis.8       redis:3.2.0-alpine  node-01  Running        Running 3 minutes ago
31ict01zi3l0spo05a4gjixwi   \_ redis.8   redis:3.2.0-alpine  node-01  Shutdown       Shutdown 16 minutes ago
bssq36i1fq20e5a2a629n83bz  redis.9       redis:3.2.0-alpine  node-01  Running        Running 3 minutes ago
e7sea97hqpd5d1pjaugxb33pv   \_ redis.9   redis:3.2.0-alpine  node-02  Shutdown       Shutdown 17 minutes ago
52e7l8s5ossbq6nndbwfrbxxq  redis.10      redis:3.2.5-alpine  node-02  Running        Running 6 seconds ago
8jozd1yew7vou0g8x458t0t9e   \_ redis.10  redis:3.2.0-alpine  node-01  Shutdown       Shutdown 9 seconds ago
21hlsx81oruek4p8de0ujztxb   \_ redis.10  redis:3.2.0-alpine  node-01  Shutdown       Shutdown 16 minutes ago
03mtra8s2zw2tomwgqsqz4sxa  redis.11      redis:3.2.5-alpine  node-02  Running        Running 25 seconds ago

サービス削除

すごいサービス消したら紐付いてたコンテナ全部消してくれる!

ターミナル1
$ docker service rm nginx
nginx
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
ターミナル2
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

まとめ

すげえ

まとめパート2

バックエンドにetcd等を用意しなくて良くなったswarmって感想。
ただファイルでnodeの管理ができないのでつらいかもしれないですが、一度構築したら必要ないので問題無い気がします。

Nginxとかscaleし易いやつで試せって話でした。試そうと思ったときに適当にdockerhubから選んだ僕があれでした。

 おまけ

REPLICASの話をつらつらと書きましたが実はgrobalモードがあります。(やる気が出たら記事に追記なりします)
気になった方は調べてみてください。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2