ubuntu22.04でcephクラスタを構築する

こんにちは。
株式会社クラスアウト インフラストラクチャ事業部の大塚です。

今回はタイトルにもあるように、ubuntu22.04のVMをベースに使いcephクラスタを構築してきたいと思います。

# 構築する環境・HW構成

今回は3台でクラスタを組んでいきたいと思います。
OSはubuntuの22.04を使用します。IPアドレスは192.168.2.37~39を割り当てます。ホスト名はk8s-ceph01～03。CPU,Memory,Diskは以下としました。cephクラスタを統括するサーバはk8s-ceph01としております。また、各ホストはディスクを最大2つは付けるようにしてください。ディスクが1つしかないとcephが「使えるdisk無いや…(´・ω・｀)」と判断してしまいます。

|ホスト名  |役割  |IPアドレス　|CPU　|Memory　|Disk1　|Disk2　|
|---|---|---|---|---|---|---|
|k8s-ceph01  |master |192.168.2.37/24 |2sockets 4cores |12.70GiB |50G |50G |
|k8s-ceph02  |worker  |192.168.2.38/24 |2sockets 4cores |9.77GiB |50G |50G |
|k8s-ceph03  |worker  |192.168.2.39/24 |2sockets 4cores |9.77GiB |50G |50G |

本当にざっくり表現すると以下の様になります。
![4f18c0b11e7a069838041e55f4f6b290.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/d6828a5c-4018-6d98-03ed-e302c6251499.png)

# 用語
## cephとは？

wikipediaから引用してみます。
オブジェクト/ブロック/ファイルストレージを分散して配置・統制することで、地震や津波とかで、例えばA拠点のＨＷ関連が全部壊れても、Ｂ拠点が生きていればデータ損失が発生せず継続して業務が遂行出来る。的な事をするためのOSSとでも考えておけばいいのかなぁと思っています。BCP的なやつ。災害が無かったとしても”HWがいつ壊れるか”なんてことは誰にもわかりませんから、データを分散させて管理することは本番環境であればより重要なわけで、比較的どんな場面にも使えそうですよね。

>オブジェクト、ブロック、ファイルレベルのストレージインタフェースを提供し、単一障害点がなく、エクサバイトレベルまで拡張可能な、フリーで利用できる完全な分散オペレーションを主な目的としている。特別なハードウェアサポートを必要としない汎用ハードウェア（英語版）を使用して、データを複製することで耐障害性を持たせている。
https://ja.wikipedia.org/wiki/Ceph

cephの公式ドキュメントは以下となります。

https://docs.ceph.com/en/quincy/#


cephは様々なコンポーネント？があります。
cephクラスタを構築するにあたり知っておいた方が良いだろうなと思うものをイメージと併せて列挙します。
※このイメージが必ず正しいとは限りません。私も現在進行形で確認中です。
結構複雑な機構なので各コンポーネントの役割についていきなり細かいところまで理解しようとしないで、最初はザックリと。徐々に役割を理解していけば良いと思います。
![b2aeab7448a1e44f2f60fec85a86196e.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/b5ea283c-6537-b38f-336a-e0d6e1895504.png)

## OSD

ザックリcephの仮想的なストレージプールを構成する物理的なHardDiskの事だと思って頂ければいいのかと思います。今回各サーバにdiskを2つ取り付けておりますがうち一方（/dev/sdb）がOSDとなります。

## MON

“MON”iterの略になります。OSDが動いているか等監視をしているようです。

## Paxos

“パクソス”と読むらしい。
MON同士の連携の為に機能してるやつっぽいです。ハートビート的な事もしていると思われます。

## RADOS

“レイドス”と読むらしい。
cephの根幹。RADOSは複数のRADOS objectで構成されていると思われる。

![6c8029ce2f80bce130ffb54aa87346ff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/3ee894ce-3a81-8218-7b70-ec973275c3e9.png)

## RADOS Object

OSDと連携していて、クライアントはこのobjectにカキカキしたりヨミヨミしたりするが、実際はobjectがリレー的な事をしてくれており、OSDにデータをカキカキヨミヨミしている。そんなことを実現する為の存在。

## CRUSH algorithm/CRUSH map

どのデータをどのOSDに格納するかを計算で算出するのがCRUSH algorithm。
CRUSH mapはどのOSDにデータが入ってて、そのOSDにアクセスするためにどのRADOS objectにアクセスすればいいか的な事が書いている。

# 構築
## aptの最新化と名前解決の設定
全台で以下のコマンドを実行してください。
```
apt update
apt upgrade -y
```

