Mountpoint for Amazon S3 とは何か

:::note warn
2023/3/21 時点の情報で作成しています。Mountpoint for Amazon S3 は現在アルファリリースであるため本番ワークロードには適しません。また将来的に動作や仕様が変更される可能性があります。動作を確認したバージョン: **0.2.0-b8363a4**
:::

## Mountpoint for Amazon S3 とは
### 概要
Mountpoint for Amazon S3 は、Amazon S3 バケットをローカルファイルシステムとしてマウントするための Rust 製ファイルクライアントです。OSS として開発されています。

https://github.com/awslabs/mountpoint-s3

現時点ではサポート OS は Linux のみで **読み込み操作専用** です。書き込み操作については将来的に新しいオブジェクトへの順次書き込みのみがサポートされる予定です。

類似のツールとしては s3fs や Goofys などが有名です。

https://github.com/s3fs-fuse/s3fs-fuse

https://github.com/kahing/goofys

### ユースケース
Mountpoint for Amazon S3 はデータレイクからの大きなファイルの読み込みなど、高いスループットを必要とする読み取り負荷の高いワークロード向けに最適化されています。ファイルシステムの完全な POSIX 仕様は実装されていません。これは意図的なものであり、将来的にも S3 のオブジェクト API に対して効率的に実行できない機能は実装される予定はありません。(ディレクトリの名前変更や既存ファイルの変更など)

現時点でサポートされる POSIX ファイルシステム操作やセマンティクスに対する考え方は doc/SEMANTICS.md に記載されています。

https://github.com/awslabs/mountpoint-s3/blob/main/doc/SEMANTICS.md

### 留意すべき点
ローカルファイルシステムとは異なり、Amazon S3 対する操作はネットワークタイムアウトなどの一時的な利用障害が発生することがあります。また Mountpoint for Amazon S3 はファイルクライアントを介してアクセスしている間にリモートのバケットやオブジェクトが変更された場合の影響について、いかなる保証もしていません。このような制限事項を許容できるワークロードでのみ使用することが推奨されます。

完全な POSIX サポートが必要なワークロードについては、Amazon EFS や Amazon FSx for Lustre などの ファイルシステムサービスを検討する必要があります。

### ロードマップ
開発ロードマップが公開されています。現時点で新規ファイルの順次書き込み操作、mkdir、rm のサポートなどが記載されています。

https://github.com/orgs/awslabs/projects/84


## 使用方法

### コンパイル
Mountpoint for Amazon S3 のアルファリリースはソースコードからコンパイルする必要があります。手順は GitHub リポジトリ の README.md の記載の通りです。

```shell
# 依存関係のインストール
# Devian 系の場合は sudo apt install fuse libfuse-dev cmake clang pkg-config
sudo yum install fuse fuse-devel cmake3 clang-devel git
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# リポジトリとサブモジュールの clone
git clone --recurse-submodules https://github.com/awslabs/mountpoint-s3.git

# コンパイル
cd mountpoint-s3
cargo build --release
```

cargo build が完了すると、`mountpoint-s3/target/release/mount-s3` にバイナリが作成されます。

### 実行
コマンドは root 権限で実行します。またマウントには有効な AWS 認証情報 (EC2 の IAM ロールや `~/.aws/credentials` ) にアクセスできる必要があります。認証情報のプロファイルはオプションで変更できないため、変更したい場合は環境変数 `AWS_PROFILE` を指定してください。

以下の例では、/mnt をマウントポイントとし、バケット foo をマウントしています。

```shell
# USAGE: mount-s3 [OPTIONS] <BUCKET_NAME> <MOUNT_POINT>
mkdir /mnt
mount-s3 foo /mnt
```

クライアントはデフォルトでバックグランドで起動され、root ユーザーのみがアクセス可能です。

```shell-session
# ls -l /mnt/test.json
-rw-r--r-- 1 root root 306424 Feb 21 02:42 /mnt/test.json

$ ls -l /mnt/test.json
ls: cannot access /mnt: Permission denied
```

root 以外のユーザーにファイルシステムのへのアクセスを許可する場合は `--allow-other` オプションを指定します。

```shell-session
$ sudo mount-s3 foo /mnt --allow-other --region ap-northeast-1

$ ls -l /mnt/test.json
-rw-r--r-- 1 root root 306424 Feb 21 02:42 /mnt/test.json
```

