こんにちは。サイオステクノロジー OSS サポート担当何敏欽です。
CentOS7/RHEL7 のシステムにおいて、まず NFS マウントして、その後に NFS マウントした領域の中のディレクトリを bind マウントしたい場合はどう設定すればいいでしょうか。
方法は二つあります。/etc/fstab に依存関係を追記するか、自動作成されたマウント Unit ファイルを /etc/systemd/system にコピーするかです。下記にぞれぞれを説明します。
2019/1/7 追記:下記に説明する「/etc/fstab に依存関係を追記する方法」と「マウント Unit ファイルを /etc/systemd/system にコピーする方法」について、一部のサービスが起動しなくなる恐れがあることを判明しました。その原因と解決方法は「2019/1/7 追記:_netdev属性をマウントエントリに追加」をご確認ください。
目次
/etc/fstab に依存関係を追記する方法
検証環境の NFS サーバ、クライアントの情報は下記のとおりです。なお、bind マウント用に /mnt/nfsclient/suika/momo/banana/ ディレクトリと /mnt/nfsclient/suika/momo/apple/strawberry ディレクトリを作成しておきます。
NFS サーバの情報 IP:10.111.3.140 エクスポートポイント:/mnt/nfsserv/ NFS クライアントの情報 IP:10.111.3.114 マウントポイント:/mnt/nfsclient/
/etc/fstab に下記のように設定を追記します。
# vim /etc/fstab 10.111.3.140:/mnt/nfsserv/ /mnt/nfsclient/ nfs x-systemd.requires=network.target,rw,nordirplus 0 0 /mnt/nfsclient/suika/momo/banana/ /mnt/nfsclient/suika/momo/apple/strawberry none bind,x-systemd.requires=network.target,x-systemd.requires-mounts-for=/mnt/nfsclient/ 0 0
mount -a コマンドを実施後に mount コマンドを実施し、ちゃんと NFS マウント→ bind マウントの順番に実施されることが確認できます。
# mount -a # mount 10.111.3.140:/mnt/nfsserv on /mnt/nfsclient type nfs4 (rw,relatime,vers=4.1,rsize=262144,wsize=262144,namlen=255,hard,nordirplus,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=10.111.3.114,local_lock=none,addr=10.111.3.140) 10.111.3.140:/mnt/nfsserv/suika/momo/banana on /mnt/nfsclient/suika/momo/apple/strawberry type nfs4 (rw,relatime,vers=4.1,rsize=262144,wsize=262144,namlen=255,hard,nordirplus,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=10.111.3.114,local_lock=none,addr=10.111.3.140)
上記設定に使用している依存関係を構成する x-systemd.requires と x-systemd.requires-mounts-for の詳細について、下記をご確認ください。
x-systemd.requires= Configures a Requires= and an After= dependency between the created mount unit and another systemd unit, such as a device or mount unit. The argument should be a unit name, or an absolute path to a device node or mount point. This option may be specified more than once. This option is particularly useful for mount point declarations that need an additional device to be around (such as an external journal device for journal file systems) or an additional mount to be in place (such as an overlay file system that merges multiple mount points). See After= and Requires= in systemd.unit(5) for details. x-systemd.requires-mounts-for= Configures a RequiresMountsFor= dependency between the created mount unit and other mount units. The argument must be an absolute path. This option may be specified more than once. See RequiresMountsFor= in systemd.unit(5) for details.
マウント Unit ファイルを /etc/systemd/system にコピーする方法
/etc/fstab を設定後、「systemctl daemon-reload」コマンドを実施すると、マウント Unit ファイルが /run/systemd/generator/ ディレクトリに作成されます。
# ll /run/systemd/generator/ -rw-r--r--. 1 root root 443 12月 11 15:33 mnt-nfsclient-suika-momo-apple-strawberry.mount -rw-r--r--. 1 root root 335 12月 11 15:33 mnt-nfsclient.mount
マウント Unit ファイルの中身は以下のとおりです。
# vim /run/systemd/generator/mnt-nfsclient.mount # Automatically generated by systemd-fstab-generator [Unit] SourcePath=/etc/fstab Documentation=man:fstab(5) man:systemd-fstab-generator(8) Before=remote-fs.target After=network.target Requires=network.target [Mount] What=10.111.3.140:/mnt/nfsserv/ Where=/mnt/nfsclient Type=nfs Options=x-systemd.requires=network.target,rw,nordirplus # vim /run/systemd/generator/mnt-nfsclient-suika-momo-apple-strawberry.mount # Automatically generated by systemd-fstab-generator [Unit] SourcePath=/etc/fstab Documentation=man:fstab(5) man:systemd-fstab-generator(8) Before=local-fs.target After=network.target Requires=network.target RequiresMountsFor=/mnt/nfsclient/ [Mount] What=/mnt/nfsclient/suika/momo/banana/ Where=/mnt/nfsclient/suika/momo/apple/strawberry Type=none Options=bind,x-systemd.requires=network.target,x-systemd.requires-mounts-for=/mnt/nfsclient/
マウント Unit ファイルを /etc/systemd/system/ にコピーした後、ファイルの中身に必要な調整を行います。その後、/etc/fstab に追記した依存関係の設定を削除します。
# cp /run/systemd/generator/mnt-nfsclient.mount /etc/systemd/system/ # cp /run/systemd/generator/mnt-nfsclient-suika-momo-apple-strawberry.mount /etc/systemd/system/ # ll /etc/systemd/system/ -rw-r--r--. 1 root root 443 12月 11 15:41 mnt-nfsclient-suika-momo-apple-strawberry.mount -rw-r--r--. 1 root root 335 12月 11 15:41 mnt-nfsclient.mount # vim /etc/systemd/system/mnt-nfsclient.mount [Unit] Description=nfs mount Before=remote-fs.target After=network.target Requires=network.target [Mount] What=10.111.3.140:/mnt/nfsserv/ Where=/mnt/nfsclient Type=nfs Options=x-systemd.requires=network.target,rw,nordirplus [Install] WantedBy=multi-user.target # vim /etc/systemd/system/mnt-nfsclient-suika-momo-apple-strawberry.mount # Automatically generated by systemd-fstab-generator [Unit] Description= bind mount Before=local-fs.target After=network.target Requires=network.target RequiresMountsFor=/mnt/nfsclient/ [Mount] What=/mnt/nfsclient/suika/momo/banana/ Where=/mnt/nfsclient/suika/momo/apple/strawberry Type=none Options=bind,x-systemd.requires=network.target,x-systemd.requires-mounts-for=/mnt/nfsclient/ [Install] WantedBy=multi-user.target[systemctl start (Unit ファイル)] を実施後、[systemctl status (Unit ファイル)] を実施し、active であることを確認します。
# systemctl start mnt-nfsclient.mount # systemctl start mnt-nfsclient-suika-momo-apple-strawberry.mount # systemctl status mnt-nfsclient.mount ● mnt-nfsclient.mount - nfs mount Loaded: loaded (/etc/systemd/system/mnt-nfsclient.mount; enabled; vendor preset: disabled) Active: active (mounted) since 水 2018-12-12 10:16:27 JST; 21s ago Where: /mnt/nfsclient What: 10.111.3.140:/mnt/nfsserv Process: 3144 ExecMount=/bin/mount 10.111.3.140:/mnt/nfsserv/ /mnt/nfsclient -t nfs -o x-systemd.requires=network.target,rw,nordirplus (code=exited, status=0/SUCCESS) # systemctl status mnt-nfsclient-suika-momo-apple-strawberry.mount ● mnt-nfsclient-suika-momo-apple-strawberry.mount - bind mount Loaded: loaded (/etc/systemd/system/mnt-nfsclient-suika-momo-apple-strawberry.mount; enabled; vendor preset: disabled) Active: active (mounted) since 水 2018-12-12 10:16:38 JST; 44s ago Where: /mnt/nfsclient/suika/momo/apple/strawberry What: 10.111.3.140:/mnt/nfsserv/suika/momo/banana Process: 3180 ExecMount=/bin/mount /mnt/nfsclient/suika/momo/banana/ /mnt/nfsclient/suika/momo/apple/strawberry -t none -o bind,x-systemd.requires=network.target,x-systemd.requires-mounts-for=/mnt/nfsclient/ (code=exited, status=0/SUCCESS)
mount コマンドを実施し、ちゃんと NFS マウント→ bind マウントの順番に実施されることが確認できます。
# mount 10.111.3.140:/mnt/nfsserv on /mnt/nfsclient type nfs4 (rw,relatime,vers=4.1,rsize=262144,wsize=262144,namlen=255,hard,nordirplus,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=10.1.3.114,local_lock=none,addr=10.111.3.140) 10.111.3.140:/mnt/nfsserv/suika/momo/banana on /mnt/nfsclient/suika/momo/apple/strawberry type nfs4 (rw,relatime,vers=4.1,rsize=262144,wsize=262144,namlen=255,hard,nordirplus,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=10.1.3.114,local_lock=none,addr=10.111.3.140)
2019/1/7 追記:_netdev属性をマウントエントリに追加
「/etc/fstab に依存関係を追記する方法」と「マウント Unit ファイルを /etc/systemd/system にコピーする方法」実施すると、下記のコマンドの実行結果が示すように、起動時に一部のサービスが正しく起動しないことが判明しました。
# journalctl -b | egrep "Found|Breaking" 1月 07 10:15:27 7.4 systemd[1]: Found ordering cycle on rpc-statd.service/start 1月 07 10:15:27 7.4 systemd[1]: Found dependency on nfs-config.service/start 1月 07 10:15:27 7.4 systemd[1]: Found dependency on local-fs.target/start 1月 07 10:15:27 7.4 systemd[1]: Found dependency on mnt-nfsclient-suika-momo-apple-strawberry.mount/start 1月 07 10:15:27 7.4 systemd[1]: Found dependency on mnt-nfsclient.mount/start 1月 07 10:15:27 7.4 systemd[1]: Found dependency on nfs-server.service/start 1月 07 10:15:27 7.4 systemd[1]: Found dependency on rpc-statd.service/start 1月 07 10:15:27 7.4 systemd[1]: Breaking ordering cycle by deleting job nfs-config.service/start
この出力では、rpc-statd.service→nfs-config.service→local-fs.target→mnt-nfsclient-suika-momo-apple-strawberry.mount→mnt-nfsclient.mount→nfs-server.service→rpc-statd.service の順序で並べられています。mnt-nfsclient-suika-momo-apple-strawberry.mount と mnt-nfsclient.mount に依存関係が設定していることが原因です。
解決方法は、/etc/fstab に下記のように修正し、_netdev 属性をマウントエントリに追加する必要があります。
10.111.3.140:/mnt/nfsserv/ /mnt/nfsclient/ nfs defaults 0 0 /mnt/nfsclient/suika/momo/banana/ /mnt/nfsclient/suika/momo/apple/strawberry none bind,_netdev 0 0