Play with DockerでSwarmクラスターことはじめ

f:id:y-ohgi:20181124020706p:plain:w200

TL;DR

Play with Docker

ブラウザ上でDockerを試せるサイト
特徴としては以下

  • 複数台インスタンスを建てれる
  • 起動した環境は4時間しか使えない
  • 使用するためにはDockerHubのIDが必要

Swarm

Dockerオーケストレーションツールの1つ。
Docker公式のツールで、dockerデーモンに最初から搭載されている。
また、同様にdockerデーモンに搭載されているdocker-composeと相性が良い*1

Kubernetesと比較して シンプルかつセキュリティ面に優れている

Swarmのコンポーネント

Swarmで登場する各コンポーネントについて

name note
ノード Swarmクラスタに参加するインスタンスを指す。
マネージャ クラスタの管理を行うノードを指す。k8sでいうコントロールプレーン
ワーカー リソースプールを提供するノードを指す。ワーカーノード
Task コンテナのことをTaskと呼ぶ。1コンテナ1Taskで、サイドカーはTaskで実現できない模様。
Service 起動するTaskと起動数を定義し、その維持を行う。冗長化とかセルフヒーリングを司る。
スケジューラ どのTaskをどのインスタンスへ配置するかを決定する
Raftコンセンサス 分散アルゴリズムの1つ。Swarm上での意思決定はこのアルゴリズムが用いられ、その特性上マネージャは奇数インスタンス必要。

Play with DockerでSwarmを試す

1. サイトへアクセス

https://labs.play-with-docker.com を立ち上げ、ログインする。
DockerHub IDが必要。

f:id:y-ohgi:20181124023407p:plain

2. インスタンスの起動

起動すると↓な画面が表示され、4時間のカウントダウンが始まる。
さっさと"Add Instance" でインスタンスを増やす。

f:id:y-ohgi:20181124023520p:plain

インスタンスを追加するとコンソールとその他メタデータが表示される

f:id:y-ohgi:20181124023547p:plain

3. Swarmの初期化

$ docker swarm init --advertise-addr eth0 でSwarmの初期化を実行。
ethが2つあるのでとりあえず "eth0" へ所属させる。

f:id:y-ohgi:20181124023901p:plain

initを実行したインスタンスがマネージャになり、このマネージャに他インスタンスをワーカーとして所属させるための $ docker swarm join コマンドが出力される。
どうせ使い捨ての環境なのでトークンとかはマスクしない。GUIをグイグイして画像編集するのはめんどい。

4. ワーカーの作成

クラスター構成にしたいので2台目のインスタンスを作成する。
"Add Instance"で2台目のインスタンスを作成し、作成したインスタンスで先程取得した $ docker swarm join ... を打ってマネージャに所属させる。

f:id:y-ohgi:20181124024414p:plain

マネージャで $ docker node ls を打ち、2台のノードが存在することを確認

f:id:y-ohgi:20181124024757p:plain

5. Serviceの作成

試しにnginxを立ててみる。

"myapp" という名前で "tcp/8080" を開放する "nginx"を作成。
$ docker service create --name myapp --publish 8080:80 nginx

f:id:y-ohgi:20181124025452p:plain

無事Serviceが起動できるとIPの横に "8080" というリンクが現れ、リンクを踏むことでブラウザ上から動作確認ができる。便利。

f:id:y-ohgi:20181124025650p:plain

6. Serviceの冗長化

クラスタ構成にしたのでワーカーを跨ってServiceを配置するよう冗長構築にしてみる
$ docker service update myapp --replicas 4

実行後に $ docker service ps myapp を実行し、複数のノードにTaskが冗長化されていることを確認。

f:id:y-ohgi:20181124025818p:plain

7. ログの確認

ちゃんと負荷分散されているかログを確認する

$ docker service logs -f myapp

f:id:y-ohgi:20181124030418p:plain

別々のノードにトラフィックが割り振られていることが確認できた。

所感

触ろう触ろうと思ってたSwarmをやっと触った。
ブラウザからクラスタを試せるのは素直に凄い

雑な感想として、本番で使うかと言われたら「KubernetesかECS使う」って答えるだろうなーと。
AWSであればECSが相性良すぎて一択だと思っているのと、他の環境であればKubernetesの方が自由度が高い*2なと。
あとそもそもオートスケーリングの機構がないので、わざわざ「クラウドな本番環境」で使用する選択肢があまり思い浮かばなかった(クラウド好き並感)。

*1:ローカルで構築した環境をそのまま本番へ反応可能

*2:というかSwarmの自由度が低い