Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Dockerを使ったローカルでの開発から本番環境へのデプロイまで

17,087 views

Published on

Docker Inc.の Jérôme Petazzoniさんが re:Invent2015で行った「From Local Docker Development to Production Deployment」というセッションの資料を、ご本人の了解を得て日本語に訳したものです。

Published in: Technology
  • Be the first to comment

Dockerを使ったローカルでの開発から本番環境へのデプロイまで

  1. 1. Dockerを使ったローカルでの開発から 本番環境へのデプロイまで (日本語版) http://www.slideshare.net/jpetazzo/from-development-environments-to-production-deployments-with-docker-compose-machine-swarm-and-ecs-cli-aws-reinvent-2015
  2. 2. このセッションに期待できること これからお話しするのは… • 開発環境のための Docker Compose • その環境を本番稼動させるまでの話 - Dockerクラスタのプロビジョニング - コンテナイメージのビルドとそのデプロイ - サービスディスカバリ • Docker Compose, Machine, Swarm, ECS みなさんが Dockerの基本は知っている前提で進めます!
  3. 3. 自己紹介 • Jérôme Petazzoni ( @jpetazzo ) • 2010年から dotCloud社でいろんなものをコンテナにしてました - polyglot PAAS - microservice - プロビジョニング、メトリクス、スケーリング… - LXCの大規模デプロイメント • 2013年からは Docker社でいろんなものをコンテナにしてました  (dotCloudは 2013年にDockerと社名を変えました…) • 今年 3年目となる技術を 5年間さわってます
  4. 4. 自己紹介 Take2 • こんにちは、Jérômeです! • ソフトウェアエンジニアです。新しい仕事始めようとしてます! • 実は明日から DockerCoins* を手がけようかと (ブロックチェーンをもつ暗号通貨的なアレ) • 同僚があらゆるところで Dockerを使って開発するので • 僕の仕事は、それをスケールする形でデプロイすることです * 架空のプロジェクトです。 DockerCoinでピザやコーヒーを買うことはできません(今はね)。
  5. 5. 準備しよう
  6. 6. 初仕事1日目に備える • ちょうど新しいラップトップを受け取ったよ! • セットアップ手順書にはたった一行:   「Docker Toolboxをインストールしましょう」 • Windows版 MacOS版、ダウンロードサイズは 180MB未満です
  7. 7. • Video: https://www.youtube.com/watch?v=g-g94H_AiOE
  8. 8. Composeを使った開発
  9. 9. Compose 新人向け作業ステップ • 次の3ステップです 1) git clone git://github.com/jpetazzo/dockercoins (*1) cd dockercoins 2) docker-compose up 3) ブラウザでアプリを開きます (*2) *1 訳者注: Docker Quickstart Terminalを起動し、コマンドを入力します *2 訳者注: http://{次のページの画面に表示されるIPアドレス}:8000/ でアクセスできます
  10. 10. Video: https://www.youtube.com/watch?v=sk3yYh1MgE0
  11. 11. これだけでなんで動くの? • “docker-compose up” は Composeにアプリを起動するよう伝えます • 必要なら、そのアプリはまずビルドされます • なぜ Composeは自分のすべき仕事がわかるのか • Composeは Compose file (docker-compose.yml) を読み、動きます
  12. 12. docker-compose.yml - シンプルな例 web: build: . ports: - “80:5000” links: - redis redis: image: redis
  13. 13. docker-compose.yml - 複雑な例(今回のアプリ) rng: build: rng ports: - “8001:80” hasher: build: hasher ports: - “8002:80” redis: image: redis worker: build: worker links: - rng - hasher - redis webui: build: webui links: - redis ports: - “8000:80” volumes: - “./webui/files/:/files/”
  14. 14. これでなんで動くの? • アプリケーションは、サービス単位に分割されていて • サービスはそれぞれ 1つのコンテナとして動きます • コンテナは、以下のいずれかをベースにして起動します - レジストリと呼ばれるライブラリに置いてある、 事前にビルドされたイメージ - Dockerfileというビルドレシピ • Compose fileにはそれらサービスの定義が書かれています (そのパラメタも。storage, network, env vars…)
  15. 15. https://github.com/jpetazzo/dockercoins
  16. 16. 今回のサンプルアプリケーション • マイクロサービスアーキテクチャー • 各サービスはそれぞれ異なる言語とフレームワークで構成 - Ruby + Sinatra - Python + Flask - Node.js + Express • それぞれサービスの種類もバラバラ - バックグラウンドワーカー - REST APIをもった Webサービス - ステートフルなデータストア - Webフロントエンド
  17. 17. マイクロサービスアーキテクチャ不可避 • マイクロサービスのメリット - チームを小さく保てる(Jeff Bezosの two-pizzaルール) - 「適切な道具を使って適切な仕事を」が実現できる - サービスはそれぞれ独立したデプロイ/スケールができる - “Adrian Cockroft, Microservices” などで映像を検索してみよう • マイクロサービスのデメリット - 分散システムにするのは難しい (疑わしく思うなら、aphyr.comをみて) - 負荷分散とサービスディスカバリが極めて重要 - “Microservices Not A Free Lunch” などで記事を探してみよう
  18. 18. クラウド上のサーバにデプロイする • ローカルと同じ手順です: 1) リモートの Dockerホストに SSH接続 2) git clone 3) docker-compose up 4) ブラウザでアプリを開きます • Demoを見てみよう
  19. 19. Demo • ssh • git clone git://github.com/jpetazzo/dockercoins cd dockercoins • docker-compose up • ブラウザでアプリを開きます(http://サーバIPアドレス:8000/) • ^C
  20. 20. Composeを使った開発フロー • シンプルな4ステップです 1) ソースコードを編集します 2) docker-compose build 3) docker-compose up 4) ブラウザを更新
  21. 21. Demo • webui/files/index.htmlを編集 • cssを変更 • docker-compose build • docker-compose up • ブラウザを更新 • ^C Video: https://www.youtube.com/watch?v=O3Bps01THBQ
  22. 22. Composeでコンテナをテイクアウト! • Dockerは環境を抽象化してくれます • Dockerホストさえあれば、どんな環境にもデプロイできます - ローカル環境 (Docker Toolboxで) - オンデマンドなクラウドインスタンス (Docker Machineで) - Bring-Your-Own-Server (オンプレやハイブリッドクラウドのために) • 抵抗のない乗り換え(& コンテキストスイッチ) • では、スケーラブルに、本番環境にデプロイする方法は?
  23. 23. いま欠けていること • クラスタのプロビジョニング • ソースコードのビルドとデプロイ • サービスディスカバリ (これがすべてではない…) 引き続き、これらにどう取り組めばいいのかを見ていきましょう。 より深く掘り下げ、ライブデモももっとお見せします!
  24. 24. クラスタのプロビジョニング
  25. 25. プロビジョニング • 手動でのインスタンス起動(CLIまたはコンソール) • AWS CLIで自動化 • Auto Scalingグループ • CloudFormationテンプレート • Docker Machine • ECS CLI
  26. 26. Docker Machine • Docker Machineは Docker Toolboxに付属してます • Dockerホストを作成することができます: - EC2、またはその他クラウド上に - ローカル環境上に(VirtualBox, OpenStack…) • Docker Swarmと組み合わせればクラスタも生成できます • 現在ある制約(いずれ改善すると期待しててください) - 一度に起動できるのは 1台 - クレデンシャルは中央管理
  27. 27. Demo export TOKEN=$(docker run swarm create) echo $TOKEN docker-machine create -d amazonec2 --swarm --swarm-master --swarm-discovery token://$TOKEN node00 & for N in $(seq 1 4); do sleep 3 docker-machine create -d amazonec2 --swarm --swarm-discovery token://$TOKEN node0$N & done wait Video: https://www.youtube.com/watch?v=LFjwusorazs
  28. 28. ECS CLI • 盗み見!? • 最先端のクラスタ生成 • AWSのベストプラクティス: - CloudFormationテンプレート - AutoScalingグループ - IAMとのインテグレーション
  29. 29. Demo • ecs-cli configure • ecs-cli up --keypair jpetazzo --capability-iam --size 10 • (ELBの追加) • (AutoScalingグループにロードバランサを関連づけ) • (DNSエントリの追加) • (ELBと ASGのためのセキュリティグループ設定) Video: https://www.youtube.com/watch?v=KqEpIDFxjNc
  30. 30. ソースコードのビルドとデプロイ
  31. 31. Dockerを使ったビルドとデプロイ • アプリの Dockerイメージをビルドするために 引き続き Composeを使ってみましょう • そしてそのイメージを Docker Registryに保存します - Docker Hub (GitHubのような SaaS。パブリックイメージは無料) - Docker Trusted Registry (商用。AWS Marketplaceなどを通してお使いいただけます) - 自前管理のレジストリ、コミュニティバージョン
  32. 32. その具体的なプラン • デプロイのたびに: 1) Composeですべてのコンテナを build 2) イメージにユニークなバージョン番号のタグをつける 3) レジストリにイメージを push 4) ビルド & プッシュしたイメージを参照している 新しい docker-compose.ymlファイルを生成 • これをスクリプトで実行しましょう
  33. 33. スクリプトあるよ! • これから使うスクリプトはすべて GitHubで公開しています • 使うのもコピーも改変も、ぜひご自由にどうぞ∼ そのスクリプトあるよ! みんな、スクリプトあるよー!! URL: https://github.com/jpetazzo/orchestration-workshop
  34. 34. Demo • build-tag-push.py • その結果ファイル (YAML) を確認する これで Dockerイメージが固まりました。 イメージは “永遠に” 維持され、もし後から必要になっても大丈夫。 (たとえば、バージョンを巻き戻したい、など) See: https://hub.docker.com/r/jpetazzo/dockercoins_webui/tags/
  35. 35. サービスディスカバリ
  36. 36. なぜサービスディスカバリが必要? • サービス Aが、サービス Bと通信する必要がある • Aはどうやって Bと通信する手段を把握するのか - サービス Aに必要なもの: アドレス、ポート、クレデンシャル • もし Bのサーバが複数あったら? - 例: 負荷分散、レプリケーション • もし Bのロケーションが時間とともに変わるなら? - 例: スケーリング、フェールオーバー • サービスディスカバリはこれらの懸念に対処しようというもの
  37. 37. 開発サイドにみられる サービスディスカバリ
  38. 38. ハードコードされたサービスディスカバリ • 開発用セットアップ: $db = mysql_connect(“localhost”); cache = Redis.new(:host => “localhost”, :port => 16379) conn, err := net.Dial(“tcp”, “localhost:8000”)
  39. 39. ハードコードされたサービスディスカバリ • 開発用セットアップ、別の例: $db = mysql_connect(“192.168.1.2”); cache = Redis.new(:host => “192.168.1.3”, :port => 6380) conn, err := net.Dial(“tcp”, “192.168.1.4:8080”)
  40. 40. ハードコードされたサービスディスカバリ • 本番用セットアップ: $db = mysql_connect(“foo.rds.amazonaws.com”, “produser”, “sesame”); cache = Redis.new(:url => “redis://:p4ssw0rd@redis-as-a-service.io/15”) conn, err := net.Dial(“tcp”, “api-42.elb.amazonaws.com:80”)
  41. 41. ハードコードされたサービスディスカバリ • 環境を切り替えるためのコード変更点が多い • エラーを起こしやすい • コードリポジトリに設定ファイルの大幅な変更、頻繁な変更が入る • 新しいサービスの追加にはこれらすべての設定変更が必要になる • メンテナンスが高コスト (S個のサービス × E個の環境) • 👻
  42. 42. Twelve-Factor App* • 環境変数: $db = mysql_connect($_ENV[“DB_HOST”], $_ENV[“DB_USER”], $_ENV[“DB_PASS”]); cache = Redis.new(:url => “redis://:#{ENV[“REDIS_PASS”]}@” + “#{ENV[“REDIS_HOST”]}:#{ENV[“REDIS_PORT”]}/” + “#{ENV[“REDIS_DB”]}”) conn, err := net.Dial(“tcp”, os.ExpandEnv(“${API_HOST}:${API_PORT}”)) *訳者注: http://twelve-factor-ja.herokuapp.com/
  43. 43. Twelve-Factor App • ソースコードと環境変数を明示的に分離する (環境は、文字通り環境変数によって定義されます) • 依然として設定ファイルのメンテナンスは必要 (環境変数のリストもメンテ対象) • 本番環境のパラメタを、容易にコードリポジトリ管理外にできる • 激しいエラーはより起きにくくなる • 😐
  44. 44. 設定データベースの利用 • 動的ルックアップ(Zookeeperで): $zk = new Zookeeper(‘127.0.0.1:2181’) $db = mysql_connect( $zk->get(‘/apps/foo/prod/db/host’), $zk->get(‘/apps/foo/prod/db/user’), $zk->get(‘/apps/foo/prod/db/pass’)); zk = Zookeeper.new(‘127.0.0.1:2181’) redis_pass = zk.get(:path => ‘/apps/foo/prod/redis/pass’) redis_host = zk.get(:path => ‘/apps/foo/prod/redis/host’) redis_port = zk.get(:path => ‘/apps/foo/prod/redis/port’) redis_db = zk.get(:path => ‘/apps/foo/prod/redis/db’) cache = Redis.new(:url => “redis://:#{redis_pass}@#{redis_host}:#{redis_port}/#{redis_db}”) c, _, err := zk.Connect([]string[“127.0.0.1”], time.Second) api_host, _, err := c.get(“/apps/foo/prod/api/host”) api_port, _, err := c.get(“/apps/foo/prod/api/port”) conn, err := net.Dial(“tcp”, fmt.Sprintf(“%s:%s”, api_host, api_port))
  45. 45. 設定データベースの利用 • 開発環境と本番環境で同じコードを使いたいなら 開発環境にも設定 DBをデプロイしなければならない • 設定ファイルのメンテナンスをする代わりに Zookeeper*クラスタの管理をしなければいけない • …もしくは開発・本番環境で異なるルックアップロジックを入れる • 😥 *他のお気に入り設定 DBでも。etcdや Consulなど。
  46. 46. ローカル負荷分散/ルーティング • よく知られたロケーションに接続する: $db = mysql_connect(“localhost”); cache = Redis.new(:host => “localhost”) conn, err := net.Dial(“tcp”, “localhost:8001”) • 開発環境:すべてのコンポーネントはローカルで稼働 • 本番環境:ローカルのロードバランサがトラフィックを捌く (例:Airbnbの SmartStack)
  47. 47. ローカル負荷分散/ルーティング • ソースコードは開発・本番間で一致させることができる • デプロイは以下の点で変わってくる - 開発環境は直接接続される - 本番環境はプロキシ、ルータ、ロードバランサが介在する • 「設定」は単に静的なポート割り当てを示したもの (どのサービスがどのポートを Listenしているのか) • 開発はしやすい。運用サイドはやることあるけど.. • 😏
  48. 48. アンバサダーパターン
  49. 49. アンバサダーを使ったコードベース • よく知られたDNS名を使います $db = mysql_connect(“db”); cache = Redis.new(:host => “redis”) conn, err := net.Dial(“tcp”, “api:8000”)
  50. 50. 接続が必要なサービスを参照する よう適切に設定した /etc/hosts を 各コンテナにおきましょう。 例えば “worker” には: 172.17.0.1 hasher 172.17.0.2 rng 172.17.0.3 redis 開発環境では webui 172.17.0.5 redis 172.17.0.3 worker 172.17.0.4 hasher 172.17.0.1 rng 172.17.0.2 containerhost
  51. 51. IPアドレスの振り方は異なります が、ソースコードは同じものが利 用できます。 “worker” 上の /etc/hosts: 10.0.0.10 hasher 10.0.0.15 rng 10.0.0.12 redis また別の開発環境では webui 10.0.0.4 redis 10.0.0.12 worker 10.0.0.20 hasher 10.0.0.10 rng 10.0.0.15 containerhost
  52. 52. Composeは Dockerの「links」を 使って /etc/hosts の設定を自動で やってくれます。 Composeさえ使えば、もう開発環 境のことはケアされています! では、複数ホストにまたがる本番 環境はどうでしょうか? 朗報です webui 172.17.0.5 redis 172.17.0.3 worker 172.17.0.4 hasher 172.17.0.1 rng 172.17.0.2 containerhost
  53. 53. workerは実際の redis, hasher, rng コンテナとは接続しません。接 続するのはアンバサダーです。 アンバサダーは本来接続したいコ ンテナへトラフィックを向かわ せます*。 *フォワード、負荷分散、プロキシ… 本番環境では redis 172.17.0.3 worker 172.17.0.4 hasher 172.17.0.1 rng 172.17.0.2 containerhost ambassador
  54. 54. 本番環境では redis 172.17.0.3 worker 172.17.0.4 hasher 172.17.0.1 rng 172.17.0.2 containerhost ambassador hasher 172.17.0.5 rng 172.17.0.4 hasher 172.17.0.8 redis 172.17.0.7 webui 172.17.0.8 redis 172.17.0.6
  55. 55. アンバサダーを使えば • ソースコードは読みやすく、クリーンに保てる • プラミング(サービスディスカバリ、ルーティング、負荷分散など コンテナ同士を繋げる作業)をなくせました! (依然として誰かはやらなければいけないけど) • プラミングは開発環境の邪魔をするものではない • プラミングについての変更は、コードベースに影響しない • 😊
  56. 56. 運用サイドにみられる サービスディスカバリ
  57. 57. どのくらいの早さでサービス更新してる?
  58. 58. ゆっくり更新 • デプロイは滅多にしない - 毎週、定刻で - ちょっとのダウンタイムは OK(数分、まぁ1時間くらいなら) • デプロイの失敗はまれ(年に1回未満) かつ/またはクリティカルな影響はない • 再設定は緊急ではない: - デプロイプロセスの中で対応している - サービス障害やダウンタイムの原因になっても、まあ OK
  59. 59. ゆっくり更新するアプリへの戦略 • 再設定はデプロイプロセスの中で実施する (再ビルド、再プッシュ、再デプロイ) • もしくは、デプロイの後で手で変更すればいいし(!) • 緊急なら: SSH + vi(!)
  60. 60. その結果 • メリット - 前払い費用は発生しない - わかりやすい* • デメリット - 各デプロイ、各変更がリスクそのもの - 長期的にみると高コスト *アプリが落ちて、復旧にしばらく時間がかかるときのあなたの上司は除く
  61. 61. まあまあ更新 • コードのデプロイ - 毎日やってる - ダウンタイムは OKじゃない(ほんのちょっとした不備ならいいかも) • 定期的にデプロイに失敗する 迅速に解決しなければいけない • 再設定は頻繁にある: - スケール up/down、ワークロードの増減、データベースの変更 - A/Bテストのためのパラメタ変更
  62. 62. まあまあ更新するアプリへの戦略 • デプロイ後の設定差し込み • パラメタを変更したかったら: 再設定(すべてを再デプロイするのではなく) • 「pushボタン」スクリプトによるプロセスの自動化
  63. 63. その結果 • メリット - わかりやすいし実装しやすい - 不要な更新作業がない (pushボタンスクリプトだけは余分だけど) • デメリット - サービスが再設定できる作りになっていなければいけない - 再設定は各設定値の変更後に走らなければいけない - デプロイシステムが不具合を起こすリスクがある
  64. 64. ワイルド*に更新 • コードのデプロイ - 継続的に起こる(1日に 10, 100, 1000回以上) - ダウンタイムは OKじゃない(散発的なリクエストの失敗さえも) • デプロイの失敗はいつも起こっている 復旧プロセスは完全に自動化されていなければならない • 再設定はアプリのライフサイクルの一部: - 計画的、非計画的なスケールにも対応した自動スケーリング - 一般化された blue/greenデプロイメント、カナリーテストなど * Wildly.「Move fast and break things」としても知られているもの
  65. 65. ワイルドに更新するアプリへの戦略 • 必須:変更があればそれを検知する仕組み • 以下を連携して使う - 監視 - 受信可能なイベントのライブストリーム - 自分自身を登録することができるサービス - 速いサイクルのポーリング • デプロイ、スケーリング、サービス停止、メトリクス閾値超の後: 自動再設定
  66. 66. その結果 • メリット - すべてが自動で動く - デプロイするとき、他に実行すべきステップはない - よりモジュラーになる (サービスの種類ごとに異なるプロセスに任せられる) • デメリット - メンテナンスが必要な余分な更新作業・サービスが増える - デプロイシステムそのものの失敗が、より危険に
  67. 67. まとめ 更新頻度 ゆっくり まあまあ ワイルド 開発サイド 運用サイド スケール 失敗 ハードコード ✅ 🚫 🚫 😃 😃 😠 😰 12-Factor ✅ 🔄 🚫 😃 😃 😕 😕 設定DB ✅ ✅ ✅ 😩 😠 😎 😎 ローカル LB/ルーター ✅ ✅ ✅ 😐 😐 😎 😎 アンバサダー ✅ ✅ ✅ 😃 😐 😎 😎 うまくいくか 対処方法
  68. 68. まとめ(字幕版) 更新頻度 ゆっくり まあまあ ワイルド 開発サイド 運用サイド スケール 失敗 ハードコード OK NO NO easy easy painfully horribly 12-Factor OK OK with RESTARTS NO easy easy meh meh 設定DB OK OK OK hard hard cool cool ローカル LB/ルーター OK OK OK medium medium/ hard cool cool アンバサダー OK OK OK easy medium/ hard cool cool うまくいくか 対処方法
  69. 69. 実践アンバサダー
  70. 70. プラン • シンプルなアプリケーションのデプロイ(trainingwheels) - ECSで - Swarmで • 複雑なアプリケーションのデプロイ(dockercoins) - ECSで - Swarmで
  71. 71. シンプルなアプリケーション,“trainingwheels” • 2つのサービス - Webサーバ - Redisデータストア • どのサーバがリクエストに応答しているかを教えてくれます • 応答リクエスト数をカウントします • 各サーバごとに独立したカウンターをもちます
  72. 72. Demo • cd ~ • git clone git://github.com/jpetazzo/trainingwheels cd trainingwheels • docker-compose up • ブラウザでアプリを開きます • ^C
  73. 73. ECSでのデプロイ • ECSでは、コンテナはタスクのメンバーとして生成されます • タスクは Task Definitionsで定義します • Task Definitionsは概念的には Composeファイルと似ています (が、フォーマットが異なります) • ECS CLIがデプロイを支援してくれます!
  74. 74. ECSでのデプロイ • ECS CLIがしてくれること: - Composeファイルから Task Definitionsを生成し - その Task Definitionsを ECSに登録します - その Task Definitionsをもとに、ECSインスタンス(EC2)を起動します • ECS CLIがしないこと: - Composeファイルに buildセクションがあると動きません (imageセクションしか受け付けません) • 既出の “build-tag-push” スクリプトを使いましょう!
  75. 75. Demo • build-tag-push.py • 環境変数 COMPOSE_FILEをセット • fixup-yaml.sh
  76. 76. ECSで “trainingwheels”をスケールさせる 現在、デプロイ & スケールさせようとすると、アプリを複数コピー することになります。それぞれが Redisをもってしまうわけです。 これを避けるために、最初のアンバサダーをデプロイします! こんな感じで: • Redisサービスのために新しい Composeファイルを作り • Redisを起動するために ECS CLIを使い、そのロケーションをメモ • Redisサービスが実際の Redisコンテナを指し示すアンバサダーにな るよう、メインの Composeファイルを更新します
  77. 77. jpetazzo/hambaのご紹介 • たくさんのコンテナを、簡単にアンバサダー配下に! • シェルなら: docker run jpetazzo/hamba <frontend-port> [backend1-addr] [backend1-port] [backend2-addr] [backend2-port] … • Composeファイルなら: redis: image: jpetazzo/hamba command: <front-port> [backend1-addr] [backend1-port] …
  78. 78. Demo (1/2) • mkdir ~/myredis • cp $COMPOSE_FILE ~/myredis • cd ~/myredis • $COMPOSE_FILEを編集 - 6379ポートをさらします - wwwサービスを削除 • ecs-cli compose up • ecs-cli compose ps • ホスト名とポート番号をメモします
  79. 79. Demo (2/2) • cd ~/trainingwheels • $COMPOSE_FILEを編集 - redisのイメージを “image: jpetazzo/hamba” に入れ替えます - “command: 6379 <redishost> <redisport>” という一文を追加 • ecs-cli compose up • ecs-cli compose scale 4 • watch ecs-cli compose ps • ブラウザでアプリを開きます
  80. 80. クリーンアップ • ecs-cli compose down • redisは後でまた使うので、走らせたままで OK
  81. 81. Swarmで “trainingwheels”をスケールさせる • ちょっと違ったアイディア! • Composeファイルは 1つをキープ • docker linksをアンバサダーで置き換え - ローカルアドレスの利用(127.X.Y.Z) - (同一ホスト上の)コンテナ間で namespaceを共有 • 他のサービスに接続する各コンテナは、そのサービスを示す プライベートなロードバランサを得ることになる • たくさんのロードバランサが必要になるけど大丈夫、 低コストなサーバリソースで動作します
  82. 82. redisコンテナと wwwコンテナは Swarmによって配置されますが、 異なるホスト上になる可能性が あります。 wwwコンテナの /etc/hostsはこん な感じ。 127.127.0.2 redis Network namespaceアンバサダー redis 172.17.2.5 containerhost ambassador www 172.17.0.4
  83. 83. このタイミングでは、 wwwから redisへの接続は「接続が拒否さ れました」となり、失敗します。 Network namespaceアンバサダー redis 172.17.2.5 containerhost ambassador ⛔ www 172.17.0.4
  84. 84. アンバサダーが起動します。 そのアンバサダーは wwwコンテ ナとネットワークの名前空間を 共有しているので、つまり、同じ ループバックインターフェイスを もっていることになります。 (お互いに localhost上で会話できます) Network namespaceアンバサダー redis 172.17.2.5 containerhost ambassador www 172.17.0.4 ambassador 127.127.0.2
  85. 85. しかし依然として接続は失敗し ます。(「接続が拒否されました」か 「タイムアウトしました」ですが、それは ロードバランサの設定によります) アプリはこれに行儀よく対処す る必要があります。 (クラッシュか再起動でも十分 行儀がいいといえます) Network namespaceアンバサダー redis 172.17.2.5 containerhost ambassador www 172.17.0.4 ⛔ ⌛ ambassador 127.127.0.2
  86. 86. アンバサダーが redisコンテナの パブリックアドレスを含むその 設定を受け取ります。 Network namespaceアンバサダー redis 172.17.2.5 containerhost ambassador www 172.17.0.4 ambassador 127.127.0.2
  87. 87. wwwから redisへのトラフィック が正常に流れます。 Network namespaceアンバサダー redis 172.17.2.5 containerhost ambassador www 172.17.0.4 ambassador 127.127.0.2 ✅
  88. 88. Demo (1/2) • eval $(docker-machine env nod00 --swarm • $COMPOSE_FILEを編集 - redisが使うイメージを “image: redis” にもどします - “command:” セクションを削除 • link-to-ambassadors.pyを実行 • docker-compose up -d • docker-compose ps • ブラウザでアプリを開きます • (まだ動きません..)
  89. 89. Demo (2/2) • create-ambassadors.pyを実行 • configure-ambassadors.pyを実行 • ブラウザでアプリを開きます • docker-compose scale www=4 • create-ambassadors.pyを実行 • configure-ambassadors.pyを実行 • ブラウザでアプリを開きます
  90. 90. アプリをスケールさせるまえに、 アンバサダーとセットにした wwwコンテナをひとつ起動。 (この例では、ステップを明確 にするために redisコンテナも一 緒に起動してしまいます) アンバサダーつきのスケーリング redis containerhost ambassador www ambassador
  91. 91. docker-compose scale www=4 4つの wwwコンテナが起動しまし たが、そのうち 3つはまだ redisと 通信することができません。 アンバサダーつきのスケーリング redis containerhost ambassador www ambassador www www www
  92. 92. create-ambassadors.py 新しい 3つの wwwコンテナが自分 のアンバサダーを確保しますが、 まだ設定がされていません。 アンバサダーつきのスケーリング redis containerhost ambassador www ambassador www www www ambassador ambassador ambassador
  93. 93. configure-ambassadors.py 新しい 3つの wwwコンテナが設定 を受け取り、redisサービスへのト ラフィックをルートできるように なります。 アンバサダーつきのスケーリング redis containerhost ambassador www ambassador www www www ambassador ambassador ambassador
  94. 94. クリーンアップ • docker-compose kill • docker-compose rm -f
  95. 95. ECSで “dockercoins”をスケールさせる • 同じテクニックを適用してみましょう • Redisサービスを分割します • Composeファイルの “redis” をアンバサダーに置き換えます • 残りは ECSに任せましょう
  96. 96. Demo (1/2) • redisのホスト名とポート番号を確認 - cd ~/myredis - ecs-cli compose ps • cd ~/dockercoins • 環境変数 COMPOSE_FILEをセット • $COMPOSE_FILEを編集 - “image: redis” を “image: jpetazzo/hamba” に変更 - “command: 6379 <redishost> <redisport>” を追加 - すべてのコンテナに “mem_limit: 100000000” を追加 - volumesを削除 • fixup-yaml.sh
  97. 97. Demo (2/2) • ecs-cli compose up • watch ecs-cli compose ps • ブラウザでアプリを開きます • ecs-cli compose scale www=4 • watch ecs-cli compose ps • ブラウザでアプリを開きます • 繰り返し!
  98. 98. • redisサービスから始めましょう… containerhost ambassador redis ECSで “dockercoins”をスケールさせる
  99. 99. • アンバサダー入りのサービスグループをひとつ起動します webui containerhost ambassador worker redis redis ECSで “dockercoins”をスケールさせる rnghasher
  100. 100. • 2番目のサービスグループを追加します webui containerhost ambassador worker redis redis ECSで “dockercoins”をスケールさせる rnghasher webui worker redis rnghasher
  101. 101. • もうひとつ…など webui containerhost ambassador worker redis redis ECSで “dockercoins”をスケールさせる rnghasher webui worker redis rnghasher webui worker redis rnghasher
  102. 102. Swarmで “dockercoins”をスケールさせる • 同じテクニックを適用しましょう • Composeファイルの “redis” をアンバサダーに置き換えます • コンテナを起動します • アンバサダーを追加します • アンバサダーに設定を差し込みます
  103. 103. Demo (1/2) • $COMPOSE_FILEを編集 - redisが使うイメージを “image: redis” にもどします - redisの “command:” セクションを削除 • link-to-ambassadors.pyを実行 • docker-compose up -d • create-ambassadors.py • configure-ambassadors.py • docker-compose ps webui • ブラウザで webuiを開きます
  104. 104. Demo (2/2) • docker compose scale webui=2 worker=10 rng=20 hasher=5 • create-ambassadors.pyを実行 • configure-ambassadors.pyを実行 • ブラウザでアプリを開きます
  105. 105. • 単純化のために、2つの Dockerホストだとします Swarmで “dockercoins”をスケールさせる containerhost ambassador
  106. 106. containerhost ambassador • docker-compose up - 繋がっていないコンテナが起動します Swarmで “dockercoins”をスケールさせる webui worker redis rng hasher
  107. 107. containerhost ambassador • 必要に応じてコンテナにアンバサダーを生成します Swarmで “dockercoins”をスケールさせる webui redis worker redis rng hasher hasher rng redis
  108. 108. containerhost ambassador • アンバサダーを設定。アプリが起動します Swarmで “dockercoins”をスケールさせる webui redis worker redis rng hasher hasher rng redis
  109. 109. containerhost ambassador • docker-compose scale Swarmで “dockercoins”をスケールさせる webui redis worker redis rng hasher hasher rng redis worker worker hasher rng hasher rng rng rng
  110. 110. containerhost ambassador • 新しいアンバサダーの生成 Swarmで “dockercoins”をスケールさせる webui redis worker redis rng hasher hasher rng redis worker worker hasher rng hasher rng rng rng redis hasher rng redis hasher rng
  111. 111. • 新しいアンバサダーに設定を差し込み containerhost ambassador Swarmで “dockercoins”をスケールさせる webui redis worker redis hasher hasher rng redis worker worker redis hasher rng redis hasher rng hasher rng rng rng hasher rng rng
  112. 112. 注目点 • そうだね、たしかにアンバサダー多いよね • でもすごく軽いんで(~1MB) docker stat $(docker ps | grep hamba | awk ‘{print $1}’) • アンバサダーを追加してもホップ数は増えません - アンバサダーはそのクライアントに対してローカル (仮想的にレイテンシはゼロ) - 外部のロードバランサと比較すればより効率的 - アンバサダーがダウンしたら、おそらくクライアントも同時にダウン
  113. 113. おさらい
  114. 114. Docker Compose • アプリケーションの可搬性: - Docker Compose + Docker Toolbox - Docker Compose + Docker Swarm - ECS CLI + ECS • インターフェース: - Composeファイル - Docker Registry
  115. 115. ECS & Swarm ハイライト • どちらも簡単なプロビジョニングを支援するもの • ECS = AWSエコシステム: - IAMやELBなど、AWSリソースの利用 - ヘルスチェックや自己回復機能の提供 • Swarm = Dockerエコシステム: - ローカルの開発環境との類似性を提案 - Docker APIを通じてリアルタイムイベントを出力 • どちらもビルドするためのツールが別途必要 (Swarmには予備的なビルドサポートはある) • どちらもプラミング/サービスディスカバリのために要追加作業
  116. 116. 将来への指針、アイディア… • みなさんからのフィードバック、心よりお待ちしております! • 特定アプリに特化したアンバサダー (SQLバウンサー*、クレデンシャルインジェクター…) • オフィシャルイメージを使ったサービスの自動的な置き換え - redis, memcached -> elasticache - mysql, postgresql -> RDS - etc. * 訳者注:不正な入力をブロックするセキュリティソフトウェアのこと
  117. 117. その他実装 • Docker APIのイベントストリームを Listenして、 コンテナの start/stopを検知する - 自動的なロードバランサの設定(ehazlett/interlock) - 設定データベースへのコンテナの追加(gliderlabs/registrator) • オーバーレイネットワーク - サードパーティ: weave, flannel, pipework - Docker network plugin(experimental.docker.com)
  118. 118. ありがとうございました!
  119. 119. コードリポジトリ: https://github.com/aws/amazon-ecs-cli https://github.com/jpetazzo/dockercoins https://github.com/jpetazzo/trainingwheels https://github.com/jpetazzo/orchestration-workshop ビデオ: https://www.youtube.com/watch?v=g-g94H_AiOE Twitterでフォローしてね: @docker @jpetazzo https://www.youtube.com/watch?v=sk3yYh1MgE0 https://www.youtube.com/watch?v=KqEpIDFxjNc https://www.youtube.com/watch?v=LFjwusorazs 備忘:ビデオには導入やデプロイプロセスの様子のみが録画されています。 もし要望がたくさんあれば、他のデモも撮影するつもりです。 https://www.youtube.com/watch?v=O3Bps01THBQ

×