![マルチホスト VM/Docker ネットワーク通信が遅いのですが、ベストプラクティスはありますか?](https://rvso.com/image/717757/%E3%83%9E%E3%83%AB%E3%83%81%E3%83%9B%E3%82%B9%E3%83%88%20VM%2FDocker%20%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E9%80%9A%E4%BF%A1%E3%81%8C%E9%81%85%E3%81%84%E3%81%AE%E3%81%A7%E3%81%99%E3%81%8C%E3%80%81%E3%83%99%E3%82%B9%E3%83%88%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B9%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%81%8B%3F.png)
VM-1 on host-1 <[cable]> network router <[cable]> host-2 with VM-2
私の理解が正しければ、VM-1 上のアプリケーションから VM-2 上の同じアプリケーションにファイルを転送する場合、データは次の経路をたどります。
- VM-1 アプリケーション ファイルをメモリ バッファに読み込み
- プログラミング言語関連の呼び出し
- オペレーティングシステムレベルの呼び出し
- seccomp/apparmor ロジック
- ファイルシステムの権限ロジック
- オペレーティングシステムのファイル処理とバッファ
- VM-1 アプリケーション データがネットワーク ソケット バッファに送信されました
- オペレーティングシステムコール
- seccomp/apparmor ロジック
- VM-1 オペレーティング システム ネットワーク スタック
- ルーティングテーブル
- ファイアウォールロジック
- ホスト 1 ハイパーバイザー仮想ネットワーク スタック
- 仮想スイッチ
- ルーティングテーブル
- ホスト 1 オペレーティング システム ネットワーク スタック
- ルーティングテーブル
- ファイアウォールロジック
- ホスト 1 物理ネットワーク カード バッファ
- ネットワークルーター
- ほぼ同じスタックが、ホスト 2 上の VM-2 にミラーリングされます。
ファイルが大きいと想定すると、すでに開かれて転送中のファイルについては、seccomp/apparmor、ルーティング、ファイアウォールに関連する手順がキャッシュ/省略されます。
しかし、1~2個のTCPパケットに収まるほど小さいメッセージで仮想マシン間で頻繁に通信する場合、問題が発生します。
すべての呼び出しとロジック処理には数百の CPU ティックが必要であり、説明したオーバースタックは CPU に大きな負荷をかけ、レイテンシに影響を与えます。
- に従ってDocker マルチホスト ネットワーク パフォーマンスのテスト [2016 年 8 月]パフォーマンスは少なくとも -13% 低下します。
- でVMware vSphere® 5 のネットワーク I/O レイテンシ「アイドル状態のシステムでは、VM あたりのラウンドトリップ遅延オーバーヘッドは約 15 ~ 20 マイクロ秒であることがわかりました。この数値は、vSphere 上のリソース競合が増加すると増加しますが、これは予想どおりです。システムがオーバーコミットされていない限り、ジッターは非常に低かったです。」
- さらに、Meltdown および Spectre Intel 修正により、パフォーマンスがさらに低下します。
質問
- VM 間の事前に開かれた通信ソケットは、説明されているリストのいずれかの手順を省略しますか?
- しますかSDN何らかの方法でこのような問題を軽減するか、パケットにさらに多くのオーバーレイと追加のヘッダーを追加するのでしょうか?
- VM-1 と VM-2 の間で通信するために、説明されているプロセスが本当に必要ですか、それとも特別な Linux の「安全性は低いがパフォーマンスは高い、自己責任で使用」ビルドがあるのでしょうか?
- Linux にこだわらなければならないのでしょうか? Docker をサポートする、より高速な *BSD のようなシステムはありますか?
- 結果として、同じホスト上でマイクロサービスを備えた VM をさらに多く配置できるようにボトルネックを軽減するためのベスト プラクティスは何ですか?
- 次のような解決策がありますかプロジェクト カリコヘルプですか、それとも低レベルに関するものですか?
答え1
VM 間の事前に開かれた通信ソケットは、説明されているリストのいずれかの手順を省略しますか?
VM/コンテナ間で事前に開かれたソケットは、TCP ハンドシェイクのオーバーヘッドのためにトリックを実行します。TLS がある場合はさらにトリックを実行します。
ハンドシェイクのオーバーヘッドは無視できるほど小さいと認められていますが、頻繁な通信について言えば、それが重要な役割を果たし始めます。
メッシュのようなコンテナ ネットワークの場合、M x N のオープン接続の境界状態を持つことはあまり賢明ではありません。独自のコンテナ通信統計に基づいた TTL を使用したシンプルなキープアライブ ソリューションの方が適しています。
TCP 接続を維持するスレッドが多すぎると別のオーバーヘッドが発生するので、必ず epoll を使用してください。
SDN は、このような問題を何らかの形で軽減するのでしょうか、それとも、パケットにさらに多くのオーバーレイと追加のヘッダーを追加するのでしょうか?
オーバーレイは追加され、多くはベンダーロックされていますが、少なくとも1つは配管SDN以下では、Docker 環境に関する関連ソリューションについて説明します。
VM-1 と VM-2 の間で通信するために、説明されているプロセスが本当に必要ですか、それとも特別な Linux の「安全性は低いがパフォーマンスは高い、自己責任で使用」ビルドがあるのでしょうか?
十分に信頼できるコミュニティと更新サポートを備えた「特別な」Linux ビルドは見つかりませんでしたが、Linux TCP スタックの速度低下に関する問題は新しいものではなく、カーネル バイパスのオプションも多数あります。Cloudflareはそれを実現する。
から私が見つけた記事遅い Linux TCP スタックはよく知られており、Linux サーバーをドロップインして勝つという選択肢はありません。毎回、Torvald の子を微調整して、独自の問題を解決する必要があります。
Linux にこだわらなければならないのでしょうか? Docker をサポートする、より高速な *BSD のようなシステムはありますか?
カーネル バイパスが適用された低速 TCP スタックを備えた最新の Linux よりも、Windows、MacOS、または *BSD のようなシステムが優れたネットワークを実現したという証拠は見つかりませんでした。
結果として、同じホスト上でマイクロサービスを備えた VM をさらに多く配置できるようにボトルネックを軽減するためのベスト プラクティスは何ですか?
つまり、ゲスト Linux とホスト Linux の 2 つのボトルネックがあります。
ホストLinuxの場合、コンテナホスティングだけでなく、さまざまなオプションを備えたカーネルバイパス戦略が存在します。Cloudflare ブログそして「なぜ Linux カーネルの TCP スタックを使用するのか?」の記事独自のアプリケーション中心の TCP スタックを作成することができます。
ゲストLinuxの場合マックヴランレイヤー3をバイパスして、Dockerコンテナを独自のMACアドレスを持つNICに直接接続するために使用できます。ブリッジよりずっといいこれは、ゲストとホストの両方の Linux ネットワークのボトルネックを大幅に軽減するためですが、ルーターの MAC アドレス テーブルをさらに 100 または 1,000 のレコードで拡張する準備ができていることを確認してください。おそらく、ネットワークをセグメント化する必要があるでしょう。
また、仮想スイッチング技術と Linux ブリッジのプレゼンテーションMacvlanよりもさらに優れたSR-IOVオプションがあります。Mellanox Ethernet アダプタ用の docker 1.9+ で利用可能プラグインとして、モードとして含まれている配管SDN、献身的にClear Containers の SRIOV プラグイン- アプリケーションに重点を置いたソリューションの検討を開始するには十分すぎるほどです。
Project Calico のようなソリューションは役立ちますか、それともより低レベルのものですか?
これはまったく別のレベルであり、SRIOV や Macvlan と比較すると大きな影響はありませんが、選択したバイパス ソリューションにほとんどオーバーヘッドをかけずにネットワーク管理を簡素化するのに役立ちます。
はい...
Docker は予期しない動作をする可能性があるため、注意深く監視してください。たとえば、Macvlan がオンになっているのに理由もなくmodprobesnf_nat
やを実行すると、余分な CPU ティックが消費されます。xt_conntrack