バケット内の特定の prefix のみをマウントしたい場合は `--prefix` オプションを指定します。指定しない場合はバケット全体がマウントされます。

```shell
# s3://foo/bar/ をマウント
mount-s3 foo /mnt --prefix bar/ --allow-other --region ap-northeast-1
```

### ログ
ログファイルはデフォルトで `$HOME/.mountpoint-s3` に出力されます。`-l`, `--log-directory` オプションを指定して出力先を変更することもできます。

* ディレクトリが存在しない場合は自動で作成されます
* mount-s3 コマンドを実行するたびに新しいファイルが作成されます
* 自動的にローテーションされたり、クリーンナップされることはありません
* フォアグラウンドオプション(`-f`, `--foreground`)で起動した場合は標準出力にも出力されます

```shell-session
# tail ~/.mountpoint-s3/mountpoint_s3_20230321145325.log
2023-03-21T14:53:25.185700Z ERROR awscrt::common-io: static: Failed to open file. path:'/root/.aws/credentials' mode:'rb' errno:2 aws-error:44(AWS_ERROR_FILE_INVALID_PATH)
2023-03-21T14:53:25.185755Z ERROR awscrt::AuthCredentialsProvider: Failed to resolve role arn during sts web identity provider initialization.
2023-03-21T14:53:25.192347Z ERROR awscrt::common-io: static: Failed to open file. path:'/root/.aws/credentials' mode:'rb' errno:2 aws-error:44(AWS_ERROR_FILE_INVALID_PATH)
```

デフォルトではエラーレベルのメッセージのみが出力されます。ログレベルを変更するには RUST_LOG 環境変数を設定します。 (`info/warn/error/debug/trace`)

```shell-session
export RUST_LOG=info
mount-s3 foo /mnt --allow-other --region ap-northeast-1
```

### アンマウント
アンマウントするには umount コマンドを実行します。

```
umount /mnt
```

## コマンドオプション
`USAGE: mount-s3 [OPTIONS] <BUCKET_NAME> <MOUNT_POINT>`
### オプション一覧
|オプション|説明|
|---|---|
|--allow-other|root 以外のユーザーにファイルシステムへのアクセスを許可|
|--allow-root|root ユーザーにファイルシステムへのアクセスを許可 |
|--auto-unmount|ユーザーが exit した際に自動でアンマウントする          
|--dir-mode \<DIR_MODE>| ディレクトリのパーミッションを指定 <br>`default: 0755`|
|--endpoint-url \<ENDPOINT_URL> | S3 エンドポイントの URL を上書きするす|
|-f, --foreground|フォアグラウンドプロセスとして実行する|
|--file-mode <FILE_MODE>| ファイルのパーミッションを指定<br> `default: 0644`|
|--gid \<GID> | Owner の GID を指定<br> `default: current user's GID`
|-h, --help|ヘルプ情報の表示
|-l, --log-directory \<LOG_DIRECTORY>|ログファイルの出力先ディレクトリを指定<br> [`default: $HOME/.mountpoint-s3`]
|--part-size \<PART_SIZE>|マルチパートダウンロード/アップロードのパートサイズを指定|
|--path-addressing|パス形式の URL を強制する|
|--prefix \<PREFIX>|マウントするバケット内のプレフィックスを指定|
|--region \<REGION>|バケットのリージョンを指定|
|--thread-count \<N>|FUSE デーモンのスレッド数を指定||
|--throughput-target-gbps \<N (Gbps)>|希望するスループットを Gbps で指定<br> `default: 10`|
|--uid \<UID> |Owner の UID を指定 <br>`default: current user's UID`|
|-V, --version|バージョン情報を表示|
|--virtual-addressing|仮想ホスト形式の URL を強制する|

### 特定ケースでの留意点
* GovCloud や中国リージョン、または FIPS や dualstack, Transfer Acceleration エンドポイントを利用する場合は `--endpoint-url` を指定します
* 高いネットワーク帯域幅を持つ EC2 インスタンスで、使用可能な帯域をデフォルトの 10 Gbps 以上にする場合は明示的に `--throughput-target-gbps` を設定します

## 参考
https://aws.amazon.com/jp/about-aws/whats-new/2023/03/mountpoint-amazon-s3/

https://aws.amazon.com/jp/blogs/storage/the-inside-story-on-mountpoint-for-amazon-s3-a-high-performance-open-source-file-client/

以上です。
参考になれば幸いです。