Docker ID で swarm クラスタへサービスをデプロイできるというもの。
そもそも評価環境や本番環境へは、ビルドはもちろんテストグリーンが保証された
CI/CD 環境などからデプロイされるべきだろうし、開発中にローカルでない環境で
ちょっと確認してみたいというレベルなら docker-machine でもいいだろうし
何がいいものかいまいちわからなかったのでさわってみました。
まとめ
Desktop to Cloud
- Docker for Mac などで行われる認証を利用して
- ユーザごとに利用可能な swarm クラスタの一覧表示
- (関連付いた組織にもすぐスイッチできる)
- (管理下にある Docker イメージの一覧も並ぶ)
- あとはクラスタを選択するだけで
- クラウド上の swarm クラスタに繋がったターミナルが起動
- Docker Cloud が使うプロキシ型ではなく個別 TCP ソケット接続
Docker Cloud
- Docker for AWS / Azure が Docker Cloud に統合されていた
- dockercloud/client で認証すると
- dockercloud/client-proxy がローカルに起動して
- export DOCKER_HOST=tcp://127.0.0.1:32768 などで
- クラウド上の swarm と直接やりとりできるようになってた
- 少なくともここまでの範囲は無料でできる
Docker Cloud から swarm クラスタ作成
既存の swarm クラスタを持ち込まず、
Docker Cloud から作る手順を確認してみる。
1. Docker Cloud へのログイン
Docker ID でログインできます。
もしログイン後の画面が下図のように Swarm Mode でなかったなら

クリックして以下の画面に切り替えてください。

2. swarm クラスタの作成
すでにある swarm クラスタを持ち込むこともできますが、ここはあえて少し面倒な
Docker Cloud へ AssumeRole で安全に AWS の操作権限を渡し、Docker Cloud の
コンソールから swarm クラスタを生成する手順にしてみます。
(原文の手順は こちら です)
2.1 AWS で IAM ロールを発行する
IAM コンソールにログインし、新しいロールを作ります。

クロスアカウントアクセスのためのロールを選び、

手順に沿って、DockerCloud の AWS Account ID と、自分の Docker ID をそれぞれ入力します。

名前を決めたら、右下のボタンからロールを生成しましょう。

2.2 Docker Cloud に渡す権限を設定する
今作った IAM ロールに、適切なポリシーを設定します。
ロールの詳細画面の Permission タブ
の中の下方、
Inline Policies
をクリックして click here
を押します。

カスタムポリシーを選択し

ポリシー名を適宜入力した上で、
Docker Cloud の要求する この権限1 を貼り付け、保存してください。

2.3 ロールの ARN をコピーする
ロールの詳細画面の一番上に表示されるこれですね。
arn:aws:iam::.. の部分を Ctrl + C
しましょう。

2.4 Docker Cloud で swarm クラスタ作成
画面上部から、Swarm の新規作成を選びます。

クラスタ名を入れつつ、サービスプロバイダに AWS を選択。
先ほどコピーした値を保存すると connected
になります。

どんなクラスタにするかを決めます。
t2.micro の manager 1 台だけのクラスタにしてみます。

Create しましょう。
3. swarm クラスタの確認
AWS 側では、Docker for AWS が起動します。
3.1 システム構成の確認
内部的には CloudFormation が使われるので、
コンソール からはテンプレートなども簡単に確認できます。
試しにデザイナで開いてみたら、最新ってこんななのですね・・

3.2 接続テスト
Docker Cloud の該当クラスタを選択すると、
そこへ接続するためのコマンドが表示されます。

ターミナルで実行すると、Docker ID での認証を求められ、
成功すると
=> You can now start using the swarm pottava/swarm by executing:
export DOCKER_HOST=tcp://127.0.0.1:32768
といったメッセージが表示され、
実際ローカルにはクラスタへのプロキシが起動しています。
$ docker container list
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2719c26c64bc dockercloud/client-proxy "/client-proxy" 27 seconds ago Up 26 seconds 127.0.0.1:32768->2375/tcp client_proxy_pottava_swarm
言われた通りに DOCKER_HOST をプロキシに向けてみると・・
$ export DOCKER_HOST=tcp://127.0.0.1:32768
$ docker container list
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
996127204e3b dockercloud/server-proxy "/server-proxy" 24 minutes ago Up 24 minutes 2376/tcp dockercloud-server-proxy.xgglvp1y2ys4sa5bphjzuxjwt.t1bdegqxaq16cxujw0ssaendn
d0b6073c4490 docker4x/l4controller-aws:aws-v17.03.1-ce-aws1 "loadbalancer run ..." 24 minutes ago Up 24 minutes l4controller-aws
ce985fdca15a docker4x/meta-aws:aws-v17.03.1-ce-aws1 "metaserver -iaas_..." 24 minutes ago Up 24 minutes 172.31.13.108:9024->8080/tcp meta-aws
b5ad87ccaca8 docker4x/shell-aws:aws-v17.03.1-ce-aws1 "/entry.sh /usr/sb..." 24 minutes ago Up 24 minutes 0.0.0.0:22->22/tcp shell-aws
5cee36ea2eab docker4x/guide-aws:aws-v17.03.1-ce-aws1 "/entry.sh" 24 minutes ago Up 24 minutes guide-aws
なるほどいい感じですね。
ノードも指定通りに立ち上がっていることがわかります。
$ docker node list
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
xgglvp1y2ys4sa5bphjzuxjwt * ip-172-31-13-108.ap-northeast-1.compute.internal Ready Active Leader
3.3 ハローワールド
Web サービスを 2 つ作ってみます。
$ docker service create --name hello -p 80:80 --detach=true dockercloud/hello-world
$ docker service create --name nginx -p 8080:80 nginx:1.11-alpine
Redis も立ててみます。
$ docker service create --name redis -p 6379:6379 --detach=true redis:3.0-alpine
Docker for AWS はサービスの生成に合わせ
ELB のリスナを自動設定してくれるわけわけですが
それを確認してみましょう。
起動した ELB の接続先は AWS-CLI などで見つかります。
$ cluster_name=<Swarm クラスタ名>
$ dns_name=$(aws elb describe-load-balancers --query "LoadBalancerDescriptions[?LoadBalancerName==\`${cluster_name}-ELB\`].DNSName" --output text)
または、Docker Cloud の該当クラスタから情報が取得できます。

