はじめに
先日、仕事でEFSを使うことがあったのですが、マウント周りの仕様を理解できておらずハマったので、しっかりと理解するために記事にまとめてみようと思います。
Elastic File Systemについて
AWSが提供するファイルストレージサービスとなり、ざっくり言えばNFSサーバを提供するAWSサービスとなります。
マウントターゲットで各アベイラビリティゾーンからEFSへアクセスするためのエンドポイントを設定し、アクセスポイントでクライアントからEFSをマウントする際のディレクトリや権限を指定します。
アクセスポイントはEFS側の領域を分割してクライアントへ提供するための機能となるため、特に領域分割せず、EFSの領域をすべて使用する場合はアクセスポイントは使用しなくても良いです。
以下にEFSマウント設定概要図を示します。
以下よりクライアント側、EFS側で設定する内容を記載します。
クライアント側の設定
クライアント側からEFSをマウントする場合、Linux等に標準でインストールされているmountコマンドに各種パラメータを指定するだけでもEFSをマウントできますが、EFSマウントヘルパーと呼ばれるパッケージをインストールすることで、マウント時のパラメータ指定等を簡略化することができます。
また、後述するアクセスポイントの設定を使用してマウントするためにはEFSマウントヘルパーをインストールする必要があります。
EFSマウントヘルパーを入れないと、アクセスポイントで指定した領域・権限でのアクセスができないため、EFSを使用するのであれば、EFSマウントヘルパーはインストールしておいたほうが良いでしょう。
EFS側の設定
EFSの設定ではファイルシステムとアクセスポイントの作成を行う必要がありますが、それぞれ何を設定するものなのかをまとめます。
ファイルシステムの設定
以下のようなEFSの基本設定を行います。
- EFSストレージクラス設定
- EFSバックアップ設定
- 暗号化有無設定
- マウントターゲット設定
- ファイルシステムポリシー設定
マウントターゲットはどのAZ(アベイラビリティーゾーン)にエンドポイントを作成するか、ファイルシステムポリシーは転送時暗号化強制や匿名アクセス禁止等のマウント時のポリシー設定が行なえます。
アクセスポイントの設定
クライアントからEFSにアクセスする際のUID(ユーザID)・GID(グループID)やEFS側のマウントポイントの設定等を行います。
アクセスポイントの設定を行うことで、EFSの特定の領域のみクライアント側からアクセスさせることができます。
クライアント側から見た場合、例えば前述の図のefs2というアクセスポイントをマウントすると、EFS側のディレクトリは/data/efs2となりますが、クライアント側はchrootを使ったときのようにルートディレクトリを直接マウントしているように見えます。
POSIXユーザ・グループ
EFSの領域に書き込みを行う際、クライアント側のUID、GIDではなく、POSIXユーザで指定したUID、GIDでアクセスを行います。
POSIXユーザを指定することでEFSの領域にあるファイルはすべてPOSIXユーザ・グループで指定したUID・GIDに固定できますが、ファイルのオーナー・グループをPOSIXユーザ・グループで固定したくない場合は、設定しないことでクライアント側のUID、GIDにすることもできます。
また、セカンダリグループIDを指定することで、セカンダリグループIDで指定したIDからのアクセスも許可することができるため、例えば以下のようにefs2の親ディレクトリがefs1でそれぞれクライアントごとにアクセスポイントが異なる場合、efs1からは/efs1/efs2ディレクトリの配下にもファイル・ディレクトリ作成可能だが、efs2からはefs1で作成したファイル・ディレクトリにアクセスできないようなことが可能です。
ルートディレクトリ作成のアクセス許可
EFS側にアクセスポイントの設定で指定したディレクトリパスが存在しない場合に、「ルートディレクトリ作成のアクセス許可」で指定したUID、GID、パーミッションでディレクトリを作成します。
存在しなかった場合にディレクトリを作ってくれるだけなので、あらかじめ手動でディレクトリを作成していたり、EFSマウント後に手動でディレクトリを作成する場合は指定しなくても問題ありません。
EFSのマウントについて
上記まででクライアント側、EFS側の設定についてまとめたため、以下ではEFSをマウントした際の動きについてまとめます。
EFSのルートディレクトリ権限
EFS側のルートディレクトリはユーザ&グループがroot:root、パーミッションは0755となります。
マウントした際の権限
これはEFSというよりUNIX系OSでマウントした際の仕様となりますが、例えば/mntにNFS領域をマウントした場合、/mntがユーザ&グループID1001:1001、パーミッション0777としていたとしてもEFSをマウントした際にはEFS側の権限となります。
アクセスポイントを使わない、もしくはアクセスポイント設定でディレクトリパスやPOSIX設定を行っていない場合、「EFSのルートディレクトリ権限」で記載した権限となります。
$ ls -ld /mnt
drwxrwxrwx. X 1001 1001 X XXX DD hh:mm /mnt
$ ls -ld /mnt
drwxr-xr-x. X root root X XXX DD hh:mm /mnt
アクセスポイントを使わないマウント
EFSマウントヘルパーをインストールしていなかったり、アクセスポイントの設定をしていない場合でも、EFSの領域をマウントすることができます。
その場合、EFSのルートディレクトリをマウントすることになり、またPOSIXユーザ設定も行えないため、EFS領域へアクセスする際のユーザ・グループでファイル・ディレクトリの読み書きすることになります。
ルートディレクトリを直接マウントする場合の注意点
ルートディレクトリマウント時、上述の権限となるため、root以外ではEFS領域に書き込みを行えません。
また、アクセスポイントの設定でPOSIXユーザの設定を行うと、POSIXユーザで指定したUID、GIDでアクセスするため、書き込みに失敗します。
もしどうしてもルートディレクトリをマウントして、POSIXユーザ設定も使用したい場合は、EFS領域をマウント後、ルートユーザでEFSのルートディレクトリの権限をPOSIX設定で指定したユーザがアクセスできる権限に変更する必要があります。
$ sudo mount -t efs -o tls fs-xxxxxxxxxxxxxxxxx:/ /mnt
$ ls -ld /mnt
drwxr-xr-x. X root root X XXX DD hh:mm /mnt
$ chmod 777 /mnt
$ ls -ld /mnt
drwxrwxrwx. X root root X XXX DD hh:mm /mnt
動作確認
EFSの設定やマウント時の動作についてまとめてきましたが、実際にどのように見えるかをいくつかのシナリオを通して改めて確認してみようと思います。
今回はマウントテスト用としてEC2インスタンスを用意してそちらで以下のシナリオを確認していこうと思います。
- 事前準備
- シナリオ1:アクセスポイントの設定無しでマウントできるか?
- シナリオ2:EFSのルートディレクトリをマウントしてec2-userで書き込みできるか?
- シナリオ3:EFSのルートディレクトリをマウントしてrootで書き込みできるか?
- シナリオ4:アクセスポイント設定でディレクトリ作成設定を行った際、ディレクトリ作成されるか?
- シナリオ5:POSIXユーザ設定を行った際、指定のユーザでファイル作成されるか?
- シナリオ6:EFSルートディレクトリ側からアクセスポイントのディレクトリにファイル作成した場合はどうなるか?
事前準備
EFSをマウントするためにEC2インスタンスにアタッチするセキュリティグループでNFSを許可しておきます。
また、アクセスポイントの機能を使用するため、EFSマウントヘルパーをインストールしておきます。
シナリオ1:アクセスポイントの設定無しでマウントできるか?
EC2インスタンス側にEFSをマウントするためのマウントポイントを作成しておきます。
$ sudo mkdir /efs1 && ls -ld /efs1
drwxr-xr-x. X root root X XXX DD hh:mm /efs1
「Elastic File System」→「ファイルシステム」より作成済みのファイルシステムの選択し、右上の「アタッチ」を選択すると以下のようなマウントコマンドが表示されるため、作成したマウントポイントに合わせて修正しつつ実行します。
$ sudo mount -t efs -o tls fs-xxxxxxxxxxxxxxxxx:/ /efs1
$ ls -ld /efs1
drwxr-xr-x. X root root X XXX DD hh:mm /efs1
元々のディレクトリ権限と同じなので分かりづらいですが、EFSをマウントしているため、上記はEFS側の権限となっています。
dfコマンドを実行し、以下のように表示されていればマウント成功です。
$ df -h /efs1
Filesystem Size Used Avail Use% Mounted on
127.0.0.1:/ 8.0E 0 8.0E 0% /efs1
シナリオ2:EFSのルートディレクトリをマウントしてec2-userで書き込みできるか?
EFSのルートディレクトリはroot:root、0755の権限となるため、結果としては、Permission deniedとなります。
$ touch /efs1/testfile
touch: cannot touch '/efs1/testfile': Permission denied
シナリオ3:EFSのルートディレクトリをマウントしてrootで書き込みできるか?
rootであれば書き込み権限があるため、問題なく作成できます。
$ sudo touch /efs1/testfile
$ ls -la /efs1/testfile
-rw-r--r--. X root root X XXX DD hh:mm /efs1/testfile
シナリオ4:アクセスポイント設定でディレクトリ作成設定を行った際、ディレクトリ作成されるか?
今回は以下のようにアクセスポイントを作成します。
| 設定項目 | 設定内容 | 備考 |
|---|---|---|
| ファイルシステム | 作成済みのEFSファイルシステムID | |
| 名前 | efs_ap | 任意の名前を指定 |
| ルートディレクトリパス | /efsdata | クライアント側に見せるEFS側ディレクトリパス |
| POSIXユーザID | 2000 | テストのため今回は2000を指定 |
| POSIXグループID | 2000 | テストのため今回は2000を指定 |
| POSIXセカンダリグループID | (空欄) | 今回は未指定 |
| 所有者ユーザID | 2000 | POSIX設定で指定したIDと同じものを指定 |
| 所有者グループID | 2000 | POSIX設定で指定したIDと同じものを指定 |
| アクセスポイントのアクセス許可 | 0755 | |
| タグ | (空欄) | 今回は未指定 |
また、ルートディレクトリをマウントしている/efs1とアクセスポイントの設定でマウントした際の違いを比較するため、アクセスポイントマウント用のディレクトリも作成しておきます。
$ sudo mkdir /efs2 && ls -ld /efs2
drwxr-xr-x. X root root X XXX DD hh:mm /efs2
アクセスポイントで指定した領域をマウントする場合も、「Elastic File System」→「アクセスポイント」から作成したアクセスポイントを選択し、右上の「アタッチ」を選択することでマウントコマンドを確認できます。
なお、前述の通り、アクセスポイントのマウントはEFSマウントヘルパーをインストールしておかないとマウントできないので、コマンドはEFSマウントヘルパーでのマウントコマンド例しか表示されません。
$ sudo mount -t efs -o tls,accesspoint=fsap-xxxxxxxxxxxxxxxxx fs-xxxxxxxxxxxxxxxxx:/ /efs2
マウント後、/efs1にマウントしているルートディレクトリからの確認と、/efs2にマウントしているアクセスポイントで指定したディレクトリからの確認を行った結果が以下となります。
$ ls -l /efs1
total x
drwxr-xr-x. X 2000 2000 X XXX DD hh:mm efsdata
$ ls -l /efs2
total 0
EFSのルートディレクトリから確認した場合、「所有者ユーザID」、「所有者グループID」、「アクセスポイントのアクセス許可」で設定した権限でディレクトリが自動的に作られていることが確認できます。
また、アクセスポイントでのマウントとなる/efs2からの確認では、EFS側の/efsdataがマウントされているため、まだ何も存在しないことが確認できます。
シナリオ5:POSIXユーザ設定を行った際、指定のユーザでファイル作成されるか?
POSIX設定を行っている場合、POSIXで指定しているユーザID、グループIDでEFS領域に書き込まれるはずなので、ec2-userで作成したファイルをcp -pでEFS領域にコピーして、POSIXで設定したユーザID、グループIDになるかを確認してみます。
ec2-userのホームディレクトリにec2userfileというテストファイルを作成して、/efs2にコピーした結果が以下となります。
$ touch ec2userfile && ls -l ec2userfile
-rw-rw-r--. 1 ec2-user ec2-user X XXX DD hh:mm ec2userfile
$ cp -p ec2userfile /efs2/ec2userfile
$ ls -l /efs2/ec2userfile
-rw-rw-r--. 1 2000 2000 X XXX DD hh:mm /efs2/ec2userfile
cp -pで権限を保持したコピーを行っても、POSIXで指定したユーザID、グループIDに変更されていることが確認できます。
また、先程/efsdataのディレクトリを2000:2000、0755の権限で作成しているため、Permission deniedにならずに正常に書き込めていることが確認できました。
シナリオ6:EFSルートディレクトリ側からアクセスポイントのディレクトリにファイル作成した場合はどうなるか?
結論から言ってしまうと、ルートディレクトリをマウントしている/efs1はアクセスポイントで設定している権限等の設定は有効にならないので、クライアント側のユーザで作られます。
また、ec2-userの場合、UID・GIDが1000:1000なので/efsdata配下には作成できずに失敗します。
$ touch /efs1/efsdata/ec2testfile
touch: cannot touch '/efs1/efsdata/ec2testfile': Permission denied
rootで作成した場合は問題なく作成でき、アクセスポイント経由ではないので、UID・GIDが変換されることなく作成されます。
$ sudo touch /efs1/efsdata/roottestfile
$ ls -l /efs1/efsdata/roottestfile
-rw-r--r--. X root root X XXX DD hh:mm /efs1/efsdata/roottestfile
アクセスポイントを使用したマウント構成の検討
EFSのマウントについてまとめ。
- EFSのルートディレクトリ権限は
root:root、0755。 - ルートディレクトリマウントではルートユーザ以外書き込めない。
- POSIX設定を行うと、指定した
UID、GIDで強制される。 - 「ルートディレクトリ作成のアクセス許可」を指定するとマウント時に指定した権限でディレクトリ作成。
EFSのルートディレクトリを使用する場合、手動でルートディレクトリの権限を変更したりしなければならず、良い手段とは言えないため、「ルートディレクトリ作成のアクセス許可」でマウント時に指定した権限のディレクトリを作成するようにした上で、クライアント側からマウントして使うのが良いかと思います。
おわりに
一度イメージできてしまえば簡単なことでも、アクセスポイントやEFSのマウント方法についてイメージできていないと、私のように想定通りにアクセスできずにハマってしまいます。
同じようにハマる人の助けになれば幸いです。





