Mac 用 Docker でのユーザーガイド付きキャッシュ

[この記事は Jeremy Yallop と David Sheets によって書かれました。

最近の Docker リリース (17.04 CE Edge 以降) では、 macOS 上のバインドマウントされたディレクトリのパフォーマンスが大幅に向上しています。(安定版チャネルの Docker ユーザーには、今後の 17.06 リリースで改善点が表示されます。ディレクトリーをバインド・マウントするためのコマンドに、キャッシュを選択的に使用可能にするための新しいオプションがあります。

マウントされたディレクトリで多数の読み取り操作を実行するコンテナーが主な受益者です。 以下は、Docker for Mac ユーザーの間で一般的に使用されているいくつかのツールとアプリケーションの改善点を示しています。 goリストは2.5×高速です。symfony は 2.7× 速く、rake は 3.5× 高速です。

囲碁リスト (2.5×スピードアップ)
Docker for Mac

リストに行きます./...モビー/モビー リポジトリ

シンフォニー (2.7×スピードアップ)
Docker for Mac

カール のメインページの symfony デモアプリ

熊手 (3.5×スピードアップ)
Docker for Mac

レーキ-T @hirowatariのベンチマーク

キャッシュを有効にする方法とタイミング、および内部で何が起こっているかの詳細については、以下をお読みください。

バインドマウントの基本

コンテナの定義特性は 分離です。デフォルトでは、コンテナの実行環境の多くの部分が他のコンテナとホストシステムの両方から分離されています。 ファイルシステムでは、分離は階層化として表示されます:実行中のコンテナのファイルシステムは、一連の インクリメンタルレイヤーその上には、コンテナー内で行われた変更を外部から隠しておくコンテナー固有の読み取り/書き込みレイヤーがあります。

既定としての分離では、コンテナーとデータを共有するために分離をバイパスする最適な方法を慎重に検討することをお勧めします。 移動中のデータの場合、Dockerは さまざまな方法 ネットワーク経由でコンテナを接続します。 保存データの場合、 ドッカーボリューム コンテナー間およびホストとデータを共有するための柔軟なメカニズムを提供します。

ボリュームを使用する最も簡単で最も一般的な方法は、コンテナの起動時にホストディレクトリをバインドマウントすることです — つまり、コンテナのファイルシステム内の指定されたポイントでディレクトリを使用できるようにすることです。 たとえば、次のコマンドはイメージを実行し alpine 、コンテナー内のホスト ディレクトリ /Users/yallop/project を次のように /project公開します。

docker run -v /Users/yallop/project:/project:cached alpine コマンド

この例では、コンテナ内のファイルに対する変更は、ホスト上の対応するファイル /project に対する変更として表示されます。 /Users/yallop/project 同様に、ホスト上の /Users/yallop/project ファイルに対する変更は、 コンテナー内の /project の下にあるファイルに対する変更として表示されます。

バインドマウントには多くのユースケースがあります。 たとえば、次のようなことができます。

  • ホスト上のエディターを使用してソフトウェアを開発し、コンテナーで開発ツールを実行する        
  • コンテナーで定期的なジョブを実行し、出力をホスト ディレクトリに格納する
  • 大規模なデータ資産をホストにキャッシュしてコンテナーで処理する

Linux でのマウントのバインド

Dockerの初心者は、コンテナのパフォーマンスオーバーヘッドがしばしば 無視できる程度に近い 多くの場合、他の形式の仮想化よりも大幅に低くなります。

Linux では、ディレクトリをバインドマウントすると、多くの Docker 機能と同様に、ホスト リソースがコンテナーに直接選択的に公開されます。 その結果、バインドマウントへのアクセスは、通常のプロセスでのファイルシステムアクセスと比較して、オーバーヘッドをほとんどまたはまったく伴いません。

Docker for Mac でのマウントのバインド

Linuxカーネルはコンテナスタイルの分離を効率的にしますが、次のようなLinux以外のオペレーティングシステムのDockerエディションでコンテナを実行します マック  追加のオーバーヘッドを伴ういくつかの追加の可動部品が含まれます。

Docker コンテナーは Linux カーネル上で実行されるため、Docker for Mac コンテナー ランタイム システムは、 ハイパーキット フレームワーク。Linux システム上で実行されているコンテナーは、macOS ファイル システムまたはネットワーク リソースに直接アクセスできないため、Docker for Mac には、Docker エンジンが使用できる方法でこれらのリソースを公開するライブラリが含まれています。

ファイルシステムリソースへのアクセスは、仮想化されたLinux上で実行されているデーモン(「トランスフューズ」)と通信する独立した非特権macOSプロセス(osxfs)によって提供されます。  コンテナ内のバインドマウントされたファイルにアクセスする or read などの open Linux システムコールは、 そうでなければなりません。

  • Linux VFSでFUSEメッセージに変換されました
  • 輸血による virtio ソケットのプロキシ
  • HyperKit によって UNIX ドメインソケットに転送される
  • OSXFSによるmacOSシステムコールとしてデシリアライズ、ディスパッチ、実行

その後、プロセス全体が逆に行われ、macOSシステムコールの結果がコンテナに返されます。

プロセスの各ステップはかなり効率的で、合計ラウンドトリップ時間は約100マイクロ秒になります。 ただし、システムコールが瞬時に行われるという通常正しい仮定の下で記述された一部のソフトウェアは、 数万件のシステムコール ユーザー向けの操作ごとに。 比較的低いオーバーヘッドでさえ、 味気ない 4桁スケールアップした場合。 その結果、Docker for Mac の最初のリリース以降、syscall の待機時間は数回短縮され、待機時間をさらに短縮する機会はいくつか残っていますが、待機時間を最適化するだけでは、すべてのアプリケーションのバインド マウントのパフォーマンスに完全に対処することはできません。

Docker でのファイル共有設計の制約 マック

上記の設計は、Linux の実行環境に厳密に適合し、最小限の構成で済み、特権のあるシステム アクセスをできるだけ少なくする必要があるという Docker for Mac の高レベルの設計目標から生じる多くの制約から生じます。

特に、Docker for Mac ファイル共有の設計の根底にある 3 つの制約があります。

最初の制約は 一貫性です: 実行中のコンテナーは、常にホスト システムと同じバインド マウントされたディレクトリのビューを持つ必要があります。Linuxでは、バインドマウントがディレクトリをコンテナに直接公開するため、一貫性は無料になります。macOSでは、一貫性を維持することは無料ではありません:変更はコンテナとホストの間で同期的に伝播する必要があります。

2 番目の制約は イベントの伝達で、いくつかの一般的なワークフローは受信するコンテナーに依存しています inotify ホスト上でファイルが変更されたとき、またはコンテナーが変更されたときにイベントを受信するホスト上のイベント。繰り返しになりますが、Linux ではイベント伝達は自動的に無料で実行されますが、Docker for Mac では、イベントが迅速かつ確実に伝達されるように追加の作業を実行する必要があります。

3 番目の制約は インターフェイスに関するもので、Docker for Mac でのバインド マウントは、簡潔 v 構文 と より精巧なインターフェース Linuxでのバインドマウント用。

これらの制約は、いくつかの代替ソリューションを除外します。 rsync を使用してファイルをコンテナーにコピーすると、高速アクセスが提供されますが、一貫性はサポートされません。NFS を使用したコンテナへのディレクトリのマウントは、一部のユースケースではうまく機能しますが、イベント伝播をサポートしていません。コンテナー ディレクトリをホストに逆マウントすると、一部のワークロードでは良好なパフォーマンスが得られる場合がありますが、非常に異なるインターフェイスが必要になります。

ユーザーガイド キャッシング

上記の設計制約は、有用な既定値を示しています。 特に、デフォルトで一貫性のないシステムは、特にカジュアルユーザー、Linux実装に慣れているユーザー、および ホスト上で docker を呼び出すソフトウェアにとって、予測不可能で驚くべき方法で動作します。

ただし、すべてのアプリケーションがLinux実装から無料で発生する保証を必要とするわけではありません。 特に、Linuxの実装では、コンテナとホストが常に一貫したビューを持つことが保証されますが、コンテナとホストの間の一時的な不整合が許容される場合があります。 一時的な不整合を許可すると、ファイルシステムの状態をキャッシュし、コンテナとmacOS間の不要な通信を回避し、パフォーマンスを向上させることができます。

アプリケーションが異なれば、必要な一貫性のレベルも異なります。 完全な一貫性が不可欠な場合があり、デフォルトのままです。 ただし、パフォーマンスを向上させるために一時的な不整合が許容できる価格であるケースをサポートするために、Docker 17.04 CE Edge にはオプションの -v新しいフラグが含まれています 。

  • 一貫性: 完全な一貫性。 コンテナー ランタイムとホストは、マウントのビューを常に同じに保ちます。  これは、前述のようにデフォルトです。
  • キャッシュ: ホストのマウントのビューは権限があります。 ホストで行われた更新がコンテナー内に表示されるまでに遅延が発生する場合があります。

たとえば、  上記のバインドマウントされたディレクトリに対してキャッシュモードを有効にするには、次のように記述します。

docker run -v /Users/yallop/project:/project:cached alpine command

また、キャッシュはマウントごとに有効になるため、各ディレクトリを異なるモードでマウントできます。 

docker run -v /Users/yallop/project:/project:cached \
-v /host/another-path:/mount/another-point:consistent \
alpine command

osxfs のドキュメント には、 一貫性 と キャッシュ  によって提供される保証に関する詳細があります。  完全な整合性が無料であるLinuxでは、キャッシュ は 一貫性と同じように動作します。

フィードバック

ディレクトリが新しい キャッシュ モードでマウントされると、いくつかの一般的なアプリケーションのパフォーマンスが大幅に向上しました。

現時点では、読み取り負荷の高いワークロードはキャッシュから最も恩恵を受けます。 書き込み負荷の高いワークロードのパフォーマンスの改善 人気のDDベースのベンチマーク、開発中です。

実際のアプリケーションを含むテストケースは、Docker for Mac開発を導く上で大きな助けになります。 そのため、ファイル共有のパフォーマンスに関するフィールドレポートやその他のコメントがある場合は、ぜひお聞かせください。

あなたは経由で連絡を取ることができます 課題トラッカー. ザ OSXFS のドキュメント パフォーマンスの問題を報告するときに提供する詳細の概要を示します。

詳細情報:

フィードバック

「Mac用Dockerでのユーザーガイド付きキャッシング」に関する0の考え