ROCK64 + Rook Ceph RADOSGW の性能を測定してみました

#はじめに
前回までのドキュメント(ROCK64 + Rook で作る、お家最強のお父さんCeph) では、ROCK64 上に Rook を用いてCeph クラスタを構築する記事をまとめさせていただきました。

https://qiita.com/rev4t/items/02726b0ac21feb55cc99

今回は、既に構築済みの Ceph クラスタに対して radosgw を構築し、簡単なベンチマークを実施した結果をまとめます。
Rook を用いた radosgw のデプロイ手順については、次の公式ドキュメントに必要な情報がまとまっています。

https://rook.io/docs/rook/v1.1/ceph-object.html

# RADOS Gateway (Object storage) の初期設定
radosgw の構築手順としては、"CephObjectStore" リソースを kubernetes 上で作成します。
radosgw のプロセス(pod)作成や必要な設定については、Rook の controller が自動的に実施するので、特に ceph コマンド等を用いて手動でやるべき作業はございません。

```bash
# rook の ceph 設定例 ディレクトリに移動します
cd rook/cluster/examples/kubernetes/ceph

# object storage のリソースを作成します
kubectl create -f object.yaml

# radosgw の pod が正常に稼働していることを確認します
kubectl -n rook-ceph get pod -l app=rook-ceph-rgw
```

# radosgw S3 credential の作成
次に、S3 の credential を作成します。

```bash
kubectl create -f object-user.yaml
kubectl -n rook-ceph describe secret rook-ceph-object-user-my-store-my-user

# describe secret 実行結果
rock64@node01:~/rook/cluster/examples/kubernetes/ceph$ kubectl -n rook-ceph describe secret rook-ceph-object-user-my-store-my-user
Name:         rook-ceph-object-user-my-store-my-user
Namespace:    rook-ceph
Labels:       app=rook-ceph-rgw
              rook_cluster=rook-ceph
              rook_object_store=my-store
              user=my-user
Annotations:  <none>

Type:  kubernetes.io/rook

Data
====
AccessKey:  20 bytes
SecretKey:  40 bytes

#AccessKey, SecretKey の確認方法
kubectl -n rook-ceph get secret rook-ceph-object-user-my-store-my-user -o yaml | grep AccessKey | awk '{print $2}' | base64 --decode
kubectl -n rook-ceph get secret rook-ceph-object-user-my-store-my-user -o yaml | grep SecretKey | awk '{print $2}' | base64 --decode
```

#s3cmd を用いた動作テスト
s3cmd を用いて、radosgw に S3 API にて PUT/GET のテストを実施します。
予め、client にてs3cmd のインストールをしておきます。

```bash
sudo apt install -y s3cmd
```

次に、credential を設定します。'~/.s3cmd' ファイルを作成しても大丈夫ですが、ここでは環境変数を用いて s3cmd の設定をします。

```bash
export AWS_HOST=rook-ceph-rgw-my-store.rook-ceph
export AWS_ENDPOINT=192.168.3.202:80
export AWS_ACCESS_KEY_ID=<AccessKey>
export AWS_SECRET_ACCESS_KEY=<SecretKey>
```

- AWS_HOST
  - object.yaml をそのまま使用した場合、hostname は 'rook-ceph.rgw-my-store.rook-ceph' となります
  - Pod の外 (k8s node) から Pod にアクセスしており、k8s の internal resolver を参照したく無い場合は、AWS_ENDPOINT の IPアドレスを指定します
- AWS_ENDPOINT
  - Pod の Endpoint を指定します
  - Rook の ネットワーク形態として Host Networking を用いている場合は ClusterIP が付かないため、k8s node の IPアドレスを指定します
    - 'kubectl -n rook-ceph describe svc rook-ceph-rgw-my-store | grep -i Endpoints'
- AWS_ACCESS_KEY_ID
  - 先ほど作成した Credential の AccessKey を指定します
- AWS_SECRET_ACCESS_KEY
  - 先ほど作成した Credential の SecretKey を指定します

##bucket作成テスト
次に、bucket を作成します。次の例では、bucket(rookbucket) を作成しております。

```bash
s3cmd mb --no-ssl --host=${AWS_HOST} --region=":default-placement" --host-bucket="" s3://rookbucket
s3cmd ls --no-ssl --host=${AWS_HOST}

# s3cmd ls 実行例
rock64@node01:~/rook/cluster/examples/kubernetes/ceph$ s3cmd ls --no-ssl --host=${AWS_HOST}
2019-10-01 00:00  s3://rookbucket
```

##object PUT/GET テスト
最後に、object の PUT/GET テストを実施します。

```bash
echo "Hello Rook" > /tmp/rookObj
s3cmd put /tmp/rookObj --no-ssl --host=${AWS_HOST} --host-bucket=  s3://rookbucket

s3cmd get s3://rookbucket/rookObj /tmp/rookObj-download --no-ssl --host=${AWS_HOST} --host-bucket=
cat /tmp/rookObj-download
```

