【参考訳】Docker 1.12 が一般利用版(GA)に

30.07.2016 in Docker using tags Docker , Swarm , translation

概要

7月28日(日本時間29日)、Docker の新しいバージョン 1.12 が GA になりました。blog にも リリースに関する投稿があり、例によって日本語訳を作成しました。内容把握の参考程度にどうぞ。なお、和訳に自信がないトコロは括弧内で原文を表記しています。

Docker 1.12 が一般利用版(GA)に:プロダクション向けに準備が整った Docker 内蔵オーケストレーション

プロダクション環境向けに一般で利用可能な(generally available) Docker 1.12 を作り上げるという、重要な一里塚(マイルストーン)達成のために手助けいただいた、コミュニティの全ての皆さまに感謝を申しあげます。Docker プロジェクトが始まって以来、Docker 1.12 は単一リリースでは最大かつ最も高度な機能群を追加しました。1.12 のオーケストレーションに関しては、多くの技術者(Docker 社員と社外貢献者の皆さん)によって、 様々な面での貢献がありました。貢献とは、オーケストレーション機能の中心となるアルゴリズム、Docker Engine への統合、ドキュメント作成、テストです。

コミュニティの皆さんからの役立つフィードバック、バグ報告、新しいアイディアに、深く感謝を申しあげます。皆さんのご協力がなければ、このように達成できなかったでしょう。特に Docker for Mac と Windows に関しては、6月の DockerCon 以降、1.12 機能に関して何万ものベータテストの皆さんにテストしていただきました。UX のアップ・ダウン投票を通し、bash タブ補完こそが、皆さんが最も必要としている機能だと知見を得られました。DockerCon での公開時点と比較すると、著しい改善を達成しました。たとえば、swarm ノードのジョイン時のワークフロー(簡単に)、エラー報告(簡単に参照)、UX の改善(より論理的に)、ネットワーク(信頼性に関する問題を改善)などです。

また、コアチームは社外メンテナかつ Docker Captain の一人である Chanwik Kaewkasi に大きな感謝を申しあげます。彼は DockreSwarm2000 という素晴らしいプロジェクトで、多くの人々をまとめ上げました。このとき、1.12 RC の swarm モードを使い、コミュニティ全体で約 2,400 ノード、10 万コンテナ近くまでスケールしました。達成できたのは、世界中に拡がるコミュニティを通した提供があったからです。ベアメタルから Raspberry Pi 、様々なクラウドから仮想マシン、x86 アーキテクチャから ARM ベースのシステムに至るまで、ありとあらゆるマシンを提供いただきました。ライブ・データを使った評価を通し、Docker の内蔵オーケストレーションは、初期リリースからちょうど半年で、Docker のオーケストレーション規模が2倍になったと認識しました。これは、アーキテクチャのスケーラビリティを立証するものであり、今後も優れたパフォーマンス最適化の余地がまだあります。

それでは、新しい内蔵オーケストレーションのアーキテクチャについてと、なぜ他のコンテナ・オーケストレーションの手法と異なる構造上の手法をとったのか、それぞれ深掘りしていきましょう。

Swarm モード構造上のトポロジー

Docker 1.12 の内蔵コンテナ・オーケストレーションとは、swarm モードとして知られている機能を有効にするための、オプションの機能セットです。swarm は非集中的(decentralized)であり、Docker ノードの高可用性グループです。各ノードは内蔵型のオーケストレーション・サブシステムであり、Docker に対応した(Dockerized)サービスをスケジュールするために。共通リソースプールを作成する全ての機能を備えています。

Docker ノードの swarm (訳者注:「群れ」や「クラスタ」の意味)は、プログラマブルなトポロジー(接続形態)を作成します。これにより、作業者はノードをマネージャ(manager)にするか、あるいはワーカ(worker)にするかを選択できます。そして、ここには複数のアベイラビリティ・ゾーンを横断して分散化するような、共通の設定を含みます。これらの役割(ロール)は動的なので、API や CLI を通していつでも変えられます。

