Cloudflare R2バケットをAWS EC2でマウントする

はじめに

Cloudflare R2は安価で高性能なオブジェクトストレージサービスだが、EC2から直接ファイルシステムのようにアクセスしたい場合がある。
今回はs3fsというツールを使って、Cloudflare R2のバケットをEC2インスタンスにマウントしてみる。

S3互換のAPIを持つR2なので、S3用のツールがそのまま使えるのが便利。

環境

AWS EC2 (Amazon Linux 2023)
Cloudflare R2
s3fs-fuse 1.95 (ソースビルド)

準備

EC2インスタンスの作成

項目設定値
名前server
OSAmazonLinux2023 AMI
アーキテクチャ64ビット(Arm)
インスタンスタイプt4g.micro
キーペアserver(新規で作成)
セキュリティグループssh (自分のIPのみ)
ストレージ8GB (gp3)

Cloudflare R2のバケットとAPIトークンを準備

  1. R2バケットの作成 (※既に作成済みであれば不要)

    • CloudflareダッシュボードからR2を選択
    • 「バケットを作成する」でバケットを作成
  2. APIトークンの作成

    1. R2オブジェクトストレージ → 概要 →「API」 → 「APIトークンの管理」を選択 create-cloudflare-apitoken-01
    2. 「Account APIトークンを作成する」を選択 create-cloudflare-apitoken-02
    3. APIの名前、権限を設定して作成する。
      • アクセス許可:「オブジェクトの読み取りと書き込み」
      • バケットを指定して作成 create-cloudflare-apitoken-03