名前解決出来る様に/etc/hostsに対してIPアドレスとホスト名を追記しておきます。
```
root@k8s-ceph01:~# cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 k8s-ceph01
192.168.2.37 k8s-ceph01
192.168.2.38 k8s-ceph02
192.168.2.39 k8s-ceph03

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
```

## ntpやdockerをインストール
全台で以下のコマンドを実行します
```
root@k8s-ceph01:~# apt install -y ntp ntpdate ntp-doc
root@k8s-ceph01:~# ntpdate ntp.nict.jp
root@k8s-ceph01:~# hwclock --systohc
root@k8s-ceph01:~# systemctl enable ntp
root@k8s-ceph01:~# systemctl start ntp
root@k8s-ceph01:~# apt install -y docker docker.io
root@k8s-ceph01:~# systemctl enable docker
root@k8s-ceph01:~# systemctl start docker
root@k8s-ceph01:~# apt install -y python3
```

## cephadmのインストールとcephクラスタのboot
masterにおいてのみ以下のコマンドを実行します。boot時に–mon-ipを指定していますがmasterとなるホストのIPアドレスを指定しておけばOKです。
“Ceph Dashboard is now available at:”の後の3行は後程使用するデータの為取っておきます。
```
root@k8s-ceph01:~# apt install -y cephadm
root@k8s-ceph01:~# which cephadm
/usr/sbin/cephadm
root@k8s-ceph01:~# cephadm bootstrap --mon-ip 192.168.2.37
Creating directory /etc/ceph for ceph.conf
Verifying podman|docker is present...
Verifying lvm2 is present...
Verifying time synchronization is in place...
Unit ntp.service is enabled and running
Repeating the final host check...
docker (/usr/bin/docker) is present
systemctl is present
lvcreate is present
Unit ntp.service is enabled and running
Host looks OK
Cluster fsid: 3399a378-06da-11ee-8592-3341d7e54bea
Verifying IP 192.168.2.37 port 3300 ...
Verifying IP 192.168.2.37 port 6789 ...
Mon IP `192.168.2.37` is in CIDR network `192.168.2.0/24`
Mon IP `192.168.2.37` is in CIDR network `192.168.2.0/24`
Internal network (--cluster-network) has not been provided, OSD replication will default to the public_network
Pulling container image quay.io/ceph/ceph:v17...
Ceph version: ceph version 17.2.6 (d7ff0d10654d2280e08f1ab989c7cdf3064446a5) quincy (stable)
Extracting ceph user uid/gid from container image...
Creating initial keys...
Creating initial monmap...
Creating mon...
Waiting for mon to start...
Waiting for mon...
mon is available
Assimilating anything we can from ceph.conf...
Generating new minimal ceph.conf...
Restarting the monitor...
Setting mon public_network to 192.168.2.0/24
Wrote config to /etc/ceph/ceph.conf
Wrote keyring to /etc/ceph/ceph.client.admin.keyring
Creating mgr...
Verifying port 9283 ...
Waiting for mgr to start...
Waiting for mgr...
mgr not available, waiting (1/15)...
mgr not available, waiting (2/15)...
mgr not available, waiting (3/15)...
mgr not available, waiting (4/15)...
mgr not available, waiting (5/15)...
mgr is available
Enabling cephadm module...
Waiting for the mgr to restart...
Waiting for mgr epoch 5...
mgr epoch 5 is available
Setting orchestrator backend to cephadm...
Generating ssh key...
Wrote public SSH key to /etc/ceph/ceph.pub
Adding key to root@localhost authorized_keys...
Adding host k8s-ceph01...
Deploying mon service with default placement...
Deploying mgr service with default placement...
Deploying crash service with default placement...
Deploying prometheus service with default placement...
Deploying grafana service with default placement...
Deploying node-exporter service with default placement...
Deploying alertmanager service with default placement...
Enabling the dashboard module...
Waiting for the mgr to restart...
Waiting for mgr epoch 9...
mgr epoch 9 is available
Generating a dashboard self-signed certificate...
Creating initial admin user...
Fetching dashboard port number...
Ceph Dashboard is now available at:

             URL: https://k8s-ceph01:8443/
            User: admin
        Password: fkt1ixdez9

Enabling client.admin keyring and conf on hosts with "admin" label
Saving cluster configuration to /var/lib/ceph/3399a378-06da-11ee-8592-3341d7e54bea/config directory
Enabling autotune for osd_memory_target
You can access the Ceph CLI as following in case of multi-cluster or non-default config:

        sudo /usr/sbin/cephadm shell --fsid 3399a378-06da-11ee-8592-3341d7e54bea -c /etc/ceph/ceph.conf -k /etc/ceph/ceph.client.admin.keyring

Or, if you are only running a single cluster on this host:

        sudo /usr/sbin/cephadm shell

Please consider enabling telemetry to help improve Ceph:

        ceph telemetry on

For more information see:

        https://docs.ceph.com/docs/master/mgr/telemetry/

Bootstrap complete.
```

