Cloudflare R2をMastodon等用に作ってみた

テクノロジーFediverse,Cloudflare R2

意外とリクエスト数が舐められない

いままでオブジェクトストレージにAmazon S3を使っていましたが、なんか高いなと。コストが。

でもそんなにストレージ容量は食ってないはず……?なんでだろう。

原因を探りにCost Explorerを覗いてみたら、APIリクエストのほうが高いということが分かりました。

8月のコストを丸々晒すことになりますが、まあいいや。

一番多くを占めている「APN3-Requests-Tier1」とは、S3の料金表でいう「PUT、COPY、POST、LIST リクエスト」のこと。
2番目につけている「APN3-TimedStorage-ByteHrs」が容量に応じた課金なので、その倍以上はリクエスト回数によるもので発生しているっぽい事実が判明しました。

API別に見てみると、このようになっています。

圧倒的PutObject

私のメインアカウントはリレーサーバーに入っていて、
連合タイムラインが中規模ぐらいのサーバーぐらいの勢いで流れています。
(いかすきーより早いです、といえば伝わる人がいるかも)

たぶんそのせいでPutObjectがものすごい回数になっている。

S3ならぬR2

いうて1,000円ちょっとではあるものの、ちょっとでもケチれるならケチりたい。

そう思って見てたら、Cloudflare R2なるものを発掘。

Cloudflareの提供するオブジェクトストレージサービスだそうです。

ちなみにR2という名前。
対抗のS3が「Simple Storage Service」で頭にSが3つ並んでるのでS3なのと同様に、
R2は「Really Requestable」「Repositioning Records」「Ridiculously Reliable」といった
Rが2つ並んだ言葉の略みたいなんですが…なんかS3ほどしっくりこない。当てつけっぽいですね。
そういえばアルファベットでSの前はR、数字で3の前は2ですね……?

一番デカデカと書いてある「エグレス料金ゼロ」というもの。
エグレス料金とは、AWSでいうインターネットへのデータ転送料金(アウト方向の料金)のことです。
AWSでは1GBあたり~0.114USDですが、それがタダというのがうたい文句です。
(競合であるWasabiも同じですね)

ただ、自分の用途ではCloudFrontの無料枠(毎月1TBは無料)のおかげで、
アウト方向の料金はかかってないので、これは無関係。

どちらかといえばこっちですね。

・ストレージ10GBが毎月無料、超えたら1GBあたり0.015USD
・書き込み操作が100万回が毎月無料、超えたら100万回あたり4.50USD
・読み取り操作が1000万回が毎月無料、超えたら100万回あたり0.36USD

これがでかい。
↑はCloudflare R2の価格。

参考に↓に執筆時点のAmazon S3(大阪リージョン)も置いておきます。
【無料枠:AWS登録から最初の12か月のみ】
・ストレージ5GBが毎月無料
・書き込み操作が2000回が毎月無料
・読み取り操作が20000回が毎月無料
【通常課金(1年目で無料枠を超えた分、および2年目以降)】
・ストレージ1GBあたり0.025USD(※最初の50TBまでこの価格)
・書き込み操作が1000回あたり0.0047USD(→100万回あたり4.70USD)
・読み取り操作が1000回あたり0.00037USD(→100万回あたり0.37USD)

ちょっとずつ安い。無料部分に関しては、AWSの無料枠すら凌駕している。
さすが後発組といったところでしょうか。

バケット作成

アカウントトップのサイドバーから「R2」を選択します。

まだCloudflareにクレジットカードを登録していない場合は、ここで登録することになります。
AWSと同様、無料枠を超えたら即課金なのでクレジットカード登録が必須なのです。
またAWSと同様、使わなければ0円です。アカウント維持費はありません。
あと、Cloudflareのフリープランを使っているぶんには、
そちらが勝手に課金プランに変わってしまうということもありません。

バケット作成画面はこんな感じ。

日本語のほうが絶対分かりやすいと思い、ここから日本語に切り替え。

ここでS3と比較した注意点は以下の通り。

  • バケット名にドットは使えない(アルファベット小文字と数字とハイフンしか使えない)
    • ドメイン名そのままつける、というS3のやり方が通用しない。仕方ないのでハイフンでつないだ。
  • リージョンという概念は存在しない
    • S3はリージョン指定が必須で、保存されるデータは絶対にそのリージョンから外に出ない…という
      コンプライアンスにめちゃくちゃ配慮された仕組み(←ってArchitecting on AWSの講師が言ってた)だったけれども
      R2にはそのような考え方はない
    • 唯一、口うるさいEUに関してだけは、「管轄を指定する」でEU領域のストレージにだけ入れることができる。
      「管轄を指定する」で選べるのはEUのみ。
  • オブジェクト公開という概念は基本ない
    • Wasabiなどと同様。AWSにもその兆候はあるけれど。
    • ただWasabiなどと違い、「Cloudflareにドメインを登録していて、そのサブドメインでアクセスさせたい」場合は
      比較的カンタンにオブジェクト公開に類する設定ができます。
      (AWSでいうとCloudFrontを設定してるイメージです)