作成されたAPIトークンの情報をメモしておく
「S3 クライアントには次の認証情報を使用します。」という記載の部分が重要となる。

  • アクセスキーID
  • シークレットアクセスキー
  • エンドポイント (例: https://1234567890abcdef.r2.cloudflarestorage.com)
create-cloudflare-apitoken-04

EC2での設定

s3fsのインストール

# 必要なパッケージのインストール
sudo dnf update -y
sudo dnf install -y git gcc gcc-c++ fuse fuse-devel libcurl-devel libxml2-devel openssl-devel make automake autoconf pkg-config

# s3fs-fuseのソースコードをダウンロード
git clone https://github.com/s3fs-fuse/s3fs-fuse.git
cd s3fs-fuse

# ビルドとインストール
./autogen.sh
./configure --prefix=/usr/local
make
sudo make install
# パスを確認
which s3fs
/usr/local/bin/s3fs

バージョンを確認する

s3fs --version
[ec2-user@ip-172-31-24-82 s3fs-fuse]$ s3fs --version
Amazon Simple Storage Service File System V1.95(commit:8d68b8a) with OpenSSL
Copyright (C) 2010 Randy Rizun <[email protected]>
License GPL2: GNU GPL version 2 <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

認証情報の設定

s3fsCloudflare R2の認証情報を設定する。認証情報ファイルを作成する方法と環境変数で設定する方法がある。

認証情報ファイルを作成する方法

認証情報ファイルの形式:

項目説明
your-bucket-nameCloudflareR2のバケット名my-r2-bucket
YOUR_ACCESS_KEY_IDアクセスキーIDabcd1234efgh5678
YOUR_SECRET_ACCESS_KEYシークレットアクセスキー1234567890abcdef1234567890abcdef12345678
# 認証情報ファイルを作成
echo "YOUR_ACCESS_KEY_ID:YOUR_SECRET_ACCESS_KEY" > ~/.passwd-s3fs
chmod 600 ~/.passwd-s3fs

環境変数で設定する方法

export AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY_ID
export AWS_SECRET_ACCESS_KEY=YOUR_SECRET_ACCESS_KEY

s3fsでのマウント

マウントポイントの作成

sudo mkdir -p /mnt/r2-bucket
sudo chown ec2-user:ec2-user /mnt/r2-bucket

fuser.confの修正

user_allow_other を有効にする。

/etc/fuse.conf
# mount_max = 1000
-# user_allow_other
+user_allow_other

マウント

s3fs [バケット名] /mnt/r2-bucket \
    -o passwd_file=/home/ec2-user/.passwd-s3fs \
    -o url=https://[エンドポイント] \
    -o use_path_request_style \
    -o allow_other

マウントの確認

df -h | grep r2-bucket
結果
s3fs               64P     0   64P   0% /mnt/r2-bucket
ls -la /mnt/r2-bucket/
結果
[ec2-user@ip-172-31-24-82 ~]$ ls -la /mnt/r2-bucket/
total 8
drwxrwxrwx. 1 ec2-user ec2-user 4096 Jan  1  1970 .
drwxr-xr-x. 3 root     root       23 Jun 28 09:35 ..
drwxr-x---. 1 ec2-user ec2-user 4096 Jan  1  1970 movie

バケット内のファイルが表示される。

実際の使用例

ファイルの読み書き

# ファイルの作成
echo "Hello from EC2!" > /mnt/r2-bucket/test.txt

# ファイルの確認
cat /mnt/r2-bucket/test.txt
Hello from EC2!

ディレクトリの作成

## s3fsの実装なのかディレクトリがR2の方にも作成されていた.
mkdir /mnt/r2-bucket/logs 
echo "Log entry 1" > /mnt/r2-bucket/logs/app.log

自動マウントの設定

/etc/fstabによる永続マウント

サーバー起動時に自動的にマウントされるように/etc/fstabに設定を追加する。

# /etc/fstabにエントリを追加
sudo tee -a /etc/fstab << 'EOF'
your-bucket-name /mnt/r2-bucket fuse.s3fs _netdev,passwd_file=/home/ec2-user/.passwd-s3fs,url=https://1234567890abcdef.r2.cloudflarestorage.com,use_path_request_style,allow_other 0 0
EOF

fstabエントリの説明

項目説明
your-bucket-nameバケット名
/mnt/r2-bucketマウントポイント
fuse.s3fsファイルシステムタイプ
_netdevネットワークが利用可能になってからマウント
passwd_file認証情報ファイルのパス
urlCloudflare R2のエンドポイント
use_path_request_styleパススタイルリクエスト使用
allow_other他のユーザーからのアクセス許可
0 0ダンプとfsckのオプション(無効)

fstabの設定確認

# fstabの内容を確認
tail -1 /etc/fstab

手動マウントテスト

# fstabエントリを使って手動マウント
sudo mount /mnt/r2-bucket

# マウント状況の確認
mount | grep r2-bucket

自動マウントのテスト

# アンマウントしてから再起動テスト
sudo umount /mnt/r2-bucket

# 再起動(または mount -a でテスト)
sudo mount -a

# マウント確認
ls -la /mnt/r2-bucket/

注意事項

  • _netdevオプションにより、ネットワークサービス開始後にマウントが実行される
  • 認証情報ファイル(~/.passwd-s3fs)はec2-userで読み取り可能である必要がある
  • /etc/fstabのエントリは実際のバケット名とエンドポイントに置き換える必要がある

アンマウント

umount /mnt/r2-bucket

または

fusermount -u /mnt/r2-bucket

トラブルシューティング

今回、マウントするにあたってバケット名を間違えてアクセスできないということがあった。
デバッグオプションを付けたら気づけたので、以下にトラブルシューティングを記載する。

よくある問題

  1. マウントできない場合
    -o dbglevel=info -f -o curldbgオプションを付けてデバッグログを確認する。
  # エンドポイントとバケット名を確認
  s3fs your-bucket-name /tmp/test \ 
    -o passwd_file=/home/ec2-user/.passwd-s3fs \
    -o url=https://1234567890abcdef.r2.cloudflarestorage.com \
    -o use_path_request_style \
    -o dbglevel=info -f -o curldbg
  1. 認証エラーが発生する場合
  # 認証情報ファイルの権限を確認
  ls -l ~/.passwd-s3fs
  # 600 (rw-------) である必要がある
  1. 権限エラーが発生する場合
  # マウントポイントの権限を確認
  ls -ld /mnt/r2-bucket
  # FUSEグループに所属しているか確認
  groups

参考

おわりに

s3fsを使うことで、Cloudflare R2バケットを通常のファイルシステムのようにEC2から扱えることを試した。

S3互換APIのおかげで、既存のS3用ツールがそのまま使えたので特に困ることはなかった。
互換性の観点でよいところが多いので、R2でも既存のツールを使えるのが非常に良い!

今後、S3の代わりにR2を使おうとなったときでも、こういう方法でマウントはできるので覚えておきたい。

ただし、ネットワーク経由のアクセスなので、パフォーマンス面での制約があることは理解しておく必要がある。
キャッシュ機能や並列転送の設定を適切に行うことで、ある程度のパフォーマンス改善は期待できそうだ。

ログファイルの保存や、バックアップデータの管理など、リアルタイム性を要求されない用途には実用的と思う。

Hugo で構築されています。
テーマ StackJimmy によって設計されています。