‫だから､ あのちょっとした魔法は､ 実は魔法じゃなかったんです｡ それがRouting Meshである｡ ルーティング・メッシュは､
‫サービスのパケットをそのサービスのためのタスクに分配する着信またはイングレスのネットワークです｡
‫これは実際にすべてのノードにまたがっており､ IPVSと呼ばれる以前からあるカーネルプリミティブを使用しています｡
‫だから､ 何か派手な新サービスがあるわけではないんです｡ 私たちは､ 本当にLinux Kernelのコアな機能について話しているだけなのです｡
‫ここで実際に行われているのは､
‫すべてのノードでロードバランシングを行い､ すべてのノードでトラフィックをリッスンすることです｡
‫この仕組みについては､ いくつかの方法があります｡
‫最初の例は､ あるコンテナから別のコンテナへの移動です｡
‫バックエンドシステム､ 例えばデータベースのレプリカを2つに増やした場合､ フロントエンドとバックエンドは､
‫実際にはIPアドレスに直接接続することはありません｡
‫Swarmがすべてのサービスの前に置くVIP（仮想IP）と呼ばれるものと実際に会話するのです｡
‫これは､ Swarmの仮想ネットワーク内のプライベートIPで､ あるサービスに対するすべてのタスクに負荷が分散されるようにするものです｡
‫ですから､ アプリケーションにワーカーという役割があり､ それが10種類のコンテナを持っていると想像していただければ､ その前にロードバランサーを置く必要はないのです｡
‫これは､ あなたのためにそれを行います｡
‫仮想ネットワーク内のあるサービスから､ 仮想ネットワーク内の別のサービスへのトラフィックについて話す場合｡
‫また､ ルーティングメッシュの仕組みの2つ目の例として､ スウォームに流入する外部トラフィックは､ 実際にスウォーム内のどのノードに当たるかを選択することができます｡
‫ワーカーノードのいずれかがその公開ポートを開いてコンテナのトラフィックを待ち､ ロードバランスに基づいてそのトラフィックを適切なコンテナに再ルーティングすることになるのです｡
‫これはどういうことかというと､ コンテナをスウォームでデプロイするときに､ それがどのサーバにあるのかを気にする必要がない､
‫ということです｡
‫コンテナに障害が発生し､ スウォームでタスクが再作成された場合､ それを別のノードに置くかもしれません｡ そして､ そのコンテナを再び動作させるために､
‫ファイアウォールを変更したり､ DNSの設定を変更したりする必要がないことも確かです｡
‫ルーティング・メッシュは､ 80番ポートのDrupalウェブサイトをスウォーム内のどのノードからでもアクセスできるようにすることで､
‫これらの問題の多くを解決しています｡ そしてバックグラウンドで､ そのサーバーからパケットを受け取り､
‫コンテナにルーティングしているのです｡ 別のノードにある場合は､ 仮想ネットワーク上にルーティングされます｡
‫同じノードにある場合は､ そのコンテナのポートに迂回させるだけです｡
‫そして､ これを可能にするために､ 私たちは何もする必要がなかったのです｡
‫これは､ すべて既成概念にとらわれないものでした｡
‫その様子を図で見てみましょう｡
‫もし私がnewsformサービスを作成し､ 3つのレプリカを持つように指示したとします｡ そして､ 3つのノードに3つのコンテナで､
‫3つのタスクを作成しました｡ そのオーバーレイネットワークの中で､ サービスのDNS名にマッピングされた仮想IPを実際に作っているわけですね｡
‫そして､
‫サービス名は､ デフォルトでは､ DNS名､ となっています｡
‫この場合､ my-webというサービスを作り､ オーバーレイネットワークにある他のコンテナは､ スウォーム内でそのサービスと話す必要がありますが､
‫彼らはmy webのDNSを使うことだけを心配すればいいのです｡
‫バーチャルIPは､
‫そのサービス内のすべてのタスク間でトラフィックを適切にバウンスします｡
‫実はこれ､ DNSラウンドロビンじゃないんです｡ 実はこれ､ ちょっと違う構成なんです｡ やろうと思えば､ それを可能にすることもできるのです｡
‫実はDNSラウンドロビンを使うという選択肢もあるんです｡
‫ラウンドロビンよりもVIPの方が優れている点は､ アプリ内のDNSキャッシュによって負荷が適切に分散されないことが多々あることです｡
‫DNSの設定でDNSクライアントと戦うのではなく､ VIPに頼っているだけなので､ 専用のハードウェアロードバランサーを購入した場合と同じような感じですね｡
‫2つ目の例では､ 実際に外部からのトラフィックが入ってきたときの様子を示しています｡
‫これは､ 先ほどDrupalで行ったことと似ています｡ 黄色いボックスを作ったとき､ my webという1つのサービスを作り､
‫2つのタスクを作り､ 2つの異なるノードに適用しました｡ それぞれのノードには､ 外部IPアドレスにビルトインのロードバランサーがあります｡
‫私の場合､
‫DigitalOceanを使っているので､ そのIPアドレスはDigitalOceanが教えてくれたものです｡ p を使ってポートで公開すると､ この例ではポート
‫80:80 を使っているので､ 3つのノードのいずれかに入ってきたトラフィックはポート
‫80:80 のロードバランサーに当たります｡ ロードバランサーは､ どのコンテナがトラフィックを取得すべきかを決定し､
‫そのトラフィックがローカルノードにあるか､ あるいはネットワーク経由で別のノードに送信する必要があるかを判断する｡
‫これも実は､ 私たちが特別な努力をすることなく､ すべてバックグラウンドで行われていることなのです｡
‫わかりました｡ では､ このRouting Meshを実際に見てみましょう｡
‫Drupalの例では､ 3つのノードすべてでリッスンする方法をすでに見ました｡
‫しかし､ そのロードバランサーの動作を確認するタスクが複数あったとしたらどうでしょう｡
‫docker service createで､
‫Elasticsearchのコンテナを作成します｡ ここではsearchと呼び､ 3つのレプリカを与えることにします｡
‫そして､ そのデフォルトのポートである9200番で公開したいと思います｡
‫この場合､ :2は今すぐデプロイできる最も簡単なバージョンなので､ 絶対に入れたいところです｡
‫その作成中に､
‫Elasticsearchが実はJSONのWeb APIでアクセスできる検索データベースであることに触れておく｡
‫だから､ カールで打つのは本当に簡単で､ このように良い例を出してくれます｡
‫docker service psで検索してみると､ それぞれのタスクが別のノードにスマートに作成されていることがわかります｡
‫ローカルホスト､ ノード1､ ポート9200でcurlを実行すると､ Elasticsearchの基本情報が返されます｡
‫その一部は､
‫実際にランダムな名前を作成することになります｡
‫それはElasticsearchの機能として出ているに過ぎない｡
‫これを何度もカールさせると､ この時はPatch､ Patchサーバー､ 3度目はJane
‫Fosterと､ こんな風に繰り返されるようになります｡
‫これは､ 実は仮想IPがロードバランサーとして働き､ 3つのタスクに負荷を分散しているのです｡
‫ルーティングメッシュについて､ もう少しだけ注意点を｡ 17で｡ 今回ご紹介する03は､ ルーティングメッシュとロードバランシングが､
‫現状ではステートレスロードバランサーになっています｡
‫Amazonのクラシックロードバランサーや他のロードバランサー技術の内部でStateを扱ったことがある人なら､ これがどういうことなのか分かるでしょう｡
‫これは基本的に､ アプリケーションでセッションクッキーを使用しなければならない場合､ または一貫性のあるコンテナが一貫性のあるクライアントと話すことを期待する場合､
‫その問題を解決するために他のものを追加する必要があるかもしれないと言っているのです｡
‫複数のタスクがあるサービスを利用すると､ その都度､ 潜在的に異なる結果が得られることになります｡
‫また､ これを詳しく説明すると､ 実はレイヤー3のロードバランサーで､ 実際にはIPとポートのレイヤーで動作しているんですね｡
‫実際にはDNSのレイヤーで動作しているわけではありません｡
‫同じサーバーで､ 同じポートで複数のウェブサイトを運営したことがある人なら､ これはまだ無理でしょう｡
‫実際に複数のウェブサイトを同じポート､ 同じスウォームで運用する場合は､
‫さらに別のパズルのピースが必要になります｡
‫幸いなことに､ これはかなり一般的な要求であり､ この2つの問題を解決するためにできるオプションがいくつかあるのです｡
‫NginxやHAProxyは､ ルーティングメッシュの前に座って､ ステートフルロードバランサーやロードバランサーのレイヤーとして機能し､
‫キャッシュや他の多くのことを行うことができるコンテナのかなり良い例があります｡
‫もしそれが必要なら､
‫このセクションのリソースにあるものをチェックするとよいでしょう｡
‫また､ Docker Enterprise版のサブスクリプションを購入すると､ UCPまたはDocker Data Centerと呼ばれるWebインターフェースが付属しています｡
‫しかし､
‫Docker Enterpriseエディションは､ Swarmノード用にサブスクリプションを取得すると､
‫ウェブプロキシ用のビルトインレイヤーが提供されます｡