Mountpoint for Amazon S3を使ってみた
まえがき
みなさんこんにちは、こんばんはつっちーです。
先日、S3バケットをローカルファイルシステムとしてマウントできるMountpoint for Amazon S3が一般公開されました。
今まではファイルシステムを使おうとするとAmazon EFSなどが候補に上がっていましたが、コストがちょっと気になるところでした。
それがS3バケットを直接マウントできるようになったということで、試してみたい!かつ設定がややこしかったので備忘録としてまとめてみました。
何がうれしいの?
今まではAWS SDKを使ってアプリケーションからオブジェクトを取得、登録などを行うことが多かったと思いますが、
S3バケットをマウントすることでシェルコマンド(ls
,cat
,find
など)や各言語の組み込み関数(open
,close
,read
,write
など)を使うことができるほか、スループットの向上も見込めるようです。
やってみる(EC2)
以降公式ガイドに沿って進めていきます。
環境
- EC2はAmazon Linux 2
- プライベートサブネットに配置
- エンドポイント:
com.amazonaws.region.s3 (Gateway)
- エンドポイント:
パッケージインストール(プライベートなので実際はS3経由)
$ wget https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.rpm
$ sudo yum install ./mount-s3.rpm
$ mount-s3 --version mount-s3 1.0.0
S3バケットをマウント
WANT_TO_MOUNT_S3_BUCKET=<your_bucket_name>
$ mkdir /mnt/s3
$ mount-s3 ${WANT_TO_MOUNT_S3_BUCKET} /mnt/s3
bucket <your_bucket_name> is mounted at /mnt/s3
動作確認
$ ls /mnt/s3 hoge.txt
$ aws s3 ls s3://<your_bucket_name>
2023-08-24 15:35:36 17 hoge.txt
マウント解除
$ umount /mnt/s3
umount: /mnt/s3: not mounted.
できること、できないこと
GitHubに記載があります。
- 既存ファイルを読み取ることができる
- 新しいファイルに書き込むことができる
- 既存ファイルに書き込む、名前を変更することはできない
- 既存ファイルを削除するにはマウント時に
--allow-delete
フラグをつける(デフォルトは不可)
上書きできないっていうのが気になるポイントですね。
MOUNT_DIRECTORY = "/mnt/s3"
def save_file(path):
file_path = "%s%s" % (MOUNT_DIRECTORY, path)
with open(file_path, "w") as f:
f.write("hogehoge")
if __name__ == "__main__":
save_file("/output.txt")
1回目(新規書き込み)はできますが、2回目(既存書き込み)はエラーになってしまいますね。
[ec2-user@ip-***]$ python demo.py
[ec2-user@ip-***]$ ls /mnt/s3
hoge.txt output.txt
[ec2-user@ip-***]$ python demo.py
IOError: [Errno 1] Operation not permitted: '/mnt/s3/output.txt'
やってみる(ECS on EC2)
ユースケースとしてはこちらの方が多い気がします。Fargateはまだ対応していないようです。
環境
- EC2はAmazon Linux 2
- プライベートサブネットに配置
- プライベートだとエンドポイントが必要になります(ちょっとお高いんですよね)
- ECS
com.amazonaws.region.ecs-agent
com.amazonaws.region.ecs-telemetry
com.amazonaws.region.ecs
- ECR
com.amazonaws.region.ecr.dkr
com.amazonaws.region.ecr.api
- ECS
Dockerfile
FROM --platform=linux/x86_64 amazonlinux:2
RUN yum update -y
RUN yum install -y wget
RUN wget https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.rpm
RUN yum install -y ./mount-s3.rpm
COPY demo.py /
CMD ["python", "demo.py"]
ECS起動(enable-execute-commandを有効化)
$ aws ecs create-service \
--cluster <your_cluster_name> \
--task-definition <your_task_definition> \
--enable-execute-command \
--service-name <your_service_name> \
--desired-count 1 \
--network-configuration "awsvpcConfiguration={subnets=[subnet-***, subnet-***],securityGroups=[sg-***]}"
マウントするためにコンテナに接続する
- Amazon ECS Execを使用する
- AWS CLI用のSession Managerプラグインをインストールする
- ここでもエンドポイントが必要: com.amazonaws.region.ssmmessages
$ aws ecs execute-command \
--cluster <your_cluster_name> \
--task <your_task_id> \
--container <your_container> \
--interactive \
--command "/bin/bash"
The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.
Starting session with SessionId: ecs-execute-command-***
マウントする(同様)
WANT_TO_MOUNT_S3_BUCKET=<your_bucket_name>
$ mkdir /mnt/s3
$ mount-s3 ${WANT_TO_MOUNT_S3_BUCKET} /mnt/s3
bucket <your_bucket_name> is mounted at /mnt/s3
うーん、設定が結構大変ですね。
少しリファクタリング
マウント処理をスクリプト化してDockerfileのCMDに仕込む
Dockerfileを修正
...
CMD ["python", "mount.sh"]
マウント処理をシェルスクリプトに記述
#!/bin/bash
S3_MOUNT_BUCKET="your_bucket_name"
MOUNT_DIRECTORY="./mnt/s3"
echo "Setup Mountpoint for S3"
mkdir $MOUNT_DIRECTORY
sudo mount-s3 $S3_MOUNT_BUCKET $MOUNT_DIRECTORY
/usr/bin/python ./demo.py
これならECS起動時にマウント処理してくれますね。
所感
なんだかECSの設定ばかりになってしまいましたが、Mountpoint for S3自体は簡単な設定で使えると思いました。WIndowsには対応していなかったり、既存ファイルの上書きができなかったりと、不便な点はいくつかありますが、手軽にファイルシステムを扱いたいときにはなかなか良い選択肢だと思います。