Cephを構築＆ファイルシステムCephFSをLinuxにマウント

# はじめに

[Ceph](https://docs.ceph.com/en/quincy/)は分散ストレージのオープンソフトウェアで、以下の3つのインターフェイスが用意されています。

※それぞれどのようなものかは筆者のざっくりとした認識で書いており間違っているかもしれません。

* (1) RADOS（Reliable Autonomic Distributed Object Store）
    * オブジェクトストレージ。AWSでいうS3、AzureだとBlob Storageのようなもの
* (2) RBD（RADOS Block Device）
    * デバイス。パソコンの内蔵ハードディスクや外付けハードディスクのようなもの(``/dev/sda``として認識されるような感じ)
* (3) CephFS(Ceph File System)
    * ネットワーク経由で他のマシンと共有可能なファイルシステム。Samba(CIFS)、NFSのようなもの

またストレージの拡張や、データを冗長化して障害に耐えられる機能も備えています。変幻自在で何とも興味深いCeph！

本記事では、Liunxマシンで以下のCeph環境を構築する方法についてご紹介します。
* Ceph本体の構築。Cephadmを利用
* Cephのファイルシステム[CephFS](https://docs.ceph.com/en/quincy/cephfs/)の構築とマウント方法
    * 最初にご紹介したインターフェイスの(3)相当

※ちなみに(2)RBD（RADOS Block Device）を使う手順は[こちらの記事](https://qiita.com/showchan33/items/3a3fa9e2d3c0f1f7b6fb)に書いております。

# 動作確認環境

#### Ceph本体（MON,MNG,OSD等）を構築するマシン
* Raspberry Pi 4 Model B 4GB
* OS : Ubuntu 22.04 LTS
* CPUアーキテクチャ : arm64

:::note info
実運用では複数台（３台など）が推奨されるはずですが、今回は試験用で1台で構築します。
:::

#### OSDと接続するディスク（ストレージ）
* Seagate BarraCuda
* 型名 : ST2000DM005
* 容量 : 2TB

ディスクは「Cephを構築するマシン」のデバイスとして以下のように認識されており、ファイルシステムを構築していない状態です。

```
$ sudo parted -l
（出力省略）
Error: /dev/sda: unrecognised disk label
Model: Logitec  (scsi)
Disk /dev/sda: 2000GB
Sector size (logical/physical): 512B/4096B
Partition Table: unknown
Disk Flags:
（出力省略）
```

#### 各ツールのバージョン

* Ceph : 17.2.5
* Docker : 20.10.23

# Cephのセットアップ

#### Cephadmのインストール

Cephの環境全般を構築するのに利用します。（[公式サイト](https://docs.ceph.com/en/quincy/cephadm/install/#distribution-specific-installations)）

```
$ sudo apt update
$ sudo apt -y install cephadm
```

:::note warn
[REQUIREMENTS](https://docs.ceph.com/en/quincy/cephadm/install/#cephadm-deploying-new-cluster)に記載のように、Python3、Docker(またはPodman)、LVM2等も利用するのでセットアップが必要です。
:::

#### Cephのインストール

Ceph環境を操作するのに使います。

```
$ sudo apt -y install ceph
```

:::note info
``ceph``コマンドを使えるようになります。
同等の操作が``cephadm shell -- ceph ...``でもできるようですが、毎回打つコマンドが長くなってしまうので``ceph``を使った方がよさそうです。
:::

#### Cephの新しいクラスターの作成

[公式サイト](https://docs.ceph.com/en/quincy/cephadm/install/#bootstrap-a-new-cluster)にしたがってbootstrapコマンドを実行します。
※ ``*<mon-ip>*``には、構築するマシンのIPアドレスを記載

```
$ sudo cephadm bootstrap --mon-ip *<mon-ip>*
```

:::note warn
bootstrapの出力で「Ceph DashboardのUsername/Password」や「クラスターのfsid」が出力されるため、消さずに控えておくことをお勧めします！
:::

#### [参考]クラスターの起動確認


bootstrapで起動したコンテナやサービスを確認してみます。
※セットアップには不要の手順です。

* Ceph Dashboardへアクセス
    * URL : https://[mon-ip]:8443/
    * UsernameとPasswordはbootstrap時に出力されたものを入力
    * 初回ログイン後はパスワードの変更が必要

* コンテナの起動確認
```
$ sudo docker ps -a | grep -e ^CONTAINER -e ceph
CONTAINER ID   IMAGE                                     COMMAND                  CREATED         STATUS         PORTS   NAMES
2f579044e7bc   quay.io/prometheus/alertmanager:v0.23.0   "/bin/alertmanager -…"   3 minutes ago   Up 3 minutes           ceph-[fsid]-alertmanager-ubuntu
a49f3e57be32   quay.io/ceph/ceph-grafana:8.3.5           "/bin/sh -c 'grafana…"   3 minutes ago   Up 3 minutes           ceph-[fsid]-grafana-ubuntu
584bbdeb7bc1   quay.io/prometheus/prometheus:v2.33.4     "/bin/prometheus --c…"   3 minutes ago   Up 3 minutes           ceph-[fsid]-prometheus-ubuntu
e24e16294c20   quay.io/prometheus/node-exporter:v1.3.1   "/bin/node_exporter …"   4 minutes ago   Up 4 minutes           ceph-[fsid]-node-exporter-ubuntu
0724377abf29   quay.io/ceph/ceph                         "/usr/bin/ceph-crash…"   4 minutes ago   Up 4 minutes           ceph-[fsid]-crash-ubuntu
0734e3708aef   quay.io/ceph/ceph:v17                     "/usr/bin/ceph-mgr -…"   8 minutes ago   Up 8 minutes           ceph-[fsid]-mgr-ubuntu-wtdnix
05aaf49dc3ab   quay.io/ceph/ceph:v17                     "/usr/bin/ceph-mon -…"   8 minutes ago   Up 8 minutes           ceph-[fsid]-mon-ubuntu
```

* サービスの起動確認
```
$ sudo systemctl list-units --type=service | grep ceph
  ceph-[fsid]@alertmanager.ubuntu.service  loaded active running Ceph alertmanager.ubuntu for [fsid]
  ceph-[fsid]@crash.ubuntu.service         loaded active running Ceph crash.ubuntu for [fsid]
  ceph-[fsid]@grafana.ubuntu.service       loaded active running Ceph grafana.ubuntu for [fsid]
  ceph-[fsid]@mgr.ubuntu.wtdnix.service    loaded active running Ceph mgr.ubuntu.wtdnix for [fsid]
  ceph-[fsid]@mon.ubuntu.service           loaded active running Ceph mon.ubuntu for [fsid]
  ceph-[fsid]@node-exporter.ubuntu.service loaded active running Ceph node-exporter.ubuntu for [fsid]
  ceph-[fsid]@prometheus.ubuntu.service    loaded active running Ceph prometheus.ubuntu for [fsid]
```

どうやら、Cephの各コンテナをsystemdのサービスを使って監視しているようです。

# OSDの追加

Ceph本体にストレージを追加していきます。ストレージの追加にはOSD(Object Storage Device Daemon)と呼ばれるものを使います。[DEPLOY OSDS](https://docs.ceph.com/en/quincy/cephadm/services/osd/#cephadm-deploy-osds)に書かれている内容に従ってコマンドを実行していきます。

#### Cephに利用可能なストレージデバイスを認識させる

```
$ sudo ceph orch apply osd --all-available-devices
Scheduled osd.all-available-devices update...
```
確認すると、利用可能なストレージが以下のように出力されます。
```
$ sudo ceph orch device ls --refresh
HOST        PATH      TYPE  DEVICE ID                  SIZE   AVAILABLE  REFRESHED  REJECT REASONS
[hostname]  /dev/sda  hdd   1Logitec_xxxxxxxxxxxxxxxx  2000G  Yes        2s ago
```

#### OSDの追加

下記コマンドでOSDを追加します。
```
$ sudo ceph orch daemon add osd --method raw [hostname]:/dev/sda
(出力結果)
Created osd(s) 0 on host '[hostname]'
```
* 補足
    * ``[hostname]``は``ceph orch device ls``の``HOST``に表示されたホスト名を入力
        * ``sudo ceph orch host ls``でもCephが認識しているホスト名を確認可能

:::note info
筆者環境だと``--method raw``を指定しないとエラーとなりました。
推測 : デフォルトはlvmで、OSDに追加するデバイスが「[論理ボリューム（LVM）](https://www.idcf.jp/words/lvm.html)」であることが前提になっており、今回は物理ボリュームなので失敗したと考えています。例えばVirtualBox上などで作られるボリュームはLVMなので（おそらく）、``--method raw``オプションは指定不要のはずです。
:::

#### 追加したOSDの確認
下記のコマンドなどで確認可能です。
```
$ sudo ceph osd stat
1 osds: 1 up (since 6m), 1 in (since 10m); epoch: e17
$ sudo ceph osd tree
ID  CLASS  WEIGHT   TYPE NAME        STATUS  REWEIGHT  PRI-AFF
-1         1.81940  root default
-3         1.81940      host [hostname]
 0    hdd  1.81940          osd.0        up   1.00000  1.00000
```
余談ですが、osd-0のコンテナが作られているのも確認できます。
```
$ sudo docker ps -a | grep ceph | grep osd
cc5db04e2dac   quay.io/ceph/ceph   "/usr/bin/ceph-osd -…"   14 minutes ago   Up 14 minutes   ceph-[fsid]-osd-0
```

# CephFSの構築

Cephのファイルシステム[CephFS](https://docs.ceph.com/en/quincy/cephfs/)を構築していきます。CephFSで必要な要素を知るには、以下の図がわかりやすそうです。
<img src="https://docs.ceph.com/en/quincy/_images/cephfs-architecture.svg">
ただ実際にやる手順が以下のように結構多いです。。。
* (1) RADOS poolの作成
* (2) ファイルシステムの作成
* (3) 作成したファイルシステムのMDS(=Metadata Server)をコンテナでデプロイ
* (4) マウントするユーザの作成

以下順に説明していきます。

### (1) RADOS poolの作成

[CREATING POOLS](https://docs.ceph.com/en/quincy/cephfs/createfs/#creating-pools)を参考に、2つのRADOS poolを作成します。

```
$ sudo ceph osd pool create cephfs_data
(出力結果)
pool 'cephfs_data' created
```
```
$ sudo ceph osd pool create cephfs_metadata
(出力結果)
pool 'cephfs_metadata' created
```

### (2) ファイルシステムの作成

[CREATING A FILE SYSTEM](https://docs.ceph.com/en/quincy/cephfs/createfs/#creating-a-file-system)を参考にコマンド実行します。

```
$ sudo ceph fs new cephfs cephfs_metadata cephfs_data
(出力結果)
new fs with metadata pool 2 and data pool 1
```
作成されたことを確認
```
$ sudo ceph fs ls
name: cephfs, metadata pool: cephfs_metadata, data pools: [cephfs_data ]
$ sudo ceph mds stat
cephfs:0
```

### (3) 作成したファイルシステムのMDSをコンテナでデプロイ

手順(2)で作成したファイルシステムのMDSを、次のコマンドでコンテナ上でデプロイします。
```
$ sudo ceph orch apply mds cephfs --placement="1 [hostname]"
(出力結果)
Scheduled mds.cephfs update...
```
:::note info
こちらの手順はCeph公式サイトではみつからず、[RedHat](https://access.redhat.com/documentation/ja-jp/red_hat_ceph_storage/5/html-single/operations_guide/index)のサイトで見つけました。
:::

以上により、Cephクラスターの状態は以下のようになっているはずです。
```
$ sudo ceph -s
  cluster:
    id:     xxxxxxxx-yyyy-zzzz-AAAA-BBBBBBBBBBBB
    health: HEALTH_WARN
            1 MDSs report slow metadata IOs
            3 pool(s) have no replicas configured
            OSD count 1 < osd_pool_default_size 3

  services:
    mon: 1 daemons, quorum [hostname] (age 2h)
    mgr: [hostname].wtdnix(active, since 2h)
    mds: 1/1 daemons up                              # 追加で起動！
    osd: 1 osds: 1 up (since 50m), 1 in (since 54m)  # 追加で起動！

  data:
    volumes: 1/1 healthy                             # 追加が反映！
    pools:   3 pools, 65 pgs                         # 追加が反映！
    objects: 24 objects, 451 KiB
    usage:   8.1 MiB used, 1.8 TiB / 1.8 TiB avail   # 追加が反映！
    pgs:     65 active+clean

  progress:
    Global Recovery Event (0s)
      [............................]
```

### (4) マウントするユーザの作成

[GENERAL PRE-REQUISITE FOR MOUNTING CEPHFS](https://docs.ceph.com/en/quincy/cephfs/mount-prerequisites/#general-pre-requisite-for-mounting-cephfs)に従って、CephFSでマウント可能なユーザを作成します。

:::note info
以下コマンドでユーザ名は``user``としていますが、適宜変更ください。
:::

```
$ sudo ceph fs authorize cephfs client.user / rw \
  | sudo tee /etc/ceph/ceph.client.user.keyring
(出力結果)
[client.user]
	key = AQAOptVqae....
```
生成した鍵のパーミッションを変更します。
```
$ sudo chmod 0600 /etc/ceph/ceph.client.user.keyring
```

Cephの認証情報に追加したユーザが反映されているのを以下のように確認できます。

```
$ sudo ceph auth list
（出力省略）
client.user
	key = AQAOptVqae....
	caps: [mds] allow rw fsname=cephfs
	caps: [mon] allow r fsname=cephfs
	caps: [osd] allow rw tag cephfs data=cephfs
（出力省略）
```

# CephFSをマウント

ようやくマウントするための準備が整いました。マウント方法は複数あるようですが、今回は[MOUNT CEPHFS USING KERNEL DRIVER](https://docs.ceph.com/en/quincy/cephfs/mount-using-kernel-driver/)の方法でマウントしていきます。
公式サイトには色々書かれていますが、下記コマンドを実行すればマウントできるはずです。

```
$ sudo mount -t ceph user@.cephfs=/ /path/to/mount
```

```
$ df -h
Filesystem   Size  Used Avail Use% Mounted on
...
[IP]:6789:/  1.8T     0  1.8T   0% /path/to/mount
```

### 解説

* ``user@.cephfs=/``のフォーマット
    * ``user`` : 手順(4)で作成したマウント用のユーザ名
    * ``cephfs`` : 手順(2)で作成したファイルシステム名
    * ``/`` : マウント元のパス
* ``/path/to/mount``
    * マウント先のパス。mkdir等で事前に作成が必要

試しに一回アンマウントして、``-v``オプションでどのようにしてマウントしているかを確認してみます。
```
$ sudo umount /path/to/mount
$ sudo mount -t ceph user@.cephfs=/ /path/to/mount -v
(出力結果)
parsing options: rw,secret=AQAOptVqae....
mount.ceph: resolved to: "[IP]:3300"
mount.ceph: trying mount with new device syntax: user@[fsid].cephfs=/
mount.ceph: options "name=user,ms_mode=prefer-crc,key=user,mon_addr=[IP]:3300" will pass to kernel
mount.ceph: switching to using v1 address with old syntax
mount.ceph: resolved to: "[IP]:6789"
mount.ceph: trying mount with old device syntax: [IP]:6789:/
mount.ceph: options "name=user,key=user,mds_namespace=cephfs,fsid=[fsid]" will pass to kernel
```

出力を見ると、mountコマンドでは指定しなかったモニターのIPやFSID、シークレット情報などを``mount.ceph``が見つけてくれていることがわかります。この辺の話は [MOUNT.CEPH – MOUNT A CEPH FILE SYSTEM](https://docs.ceph.com/en/quincy/man/8/mount.ceph/) 等に説明があります。

ちなみに以下のように全ての情報を引数で指定することも可能です。

```
$ sudo mount -t ceph \
  user@[fsid].cephfs=/ \
  /path/to/mount \
  -o mon_addr=[IP]:6789,secret=AQAOptVqae....
```

### 使えそうなマウント設定

#### /etc/fstab での設定

[こちら](https://docs.ceph.com/en/mimic/cephfs/fstab/)のサイトにも解説がありますが、``/etc/fstab``に以下のように追記してマウントできました。
```/etc/fstab
[IP]:6789:/ /path/to/mount ceph name=user 0 0
```
尚、``[IP]:6789``は省略して以下でもOKです。
```/etc/fstab
:/ /path/to/mount ceph name=user 0 0
```

#### autofs での設定
autofsの場合はマウントパスを指定するファイル内で、以下を追記するとマウントできました。
こちらはfstabとは異なり、``[IP]:6789:``を記入しないとマウント出来ませんでした。
```
some-path -fstype=ceph,name=user [IP]:6789:/
```

# その他

## OSDのメモリ利用量の変更

ラズパイでCephを構築してファイルコピーなどをやろうとすると、ceph-osdのプロセスがメモリをすぐに喰いつぶしてしまいマシンが止まります。。。なので[osd_memory_target](https://docs.ceph.com/en/quincy/rados/configuration/bluestore-config-ref/#confval-osd_memory_target)コマンドで、OSDで利用するメモリサイズを変更したほうが良さそうです。
ドキュメントにデフォルト4Giとありますが、確認してみると確かにそのようで。。。
```
$ sudo ceph config get osd.0 osd_memory_target
4294967296
```
500MBくらいに変更しようとしたら「下限を超えている」と怒られました。
```
$ sudo ceph config set osd.0 osd_memory_target 500000000
Error EINVAL: error parsing value: Value '500000000' is below minimum 939524096
```
そこで、エラーに出ている数値（許容される最大値）に変更すると通りました。
```
$ sudo ceph config set osd.0 osd_memory_target 939524096
```

:::note warn
設定を反映するには**マシンの再起動**が必要です。
未確認ですが、``docker container restart [OSDコンテナ名]``でコンテナを再起動して反映される可能性もあります。
:::

#### OSDを再起動するスクリプト（23/02/19追記）

OSDのメモリ利用量の上限を変更してもメモリを喰いつぶす問題が解決しないため、OSDを再起動するシェルスクリプトを作成して、下記GitHubに格納しました。

https://github.com/showchan33/ceph-osd-restarter