## serverに対してrootで直接ssh出来るようにする。
ubuntu22.04はrootで直接ssh出来ないようになっている為、それを解除してrootでssh出来るようにします。
全台で以下のコマンドを実行します。
```
root@k8s-ceph01:~# cp -p /etc/ssh/sshd_config /etc/ssh/sshd_config.20230610
root@k8s-ceph01:~# vi /etc/ssh/sshd_config
root@k8s-ceph01:~# diff /etc/ssh/sshd_config /etc/ssh/sshd_config.20230610 
123d122
< PermitRootLogin yes
root@k8s-ceph01:~# passwd root
New password:
Retype new password:
passwd: password updated successfully
root@k8s-ceph01:~# systemctl restart ssh
```

## /etc/ceph上にあるceph.pubキーをworkerに登録する
master上にあるceph.pubを各ホストに登録します。
masterで以下のコマンドを実行します。
```
root@k8s-ceph01:~# cd /etc/ceph
root@k8s-ceph01:/etc/ceph# ls -ltr
total 12
-rw-r--r-- 1 root root 595 Jun  9 15:29 ceph.pub
-rw-r--r-- 1 root root 175 Jun  9 15:31 ceph.conf
-rw------- 1 root root 151 Jun  9 15:31 ceph.client.admin.keyring
root@k8s-ceph01:/etc/ceph# ssh-copy-id -f -i /etc/ceph/ceph.pub root@k8s-ceph02
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/etc/ceph/ceph.pub"
The authenticity of host 'k8s-ceph02 (192.168.2.38)' can't be established.
ED25519 key fingerprint is SHA256:NNrrE4rP4uzXNgrvbWLbWkmmt9sexpblZlwtbYt9B7Y.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
root@k8s-ceph02's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@k8s-ceph02'"
and check to make sure that only the key(s) you wanted were added.

root@k8s-ceph01:/etc/ceph# ssh-copy-id -f -i /etc/ceph/ceph.pub root@k8s-ceph03
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/etc/ceph/ceph.pub"
The authenticity of host 'k8s-ceph03 (192.168.2.39)' can't be established.
ED25519 key fingerprint is SHA256:P4SAQ+oywS9FZ2PDDDh8mBFzN4hmlpWC4SgUwvcqWuM.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
root@k8s-ceph03's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@k8s-ceph03'"
and check to make sure that only the key(s) you wanted were added.
```

## workerに登録されているか確認する
各workerのauthorized_keysファイルにceph.pubが登録されているかを確認します。
以下がその実行結果です。
```
root@k8s-ceph02:~# cat /root/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQClJXZOHkZjQAuRtnsJ61muDtaTb1npdzzVbux0vHcsAR8Z5cSkBWs36tB+17B8624paUBQY53F2Nu190qVkuTi+MujcRnQmxkF/7X3LMGdhmtAXexvaxgCRAgGMKQvyZqz9gmv9eooKMQNKsDWbDuaqBW2ti31lzpdnsALhwY9VhESW5PERlJhSIzDzsb8Y8njosA666bCNfhHKjVOI2pCpARwpcbn4E335+sXxG+1qTDYUyCMePWXZqd88rFsxwH4Mxa7rKQEiFSJa8+3j+lBguziL0PWIBzt0pbdXbqYwQhJRscwxSUyaZRXxVXWvJ8IYF9uqdIaHKBWPViPf5j2BPiZA8WVbrIj+ZG1DvLY4WthswgojtZ2IerviLuk9ycw1mFdawyjqw6uD1Q/3hCIIC1HhZgcSew+iF+qTks1t1U2JOYbbgykuAsM7VWTs2CmyFdKtwoh9HNHjQ8oL7zeAoLt0vM8O8kznoOj5rLxYcKB+9f2mcG3JK5JnyF/gOM= ceph-3399a378-06da-11ee-8592-3341d7e54bea

root@k8s-ceph03:~# cat /root/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQClJXZOHkZjQAuRtnsJ61muDtaTb1npdzzVbux0vHcsAR8Z5cSkBWs36tB+17B8624paUBQY53F2Nu190qVkuTi+MujcRnQmxkF/7X3LMGdhmtAXexvaxgCRAgGMKQvyZqz9gmv9eooKMQNKsDWbDuaqBW2ti31lzpdnsALhwY9VhESW5PERlJhSIzDzsb8Y8njosA666bCNfhHKjVOI2pCpARwpcbn4E335+sXxG+1qTDYUyCMePWXZqd88rFsxwH4Mxa7rKQEiFSJa8+3j+lBguziL0PWIBzt0pbdXbqYwQhJRscwxSUyaZRXxVXWvJ8IYF9uqdIaHKBWPViPf5j2BPiZA8WVbrIj+ZG1DvLY4WthswgojtZ2IerviLuk9ycw1mFdawyjqw6uD1Q/3hCIIC1HhZgcSew+iF+qTks1t1U2JOYbbgykuAsM7VWTs2CmyFdKtwoh9HNHjQ8oL7zeAoLt0vM8O8kznoOj5rLxYcKB+9f2mcG3JK5JnyF/gOM= ceph-3399a378-06da-11ee-8592-3341d7e54bea
```