作成するとこんな画面になります。

ドメイン設定

オブジェクト公開的なサムシングをしないとMastodonでは使えませんので、「設定」タブに移ります。

下側のr2.devドメインを使って設定している人も散見されますが、公式では非推奨です。
(レートリミットは特に書いてないものの…)

上側の「カスタム ドメイン」の横の「ドメインに接続」をクリックします。

ここで利用予定のサブドメインを入力します。

もし移行の場合、↓のような確認画面が出て、勝手にDNSを書き換えてくれます。便利。
(便利だけど書き換えると当然書き換え前を参照しなくなるので、データを移行してからにしましょう)

CORS設定

S3ではCloudFrontを使ってCORSポリシーを設定していましたが、こちらはバケット設定から行います。

「CORSポリシーを追加する」をクリックして、↓を入力します。

[
  {
    "AllowedOrigins": [
      "*"
    ],
    "AllowedMethods": [
      "GET"
    ],
    "AllowedHeaders": [
      "*"
    ]
  }
]

APIトークン(アクセスキー)の作成

IAMユーザーでアクセスキーを発行するのと同等です。

管理画面右上の「R2 API トークンの管理」をクリックします。

次の画面で「API トークンを作成する」をクリックするとこうなります。

  • トークン名は分かりやすい名前をつける(全角文字もOK)
  • 権限は(すっごいざっくりしてますが)書き込めないといけないので、下から2番目を選択。
  • バケットの指定で、特定のバケットにのみ適用する。
  • TTLやIPアドレスフィルタはよしなに(IPアドレスフィルタリングはVPNのIPアドレスがいいかもですね)

ここまで設定すれば完了。
その次の画面で「トークンの値」「アクセス キーID」「シークレット アクセス キー」が表示されます。

API アクセスキーの設定

Mastodonの場合

実は公式ヘルプがあります。

sudo su - mastodon
cd live
vi .env.production

以下の項目を書き換えます。

S3_ENABLED=true(※そのまま)
S3_PROTOCOL=https(※そのまま)
S3_BUCKET=files-mstdn-pokete-com(※R2バケット名に書き換える)
S3_REGION=auto(※autoにするといいらしい)
S3_HOSTNAME=files.mstdn.pokete.com(※上の「ドメイン設定」で指定したアドレス)
AWS_ACCESS_KEY_ID=(※さっきのアクセスキーID)
AWS_SECRET_ACCESS_KEY=(※さっきのシークレットアクセスキー)
S3_ALIAS_HOST=files.mstdn.pokete.com(※上の「ドメイン設定」で指定したアドレス)

S3_ENDPOINT=https://【ひみつ】.r2.cloudflarestorage.com/(※もしコメントアウトされていたら外す、↓参考)

S3エンドポイントは、R2バケット設定の一番上にあるバケット詳細から「S3 API」を確認します。
このURLからバケット名を削って、スラッシュまで残したものを設定します。

ここまで設定したらたぶん大丈夫。

Misskeyの場合

コントールパネル>設定>オブジェクトストレージ の設定を以下のようにしてください。

※サンプルのURLからMastodon感があふれてますが、↑のMastodon用を流用してるだけです

  • Base URL
    • https://files.mstdn.pokete.com(※上の「ドメイン設定」で指定したアドレス)
  • Bucket
    • files-mstdn-pokete-com(※R2バケット名)
  • Prefix
    • (任意)
  • Endpoint
    • 【ひみつ】.r2.cloudflarestorage.com(※このリストの下部参照)
  • Region
    • us-east-1(※空欄ではダメなのでus-east-1とする)
  • Access key
    • (※さっきのアクセスキーID)
  • Secret key
    • (※さっきのシークレットアクセスキー)
  • SSLを使用する
    • ON
  • Proxyを利用する
    • ON(でいいはず)
  • アップロード時にpublic-readを設定する
    • OFF(でいいはず)
  • s3ForcePathStyle
    • ON(でいいはず)

Endpointは、R2バケット設定の一番上にあるバケット詳細から「S3 API」を確認します。
このURLからhttps://とバケット名を削って、スラッシュも消したものを設定します。

おわり

ドメイン直下にアクセスして、(特に設定してなければ)↓の404画面が出ればOK。

(特殊な設定をしないと)無骨なXMLが出てきてしまうS3と違って、マトモですね。

しばらくこれで使ってみて、どのぐらいのコストになるかなーというのを観察してみようと思います。