マネージャが責任を持つのは、クラスタのオーケストレーション、サービス API の提供、タスク(コンテナ)のスケジューリング、障害ヘルスチェック機能を持つコンテナの割り当て(addressing)などです。対照的に、ワーカ・ノードはよりシンプルな機能を提供します。機能とは、タスクをコンテナを通して実行し、特定のコンテナに対するデータ通信をルーティングします。プロダクション環境で強く推奨するのは、「マネージャ」と「ワーカ」のどちらか1つの役割を持たせることです。swarm モードでは、マネージャはコンテナを実行しません。つまり、負荷と攻撃対象領域(attack surface)を減らします。分けることが swarm ノードのセキュリティ優位点の1つです。ワーカ・ノードはデータベースの情報やサービス API にアクセスできません。ワーカ・ノードができるのは、作業を受け付け、状態を報告するだけです。つまり、問題のあるワーカ・ノードがシステムに与えうる影響を最小限にします。

これらのノード間通信の設計に、私たちのチームはかなり注力しました。マネージャとワーカは一貫性、スピード、ボリュームの各用途ごとに、異なる通信が必要です。そのため、2つの異なった通信手法を使います。Raft (ラフト)はマネージャ間のデータ共有で、強い一貫性を保つために(書き込み速度とボリュームの制限を犠牲にし)使います。一方の gossip (ゴシップ)はワーカとの高速な通信とハイ・ボリューム(albeit で結果の一貫性)のために使います。そして、マネージャとワーカ間の通信には、これだけではまだ条件を満たしません。条件の1つは全てが共通する暗号化通信を行うことであり、デフォルトでは mTLS を使います。

マネージャからワーカへの通信

ワーカ・ノードはマネージャ・ノードとの通信に gRPC を使います。これは高速なプロトコルであり、厳しいネットワーク状況でも良好に機能します。そのため、インターネットでの接続(HTTP/2 上に構築)と、内蔵バージョン管理(各ワーカ・ノードで異なったバージョンの Engine が動いていても、同じマネージャ・ノードが通信できます)をも可能にしました。マネージャはワーカに対して実行するタスク・セットを送ります。ワーカは割り当てられたタスクの状態とハートビートをマネージャに対して報告します。この仕組みにより、マネージャはワーカが動作しているのを把握できるのです。

下図はマネージャ・コードのディスパッチャ(dispatcher;発信者、通信指令、配送係)コンポーネントを図式化したものです。どのようにワーカと通信するかを示します。ディスパッチャは各ワーカにタスクを命令する役割を持ちます。対してワーカの役割は、タスクをコンテナに置き換え、コンテナを作成することです。

上図をもとに、Docker サービスが作成され、最終的にコンテナ群を実行するまで何が起こっているかを簡単にみていきましょう。

  • サービス作成

    • ユーザは API にサービス定義を送信します。API は受信し、補完します。
    • オーケストレータ(orchestrator)は、(ユーザによって定義される)期待状態(desired state)を、実際の状態(swarm 上で何が動いているべきか)になるように調整します。API から指定された新しいサービス作成に応答し、タスクを作成します(今回の例では、ユーザはサービスのために1つのインスタンスをリクエストしたと想定します)。
    • アロケータ(allocator)は、タスク用にリソースを割り当てます。全く新しいサービスを作成(API によって作成)し、全く新しいタスクを作成(オーケストレータによって作成)し、どちらにも IP アドレスを割り当てるのに注目します。
    • スケジューラ(scheduler)には、ワーカ・ノードにタスクを割り当てる役割があります。タスクにはノードが割り当てられていないため、スケジューリングが始まります。最適な条件(コンテナやリソースなどに基づく)を見つけ、最終的にはタスクにノードの1つを割り当てます。
    • ディスパッチャ(dispatcher)は、ワーカが接続する場所です。ワーカがディスパッチャに接続したら、命令を待ちます。この方法により、スケジューラによって割り当てられたタスクは、最終的にワーカに対して流されます。
  • サービスの更新

    • ユーザは API を経由してサービス定義を更新します(例:インスタンスを1つから3つに増やします)。API は受信し、保管します。
    • オーケストレータは期待状態と実際の状態を調整します。ユーザは3つのインスタンスを必要としますが、実施には1つしか動いていないのに注目します。そのため、2つの追加タスク作成という反応をします。
    • アロケータとスケジューラとディスパッチャは、先ほど説明した手順を繰り返し、2つのタスクをワーカ上に配置します。
  • ノード障害

    • ディスパッチャは(ハートビート機能によって)接続に失敗するノードを検出します。そして、ノードに DOWN(ダウン状態)とフラグ付けします。
    • オーケストレータは再調整します。3つのインスタンスが実行されるべきですが、そのうちの1を残して障害が起こりました。新しいタスクを生成するよう反応します。
    • アロケータとスケジューラとディスパッチャは、先ほど説明した手順を繰り返し、2つのタスクを新しいワーカ上に配置します。

  • ワーカはゴシップ・ネットワークを使い、オーバレイ・ネットワーク情報を相互に通信します。ゴシップはハイ・ボリュームで、よりスケールできるようピア・ツー・ピア(P2P)ネットワークで設計されています。ノードはタスクを受信すると、コンテナを開始し、他のノードに状態を伝えます。伝えるのは特定のオーバレイ・ネットワーク上でコンテナが開始したという情報です。ブロードキャスト通信はワーカ層で処理されます。スケールを達成できるのは、情報の伝播先は一定数のランダムなノードだけであり、全てのノードに対してではないためです。それで、swarm (クラスタの)大きさにかかわらず動作します。