## cephCLIの有効化
masterに対してのみ実行します。
cephCLIの有効化を行います。cephadm shellコマンドを実行し、quincyというcephバージョンをリポジトリに追加。
ceph-commonをインストールし、インストールされているかを確認する為にcephadm -vを実行しています。
出力として”ceph version 17.2.6 (d7ff0d10654d2280e08f1ab989c7cdf3064446a5) quincy (stable)”と
ありますので、問題無いかと。
このタイミングでcephadm –statusを叩いてみるとOSDについてwarning healthとなっていますが想定内です。cephはデフォルトで3つ以上無いとunHealthyと考えるようです。
```
root@k8s-ceph01:/etc/ceph# cephadm shell
Inferring fsid 3399a378-06da-11ee-8592-3341d7e54bea
Inferring config /var/lib/ceph/3399a378-06da-11ee-8592-3341d7e54bea/mon.k8s-ceph01/config
Using ceph image with id '52bedc025a3c' and tag 'v17' created on 2023-05-31 16:07:02 +0000 UTC
quay.io/ceph/ceph@sha256:9150041c77bf23a948d7161b484f6e55ff4c75092a453ea6f7885b8e4337de43
root@k8s-ceph01:/# cephadm add-repo --release quincy
Writing repo to /etc/yum.repos.d/ceph.repo...
Enabling EPEL...
Completed adding repo.
root@k8s-ceph01:/# cephadm install ceph-common
Installing packages ['ceph-common']...
root@k8s-ceph01:/# ceph -v
ceph version 17.2.6 (d7ff0d10654d2280e08f1ab989c7cdf3064446a5) quincy (stable)
root@k8s-ceph01:/# ceph status
  cluster:
    id:     3399a378-06da-11ee-8592-3341d7e54bea
    health: HEALTH_WARN
            OSD count 0 < osd_pool_default_size 3

  services:
    mon: 1 daemons, quorum k8s-ceph01 (age 11m)
    mgr: k8s-ceph01.hetslx(active, since 9m)
    osd: 0 osds: 0 up, 0 in

  data:
    pools:   0 pools, 0 pgs
    objects: 0 objects, 0 B
    usage:   0 B used, 0 B / 0 B avail
    pgs:
```

## cephクラスタにホストを入れる
masterにおいて以下のコマンドを実行してクラスタに入れます。
ceph orch host lsコマンドで実際にクラスタとして参画してるかを確認することが可能です。
```
root@k8s-ceph01:/# ceph orch host add k8s-ceph02 192.168.2.38
Added host 'k8s-ceph02' with addr '192.168.2.38'
root@k8s-ceph01:/# ceph orch host add k8s-ceph03 192.168.2.39
Added host 'k8s-ceph03' with addr '192.168.2.39'
root@k8s-ceph01:~# ceph orch host ls
HOST        ADDR          LABELS  STATUS
k8s-ceph01  192.168.2.37  _admin
k8s-ceph02  192.168.2.38
k8s-ceph03  192.168.2.39
3 hosts in cluster
```

