ファイルシステム共有 [osxfs]

osxfs は Docker Desktop for Mac 限定の、新しい共有ファイルシステムのソリューションです。 osxfs は macOS ファイルシステム・ツリーを Docker コンテナ内にバインド・マウントするにあたり、ネイティブに近いユーザ体験を提供します。この目的のため、 osxfs の機能には、古典的な Linux ファイルシステムとは異なる数々のユニークな機能があります。

大文字と小文字の区別(case sensitivity)

Docker Desktop for Mac では、コンテナ内のファイルシステム操作が、 macOS で操作するのと同じように行えます。macOS 上のファイルシステムが大文字小文字を区別するなら、その挙動は macOS からコンテナ内にバインド・マウントする場合も同じです。

macOS Sierra と以前では、デフォルトのファイルシステムは HFS+ です。 macOS Hight Sierra では、デフォルトのファイルシステムは APFS です。いずれもデフォルトで大文字小文字を区別しますが、バージョンによって大文字小文字を区別するものとしないものがあります。

大文字小文字の挙動がどうなるかは、バインド・マウントに用いるフォーマット形式が HFS+ か APFS かに依存します。 APFS FAQ をご覧ください。

同じ Mac 上のソフトウェアは大文字小文字の機能に依存していますので、root パーティションの再フォーマットは推奨しません。


osxfs では、 Dockerはファイスシステムリソースに対してアクセス可能です。つまり、 Docker Desktop for Mac ユーザは osxfs にアクセスしますが、 root としては実行できません。もしも macOS ユーザが administrator であれば、 osxfs は administrator 権限を継承します。私たちはセキュリティと使いやすさのバランスをとるために、ファイルシステム処理から権限を落とせるように取り組んでいます。 osxfs の動作は、追加の権限チェックがなく、追加のアクセス制御もありません。コンテナ内の全てのプロセスは、コンテナを起動した Docker ユーザによって同じ方法で同じオブジェクトに対してアクセスできます。

名前空間(namespaces)

macOS ファイルシステムの大部分は、 -v バインド・マウント構文をコンテナで用いてユーザによってアクセス可能です。以下のコマンドを実行すると、 r-base という名称のイメージからコンテナを実行し、macOS ユーザの ~/Desktop/ ディレクトリをコンテナ内の /Desktop としてマウントします。

$ docker run -it -v ~/Desktop:/Desktop r-base bash

ユーザの ~/Desktop/ ディレクトリは、コンテナ内の / ディレクトリ以下に見えるようになります。

root@2h30fa0c600e:/# ls
Desktop      boot    etc     lib     lib64   media   opt     root    sbin    sys     usr
bin  dev     home    lib32   libx32  mnt     proc    run     srv     tmp     var

デフォルトでは、 /Users//private//tmp ディレクトリにあるファイルを共有可能です。ディレクトリツリーの追加や削除を Docker に反映するには、 Docker の設定、 鯨アイコン -> Preferences -> File sharing にある Fire sharing のタブを使います( 設定のページ をご覧ください)。

-v バインドマウントで使う他のすべてのパスは、Docker コンテナが稼働する Moby Linux 仮想マシンをソースとしますので、引数では -v /var/run/docker.sock:/var/run/docker.sock のような指定が動作します。もしも macOS のパスが共有されたおらず、仮想マシン上に存在しなければ、仮想マシンを生成せずにバインド・マウントは失敗します。パスは既に仮想マシン上に存在するものであり、含まれるファイルは Docker に予約済みであり、macOS 側には露出(export)できません。

所有権(Ownership)

初期化時、あらゆるコンテナ化したプロセスは、自身のオブジェクトに対して uidgid といったオブジェクトのメタデータ所有者をリクエストします。あらゆるコンテナ化したプロセスにおいて、 chown コマンドなどを用いて共有ファイルシステムオブジェクト上の所有権を変更すると、新しい所有者情報はオブジェクトの拡張属性 com.docker.owner`内に存在します。所有者メタデータの変更に伴い、それに続く処理では以前にセットした値を返します。所有者を元にした権限(ownership-based permissions)は、macOS ファイルシステムレベル上のみ強制されるもので、Docker を実行しているユーザによるプロセスであればすべてアクセス可能です。もしもユーザがオブジェクトに対する拡張属性を読み込む権限が無ければ(オブジェクトのパーミッションが :code:`0000 のような場合)、 osxfs はユーザが読み書きできるような拡張属性を得られるよう、アクセスコントロールリスト(ACL)のエントリを追加しようとします。割り当てに失敗すると、オブジェクトはプロセスの所有者のものとして表示され、拡張属性は再び読み込み可能なものとして表示します。

