2016/6/16追記
Docker本体にSwarmKitとの連携機能が追加されてました。
PullRequest:GH-23361
SwarmKit単体で使うというより、DockerCLIとの統合する方向のようですね。
docker CLIに以下のようなコマンドが追加されました。
swarm init
swarm join
swarm leave
swarm update
swarmクラスタノード管理用のコマンドも追加されています。
node_accept
node_reject
node_promote
node_demote
node_inspect
node_update
node_tasks
node_ls
node_rm
swarmクラスタ上でのジョブ実行用コマンドも追加です。
service create
service inspect
service update
service remove
service tasks
最後に、複数サービスから構成されるアプリケーション用にDocker Stacks
機能(コマンド)も追加されていました。
stack
deploy
各コマンドの詳細、ドキュメントはこちらです。
Docker Stacks
についてのドキュメントはこちらです。
参考までにswarm init
とswarm join
のヘルプは以下のようなものとのことです。
swarm init
Usage: docker swarm init [OPTIONS]
Initialize a Swarm.
Options:
--auto-accept value Acceptance policy (default [worker,manager])
--force-new-cluster Force create a new cluster from current state.
--help Print usage
--listen-addr value Listen address (default 0.0.0.0:2377)
--secret string Set secret value needed to accept nodes into cluster
Initialize a Swarm cluster. The docker engine targeted by this command becomes a manager
in the newly created one node Swarm cluster.
swarm join
Usage: docker swarm join [OPTIONS] HOST:PORT
Join a Swarm as a node and/or manager.
Options:
--help Print usage
--listen-addr value Listen address (default 0.0.0.0:2377)
--manager Try joining as a manager.
--secret string Secret for node acceptance
Join a node to a Swarm cluster. If the --manager
flag is specified, the docker engine
targeted by this command becomes a manager
. If it is not specified, it becomes a worker
.
---2016/6/16追記 End---
何気なくDocker社のリポジトリを見てたらSwarmKitなるものがありました。
調べてみたら発表されたばかりみたいであまり資料がありませんでした。
紹介記事(英語)
気になったので早速使ってみることにしました。
SwarmKit is 何?
一言で言うと(分散)マルチホスト環境でのDockerコンテナのオーケストレーションを行ってくれるツールとのことです。
類似のプロダクトとしてはHashicorpのnomadやMesos+Marathonがありますね。
私のつたない英語訳だと誤解を招きそうなので、READMEから引用しておきますので詳細はこちらを参照してください。
SwarmKit is a toolkit for orchestrating distributed systems at any scale. It includes primitives for node discovery, raft-based consensus, task scheduling and more.
Its main benefits are:
- Distributed: SwarmKit uses the Raft Consensus Algorithm in order to coordinate and does not rely on a single point of failure to perform decisions.
- Secure: Node communication and membership within a Swarm are secure out of the box. SwarmKit uses mutual TLS for node authentication, role authorization and transport encryption, automating both certificate issuance and rotation.
- Simple: SwarmKit is operationally simple and minimizes infrastructure dependencies. It does not need an external database to operate.
ConsulやNomadと同じくRaft実装みたいですね。
機能一覧はFeaturesに記載されています。
セットアップ
環境
以下ではMac(OSX)で作業しています。DockerはDocker for Mac(beta)
を利用しています。
それ以外の環境の方は適宜読み替えてください。
セットアップ
SwarmKitのバイナリでの配布は行われていないようでした。
Githubのリポジトリからソースを取得してビルドしました。
# ソース取得
go get -d github.com/docker/swarmkit/...
cd $GOPATH/src/github.com/docker/swarmkit
# 確認
go test $(go list ./... | grep -v vendor)
# ビルド
make binaries
bin
ディレクトリの下に以下のファイルが作成されます。
bin/
├── protoc-gen-gogoswarm
├── swarm-bench
├── swarmctl
└── swarmd
以下ではswarmdとswarmctlにパスが通った状態とします。
swarmクラスタのセットアップ
swarmdを使ってみます。
swarmdのヘルプは以下のような感じでした。
$ swarmd --help
Run a swarm control process
Usage:
bin/swarmd [flags]
Flags:
-c, --ca-hash string Specifies the remote CA root certificate hash, necessary to join the cluster securely
--election-tick value Defines the amount of ticks (in seconds) needed without a Leader to trigger a new election (default 3)
--engine-addr string Address of engine instance of agent. (default "unix:///var/run/docker.sock")
--force-new-cluster Force the creation of a new cluster from data directory
--heartbeat-tick value Defines the heartbeat interval (in seconds) for raft member health-check (default 1)
--hostname string Override reported agent hostname
--join-addr string Join cluster with a node at this address
--listen-control-api string Listen socket for control API (default "/var/run/docker/cluster/docker-swarmd.sock")
--listen-debug string Bind the Go debug server on the provided address
--listen-remote-api string Listen address for remote API (default "0.0.0.0:4242")
-l, --log-level string Log level (options "debug", "info", "warn", "error", "fatal", "panic") (default "info")
--manager Request initial CSR in a manager role
-s, --secret string Specifies the secret token required to join the cluster
-d, --state-dir string State directory (default "/var/lib/docker/cluster")
-v, --version Display the version and exit
最初のノードの作成
以下のコマンドで最初のノードを作成します。
$ swarmd -d /tmp/node-1 --listen-control-api /tmp/manager1/swarm.sock --hostname node-1
続いて2つノードを追加してみます。
$ swarmd -d /tmp/node-2 --hostname node-2 --join-addr 127.0.0.1:4242
$ swarmd -d /tmp/node-3 --hostname node-3 --join-addr 127.0.0.1:4242
管理作業はswarmctl
コマンドで行うようです。
Swarmクラスタ内のノード一覧を表示してみます。
# swarmctlコマンドの接続先
$ export SWARM_SOCKET=/tmp/manager1/swarm.sock
# 一覧表示(ls)
$ swarmctl node ls
3ノードがSwarmクラスタに参加している状態となりました。
Swarmクラスタでのサービス実行
クラスタ上でサービスを実行するのはswarmctl service
サブコマンドを使うようです。help表示は以下のようになりました。
$ swarmctl help service
Service management
Usage:
bin/swarmctl service [command]
Aliases:
service, svc
Available Commands:
inspect Inspect a service
ls List services
create Create a service
update Update a service
remove Remove a service
Global Flags:
-n, --no-resolve Do not try to map IDs to Names when displaying them
-s, --socket string Socket to connect to the Swarm manager (default "/tmp/manager1/swarm.sock")
Use "swarmctl service [command] --help" for more information about a command.
では早速何か起動してみましょう。ここでは例としてredisを起動してみます。
サービス起動
$ swarmctl service create --name redis --image redis:3.0.5
起動できましたか?
サービス起動確認
swarmctl service ls
コマンドで確認しましょう。
$ swarmctl service ls
ID Name Image Instances
-- ---- ----- ---------
2v5ima52ubn1szmrw5qxwiy00 redis redis:3.0.5 1
起動しているみたいですね。
サービス詳細確認
swarmctl service inspect [サービス名]
で詳細確認できるようです。
$ swarmctl service inspect redis
ID : 2v5ima52ubn1szmrw5qxwiy00
Name : redis
Instances : 1
Template
Container
Image : redis:3.0.5
Task ID Service Instance Image Desired State Last State Node
------- ------- -------- ----- ------------- ---------- ----
f1r7p3b5m3hxvi7ggd14yppxe redis 1 redis:3.0.5 RUNNING RUNNING 3 minutes ago node-1
ついでにdockerコマンド側からも起動状況を見てみましょう。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e57a1aca66f3 redis:3.0.5 "/entrypoint.sh redis" About a minute ago Up About a minute 6379/tcp redis.1.f1r7p3b5m3hxvi7ggd14yppxe
redisコンテナが起動してるのが確認できると思います。
サービスUPDATE
サービスのインスタンス数を増やすなど、属性の更新ができるようです。
インスタンス数を6に増やしてみます。
# 増やしてみるよ
$ swarmctl service update redis --instances 6
2v5ima52ubn1szmrw5qxwiy00
# 確認してみるよ
$ swarmctl service inspect redis
ID : 2v5ima52ubn1szmrw5qxwiy00
Name : redis
Instances : 6
Template
Container
Image : redis:3.0.5
Task ID Service Instance Image Desired State Last State Node
------- ------- -------- ----- ------------- ---------- ----
f1r7p3b5m3hxvi7ggd14yppxe redis 1 redis:3.0.5 RUNNING RUNNING 7 minutes ago node-1
37xq1iluq89q9ln140way2wuj redis 2 redis:3.0.5 RUNNING RUNNING 18 seconds ago node-3
chvth7r9ol2nhll0o6basebap redis 3 redis:3.0.5 RUNNING RUNNING 18 seconds ago node-2
6d79qrshr74d1x7x0y57hercd redis 4 redis:3.0.5 RUNNING RUNNING 18 seconds ago node-2
etfpywpqz9zi0x90mhbzly5zs redis 5 redis:3.0.5 RUNNING RUNNING 18 seconds ago node-1
43fackr1v05f6w7yuwc2uf2px redis 6 redis:3.0.5 RUNNING RUNNING 18 seconds ago node-3
増えてそうですね。nodeの分散もできているようです。
dockerコマンド側からも見てみましょう。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
44747f6bf347 redis:3.0.5 "/entrypoint.sh redis" About a minute ago Up About a minute 6379/tcp redis.6.43fackr1v05f6w7yuwc2uf2px
655a2bf55185 redis:3.0.5 "/entrypoint.sh redis" About a minute ago Up About a minute 6379/tcp redis.4.6d79qrshr74d1x7x0y57hercd
e1a1e2e993bc redis:3.0.5 "/entrypoint.sh redis" About a minute ago Up About a minute 6379/tcp redis.3.chvth7r9ol2nhll0o6basebap
43bc0449a374 redis:3.0.5 "/entrypoint.sh redis" About a minute ago Up About a minute 6379/tcp redis.2.37xq1iluq89q9ln140way2wuj
9cbb0c1a419a redis:3.0.5 "/entrypoint.sh redis" About a minute ago Up About a minute 6379/tcp redis.5.etfpywpqz9zi0x90mhbzly5zs
e57a1aca66f3 redis:3.0.5 "/entrypoint.sh redis" 9 minutes ago Up 9 minutes 6379/tcp redis.1.f1r7p3b5m3hxvi7ggd14yppxe
今回はすべてのノードが同じホストのため6インスタンスすべてが見えていますね。
おそらく各ノード別マシンでswarmクラスタを組めば、docker psも次ノードの分のみ表示されるのだと思います。(まだ試してません)
swarmctl service update
では、実行イメージの更新だったり、ローリングアップデートもできるようです。
ノードの停止(drain)
ノードを停止して、サービスのインスタンスが再配置される様子を見てみましょう。
# node-1を停止
$ swarmctl node drain node-1
# 確認
$ swarmctl node ls
ID Name Membership Status Availability Manager status
-- ---- ---------- ------ ------------ --------------
08ru842rs9yam node-1 ACCEPTED READY DRAIN REACHABLE *
185o4l4u6nnqh node-3 ACCEPTED READY ACTIVE
3ebkf6w3m1dnd node-2 ACCEPTED READY ACTIVE
再配置の確認
node-1を停止しましたので6インスタンスがnode-2とnode-3に割り振られるはずです。
確認してみましょう。
$ swarmctl service inspect redis
ID : 2v5ima52ubn1szmrw5qxwiy00
Name : redis
Instances : 6
Template
Container
Image : redis:3.0.5
Task ID Service Instance Image Desired State Last State Node
------- ------- -------- ----- ------------- ---------- ----
6dfvxo1hx0ml7wvuly76qzox7 redis 1 redis:3.0.5 RUNNING RUNNING 2 minutes ago node-2
37xq1iluq89q9ln140way2wuj redis 2 redis:3.0.5 RUNNING RUNNING 9 minutes ago node-3
chvth7r9ol2nhll0o6basebap redis 3 redis:3.0.5 RUNNING RUNNING 9 minutes ago node-2
6d79qrshr74d1x7x0y57hercd redis 4 redis:3.0.5 RUNNING RUNNING 9 minutes ago node-2
93vr14ppi1quw5iekzuct8r5i redis 5 redis:3.0.5 RUNNING RUNNING 2 minutes ago node-3
43fackr1v05f6w7yuwc2uf2px redis 6 redis:3.0.5 RUNNING RUNNING 9 minutes ago node-3
node-1で起動しているインスタンスがなくなり、node-2とnode-3に再配置されました。
おまけ:swarmctlサブコマンドごとのヘルプ
ビルドが面倒な方のためにヘルプを貼り付けておきます。
サブコマンド、サブサブコマンドについてはオプションが指定できそうなものは記載しています。
(記載が無いもので知りたいものがあれば@yamamoto-febcまで連絡ください。載せます。)
swarmctl
$ swarmctl --help
Control a swarm cluster
Usage:
bin/swarmctl [command]
Available Commands:
node Node management
service Service management
task Task management
version Print version number of swarm.
network Network management
cluster Cluster management
Flags:
-n, --no-resolve Do not try to map IDs to Names when displaying them
-s, --socket string Socket to connect to the Swarm manager (default "/var/run/docker/cluster/docker-swarmd.sock")
Use "swarmctl [command] --help" for more information about a command.
swarmctl node
$ swarmctl node --help
Node management
Usage:
swarmctl node [command]
Available Commands:
accept Accept a node into the cluster
remove Remove a node
inspect Inspect a node
ls List nodes
activate Activate a node
pause Pause a node
drain Drain a node
promote Promote a node to a manager
demote Demote a node from a manager to a worker
Global Flags:
-n, --no-resolve Do not try to map IDs to Names when displaying them
-s, --socket string Socket to connect to the Swarm manager (default "/var/run/docker/cluster/docker-swarmd.sock")
Use "swarmctl node [command] --help" for more information about a command.
swarmctl service
$ swarmctl service --help
Service management
Usage:
swarmctl service [command]
Aliases:
service, svc
Available Commands:
inspect Inspect a service
ls List services
create Create a service
update Update a service
remove Remove a service
Global Flags:
-n, --no-resolve Do not try to map IDs to Names when displaying them
-s, --socket string Socket to connect to the Swarm manager (default "/var/run/docker/cluster/docker-swarmd.sock")
Use "swarmctl service [command] --help" for more information about a command.
swarmctl service create
$ swarmctl service create --help
Create a service
Usage:
bin/swarmctl service create [flags]
Flags:
--args value container args (default [])
--constraint value Placement constraint (node.labels.key==value) (default [])
--cpu-limit string CPU cores limit (e.g. 0.5)
--cpu-reservation string number of CPU cores reserved (e.g. 0.5)
--env value container env (default [])
--image string container image
--instances uint number of instances for the service (default 1)
--label value service label (key=value) (default [])
--memory-limit string memory limit (e.g. 512m)
--memory-reservation string amount of reserved memory (e.g. 512m)
--mode string one of replicated, global (default "replicated")
--name string service name
--network string network name
--ports value ports (default [])
--restart-condition string condition to restart the task (any, failure, none) (default "any")
--restart-delay string delay between task restarts (default "5s")
--restart-max-attempts uint maximum number of restart attempts (0 = unlimited)
--restart-window string time window to evaluate restart attempts (0 = unbound) (default "0s")
--update-delay string delay between task updates (0s = none) (default "0s")
--update-parallelism uint task update parallelism (0 = all at once)
Global Flags:
-n, --no-resolve Do not try to map IDs to Names when displaying them
-s, --socket string Socket to connect to the Swarm manager (default "/tmp/manager1/swarm.sock")
swarmctl task
$ swarmctl task --help
Task management
Usage:
swarmctl task [command]
Available Commands:
ls List tasks
inspect Inspect a task
remove Remove a task
Global Flags:
-n, --no-resolve Do not try to map IDs to Names when displaying them
-s, --socket string Socket to connect to the Swarm manager (default "/var/run/docker/cluster/docker-swarmd.sock")
Use "swarmctl task [command] --help" for more information about a command.
swarmctl network
$ swarmctl network --help
Network management
Usage:
swarmctl network [command]
Available Commands:
inspect Inspect a network
ls List networks
create Create a network
remove Remove a network
Global Flags:
-n, --no-resolve Do not try to map IDs to Names when displaying them
-s, --socket string Socket to connect to the Swarm manager (default "/var/run/docker/cluster/docker-swarmd.sock")
Use "swarmctl network [command] --help" for more information about a command.
swarmctl network create
$ swarmctl network create --help
Create a network
Usage:
bin/swarmctl network create [flags]
Flags:
--driver string Network driver
--gateway value Gateway IP addresses for network segments (default [])
--ip-range value IP ranges to allocate from within the subnets (default [])
--ipam-driver string IPAM driver
--name string Network name
--opts value Network driver options (default [])
--subnet value Subnets in CIDR format that represents a network segments (default [])
Global Flags:
-n, --no-resolve Do not try to map IDs to Names when displaying them
-s, --socket string Socket to connect to the Swarm manager (default "/tmp/manager1/swarm.sock")
swarmctl cluster
$ swarmctl cluster --help
Cluster management
Usage:
swarmctl cluster [command]
Available Commands:
inspect Inspect a cluster
ls List clusters
update Update a cluster
Global Flags:
-n, --no-resolve Do not try to map IDs to Names when displaying them
-s, --socket string Socket to connect to the Swarm manager (default "/var/run/docker/cluster/docker-swarmd.sock")
Use "swarmctl cluster [command] --help" for more information about a command.
swarmctl cluster update
$ swarmctl cluster update
Error: cluster name missing
Usage:
bin/swarmctl cluster update <cluster name> [flags]
Flags:
--autoaccept value Roles to automatically issue certificates for (default [])
--certexpiry duration Duration node certificates will be valid for (default 2160h0m0s)
--heartbeatperiod duration Period when heartbeat is expected to receive from agent
-h, --help help for update
--secret value Secret required to join the cluster (default [])
--taskhistory int Number of historic task entries to retain per instance or node
Global Flags:
-n, --no-resolve Do not try to map IDs to Names when displaying them
-s, --socket string Socket to connect to the Swarm manager (default "/tmp/manager1/swarm.sock")
まとめ
READMEから一通りSwarmKitを触ってみました。
これまではSwarmクラスタの構築に別途KVS(etcdやconsul)の構築が必要でしたが、swarmdがそのあたりを隠蔽してくれているようです。
ネットワーク周りやデータボリューム周りなど、マルチホストでクラスタを組む場合はいろいろ気になりますが、まだまだ開発中のようで情報が少ないです。
nomadやMesos+Marathonなどと比べてのメリットもまだよくわかっていません。(私が読み解けてないだけかもしれないです、、、)
もう少し開発状況を見守ってみようと思います。
以上です。