お父さんの小遣いで作れる Ceph Server、Cluster HAT + Raspberry Pi Zeroで構築できました

# はじめに
Ceph は OpenStack や Kubernetes の世界では Volume や Object Storage として良く使われていますが、分散システムで沢山のノードが必要なこともあり、個人用途として自宅で使う人は滅多に居ない状況であると思います。
また、すでに個人用途・法人用途共に世の中には膨大な数のストレージサービスが存在しており、とても便利かつ安価に利用できます。

しかしながら、何事も Do It Yourself で自分で構築しないと気が済まない人も少なからずいらっしゃると思います。そんな人に是非オススメしたいのが、今回紹介させていただく 「お父さんの小遣いで作れる Ceph Server」になります。

お父さんの小遣いは人により定義は大きく変わると思われますが、今回は 予算3万円以内 といたしました。

# コンセプト
次のようなコンセプトで、サーバを構築しました。

- お父さんの小遣い(3万円くらい)でも十分に作れること
- Ceph rbd および radosgw が動くこと
- Bluestore が動くこと
- デプロイに関しては、プロダクト品質にこだわること (きっちり自動化)

# ハードウェア
ハードウェア構成は、次のような構成になりました。3万円に若干足が出ているような気もしますが。。工夫次第ではもう少し安く入手できるかもしれません。

- Cluster HAT
    - Raspberry Pi Zero を4台まで簡単に接続できるボード
    - https://clusterhat.com
    - 4,000 円程度
- Raspberry Pi Zero
    - 700 円程度 (ただし、お店によっては購入制限あり)
    - https://www.switch-science.com/catalog/3190/
- Cluster HAT Case
    - 1,500 円程度
    - https://www.modmypi.com/raspberry-pi/cases-183/raspberry-pi-b-plus2-and-3-cases-1122/cases-for-hats-and-boards-1133/cluster-hat-case
- Raspberry Pi Model B
    - 5,000 円程度
    - https://www.switch-science.com/catalog/3050/
- SD Card x4
    - 1枚 3,000 円程度 x 4 = 12,000 円
- Raspberry Pi 用電源
    - 2.5Aに対応したUSB電源ケーブル
    - 普通のUSBケーブルだと、パワー不足で刺さる可能性があるので注意

