「バインドマウント」とは何ですか?どうすれば作れますか?何に適していますか?
何かにバインドマウントを使用するように言われましたが、それが何であるか、またはその使用方法がわかりません。
承認された回答:
バインドマウントとは何ですか?
バインドマウント ディレクトリツリーの代替ビューです。従来、マウントはストレージデバイスのビューをディレクトリツリーとして作成します。代わりに、バインドマウントは既存のディレクトリツリーを取得し、それを別のポイントに複製します。バインドマウント内のディレクトリとファイルは、元のディレクトリと同じです。 2つのビューには同じデータが表示されるため、一方の変更はすぐにもう一方の側に反映されます。
たとえば、Linuxコマンドを発行した後-
mount --bind /some/where /else/where
ディレクトリ/some/where
および/else/where
/some/where
のコンテンツである同じコンテンツを持っている 。 (/else/where
の場合 空ではなかったため、以前のコンテンツは非表示になりました。)
ハードリンクやシンボリックリンクとは異なり、バインドマウントはファイルシステムに保存されているものに影響を与えません。これはライブシステムの所有物です。
バインドマウントを作成するにはどうすればよいですか?
bindfs
bindfs
filesystemは、ディレクトリツリーのビューを作成する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がどのように動作するかを知っている場合にのみ明らかになります。
ディレクトリツリーのレベルで機能するFUSEbindfsとは異なり、FreeBSDのnullfsはカーネルのより深いところで機能するため、/else/where
の下にマウントポイントがあります。 表示されません:/some/where
と同じマウントポイントの一部であるツリーのみ /else/where
の下に反映されます 。
nullfsファイルシステムは他のBSDバリアント(OS X、OpenBSD、NetBSD)で使用できる場合がありますが、デフォルトシステムの一部としてコンパイルされていません。
Linuxバインドマウント
Linuxでは、バインドマウントはカーネル機能として利用できます。 mount
で作成できます コマンド、--bind
のいずれかを渡すことによって コマンドラインオプションまたはbind
マウントオプション。次の2つのコマンドは同等です。
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
など)オプションで、必要な他のオプションと一緒に。 「デバイス」は既存のツリーです。ファイルシステム列には、none
を含めることができます または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ではマウントを共有として宣言できます。 、スレーブ 、プライベート またはバインド不可 。これは、そのマウント操作がマウントポイントを複製するバインドマウントに反映されるかどうかに影響します。詳細については、カーネルのドキュメントを参照してください。
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のみがアクセスできるディレクトリにバインドマウントを作成し、読み取り専用にしてから、パブリックマウントポイントに移動します。以下のスニペットでは、/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は無意味になります。アリスのユーザーIDが1000、ボブのユーザーIDが1001のシステムで、マルチユーザーファイルシステム(ext4、btrfs、zfs、UFSなど)で作成されたディスクがあり、そのディスクにアクセスできるようにしたいとします。アリスのユーザーIDが1001で、ボブのユーザーIDが1000のシステム。ディスクを直接マウントすると、アリスのファイルはボブが所有しているように見え(ユーザーIDが1001であるため)、ボブのファイルはアリスが所有しているように見えます(ユーザーIDは1000です。
bindfsを使用してユーザーIDを再マップできます。まず、rootのみがアクセスできるプライベートディレクトリにディスクパーティションをマウントします。次に、パブリックエリアに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
起動していないシステムのユーザーのホームフォルダにあるファイルに許可された方法でアクセスするにはどうすればよいですか?を参照してください。マウント–他のユーザーを自分自身の別の例としてバインドします。
刑務所またはコンテナへの取り付け
chroot jailまたはコンテナは、システムのディレクトリツリーのサブツリーでプロセスを実行します。これは、アクセスが制限されたプログラムを実行する場合に役立ちます。自身のファイルとそれが提供するファイルにのみアクセスできるネットワークサーバーを実行しますが、同じコンピューターに保存されている他のデータにはアクセスできません)。 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を一般化します。バインドマウントは、名前空間に柔軟な方法でデータを入力する方法です。例については、プロセスに同じファイル名の別のファイルを読み取らせるを参照してください。
別のディストリビューションを実行する
chrootの別の使用法は、ディレクトリに別のディストリビューションをインストールし、そこからプログラムを実行することです。ハードコードされたパスにファイルが必要な場合でも、ベースシステムに存在しないか、コンテンツが異なります。これは、たとえば、混合パッケージをサポートしない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マウントまたはバインドマウントは、元のサブマウントの背後に隠されていたディレクトリを公開します。
関連:別のファイルからの情報を使用してファイルの値を更新しますか?
たとえば、/tmp
にtmpfsファイルシステムがマウントされているとします。 。 /tmp
の下にファイルがあった場合 tmpfsファイルシステムが作成されたとき、これらのファイルはまだ残っている可能性があり、事実上アクセスできませんが、ディスク領域を占有しています。実行
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)
/etc/exports
にあります および/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
/else/where/is/my
へ 、次にrealpath
/else/where/is/my/file
を報告します /else/where
の下にあります 、/some/where
の下ではありません 。
バインドマウントの副作用
再帰的なディレクトリトラバーサル
バインドマウントを使用する場合は、バックアップやインデックス作成など、ファイルシステムツリーを再帰的にトラバースするアプリケーションを処理する必要があります(たとえば、データベースの検索を構築するため)。
通常、バインドマウントは、再帰的なディレクトリトラバーサルから除外する必要があります。これにより、各ディレクトリツリーは、元の場所で1回だけトラバーサルされます。 bindfsとnullfsを使用して、可能であれば、これらのファイルシステムタイプを無視するようにトラバーサルツールを設定します。 Linuxバインドマウントはそのように認識できません。新しい場所は元の場所と同じです。 Linuxバインドマウント、またはパスのみを除外でき、ファイルシステムタイプを除外できないツールを使用する場合は、バインドマウントのマウントポイントを除外する必要があります。
ファイルシステムの境界で停止するトラバーサル(例:find -xdev
、rsync -x
、du -x
、…)は、bindfsまたはnullfsマウントポイントに遭遇すると自動的に停止します。これは、そのマウントポイントが別のファイルシステムであるためです。 Linuxバインドマウントの場合、状況は少し複雑になります。ファイルシステムの境界が存在するのは、バインドマウントが別のファイルシステムを移植している場合のみであり、同じファイルシステムの別の部分を移植している場合はありません。
バインドマウントを超える
バインドマウントは、別の場所にあるディレクトリツリーのビューを提供します。それらは同じファイルを公開しますが、おそらくマウントオプションが異なり、(bindfsを使用して)所有権と権限が異なります。ディレクトリツリーの変更されたビューを表示するファイルシステムは、オーバーレイファイルシステムと呼ばれます。 またはスタック可能なファイルシステム 。より高度な変換を実行するオーバーレイファイルシステムは他にもたくさんあります。ここにいくつかの一般的なものがあります。希望するユースケースがここに記載されていない場合は、FUSEファイルシステムのリポジトリを確認してください。
- loggedfs —デバッグまたは監視の目的ですべてのファイルシステムアクセスをログに記録します(構成ファイルの構文、特定のファイルを作成したプログラムまたはスクリプトを見つけることは可能ですか?、プログラムによってアクセスされるファイルを一覧表示します)
表示されているファイルをフィルタリングする
-
clamfs —ファイルが読み取られたときにウイルススキャナーを介してファイルを実行します
-
filterfs —ファイルシステムの一部を非表示にする
-
rofs —読み取り専用ビュー。
bindfs -r
に似ています 、もう少し軽量です。 -
ユニオンマウント—複数のファイルシステム(ブランチと呼ばれる)を提供します )単一のディレクトリの下:
tree1
の場合foo
が含まれています およびtree2
bar
が含まれています 次に、それらのユニオンビューには両方のfoo
が含まれます およびbar
。新しいファイルは、特定のブランチ、またはより複雑なルールに従って選択されたブランチに書き込まれます。この概念には、次のようないくつかの実装があります。- aufs — Linuxカーネルの実装ですが、アップストリームで何度も拒否されました
- funionfs —FUSEの実装
- mhddfs — FUSE、空き領域に基づいてブランチにファイルを書き込みます
- オーバーレイ— Linuxカーネルの実装、Linuxv3.18でアップストリームにマージ
- unionfs-fuse —キャッシュおよびコピーオンライト機能を備えたFUSE
ファイル名とメタデータを変更する
- ciopfs —大文字と小文字を区別しないファイル名(Windowsファイルシステムのマウントに役立つ場合があります)
- convmvfs —ファイル名を文字セット間で変換します(例)
- posixovl — Unixファイル名とその他のメタデータ(権限、所有権など)をVFATなどのより制限されたファイルシステムに保存します(例)
変更されたファイルの内容を表示する
- avfs —アーカイブファイルごとに、アーカイブのコンテンツを含むディレクトリを表示します(例、その他の例)。特定のアーカイブをディレクトリとして公開するFUSEファイルシステムも多数あります。
- fuseflt —ファイルを読み取るときにパイプラインを介してファイルを実行します。テキストファイルまたはメディアファイルを再コーディングするには(例)
- lzopfs —圧縮ファイルの透過的な解凍
- mp3fs —読み取り時にFLACファイルをMP3にトランスコードします(例)
- scriptfs —スクリプトを実行してコンテンツ(一種のローカルCGI)を提供します(例)
コンテンツの保存方法を変更する
- chironfs —複数の基盤となるストレージ(ディレクトリツリーレベルのRAID-1)にファイルを複製します
- copyfs —ファイルのすべてのバージョンのコピーを保持します
- encfs —ファイルを暗号化する
- pcachefs —低速のリモートファイルシステム用のオンディスクキャッシュレイヤー
- simplecowfs —提供されたビューを介して変更をメモリに保存し、元のファイルをそのまま残します
- ウェイバック—ファイルのすべてのバージョンのコピーを保持します