どのような意味が?

それで、Docker 1.12 オーケストレーションが開発者やオペレータにとってどのような意味があるのでしょうか。今回のリリースでは実に3つの重要なテーマがあり、以下のようなリッチなアーキテクチャをもたらします。

  • フォールト・トレラントな(耐障害性の)アプリケーション・デプロイ・プラットフォーム 。モダンなアプリケーションで増えているのは、マイクロサービス・アーキテクチャ型の設計です。これは、ユーザが複数の異なるサービスを処理するために必要な、データを戻す処理を提供(process of serving back data)します。現実世界のマシンは常に故障するため、これらのマイクロサービスではランダムな障害発生に絶え間なく直面します。Docker 1.12 はマネージャのクォーラム(quorum)の活用により、SPOF (単一障害点)がゼロになる力を提供します。加えて、サービスの抽象化により、複数のレプリカ実行や、ホストで障害が発生しても迅速な再スケジュールを提供します。

  • スケールとパフォーマンス 。Docker 1.12 の swarm モード・オーケストレーション設計は、スケールとパフォーマンスに対する考慮にもとづいています。たとえば、内部の Raft 分散ストアはインメモリのキャッシュ・レイヤを通して、電光石火の如く素早い読み込みに最適化しています。キャッシュは素早い読み込みをもたらしますが、書き込みはどうでしょう。もちろん、各マシンのキャッシュは無効化や更新されるでしょう。私たちの解決策は、オーケストレーション機構の後で処理する設計です。読み込みが集中しても、Raft ストアへの書き込みを絶対に行う設計です。オーケストレーション・システムに組み合わせの判定を導く設計は、一般的なキーバリュー・ストアをベースとするオーケストレータよりも、優れた性能をもたらします。

  • 安全なネットワーク機能 。多くのシステムではセキュリティを有効化するためには、TLS 証明書の生成、異なるポート上でのシステム実行、暗号化されておらず安全ではないネットワークにパケットが流れ出ないよう、トラフィックの流れを調整する必要があるでしょう。Docker 1.12 ではこれら全てを難しい設定を一切必要とせず[*] 利用できます。システムは「デフォルトで安全」です。つまり、安全なアプリケーション管理プラットフォームを準備するために、セキュリティ専門家を必要としません。

[*] この記述には小さな例外があります。オーバレイ・ネットワークのトラフィックです。現時点の Docker バージョンでは、暗号化を有効化するためにはフラグの手入力 -o encrypted (on docker network create -d overlay が必要です。それ以外のトラフィックは、デフォルトで暗号化されています。

Docker 1.12 Swarm モードのディープ・ダイブを確認しましょう:

参照