この直後にceph status(ceph -s)を実行してもmonが1つだけで増えたりしません。
またceph orch device lsでもmaster分しか出力されません。
```
root@k8s-ceph01:~# ceph orch device ls
HOST        PATH      TYPE  DEVICE ID                   SIZE  AVAILABLE  REFRESHED  REJECT REASONS
k8s-ceph01  /dev/sdb  hdd   QEMU_HARDDISK_drive-scsi1  53.6G  Yes        15m ago

root@k8s-ceph01:/# ceph status
  cluster:
    id:     3399a378-06da-11ee-8592-3341d7e54bea
    health: HEALTH_WARN
            OSD count 0 < osd_pool_default_size 3

  services:
    mon: 1 daemons, quorum k8s-ceph01 (age 13m)
    mgr: k8s-ceph01.hetslx(active, since 10m)
    osd: 0 osds: 0 up, 0 in

  data:
    pools:   0 pools, 0 pgs
    objects: 0 objects, 0 B
    usage:   0 B used, 0 B / 0 B avail
    pgs:
```

watchコマンドで静観していると、暫く後処理が開始されることが分かると思います。以下のlogの場合”progress”から3行がそれになります。
結果的に今回の3つのホストでクラスタを組む場合、MONが3つであれば一旦OKです。
```
Every 2.0s: ceph status                                k8s-ceph01: Fri Jun  9 15:46:02 2023

  cluster:
    id:     3399a378-06da-11ee-8592-3341d7e54bea
    health: HEALTH_WARN
            OSD count 0 < osd_pool_default_size 3

  services:
    mon: 1 daemons, quorum k8s-ceph01 (age 17m)
    mgr: k8s-ceph01.hetslx(active, since 14m)
    osd: 0 osds: 0 up, 0 in

  data:
    pools:   0 pools, 0 pgs
    objects: 0 objects, 0 B
    usage:   0 B used, 0 B / 0 B avail
    pgs:

  progress:
    Updating crash deployment (+1 -> 2) (0s)
      [............................]

Every 2.0s: ceph status                                k8s-ceph01: Fri Jun  9 15:49:23 2023

  cluster:
    id:     3399a378-06da-11ee-8592-3341d7e54bea
    health: HEALTH_WARN
            OSD count 0 < osd_pool_default_size 3

  services:
    mon: 3 daemons, quorum k8s-ceph01,k8s-ceph02,k8s-ceph03 (age 57s)
    mgr: k8s-ceph01.hetslx(active, since 18m)
    osd: 0 osds: 0 up, 0 in

  data:
    pools:   0 pools, 0 pgs
    objects: 0 objects, 0 B
    usage:   0 B used, 0 B / 0 B avail
    pgs:
```

## /dev/sdbをOSDに追加する。
masterにおいて以下を実行します。
暫く後、ceph statusを実行するとOSDの欄が3になるかと思います。
```
root@k8s-ceph01:/# ceph orch apply osd --all-available-devices
Scheduled osd.all-available-devices update...
root@k8s-ceph01:/# ceph status
  cluster:
    id:     3399a378-06da-11ee-8592-3341d7e54bea
    health: HEALTH_OK

  services:
    mon: 3 daemons, quorum k8s-ceph01,k8s-ceph02,k8s-ceph03 (age 3m)
    mgr: k8s-ceph01.hetslx(active, since 21m), standbys: k8s-ceph02.zlxpfe
    osd: 3 osds: 2 up (since 3s), 3 in (since 10s)

  data:
    pools:   0 pools, 0 pgs
    objects: 0 objects, 0 B
    usage:   419 MiB used, 50 GiB / 50 GiB avail
    pgs:
```

## ceph WebUIにアクセスする
https://”masterのIPアドレス”:8443/にWebブラウザで接続します。
以下の様な画面が表示されると思うので、bootした際に出力されたデータをここに入力します。ユーザはadmin固定かと思います。
![2023061001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/7ff2e436-5311-af95-cd45-1b2a651cf873.png)
ログインが上手くいくとadminのパスワードを変えろと指示が飛んでくるので任意のものに変更します。
![2023061002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/fe983460-705d-c803-508d-9c2318fc2efa.png)
パスワード変更が上手くいくと再度ログイン画面が表示されるのでadminと設定したパスワードでログインをします。上手くログインが出来ると以下の様なdashboardが表示されるかと思います。
この画面ではcephクラスタのステータスやMONやOSDの数等が確認できますね。
![2023061003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/63e00c49-6452-1276-a003-b08ada44b568.png)
どのホストにどんなサービスが乗っかっているかグラフィカルにわかるので、クラスタの全体感を理解するのに役に立ちそうです。
![2023061004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/097b4717-d9ac-4a3c-617a-069aea7f7554.png)