Dockerを使ってみたい案件があり、デプロイ方法について色々検討している今日この頃。
新しいツールということもあって、 軽くググってみただけでもKubernetesとかMesosとかあるいはもっと別な方法が色々と出てくるし、 逆にいえば「これが決定版!」とはまだどれも言えそうにはない雰囲気。
サードパーティ製のツールはどれもそれなりに利点はありそうだけど、 一方で学習コストが高くついて辛い感じもあり、 また個人的にはDocker Compose使って作業してたんでそれを流用できないというのも気が進まないポイントであった。
実際のとこそこまで機能はいらないし、いっそConsulのイベント機能で無理やり…とか考えたりもした。
そんな感じで正直なところ迷走していたのだが、 公式ツールであるところのSwarmが去年末の段階で1.0.0をリリースしていたらしいということに今更になって気づく。
(なんでか見逃してましたね。)
公式ツールという安心感もあるし、何より使い慣れたComposeも使える!
というわけでひとまず使い方を勉強してみた。
導入
Docker Engine
いわばDocker動かす本体。
Machineと連携させるには素で入る方じゃなくてEngineがついた方を入れる必要があるらしい。
ということで、公式ドキュメントに従ってインストールを進める。
長くなるので省略するが、OSごとの子細なやり方が書いてあるので迷うことはないだろう。
yumなりaptなりで簡単に入れられる。
Docker Compose
ymlファイルからコンテナを起動するためのツール。毎回長ったらしいコマンドを記述しないで済む。
以前本家の方で書いた記事があったのでそっちでも。
Docker Machine
他のホストにDockerの動作環境を用意し、あたかもローカル環境であるかのようにコントロールできるツール。
Docker Swarm
クラスタを制御するためのもの。Machineの方を入れれば使える。
VMで動かしてみる
大雑把な流れとしては
- クラスタ操作のためのトークンを作成
- Machineへ操作のためのマスタを追加
- Machineへ実際にデプロイするノードを追加
- マスタをコントロールできるように環境変数を設定
- 各種Docker操作
といった感じな模様。
ひとまずVirtualBoxを使ったサンプルをこなしてみる。
1. クラスタ操作のためのトークンを作成
操作端末(じゃなくても良いけど)でswarmイメージを使ってトークンを生成する。
docker run --rm swarm create
以降の操作で用いるのでコピペ保管しておくこと。
どうやらトークンではなくてConsulを使って連携させることもできるみたいだけど、 今回は時間なかったので今度試す。
なんかConsul依存度が高まってくなぁ。
追記: consulのKVを使う場合
この手順を飛ばし、以降の操作におけるtoken://<TOKEN>
の部分をconsul://<consulのURL>/<必要ならキーを入力>
という感じで使える。
2. Machineへ操作のためのマスタを追加
ドライバとしてvirtualbox
、オプションとしてswarm
とswarm-master
、そしてトークンを指定してVMを作成する。
docker-machine create -d virtualbox --swarm --swarm-master --swarm-discovery token://<TOKEN> master
ちなみにVMじゃなくて実機を使う場合は、ドライバとしてgeneric
を指定し、
generic-ssh-user
generic-ssh-key
generic-ip-address
あたりのオプションを記述してやればいける、はず。
これは自宅環境だと試せなかったのでそのうち。
3. Machineへ実際にデプロイするノードを追加
マスタの時のからswarm-master
オプションを抜いた感じ。
docker-machine create -d virtualbox --swarm --swarm-discovery token://<TOKEN> node1 docker-machine create -d virtualbox --swarm --swarm-discovery token://<TOKEN> node2
ひとまず2つほど。
4. マスタをコントロールできるように環境変数を設定
docker-machine env
コマンドで必要なことは出力してくれるので、evalに食わせればOK。
よく使いそうなので実用上はエリアスに入れとくと良いかも。
eval "$(docker-machine env --shell bash --swarm master)"
これで端末でdockerコマンドを打つと、先ほど作成したmasterのDockerを操作できる。(docker info
とかでクラスタの状況も確認できる。)
ちなみに下記のコマンドで元に戻せる。
eval "$(docker-machine env -u)"
5. 各種Docker操作
色々と細かいことを書いても長くなってしまうので肝心なとこだけ。
とりあえず雑多にdocker-compose.ymlを用意してみる。
nginx: image: nginx:latest environment: - "constraint:node==node*"
nginx:latest
をnode
と名のついたノードにだけデプロイする、の意味。
とりあえずupしてみる。
docker-compose up -d node2: Pulling nginx:latest... : downloaded master: Pulling nginx:latest... : downloaded node1: Pulling nginx:latest... : downloaded docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8fa0a4a3a719 nginx "nginx -g 'daemon off" 46 seconds ago Up 45 seconds 80/tcp, 443/tcp node1/swarm_nginx_1
クラスタ全体でイメージはダウンロードするようだが、 起動は一個だけ。
次に起動するコンテナを増やしてみる。
docker-compose scale nginx=3 Creating and starting swarm_nginx_2 ... done Creating and starting swarm_nginx_3 ... done docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f521e8b48602 nginx "nginx -g 'daemon off" 20 seconds ago Up 19 seconds 80/tcp, 443/tcp node1/swarm_nginx_3 109dfb5794fe nginx "nginx -g 'daemon off" 20 seconds ago Up 19 seconds 80/tcp, 443/tcp node2/swarm_nginx_2 8fa0a4a3a719 nginx "nginx -g 'daemon off" 3 minutes ago Up 3 minutes 80/tcp, 443/tcp node1/swarm_nginx_1
masterを避けて指定個数が散らばって起動されることが確認できる。
ちなみに普通にdocker-compose kill
でそれぞれ殺せる。
ノード自体が要らなくなった場合はdocker-machine ls
で確認してstop
&rm
で。
実際上はローカルのプライベートリポジトリに登録したイメージを配布する目論見。
最初のイメージのダウンロードがどの程度時間かかるのかが気になるところ。
明示的にホストのポートを指定して起動するような場合、バッティングすると当然起動時にエラーとなってしまうのだが、 これをいかに避けるかが目下のところ悩みどころ。
せっかくswarmで運用するならば具体的な番号を避けてコンテナ間のlinkを使うべきだというのは分かっちゃいるが、 現状そこまで完全にDockerまかせで運用する覚悟があるわけでもないので…