回答:
バインドマウントは、ディレクトリツリーの別の図です。従来、マウントにより、ストレージデバイスのビューがディレクトリツリーとして作成されます。代わりに、バインドマウントは既存のディレクトリツリーを取得し、別のポイントで複製します。バインドマウント内のディレクトリとファイルは、元のものと同じです。2つのビューは同じデータを表示するため、一方の変更はすぐに他方に反映されます。
たとえば、Linuxコマンドを発行した後
mount --bind /some/where /else/where
ディレクトリ/some/where
と/else/where
同じコンテンツを持っています。
ハードリンクやシンボリックリンクとは異なり、バインドマウントはファイルシステムに保存されているものには影響しません。ライブシステムのプロパティです。
bindfs
ファイルシステムは、FUSEのディレクトリツリーのビューを作成するファイルシステム。たとえば、コマンド
bindfs /some/where /else/where
/else/where
の内容/some/where
が表示されるマウントポイントを作成します。
bindfsは別個のファイルシステムであるため、ファイル/some/where/foo
と/else/where/foo
アプリケーションには異なるファイルとして表示されます(bindfsファイルシステムには独自のst_dev
値があります)。一方の変更は「魔法のように」他方に反映されますが、ファイルが同じであるという事実は、bindfsの動作を知っている場合にのみ明らかです。
Bindfsにはマウントポイントに関する情報がないため、の下/some/where
にマウントポイントがある場合は、の下に別のディレクトリとして表示され/else/where
ます。その下のファイルシステムのマウントまたはアンマウントは、対応するディレクトリの変更として/some/where
表示されます/else/where
。
Bindfsはファイルのメタデータの一部を変更できます。ファイルの偽の許可と所有権を示すことができます。詳細についてはマニュアルを参照し、例については以下を参照してください。
bindfsファイルシステムは、root以外のユーザーとしてマウントできます。FUSEファイルシステムをマウントする権限のみが必要です。ディストリビューションによっては、fuse
グループに所属する必要があるか、すべてのユーザーに許可される場合があります。FUSEファイルシステムをアンマウントするfusermount -u
にはumount
、の代わりにを使用します、例えば
fusermount -u /else/where
FreeBSDは、nullfs
ファイルシステムの代替ビューを作成するファイルシステムを提供します。次の2つのコマンドは同等です。
mount -t nullfs /some/where /else/where
mount_nullfs /some/where /else/where
いずれかのコマンドを発行する/else/where
と、の内容/some/where
が表示されるマウントポイントになります。
nullfsは個別のファイルシステムであるため、ファイル/some/where/foo
と/else/where/foo
アプリケーションには異なるファイルとして表示されます(nullfsファイルシステムには独自のst_dev
値があります)。一方の変更は「魔法のように」他方に反映されますが、ファイルが同じであるという事実は、nullfsの動作を知っている場合にのみ明らかです。
ディレクトリツリーのレベルで作用するヒューズbindfsとは異なり、FreeBSDのNULLFSは、カーネル内のより深い作用するので、下にマウントポイントを/else/where
表示されない:同じマウントポイントの一部のみツリー/some/where
の下に反射されます/else/where
。
nullfsファイルシステムは、他のBSDバリアント(OS X、OpenBSD、NetBSD)で使用できる場合がありますが、デフォルトシステムの一部としてコンパイルされません。
Linuxでは、バインドマウントはカーネル機能として使用できます。コマンドラインオプションまたはマウントオプションのmount
いずれかを渡すことにより、コマンドで作成できます。次の2つのコマンドは同等です。--bind
bind
mount --bind /some/where /else/where
mount -o bind /some/where /else/where
ここで、「デバイス」/some/where
は、オンディスクファイルシステムの場合のようなディスクパーティションではなく、既存のディレクトリです。マウントポイント/else/where
は、通常どおり既存のディレクトリである必要があります。どちらの方法でもファイルシステムの種類が指定されていないことに注意してください。バインドマウントを作成すると、ファイルシステムドライバーは使用されず、元のマウントからカーネルデータ構造がコピーされます。
mount --bind
非ディレクトリを非ディレクトリにマウントすることもサポート/some/where
しています。通常のファイルにすることができます(この場合/else/where
、通常のファイルも必要です)。
Linuxのバインドマウントは、元のバインドマウントとほとんど区別できません。このコマンドdf -T /else/where
は、と同じデバイスと同じファイルシステムタイプを表示しdf -T /some/where
ます。ファイル/some/where/foo
と/else/where/foo
は、まるでハードリンクであるかのように区別できません。マウント解除することが可能/some/where
で、その場合/else/where
はマウントされたままになります。
古いカーネル(3.xまでは正確にいつになるかはわかりません)では、バインドマウントは元のカーネルとまったく区別できませんでした。最近のカーネルはバインドマウントを追跡し、PID / mountinfoを介して情報を公開します。これによりfindmnt
、バインドマウントを示すことができます。
にバインドマウントエントリを配置できます/etc/fstab
。必要な他のオプションと一緒に、オプションにbind
(rbind
など)を含めるだけです。「デバイス」は既存のツリーです。filesystemカラムにはnone
or を含めることができますbind
(無視されますが、ファイルシステム名を使用すると混乱するでしょう)。例えば:
/some/where /readonly/view none bind,ro
マウントポイントが下にある場合/some/where
、その内容はの下に表示されません/else/where
。代わりにbind
、rbind
下のマウントポイントを複製することもできます/some/where
。たとえば/some/where/mnt
、がマウントポイントの場合
mount --rbind /some/where /else/where
と同等です
mount --bind /some/where /else/where
mount --bind /some/where/mnt /else/where/mnt
さらに、Linuxでは、マウントをshared、slave、privateまたはunbindableとして宣言できます。これは、そのマウント操作が、マウントポイントを複製するバインドマウントに反映されるかどうかに影響します。詳細については、カーネルのドキュメントを参照してください。
Linuxは、マウントを移動する方法も提供します。--bind
コピー、--move
マウントポイントの移動。
2つのバインドマウントされたディレクトリで異なるマウントオプションを使用することができます。ただし、奇妙な点があります。バインドマウントの作成とマウントオプションの設定はアトミックに行うことはできず、2つの連続した操作である必要があります。(古いカーネルではこれが許可されていませんでした。)たとえば、次のコマンドは読み取り専用ビューを作成しますが、/else/where
読み取り/書き込みが行われる時間が少しあります。
mount --bind /some/where /else/where
mount -o remount,ro,bind /else/where
システムがFUSEをサポートしていない場合、同じ効果を達成するための古典的なトリックは、NFSサーバーを実行し、公開したいファイルをエクスポートし(アクセスを許可localhost
)、同じマシンにマウントすることです。これには、メモリとパフォーマンスの点でかなりのオーバーヘッドがあります。したがって、バインドマウントには、利用可能な場合に明確な利点があります(これは、FUSEのおかげでほとんどのUnixバリアントにあります)。
セキュリティ上の理由から、または誤って変更しないようにするための安全層として、ファイルシステムの読み取り専用ビューを作成すると便利です。
bindfsの場合:
bindfs -r /some/where /mnt/readonly
Linuxでは、簡単な方法:
mount --bind /some/where /mnt/readonly
mount -o remount,ro,bind /mnt/readonly
これにより、/mnt/readonly
読み取り/書き込み中の短い間隔が残ります。これがセキュリティ上の懸念事項である場合、まずルートのみがアクセスできるディレクトリにバインドマウントを作成し、読み取り専用にしてから、パブリックマウントポイントに移動します。以下のスニペットでは、/root/private
(マウントポイントの上のディレクトリ)がプライベートであることが重要であることに注意してください。元のアクセス許可/root/private/mnt
は、マウントポイントの背後に隠されているため、無関係です。
mkdir -p /root/private/mnt
chmod 700 /root/private
mount --bind /some/where /root/private/mnt
mount -o remount,ro,bind /root/private/mnt
mount --move /root/private/mnt /mnt/readonly
ファイルシステムは、数値IDでユーザーとグループを記録します。場合によっては、同じユーザーに異なるユーザーIDを割り当てる複数のシステムになることがあります。これはネットワークアクセスの問題ではありませんが、ディスク上のシステム間でデータを運ぶときにユーザーIDを無意味にします。AliceのユーザーIDが1000で、BobのユーザーIDが1001であるシステムに、マルチユーザーファイルシステム(ext4、btrfs、zfs、UFSなど)で作成されたディスクがあり、そのディスクにアクセスできるようにしたいとします。 AliceのユーザーIDが1001で、BobのユーザーIDが1000のシステム。ディスクを直接マウントすると、AliceのファイルはBobの所有者として表示され(ユーザーIDは1001である)、BobのファイルはAliceの所有者として表示されます(ユーザーIDは1000)。
bindfsを使用して、ユーザーIDを再マップできます。まず、ルートのみがアクセスできるプライベートディレクトリにディスクパーティションをマウントします。次に、パブリックエリアにbindfsビューを作成し、ユーザーIDとグループIDを再マッピングして、アリスとボブのユーザーIDとグループIDを交換します。
mkdir -p /root/private/alice_disk /media/alice_disk
chmod 700 /root/private
mount /dev/sdb1 /root/private/alice_disk
bindfs --map=1000/1001:1001/1000:@1000/1001:@1001/1000 /root/private/alice_disk /media/alice_disk
参照1が、許容非起動したシステムのユーザのホームフォルダのファイルにアクセスどのように?そして、他の例として自分で他のユーザーをバインドします。
chroot監獄やコンテナは、システムのディレクトリツリーのサブツリーでプロセスを実行します。これは、アクセスを制限してプログラムを実行するのに役立ちます。たとえば、同じサーバーに保存されている他のデータではなく、自身のファイルとそのファイルのみにアクセスできるネットワークサーバーを実行します。chrootの制限は、プログラムが1つのサブツリーに限定されることです。独立したサブツリーにアクセスできません。バインドマウントを使用すると、他のサブツリーをそのメインツリーに移植できます。これにより、Linuxでのコンテナーの最も実用的な使用法の基礎となります。
たとえば、マシンがの/usr/sbin/somethingd
データにのみアクセスできるサービスを実行するとします/var/lib/something
。これらのファイルの両方を含む最小のディレクトリツリーはルートです。サービスをどのように制限できますか?1つの可能性は、サービスが必要とするすべてのファイル(少なくとも/usr/sbin/somethingd
いくつかの共有ライブラリ)へのハードリンクを作成すること/var/lib/something
です。しかし、これは面倒です(ハードリンクは、ファイルがアップグレードされるたびに更新する必要がある)、及び場合は動作しません/var/lib/something
し、/usr
異なるファイルシステム上にあります。より良い解決策は、アドホックルートを作成し、マウントを使用してそれを設定することです。
mkdir /run/something
cd /run/something
mkdir -p etc/something lib usr/lib usr/sbin var/lib/something
mount --bind /etc/something etc/something
mount --bind /lib lib
mount --bind /usr/lib usr/lib
mount --bind /usr/sbin usr/sbin
mount --bind /var/lib/something var/lib/something
mount -o remount,ro,bind etc/something
mount -o remount,ro,bind lib
mount -o remount,ro,bind usr/lib
mount -o remount,ro,bind usr/sbin
chroot . /usr/sbin/somethingd &
Linuxのマウント名前空間は、chrootを一般化します。バインドマウントは、柔軟な方法で名前空間を設定する方法です。例については、プロセスに同じファイル名の異なるファイルを読み取らせるを参照してください。
chrootsのもう1つの用途は、ベースシステム上に存在しない、またはコンテンツが異なるハードコードパスにファイルが必要な場合でも、ディレクトリに異なるディストリビューションをインストールし、そこからプログラムを実行することです。これは、たとえば、混合パッケージをサポートしていない64ビットシステムに32ビットディストリビューションをインストールしたり、互換性をテストするために古いリリースのディストリビューションまたは他のディストリビューションをインストールしたり、新しいリリースをインストールしてテストしたりするのに役立ちます安定したベースシステムなどを維持しながら最新機能を使用できます。64ビットDebian / Ubuntuで32ビットプログラムを実行する方法を参照してください。Debian / Ubuntuの例。
ディレクトリーの下にディストリビューションの最新パッケージがインストールされているとします。ここで/f/unstable
、でそのディレクトリーに切り替えてプログラムを実行しchroot /f/unstable
ます。このインストールからホームディレクトリを使用できるようにするには、それらをchrootにバインドマウントします。
mount --bind /home /f/unstable/home
プログラムschrootはこれを自動的に行います。
ファイルシステムをディレクトリにマウントすると、ディレクトリの背後にあるものが隠されます。そのディレクトリ内のファイルは、ディレクトリがアンマウントされるまでアクセスできなくなります。BSD nullfsおよびLinuxバインドマウントはマウントインフラストラクチャよりも低いレベルで動作するため、ファイルシステムのnullfsマウントまたはバインドマウントは、元のサブマウントの背後に隠されていたディレクトリを公開します。
たとえば、tmpfsファイルシステムがにマウントされているとします/tmp
。ファイルが下があった場合には/tmp
tmpfsファイルシステムを作成したときに、これらのファイルがまだ効果的にアクセスできないが、ディスクスペースを取って、残る場合があります。走る
mount --bind / /mnt
(Linux)または
mount -t nullfs / /mnt
(FreeBSD)でルートファイルシステムのビューを作成します/mnt
。ディレクトリ/mnt/tmp
は、ルートファイルシステムのディレクトリです。
一部のNFSサーバー(NFSv4以前のLinuxカーネルNFSサーバーなど)は、ディレクトリをエクスポートするときに常に実際のディレクトリの場所をアドバタイズします。つまり、クライアントが要求するserver:/requested/location
と、サーバーはその場所でツリーにサービスを提供します/requested/location
。クライアントが要求できるようにすることが望ましい場合がある/request/location
が、実際には下のファイルを提供します/actual/location
。NFSサーバーが代替ロケーションの提供をサポートしていない場合、予想されるリクエストに対してバインドマウントを作成できます。
/requested/location *.localdomain(rw,async)
in /etc/exports
および次のin /etc/fstab
:
/actual/location /requested/location bind bind
ファイルを/some/where/is/my/file
表示するためにシンボリックリンクを作成したい場合があります/else/where
が、使用file
するアプリケーションはシンボリックリンクを展開して拒否し/some/where/is/my/file
ます。バインドマウントは、これを回避できます。bind-mount /some/where/is/my
to /else/where/is/my
、そして、realpath
報告/else/where/is/my/file
するのは、under /else/where
ではなくunder /some/where
です。
バインドマウントを使用する場合は、バックアップやインデックス作成など、ファイルシステムツリーを再帰的にトラバースするアプリケーション(たとえば、ロケートデータベースの構築)を処理する必要があります。
通常、各ディレクトリツリーが元の場所で1回だけトラバースされるように、バインドマウントは再帰的なディレクトリトラバーサルから除外する必要があります。bindfsおよびnullfsを使用して、可能であれば、これらのファイルシステムタイプを無視するようにトラバーサルツールを設定します。Linuxバインドマウントはそのように認識できません。新しい場所は元の場所と同等です。Linuxバインドマウント、またはファイルシステムタイプではなくパスのみを除外できるツールを使用する場合、バインドマウントのマウントポイントを除外する必要があります。
ファイルシステムの境界で停止トラバーサル(例えばfind -xdev
、rsync -x
、du -x
彼らはそのマウントポイントが異なるファイルシステムであるため、bindfsまたはNULLFSは、マウントポイント遭遇したとき、...)が自動的に停止します。Linuxバインドマウントでは、状況はもう少し複雑です。ファイルシステムの境界は、バインドマウントが同じファイルシステムの別の部分をグラフトする場合ではなく、異なるファイルシステムをグラフトする場合にのみ存在します。
バインドマウントは、別の場所にあるディレクトリツリーのビューを提供します。それらは、おそらく異なるマウントオプションと(bindfsを使用して)異なる所有権とアクセス許可を持つ同じファイルを公開します。ディレクトリツリーの変更されたビューを提示するファイルシステムは、オーバーレイファイルシステムまたはスタッカブルファイルシステムと呼ばれます。より高度な変換を実行する他の多くのオーバーレイファイルシステムがあります。ここにいくつかの一般的なものがあります。目的のユースケースがここで説明されていない場合は、FUSEファイルシステムのリポジトリを確認してください。
bindfs -r
、もう少し軽量です。連合マウント -現在複数のファイルシステム(と呼ばれる枝単一のディレクトリの下に)次の場合にtree1
含まれているfoo
とtree2
含まれbar
、その後彼らの労働組合のビューが両方含まれていfoo
とbar
。新しいファイルは、特定のブランチ、またはより複雑なルールに従って選択されたブランチに書き込まれます。この概念には、次のようないくつかの実装があります。
mount --bind /dir1 /dir1
するの?マウントのソースとターゲットが異なる場合とどう違いますか?
/proc/self/mountinfo
。chrootについては、分離に使用できますが、単独では使用できません。ただし、マウント名前空間は必要ありません。ファイルシステムの名前空間部分にはchrootで十分です。chrootのプロセスがchrootの外部のプロセスと同じユーザーとして実行されないようにする必要があります。
バインドマウントを使用すると、ホストマシンのファイルまたはディレクトリがコンテナにマウントされるため、ホストマシンのファイルディレクトリ内で行った変更はすべて、ディレクトリのコンテナ内で自動的に使用可能になります。