# 外観
Cluster HAT Case に各部品を組み上げていくと、次のような外観のものが出来上がります。
大きさは、Amazon ECHO Dot より少し大きい程度なので、かなり小さいと思います。
![IMG_7330.jpg](https://qiita-image-store.s3.amazonaws.com/0/96389/498e5b07-b2aa-e10a-ed37-b9933df68136.jpeg)

# ノードの初期設定
はじめに、次のようなコマンドにて、Raspberry Pi Zero の各ノードを初期設定します。
ポイントとしては、ceph のデータ領域を LVM で構成しています。root partition に 20GB を割り当て、残りの領域については LVM として割り当てます。
 
```bash
# node 電源ON
clusterhat on p1

# node に SSH login
node SSH login
ssh pi@p1.local

# volume のリサイズ
sudo resize2fs /dev/mmcblk0p2 20G
sudo fdisk /dev/mmcblk0
# d 2
# n p 2 98304 +20G w
sudo reboot
sudo resize2fs /dev/mmcblk0p2 20G

# LVM の設定
sudo fdisk /dev/mmcblk0
# n p 3 42041344 249737215
# t 3 8e w
sudo partprobe /dev/mmcblk0
sudo apt update
sudo apt install lvm2

# 再作成する場合は、古いリソースを一旦削除する
sudo lvremove /dev/vg1/lv1
sudo vgremove vg1
sudo pvremove /dev/mmcblk0p3

sudo pvcreate /dev/mmcblk0p3
sudo pvdisplay
sudo vgcreate vg1 /dev/mmcblk0p3
sudo vgdisplay
# filestore を使う場合は、journal volume(lv1-journal) を作成する
# rocksdb の場合は不要
sudo lvcreate --name lv1-journal --size 200MB vg1
sudo lvcreate --name lv1 --size 98GB vg1
sudo lvdisplay

# Swap ファイルのサイズを 2GB に増やす
sudo vi /etc/dphys-swapfile
+-+-
CONF_SWAPSIZE=2048
+-+-
sudo systemctl stop dphys-swapfile
sudo systemctl start dphys-swapfile

# SSH authorized_keys の設定
mkdir ~/.ssh
vi ~/.ssh/authorized_keys

```

# ソフトウェアの準備
Raspberry Pi の OS としては、Cluster HAT が提供している Raspbian を使用します。基本的には Raspbian と同一ですが、Cluster HAT を制御するためのソフトウェア等がインストールされているので、自分でオリジナルの Raspbian をカスタマイズするよりも便利です。

なお、今回の構成では Raspberry Pi Zero に刺した SDカード内に Ceph のデータ領域を作成する必要があるため、Linux LVM に対応した Ceph version 12.2.8 (Luminous) をビルドしました。

Raspberry Pi Zero 向けの Ceph バイナリを構築するには少々のコツと1週間程度のビルド時間を要しました。次のドキュメントを参考に、一部コードを修正すれば、無事に稼働するようになりました.

https://tracker.ceph.com/issues/23387

## LLVM ビルド手順

```bash
git clone https://github.com/llvm-mirror/llvm.git
cd llvm
git checkout release_70
cd tools
git clone https://github.com/llvm-mirror/clang.git
cd clang
git checkout release_70
cd ..
git clone https://github.com/llvm-mirror/lld.git
cd lld
git checkout release_70
cd ../../..
mkdir llvm-build
cd llvm-build
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD=ARM ../llvm
make
make install
update-alternatives --install /usr/bin/cc cc /usr/local/bin/clang 100
update-alternatives --install /usr/bin/c++ c++ /usr/local/bin/clang++ 100
update-alternatives --install /usr/bin/cpp cpp /usr/local/bin/clang-cpp 100
```

## Ceph パッケージのビルド手順

```bash
curl -O http://www.trial-ride.net/patch-armhf-new.diff
git clone https://github.com/ceph/ceph.git
cd ceph
git checkout -b v12.2.8 refs/tags/v12.2.8
git submodule update --init --recursive
patch -p1 < ../patch-armhf-new.diff
./install-deps.sh
sed -i 's/\(WITH_CEPHFS_JAVA\)=ON/\1=OFF/' debian/rules

sudo apt install reprepro
git add .
git commit -m "support for raspbian"
./make-debs.sh /home/pi/ceph-build
cd /home/pi/ceph-build/Raspbian
tar czvf ceph-repo-12.2.8-armhf.tar.gz db dists pool stretch
```

# デプロイ手順
Ceph のデプロイ方法として、ceph-ansible を用いました。ceph-ansible は様々な構成に対応したプロダクション品質のデプロイツールなので、事業者だけではなく個人でも安心して使えます。

次のような手順にてデプロイを実施しました。

```bash
# ceph-ansible のインストール
sudo apt install -y git
git clone https://github.com/ceph/ceph-ansible.git
cd ceph-ansible
export branch=stable-3.2
git checkout $branch
cd ~

# jewel をデプロイする場合は、stable-3.0 にする必要がある
# luminous, mimic の場合は stable-3.2 を指定する
sudo apt install -y virtualenv python-dev libffi-dev libssl-dev
virtualenv venv
source venv/bin/activate

# stable-3.0 の場合
pip install -r ceph-ansible/tests/requirements.txt
# stable-3.2 の場合
pip install -r ceph-ansible/requirements.txt

sudo mkdir /etc/ansible
sudo vi /etc/ansible/hosts
+++
[mons]
p1.local
p2.local
p3.local

[osds]
p1.local
p2.local
p3.local

[mgrs]
p1.local
p2.local
p3.local

[rgws]
p1.local
p2.local
p3.local
+++

sudo ln -s ~/ceph-ansible/group_vars /etc/ansible/group_vars
cd ~/ceph-ansible
cd group_vars
cp all.yml.sample all.yml
vi all.yml
+++
ceph_origin: repository
ceph_repository: custom
ceph_stable: True
ceph_stable_release: luminous
cephx: true
monitor_interface: "usb0"
journal_size: 2048
osd_mkfs_options_xfs: -f -i size=2048
osd_mount_options_xfs: noatime,largeio,inode64,swalloc
public_network: 172.19.181.0/24
cluster_network: 172.19.181.0/24

ceph_origin: repository
ceph_repository: custom
ceph_custom_repo: http://www.trial-ride.net/ceph-raspbian.armv6
+++

cp osds.yml.sample osds.yml
vi osds.yml
# filestore の場合
+++
osd_objectstore: filestore
osd_scenario: lvm
lvm_volumes:
  - data: lv1
    data_vg: vg1
    journal: lv1-journal
    journal_vg: vg1
+++
# rocksdb の場合
+++
osd_objectstore: bluestore
osd_scenario: lvm
lvm_volumes:
  - data: lv1
    data_vg: vg1
+++

cd ..
cp site.yml.sample site.yml

# デプロイの実行
ansible-playbook site.yml -b
```

# ベンチマーク結果
rados bench を実行した結果は、次のようになりました。
性能に関しては、あまり早くはないです。。

```bash
pi@p1:~ $ sudo rados mkpool mypool
pi@p1:~ $ sudo rados -p mypool bench 10 write -b 123
hints = 1
Maintaining 16 concurrent writes of 123 bytes to objects of size 123 for up to 10 seconds or 0 objects
Object prefix: benchmark_data_p1_13471
  sec Cur ops   started  finished  avg MB/s  cur MB/s last lat(s)  avg lat(s)
    0       2         2         0         0         0           -           0
    1      15        77        62 0.00708616 0.00727272    0.280682    0.232659
    2      16       144       128 0.00740415 0.00774193    0.128686    0.231646
    3      16       214       198 0.00766135 0.00821114    0.281453    0.231473
    4      16       270       254 0.00738524 0.00656891    0.216874     0.24727
    5      16       338       322 0.00749572 0.00797653    0.218095    0.243478
    6      16       404       388 0.00753443 0.00774193    0.175373     0.24238
    7      16       478       462 0.00769518 0.00868034    0.160927    0.239925
    8      16       553       537 0.00782772 0.00879765    0.145773    0.235024
    9      16       628       612 0.00793464 0.00879765    0.199223    0.231789
   10      16       696       680 0.00793851 0.00797653    0.179024    0.231877
Total time run:         10.160294
Total writes made:      697
Write size:             123
Object size:            123
Bandwidth (MB/sec):     0.00804696
Stddev Bandwidth:       0.000705981
Max bandwidth (MB/sec): 0.00879765
Min bandwidth (MB/sec): 0.00656891
Average IOPS:           68
Stddev IOPS:            6
Max IOPS:               75
Min IOPS:               56
Average Latency(s):     0.232101
Stddev Latency(s):      0.0742895
Max latency(s):         0.733679
Min latency(s):         0.080719
Cleaning up (deleting benchmark objects)
Removed 697 objects
Clean up completed and total clean up time :8.070982
```

# まとめ
今回のドキュメントでは、「お父さんの小遣いで Ceph Cluster を作れる?」をテーマにして Cluster HAT を色々と弄り倒した結果をまとめさせていただきました。
結果としては、自分で作るよりはクラウドサービスを買ったほうが早いし安いかも。。ということになってしまいましたが、いつかは状況が逆転する時が訪れる可能性は十分あると予想しております。

例えば、今年の Ceph Day Berlin にて Ambedded さんが発表されていたスライドを見たところ、ARMベースで ceph cluster を構築すると、沢山のDiskを1ホストに高密度実装することの欠点(NUMA Memory Access のボトルネック、1ホストが壊れると沢山のOSDが止まってサービス影響が大きい、等)から解放されたり、消費電力が低減できるとのことで、とても合理的に見受けられます。

今年は AWS EC2 等でも ARMアーキテクチャのインスタンスが使えるようになり、色々と ARM に追い風が吹いてきているようです。今後も ARM の動向は見逃せませんね。

  - https://www.slideshare.net/Inktank_Ceph/ceph-day-berlin-5-reasons-to-use-armbased-microserver-architecture-for-ceph-cluster