接続してみましょう。
$ curl -i $dns_name
$ curl -i $dns_name:8080
$ redis-cli -h $dns_name
うまく動いていることが確認できたのでサービスを停止します。
$ docker service rm hello nginx redis
4. Desktop to Cloud でデプロイ
Docker for Mac の機能を使って Swarm クラスタに接続します。
今回のように Docker for AWS な環境だとあまり恩恵も感じませんが
持ち込みの Swarm クラスタだと少しうれしいかもしれません。
かもしれません。
4.1 ログイン
Mac 右上のメニューバーから Docker ID でログイン

4.2 クラスタの選択
認証されると、そのユーザに紐づく swarm クラスタや
管理下にある Docker イメージが一覧として表示されます。
そこから接続したいクラスタを選びます。

4.3 接続確認
起動したターミナルは DOCKER_HOST がクラウド側の
swarm をみているので、すぐクラスタに接続できます。
[swarm] ~ $ docker node list
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
xgglvp1y2ys4sa5bphjzuxjwt * ip-172-31-13-108.ap-northeast-1.compute.internal Ready Active Leader
プロキシも立たないまま、3.2 と同じ状況になりましたね!
4.4 デプロイ
デモでやっていたように、スタックでデプロイしてみましょう。
Docker 社がよく使う投票アプリのスタック定義を取得して
[swarm] ~ $ curl -O https://raw.githubusercontent.com/docker/example-voting-app/master/docker-stack.yml
デプローイ。
[swarm] ~ $ docker stack deploy --compose-file docker-stack.yml voting
Creating network voting_default
Creating network voting_frontend
Creating network voting_backend
Creating service voting_visualizer
Creating service voting_redis
Creating service voting_db
Creating service voting_vote
Creating service voting_result
Creating service voting_worker
t2.micro のリソース的になかなかシビアな感じはありつつも
サービスがこんな感じで REPLICA 数揃うまで待ちます。
[swarm] ~ $ docker service list
ID NAME MODE REPLICAS IMAGE PORTS
anka9rf9o3ea voting_redis replicated 2/2 redis:alpine *:0->6379/tcp
ibqx2lcvxr45 voting_db replicated 1/1 postgres:9.4
ie62ji0m4pys voting_result replicated 1/1 dockersamples/examplevotingapp_result:before *:5001->80/tcp
n0atzubw917t voting_visualizer replicated 1/1 dockersamples/visualizer:stable *:8080->8080/tcp
p6clvuqr507g dockercloud-server-proxy global 1/1 dockercloud/server-proxy:latest *:2376->2376/tcp
rpkhch1gk8er voting_worker replicated 1/1 dockersamples/examplevotingapp_worker:latest
xc3lkdefp2n4 voting_vote replicated 2/2 dockersamples/examplevotingapp_vote:before *:5000->80/tcp
この状態で ELB のリスナーを確認すると

増えてます。
接続してみましょう!
http://${dns_name}:5001/
で投票結果を起動しつつ
http://${dns_name}:5000/
で投票すると、結果が変わりますね。
複数ブラウザで UserAgent を変えれば票も増えます。
これが

こっちでクリックすると

こうなる

4.5 後片付け
DockerCon のデモではサービスのアップデートをしていましたが
まあできるでしょうということで、あとは片付けます。
[swarm] ~ $ docker stack rm voting
Removing service voting_redis
Removing service voting_db
Removing service voting_result
Removing service voting_visualizer
Removing service voting_worker
Removing service voting_vote
Removing network voting_default
Removing network voting_backend
Removing network voting_frontend
Docker Cloud から Swarm クラスタを破棄します。

おわり
ではありません!!!!
おい、Docker for AWS で生成したリソースが消えてないぞ。
あれですかね、持ち込みの Swarm クラスタと勘違いしてるのかな?
Docker Cloud 上のマスタだけ決して満足してしまったのかw
ということで CloudFormation コンソールに赴いて
手動でしっかり消しましょう・・・

所感
冒頭の疑問はあまり解消されませんでした・・
-
Resource が * だったり、少々過大な権限になってますね・・ ↩