バインドマウントとは何ですか?


325

「バインドマウント」とは何ですか?どうやって作るの?それは何の役に立つのですか?

私は何かにバインドマウントを使用するように言われましたが、それが何であるか、またはそれをどのように使用するかを理解していません。


2
マウントとシンボリックリンクの間に有用な代替明確化:quora.com/...
チャーリー・パーカー

回答:


564

バインドマウントとは何ですか?

バインドマウントは、ディレクトリツリーの別の図です。従来、マウントにより、ストレージデバイスのビューがディレクトリツリーとして作成されます。代わりに、バインドマウントは既存のディレクトリツリーを取得し、別のポイントで複製します。バインドマウント内のディレクトリとファイルは、元のものと同じです。2つのビューは同じデータを表示するため、一方の変更はすぐに他方に反映されます。

たとえば、Linuxコマンドを発行した後

mount --bind /some/where /else/where

ディレクトリ/some/where/else/where同じコンテンツを持っています。

ハードリンクやシンボリックリンクとは異なり、バインドマウントはファイルシステムに保存されているものには影響しません。ライブシステムのプロパティです。

バインドマウントを作成するにはどうすればよいですか?

bindfs

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

nullfs

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バインドマウント

Linuxでは、バインドマウントはカーネル機能として使用できます。コマンドラインオプションまたはマウントオプションのmountいずれかを渡すことにより、コマンドで作成できます。次の2つのコマンドは同等です。--bindbind

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。必要な他のオプションと一緒に、オプションにbindrbindなど)を含めるだけです。「デバイス」は既存のツリーです。filesystemカラムにはnoneor を含めることができますbind(無視されますが、ファイルシステム名を使用すると混乱するでしょう)。例えば:

/some/where /readonly/view none bind,ro

マウントポイントが下にある場合/some/where、その内容はの下に表示されません/else/where。代わりにbindrbind下のマウントポイントを複製することもできます/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では、マウントをsharedslaveprivateまたは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。ファイルが下があった場合には/tmptmpfsファイルシステムを作成したときに、これらのファイルがまだ効果的にアクセスできないが、ディスクスペースを取って、残る場合があります。走る

mount --bind / /mnt

(Linux)または

mount -t nullfs / /mnt

(FreeBSD)でルートファイルシステムのビューを作成します/mnt。ディレクトリ/mnt/tmpは、ルートファイルシステムのディレクトリです。

異なるパスでのNFSエクスポート

一部の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/myto /else/where/is/my、そして、realpath報告/else/where/is/my/fileするのは、under /else/whereではなくunder /some/whereです。

バインドマウントの副作用

再帰的なディレクトリトラバーサル

バインドマウントを使用する場合は、バックアップやインデックス作成など、ファイルシステムツリーを再帰的にトラバースするアプリケーション(たとえば、ロケートデータベースの構築)を処理する必要があります

通常、各ディレクトリツリーが元の場所で1回だけトラバースされるように、バインドマウントは再帰的なディレクトリトラバーサルから除外する必要があります。bindfsおよびnullfsを使用して、可能であれば、これらのファイルシステムタイプを無視するようにトラバーサルツールを設定します。Linuxバインドマウントはそのように認識できません。新しい場所は元の場所と同等です。Linuxバインドマウント、またはファイルシステムタイプではなくパスのみを除外できるツールを使用する場合、バインドマウントのマウントポイントを除外する必要があります。

ファイルシステムの境界で停止トラバーサル(例えばfind -xdevrsync -xdu -x彼らはそのマウントポイントが異なるファイルシステムであるため、bindfsまたはNULLFSは、マウントポイント遭遇したとき、...)が自動的に停止します。Linuxバインドマウントでは、状況はもう少し複雑です。ファイルシステムの境界は、バインドマウントが同じファイルシステムの別の部分をグラフトする場合ではなく、異なるファイルシステムをグラフトする場合にのみ存在します。

バインドマウントを超える

