mount-s3を試す

## やりたいこと
夏休みで不在にしてる間に、S3をマウントできる機能が出てたので試してみる。
[Mountpoint for S3 - What's New](https://aws.amazon.com/jp/about-aws/whats-new/2023/03/mountpoint-amazon-s3/)

## 用意するもの
- Amazon Linux2インスタンス ... 一台
  - たまたまGraviton2（ARM）インスタンスがあったのでそれを使ったが、IntelでもOK。
- S3の適当なバケット ... 一つ

## 実験

### 1. ログイン
SSM Session Managerでインスタンスに接続し、ホームディレクトリに移動。
```bash
sh-4.2$ cd
sh-4.2$ pwd
/home/ssm-user
```

### 2. インストール
`wget`でARM版をダウンロードしてインストール。
```bash
sh-4.2$ wget https://s3.amazonaws.com/mountpoint-s3-release/latest/arm64/mount-s3.rpm
sh-4.2$ sudo yum install ./mount-s3.rpm
sh-4.2$ mount-s3 --version
mount-s3 1.0.0
```
ちなみにx86_64（Intel）の場合はこちらを使う。
```bash
wget https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.rpm
```

インストール完了。
```bash
sh-4.2$ which mount-s3
/usr/bin/mount-s3
sh-4.2$ rpm -qi mount-s3
Name        : mount-s3
Version     : 1.0.0
Release     : 1
Architecture: aarch64
Install Date: Mon 14 Aug 2023 09:13:25 AM UTC
Group       : Unspecified
Size        : 57238837
License     : Apache-2.0
Signature   : (none)
Source RPM  : mount-s3-1.0.0-1.src.rpm
Build Date  : Tue 08 Aug 2023 03:19:37 PM UTC
Build Host  : ip-172-31-46-192.ec2.internal
Relocations : (not relocatable)
URL         : https://github.com/awslabs/mountpoint-s3
Summary     : Mountpoint for Amazon S3
Description :
Mountpoint for Amazon S3 is a simple, high-throughput file client for
mounting an Amazon S3 bucket as a local file system. With Mountpoint for Amazon
S3, your applications can access objects stored in Amazon S3 through file
operations like open and read. Mountpoint for Amazon S3 automatically
translates these operations into S3 object API calls, giving your applications
access to the elastic storage and throughput of Amazon S3 through a file
interface.
```
`mount-s3 --help`でヘルプを表示できる。

```bash
sh-4.2$ mount-s3 --help
Mountpoint for Amazon S3

Usage: mount-s3 [OPTIONS] <BUCKET_NAME> <DIRECTORY>

Arguments:
  <BUCKET_NAME>  Name of bucket to mount
  <DIRECTORY>    Directory to mount the bucket at
...（略）
```
### 3. マウント
適当なS3バケットを探す。
その後、これまた適当なディレクトリを作成してマウント。
```bash
sh-4.2$ aws s3 ls | grep my-bucket-4-handson
2023-03-02 01:56:32 my-bucket-4-handson
sh-4.2$ mkdir mountpoint-4-s3-test
sh-4.2$ mount-s3 my-bucket-4-handson ./mountpoint-4-s3-test/
bucket my-bucket-4-handson is mounted at ./mountpoint-4-s3-test/
```
マウントできた。

### 4. 確認
`df -k`には出てこないっぽい。`mount`には出る。
```bash
sh-4.2$ df -k
Filesystem       1K-blocks    Used Available Use% Mounted on
devtmpfs            441552       0    441552   0% /dev
tmpfs               479624       0    479624   0% /dev/shm
tmpfs               479624     356    479268   1% /run
tmpfs               479624       0    479624   0% /sys/fs/cgroup
/dev/nvme0n1p1     8367084 3516304   4850780  43% /
/dev/nvme0n1p128     10202    2792      7410  28% /boot/efi
sh-4.2$ mount --types fuse
mountpoint-s3 on /home/ssm-user/mountpoint-4-s3-test type fuse (rw,nosuid,nodev,noatime,user_id=1001,group_id=1001,default_permissions)
```
いろんなコマンドを試してみる。
```bash
sh-4.2$ cd mountpoint-4-s3-test/
sh-4.2$ ls -F
Cfn/  Commands/  Data/  datalake/  glue/  workspaces/
sh-4.2$ mkdir testdir
sh-4.2$ file testdir
testdir: directory
sh-4.2$ cd Cfn
sh-4.2$ ls
latest  nested-version  xsr-version
sh-4.2$ du -ks .
92      .
h-4.2$ find ./Cfn -name *.yml
./Cfn/latest/emr.yml
./Cfn/latest/lakeformation_prep.yml
./Cfn/latest/redshift-and-glue.yml
./Cfn/latest/redshift-public.yml
./Cfn/latest/redshift.yml
./Cfn/latest/vpc.yml
./Cfn/xsr-version/glue.yml
./Cfn/xsr-version/redshift.yml
./Cfn/xsr-version/vpc.yml
```
読み書きをしてみる。
```bash
sh-4.2$ echo "aaa" > a.txt  # ファイルの作成
sh-4.2$ ls a.txt
a.txt
sh-4.2$ cat a.txt  # ファイルの読み取り
aaa
```
ちなみにちゃんと作成されていることはマネコンからも分かる。
![mount-s3-test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/0d8b108e-7e9e-0b9c-cc7d-c8aa88109544.png)

修正や削除を試みるが、いずれもエラーとなった。
```bash
sh-4.2$ echo "aaa" >> a.txt  # ファイルへの追記
sh: a.txt: Operation not permitted
sh-4.2$ mv a.txt A.txt  # ファイル名の変更あるいは移動
mv: cannot move ‘a.txt’ to ‘A.txt’: Function not implemented
sh-4.2$ rm a.txt  # ファイルの削除
rm: cannot remove ‘a.txt’: Operation not permitted
sh-4.2$ ls -l a.txt
-rw-r--r-- 1 ssm-user ssm-user 4 Aug 14 11:17 a.txt
```
[GitHub](https://github.com/awslabs/mountpoint-s3/blob/main/doc/SEMANTICS.md)に挙動の制約について記載あり。この辺か。
> Mountpoint supports writing only to new files, and writes to new files must be made sequentially. If you try to open an existing file with write access, the open operation will fail with a permissions error.

`--allow-delete`なるマウントオプションがあったので、試してみる。
修正は依然NGだが、削除はできるようになった。

```bash
sh-4.2$ sudo umount /home/ssm-user/mountpoint-4-s3-test  # いったんアンマウント
sh-4.2$ mount-s3 my-bucket-4-handson ./mountpoint-4-s3-test/ --allow-delete  # --allow-deleteオプションで再度マウント
bucket my-bucket-4-handson is mounted at ./mountpoint-4-s3-test/
sh-4.2$ echo "bbb" > b.txt  # ファイルの作成
sh-4.2$ ls b.txt
b.txt
sh-4.2$ echo "bbb" >> b.txt  # ファイルへの追記
sh: b.txt: Operation not permitted
sh-4.2$ mv b.txt B.txt  # ファイル名の変更あるいは移動
mv: cannot move ‘b.txt’ to ‘B.txt’: Function not implemented
sh-4.2$ ls -l b.txt
-rw-r--r-- 1 ssm-user ssm-user 4 Aug 14 11:18 b.txt
sh-4.2$ rm b.txt  # ファイルの削除
sh-4.2$  # 削除成功
```

ちなみにUNIXのファイルパーミッションは644＝所有者は読み書き可能に設定されており、これらの挙動はファイルパーミッションとは関係ないことが分かる。また今回、IAMクレデンシャルは管理者権限なので、IAMポリシーとも関係なく、純粋に`mount-s3`の仕様ということになる。

このあたりの設計思想は、前出のGitHubドキュメントにも記載されている。
> **Behavior tenets**
> While the rest of this document gives details on specific file system behaviors, we can summarize the Mountpoint approach in three high-level tenets:
> - Mountpoint does not support file behaviors that cannot be implemented efficiently against S3's object APIs. It does not emulate operations like rename that would require many API calls to S3 to perform.
> - Mountpoint presents a common view of S3 object data through both file and object APIs. It does not emulate POSIX file features that have no close analog in S3's object APIs, such as ownership and permissions.
> - When these tenets conflict with POSIX requirements, Mountpoint fails early and explicitly. We would rather cause applications to fail with IO errors than silently accept operations that Mountpoint will never successfully persist, such as extended attributes.

終わったらアンマウント。
```bash
sh-4.2$ sudo umount ./mountpoint-4-s3-test/  # アンマウント
sh-4.2$  # アンマウント完了
```

## 所感
とりあえず「使ってみた」レベルだが、クイックにS3を操作するには便利で、`aws s3`コマンドより使い勝手がいい。踏み台EC2から該当バケットの中を探索するといった運用用途には向きそうだ。

一方で、既存ファイルの修正、移動、リネームはできず、その点は通常のファイルシステムの使用感や運用イメージとはだいぶ異なる。`chmod`などもサポートされていない。前出のTenetsを鑑みても、ファイルサーバーやアプリケーションストレージの包括的な代替手段というよりは、あくまで**運用者がS3に手軽にファイルシステムライクにアクセスするための機能**として作られていることが窺われる。

S3をマウントしてファイルサーバー的に使いたい、というニーズはかなり昔からある。が、そもそもS3はAPIを通じてオブジェクト単位での操作を行うオブジェクトストレージであり、一般的なファイルサーバーが前提とするブロックストレージとは別物である。権限モデルも異なる。`mount-s3`を含めて、S3マウントのソリューションはあくまでエミュレーションであり、通常のPOSIXファイルシステム（あるいはWindowsファイルシステム）とは非互換の部分が少なからずある。使い方を誤ると、性能や運用に深刻な課題を抱えることになりかねない。
ファイルサーバーのクラウド移設には、EFSやFSxなど適した選択肢が他にある。コンテナやLambda上のアプリケーションから使うための一時的なストレージが欲しいというだけなら、（ブロックストレージである）エフェメラルボリュームがあるし、永続的・大容量が要件であればやはりEFSを検討すべきだろう。

## まとめ
**`mount-s3`は便利だが、用途を絞って使うのが妥当**、というのがいったんの結論。
今後のロードマップや現場実装を注視していきたいところである。

## 参考
[What's New](https://aws.amazon.com/jp/about-aws/whats-new/2023/03/mountpoint-amazon-s3/)
[Blog](https://aws.amazon.com/jp/blogs/storage/the-inside-story-on-mountpoint-for-amazon-s3-a-high-performance-open-source-file-client/)
[公式ドキュメント](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mountpoint.html)
[Mountpoint for Amazon S3 file system behavior （GitHub）](https://github.com/awslabs/mountpoint-s3/blob/main/doc/SEMANTICS.md)