# radosgw サービスの外部への公開
Rook ではデフォルトだと k8s クラスタ内でのみサービスが利用できる設定になっております。
クラスタ外部からサービスを利用する場合は rgw-external.yaml を別途設定し、type: NodePort にて Service を作成します。

Host Networking にて Ceph のデプロイを実施した場合は Service(rook-ceph-rgw-my-store) に Cluster-IP が付いておりませんが、rgw-external.yaml を作成することで、Service(rook-ceph-rgw-my-store-external)にて Cluster-IP が使用できるようになります。

```bash
kubectl create -f rgw-external.yaml
```

#RADOWGWの性能測定
RADOSGW のベンチマーク方法としては、minio で使用されている s3-benchmark を使用いたしました。
オリジナル(fork元) の s3-benchmark は Wasabi Technologies (S3互換のオブジェクトストレージサービスを提供している会社)が github 上に公開しているツールになります。オリジナル版を試したところ、S3 API の認証が通りませんでしたので、minio版 を使う方が良さそうです。

https://github.com/minio/s3-benchmark

ROCK64 は arm64 アーキテクチャのため、GitHub の repository 内に含まれている amd64バイナリは使用できません。次の手順で、arm64版の s3-benchmark コマンドを build します。

```bash
git clone https://github.com/minio/s3-benchmark.git
cd s3-benchmark

export GOPATH=$HOME/golang
export PATH=$GOPATH/bin:$PATH
go get ./...
go build s3-benchmark.go
```

##ベンチマーク結果
s3-benchmark を使用して 1MB のファイルを PUT / GET / DELETE したところ、次の結果が得られました。

- PUT
  - 5.6 operations/sec (5.6MB/sec)
- GET
  - 23.6 operations/sec (23.6MB/sec)
- DELETE
  - 8.4 operations/sec

Object Storage の性能を検討する際には膨大な量の Object を PUT した後の挙動をしっかりと見る必要はありますが、個人用途の使用であればそれほど気にする必要もないので、今回のベンチマーク結果にて十分良い結果が得られたと考えて良さそうです。

```bash
./s3-benchmark -a ${AWS_ACCESS_KEY_ID} -s ${AWS_SECRET_ACCESS_KEY} -b rookbucket -t 1 -u http://10.108.209.124:80

# benchmark 出力結果 (num_threads = 1)
S3 benchmark program v3.0
Parameters: url=http://10.108.209.124:80, bucket=rookbucket, duration=10, threads=1, loops=1, size=1M
Thu, 24 Oct 2019 08:44:14 GMT Loop 1: PUT time 10.1 secs, objects = 56, speed = 5.6MB/sec, 5.6 operations/sec.
Thu, 24 Oct 2019 08:44:25 GMT Loop 1: GET time 10.0 secs, objects = 236, speed = 23.6MB/sec, 23.6 operations/sec.
Thu, 24 Oct 2019 08:44:31 GMT Loop 1: DELETE time 6.6 secs, 8.4 operations/sec.
Benchmark completed.

# benchmark 出力結果 (num_threads = 10)
rock64@node01:~/s3-benchmark$ ./s3-benchmark -a ${AWS_ACCESS_KEY_ID} -s ${AWS_SECRET_ACCESS_KEY} -b rookbucket -t 10 -u http://10.108.209.124:80
S3 benchmark program v3.0
Parameters: url=http://10.108.209.124:80, bucket=rookbucket, duration=10, threads=10, loops=1, size=1M
Thu, 24 Oct 2019 08:45:53 GMT Loop 1: PUT time 10.7 secs, objects = 135, speed = 12.6MB/sec, 12.6 operations/sec.
Thu, 24 Oct 2019 08:46:03 GMT Loop 1: GET time 10.2 secs, objects = 510, speed = 50.2MB/sec, 50.2 operations/sec.
Thu, 24 Oct 2019 08:46:12 GMT Loop 1: DELETE time 8.6 secs, 15.7 operations/sec.
Benchmark completed.
```

#おわりに
今回の検証では、ROCK64 上に Rook を用いて RADOSGW を構築し、ベンチマークを実施しました。結果としては、個人用途であれば十分な性能のS3互換 Object Storage を構築することができました。

今回の内容は個人用途を想定しておりますが、Ceph 自体はとてもスケール性能が高く障害への耐性も強いため、ハードウェア構成を少し工夫すれば企業内での利用や外部サービスの用途で活用することは容易にできそうです。
ROCK64 をプロダクション環境で利用するのは安定性・運用の面で厳しいかもしれませんが、例えば Ambedded Technology 社が販売している Mars400 のような筐体を用いると、コスト効率が抜群に高い分散型のストレージを簡単に作れるかもしれません。

https://www.ambedded.com/Ceph_Storage.html