バインドマウントは、別の場所にあるディレクトリツリーのビューを提供します。それらは、おそらく異なるマウントオプションと(bindfsを使用して)異なる所有権とアクセス許可を持つ同じファイルを公開します。ディレクトリツリーの変更されたビューを提示するファイルシステムは、オーバーレイファイルシステムまたはスタッカブルファイルシステムと呼ばれます。より高度な変換を実行する他の多くのオーバーレイファイルシステムがあります。ここにいくつかの一般的なものがあります。目的のユースケースがここで説明されていない場合は、FUSEファイルシステムのリポジトリを確認してください。

可視ファイルをフィルタリングする

  • clamfs読み取られたファイルをウイルススキャナーで実行する
  • filterfs —ファイルシステムの一部を隠す
  • rofs —読み取り専用ビュー。と同様にbindfs -r、もう少し軽量です。
  • 連合マウント -現在複数のファイルシステム(と呼ばれる単一のディレクトリの下に)次の場合にtree1含まれているfootree2含まれbar、その後彼らの労働組合のビューが両方含まれていfoobar。新しいファイルは、特定のブランチ、またはより複雑なルールに従って選択されたブランチに書き込まれます。この概念には、次のようないくつかの実装があります。

ファイル名とメタデータを変更する

  • ciopfs —大文字と小文字を区別しないファイル名(Windowsファイルシステムのマウントに役立ちます)
  • convmvfs —文字セット間でファイル名を変換します(
  • posixovl — VFATなどのより制限されたファイルシステムにUnixファイル名とその他のメタデータ(許可、所有権など)を保存します(

変更されたファイルの内容を表示する

コンテンツの保存方法を変更する

  • chironfs —ファイルを複数のストレージ(ディレクトリツリーレベルのRAID-1)に複製します
  • copyfs —ファイルのすべてのバージョンのコピーを保持します
  • encfs —ファイルを暗号化する
  • pcachefs —遅いリモートファイルシステム用のディスク上のキャッシュ層
  • simplecowfs —提供されたビューを使用して変更をメモリに保存し、元のファイルをそのまま残します
  • ウェイバック —ファイルのすべてのバージョンのコピーを保持する

1
systemdでそれを行う方法の例を追加することができます。utcc.utoronto.ca
space

1
何をmount --bind /dir1 /dir1するの?マウントのソースとターゲットが異なる場合とどう違いますか?
マーク

linux 5.0を使用して、/ proc / self / mountinfoにレコードが表示されませんでした。カーネルは、バインドマウントであるかどうかを教えてくれません。また、プロセスはchrootを簡単に破ることができるため、マウント名前空間によって分離を行う必要があります。
炸鱼薯条德里克

@炸鱼薯条德里克リンクされた質問unix.stackexchange.com/questions/295525/…アドレス/proc/self/mountinfo。chrootについては、分離に使用できますが、単独では使用できません。ただし、マウント名前空間は必要ありません。ファイルシステムの名前空間部分にはchrootで十分です。chrootのプロセスがchrootの外部のプロセスと同じユーザーとして実行されないようにする必要があります。
ジル

@Markディレクトリをそれ自体にバインドマウントすることは、あまり役に立ちません。特定のディレクトリの下にマウントされているファイルシステムを隠すためにそれを使用できると思いますが、私がそれを具体的にやりたいと思った時期は思いつきません。
ジル

-1

バインドマウントを使用すると、ホストマシンのファイルまたはディレクトリがコンテナにマウントされるため、ホストマシンのファイルディレクトリ内で行った変更はすべて、ディレクトリのコンテナ内で自動的に使用可能になります。


これはバインドマウントを使用する方法の1つですが、バインドマウント自体はコンテナとは関係ありません。私は答えでそれを言及していますが、「コンテナ」ではなく「刑務所」という名前で。「コンテナ」を追加することは価値のある編集になります(私はそれを行います)。これはまた貧弱な記述です:なぜ外部で行われた変更は内部で利用可能であると言及するのに、他の方法で言及しないのですか?
ジル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.