ファイルシステムイベント(File system events)

大部分の inotify イベントはバインド・マウントでサポートしています。また、 dnotifyfanotify (あまりよくテストされていません)もサポートしています。つまり、macOS からのファイルシステムイベントは、コンテナ内のプロセスに対しても送信され、あらゆるリッスンしているプロセスがトリガとなります。

以下は サポートしているファイルシステムイベントです

  • 作成
  • 変更
  • 属性変更
  • 削除
  • ディレクトリ変更

以下は 一部サポートしているファイルシステムイベントです

  • ソース上で IN_DELETE をトリガとする移動イベントによる名前変更と、名前変更先の IN_MODIFY

以下は サポートしていないファイルシステムイベントです

  • オープン
  • アクセス
  • クローズイベント
  • アンマウント・イベント(マウントをご覧ください)

いくつかのイベントは何度も送られます。コンテナ間のイベントは反映しないという制約があります。各イベントは macOS を起点としているものだけです。

マウント(Mounts)

共有ボリューム上では macOS マウント構造は見えませんが、ボリュームの内容は見えます。ボリュームの中身として表示されるのは、共有ファイルシステム上の場所にあるものと同一のファイルシステムです。macOS ボリュームのマウントおよびアンアウントとは、コンテナの中に対するバインド・マウントでもあるので、コンテナ内においては予期しない挙動が発生する場合もあります。アンマウントイベントはサポートされていません。マウント・エクスポートのサポートは計画中ですが、まだ開発中です。

ファイルタイプ

シンボリックリンク、ハードリンク、ソケットファイル、名前付きパイプ、通常のファイル、ディレクトリをサポートしています。ソケットファイルと名前付きパイプは、コンテナと macOS プロセス間のみで送信(transmit)するだけです。つまりハイパーバイザを横断する送信は、まだサポートしていません。キャラクタおよびブロックデバイスファイルはサポート外です。

拡張属性(Extended attributes)

拡張属性はまだサポートしていません。

技術

osxfs は OSXUFSE を使いません。 osxfs は macOS ユーザー空間プロセスと macOS カーネル間で、あるいは、その配下、内部では動作しません。

SSH エージェント転送(SSH agent forwarding)

Docker Desktop for Mac はホスト側の SSH エージェントをコンテナ内で利用できます。そのためには、

  1. SSH エージェントの助っ人をバインド・マウントするため、 docker run コマンドで以下のパラメータを追加: --mount type=bind,src=/run/host-services/ssh-auth.sock,target=/run/host-services/ssh-au
--mount type=bind,src=/run/host-services/ssh-auth.sock,target=/run/host-services/ssh-auth.sock
  1. SSH_AUTH_SOCK 環境変数をコンテナに追加: -e SSH_AUTH_SOCK="/run/host-services/ssh-auth.sock"
-e SSH_AUTH_SOCK="/run/host-services/ssh-auth.sock"

Docker Compose で SSH エージェントを有効化するには、サービスに以下のフラグを追加します:

services:
  web:
    image: nginx:alpine
    volumes:
      - type: bind
        source: /run/host-services/ssh-auth.sock
        target: /run/host-services/ssh-auth.sock
    environment:
      - SSH_AUTH_SOCK=/run/host-services/ssh-auth.sock

パフォーマンス問題、ソリューション、ロードマップ

ヒント

Docker 17.04 CE Edge リリースで利用可能になった新しい設定オプションについて学ぶには ボリューム・マウント(共有ファイルシステム)のためのパフォーマンス・チューニング をご覧ください。

(TBD、将来的に変更する可能性があるため。また、マニュアル本編とは直接関係がないため)




参考

File system sharing (osxfs)
https://docs.docker.com/docker-for-mac/osxfs/