本文发布于Cylon的收藏册,转载请著名原文链接~


开篇常例 - 概述

Ceph 是一个广泛使用的开源存储平台。 它提供高性能、可靠性和可扩展性。 Ceph 分布式存储系统提供了对象存储、块存储和文件级存储。 Ceph 旨在提供无单点故障的分布式存储系统。

在本教程中,将通过 ceph-adm 方式在 CentOS 7 上安装和构建 Ceph 集群。该实验的 Ceph 集群需要以下 Ceph 组件:

  • Ceph OSD (ceph-osd) - 处理数据存储、数据复制和恢复;通常一个Ceph集群至少需要两台 OSD 服务器 。
  • Ceph Monitor (ceph-mon) - 监视集群状态、OSD 映射和 CRUSH 映射,我们在这里与 cephadm 或 OSD 公用一个节点
  • Ceph 元数据服务器 (ceph-mds) - 这是使用 CephFS 所需的组件。

有了上面的条件,我们实验环境所需要的节点如下:

  • 三台服务器节点,CentOS 7

注:CentOS 7 可安装最高级别的 ceph 版本就是 O 版

本教程中的服务器将使用以下主机名和 IP 地址:

主机名 IP地址 作用
cephadmin 10.0.0.20 作为 ceph 管理节点,以管理与部署 ceph 集群
osd01 10.0.0.21
osd02 10.0.0.22
any any 作为 Ceph Client 的角色

注:所有 OSD 节点都需要两个分区,一个根(/)分区和一个空分区,稍后用作 Ceph 数据存储。

REQUIREMENTS

使用 cephadm 安装 ceph 集群,所需要的先决条件如下:

必要条件:

  • Python 3,因为 cephadm 是一个 python3 脚本,所以需要每个节点都需要安装 python3
  • Systemd
  • Podman or Docker:cephadm 安装的集群是一种以 “容器方式” 运行在对应的 ceph node 之上
  • LVM2:ceph OSD 是通过 LVM 来使用的,所以需要在每个 OSD 节点之上安装 LVM2

非必要条件:

  • chrony or NTP:ceph 强依赖每个节点之上的时间
  • Internet
  • 域名解析:ceph 集群对于 ceph node 来说是通过 hostname.random_str 识别的的

Step 1 配置节点

此步骤,将配置所有 3 个节点,为安装 Ceph 集群做好准备。 建议在所有节点上按照并运行以下所有命令。 并确保所有节点上都安装了 ssh-server。

创建ceph用户(可选)

useradd -d /home/cephuser -m cephuser 
echo 1|passwd cephuser --stdin

创建新用户后,我们需要为“cephuser” 配置 sudo。 他必须能够以 root 身份运行命令并无需密码即可获得 root 权限。

运行以下命令为用户创建 sudoers 文件并使用 sed 编辑 /etc/sudoers 文件。

echo "cephuser ALL = (root) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/cephuser
chmod 0440 /etc/sudoers.d/cephuser
sed -i s'/Defaults requiretty/#Defaults requiretty'/g /etc/sudoers

Note:上述 通过 ceph-deploy 需要配置,cephadm 中没有强制

安装配置 NTP 服务(可选)

因为分布式存储需要依赖时间,所以需要对所有 OSD 节点的时间保持一致,这里时间同步的软件可以随意选择,

yum install -y ntp ntpdate ntp-doc
ntpdate 0.us.pool.ntp.org
hwclock --systohc
systemctl enable ntpd.service
systemctl start ntpd.service

可以不准备,随意启动一个服务即可,否则安装会出现如下提示

$ cephadm bootstrap --mon-ip cephadmin

Verifying podman|docker is present...
Verifying lvm2 is present...
Verifying time synchronization is in place...
No time sync service is running; checked for ['chrony.service', 'chronyd.service', 'systemd-timesyncd.service', 'ntpd.service', 'ntp.service', 'ntpsec.service', 'openntpd.service']
Installing packages ['chrony']...
Enabling unit chronyd.service
No time sync service is running; checked for ['chrony.service', 'chronyd.service', 'systemd-timesyncd.service', 'ntpd.service', 'ntp.service', 'ntpsec.service', 'openntpd.service']
Repeating the final host check...
docker (/usr/bin/docker) is present
systemctl is present
lvcreate is present
Unit chronyd.service is enabled and running
Host looks OK
Cluster fsid: 19c90bda-2fb8-11ee-9128-000c293e5d57
Address: cephadmin is not a valid IP address
Verifying IP cephadmin port 3300 ...
Address: cephadmin is not a valid IP address
Verifying IP cephadmin port 6789 ...
Address: cephadmin is not a valid IP address
Cannot infer CIDR network for mon IP `cephadmin` : 'cephadmin' does not appear to be an IPv4 or IPv6 address
Cannot infer CIDR network for mon IP `cephadmin` : 'cephadmin' does not appear to be an IPv4 or IPv6 address
ERROR: Cannot infer CIDR network. Pass --skip-mon-network to configure it later

关闭 SELInux

在所有 Ceph Node 节点上关闭 SELInux,可以根据下面命令使用 sed 操作

sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

配置 Hosts 文件

这里主机名可以根据自己选择进行,如果你有 DNS 服务,那么也可以通过注册在 DNS 内的服务进行

$ tee >> /etc/hosts << EOF
10.0.0.20        ceph-octopus-cephadm
10.0.0.21        ceph-octopus-01
10.0.0.22        ceph-octopus-02
EOF

安装依赖

# centos 7
yum install -y python3 lvm2 docker-ce
# centos 8
dnf install -y python3 lvm2 podman

Step2 下载 cephadm 并 修改 cephadm 镜像地址

获取 cephadm 脚本

步骤参考了 ceph 官方安装手册 [1] ,需要注意的是 cephadm 脚本也是需要按照版本来的

curl --silent --remote-name --location https://github.com/ceph/ceph/raw/octopus/src/cephadm/cephadm
chmod +x cephadm

这个步骤主要是为了使 cephadm 可以正常的拉去 ceph 镜像,你可以通过 docker load 方式导入到 ceph node 之上,但是 ceph 镜像必须通过私有镜像进行拉取(存在 reposig 认证)其他 ceph 组件(prometheus, node-exporter..)可以通过 docker load 导入

cephadm 最上面几行写明了要拉去镜像的镜像仓库地址,可以在有互联网机器上下载好,push 到私有镜像仓库中,如果没有私有镜像仓库,可以 run 一个 docker registry ,这个步骤是强制的;其他组件是可以通过 docker load 方式获得

$ head -20 cephadm 
#!/usr/bin/python3

# Default container images -----------------------------------------------------
DEFAULT_IMAGE = 'quay.io/ceph/ceph:v15'
DEFAULT_IMAGE_IS_MASTER = False
DEFAULT_PROMETHEUS_IMAGE = 'quay.io/prometheus/prometheus:v2.18.1'
DEFAULT_NODE_EXPORTER_IMAGE = 'quay.io/prometheus/node-exporter:v0.18.1'
DEFAULT_ALERT_MANAGER_IMAGE = 'quay.io/prometheus/alertmanager:v0.20.0'
DEFAULT_GRAFANA_IMAGE = 'quay.io/ceph/ceph-grafana:6.7.4'
# ------------------------------------------------------------------------------

LATEST_STABLE_RELEASE = 'octopus'
DATA_DIR = '/var/lib/ceph'
LOG_DIR = '/var/log/ceph'
LOCK_DIR = '/run/cephadm'
LOGROTATE_DIR = '/etc/logrotate.d'
UNIT_DIR = '/etc/systemd/system'
LOG_DIR_MODE = 0o770
DATA_DIR_MODE = 0o700
CONTAINER_INIT=False

Run docker registry

拉去 docker registry

docker pull registry

镜像保存路径放置在当前工作目录中

Note: 如果你没有独立的私有镜像仓库,那么请保留 docker registry,直到你不对 ceph 集群进行扩展

执行下面命令,运行 docker registry

docker run \
  --detach \
  --name registry \
  --hostname registry \
  --volume $(pwd)/registry:/var/lib/registry/docker/registry \
  --publish 5000:5000 \
  --restart unless-stopped \
  registry:latest

在所有 ceph node 之上执行下面命令,需要自行替换 registry_host 部分

现象:https://xxx:5000/v2/: http: server gave HTTP response to HTTPS client

tee /etc/docker/daemon.json << EOF
{
    "insecure-registries": ["registry_host:5000"]
}
EOF

Step 3 引导一个新集群

在上面步骤都完成后,可以直接去引导一个新集群了

可以选择性执行下面步骤

这里是安装 ceph 客户端时需要用到的,例如 ceph-common, ceph-fuse 都会用到这些

$ ./cephadm add-repo --release octopus

cephadm 命令能够:

  • 引导一个新集群
  • 使用 ceph cli 启动容器化的 shell
  • 用于调试容器化的 ceph daemon

O 版的安装命令是通过 github 下载,要注意的是,每个版本号的 cephadm 命令不通用

# curl --silent --remote-name --location https://github.com/ceph/ceph/raw/pacific/src/cephadm/cephadm
# chmod +x cephadm
# ./cephadm add-repo --release octopus
# install命令旨在将 cephadm 安装到环境变量中
# ./cephadm install 

开始引导一个新的 ceph 集群

创建 Ceph 集群的第一步是在 Ceph 集群的管理几点上执行命令 cephadm bootstrap,这个命令的行为会创建 Ceph 集群中的第一个 “monitor” 守护进程,这需要提供一个 “IP地址” 而不可以是 “域名”。

这里将 ceph monitor 部署在管理节点上了,以节省 Node 数量

$ cephadm bootstrap --mon-ip 10.0.0.20

Verifying podman|docker is present...
Verifying lvm2 is present...
Verifying time synchronization is in place...
Unit chronyd.service is enabled and running
Repeating the final host check...
docker (/usr/bin/docker) is present
systemctl is present
lvcreate is present
Unit chronyd.service is enabled and running
Host looks OK
Cluster fsid: 420ccab4-2fb8-11ee-9f5c-000c293e5d57
Verifying IP 10.0.0.20 port 3300 ...
Verifying IP 10.0.0.20 port 6789 ...
Mon IP `10.0.0.20` is in CIDR network `10.0.0.0/24`
Mon IP `10.0.0.20` is in CIDR network `10.0.0.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...
Non-zero exit code 1 from /usr/bin/docker pull quay.io/ceph/ceph:v17
/usr/bin/docker: stderr Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
ERROR: Failed command: /usr/bin/docker pull quay.io/ceph/ceph:v17
[root@cephadmin ~]# systemctl start docker 
[root@cephadmin ~]# cephadm bootstrap --mon-ip 10.0.0.20
Verifying podman|docker is present...
Verifying lvm2 is present...
Verifying time synchronization is in place...
Unit chronyd.service is enabled and running
Repeating the final host check...
docker (/usr/bin/docker) is present
systemctl is present
lvcreate is present
Unit chronyd.service is enabled and running
Host looks OK
Cluster fsid: 4d128cbe-2fb8-11ee-8326-000c293e5d57
Verifying IP 10.0.0.20 port 3300 ...
Verifying IP 10.0.0.20 port 6789 ...
Mon IP `10.0.0.20` is in CIDR network `10.0.0.0/24`
Mon IP `10.0.0.20` is in CIDR network `10.0.0.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 10.0.0.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 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 cephadmin...
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://cephadmin:8443/
	    User: admin
	Password: eqlf3jh1i1

Enabling client.admin keyring and conf on hosts with "admin" label
Saving cluster configuration to /var/lib/ceph/4d128cbe-2fb8-11ee-8326-000c293e5d57/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/local/bin/cephadm shell --fsid 4d128cbe-2fb8-11ee-8326-000c293e5d57 -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/local/bin/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.

成功后会看到 ceph dashboard 的界面,默认密码会输出到控制台,第一次登陆会要求修改默认密码

在安装将生成一个最小的 ceph.conf 仅适用于引导阶段的配置文件,通过进入 mon 容器查看

$ docker exec -it ceph-350494de-d23f-11ea-be85-525400d32681-mon.mon0 cat /etc/ceph/ceph.conf # 

向 ceph 集群导入 osd node

向每个 node 导入 ssh key,下面的操作是通过进入管理容器执行的

ssh-copy-id -f -i /etc/ceph/ceph.pub root@*<new-host>*

添加一个主机到 ceph 集群

ceph orch host add *newhost*

部署一个新的 mon,你可以给新加入的主机打上标签

# ceph orch host label add *<hostname>* mon
ceph orch apply mon *<number-of-monitors>*

向集群部署新的组件

ceph orch apply mon *<number-of-monitors>*
ceph orch apply mon *<host1,host2,host3,...>*

部署 osd damon 在新的主机之上

ceph orch daemon add osd *<host>*:*<device-path>*
ceph orch daemon add osd host1:/dev/sdb

这是可以列出正在管理的服务器 cephadm 使用 host ls 命令:

ceph orch host ls 

到此,如果你只使用 RDB 块存储,这里已经部署完成了,如果需要选择使用 文件存储 CephFS,或者对象存储 RGW,可以在另外部署相应的组件,部署的组件是根据按需使用进行部署

osd device 命令也可以列出对应的设备

ceph orch device ls 

在 Ceph 中一切存储的基础都是基于 RADOS 集群

Troubleshooting

TypeError: init() missing 2 required positional arguments: ‘hostname’ and ‘addr’

现象:实际上输入了 hostnameaddr 也是出现这个问题

$ ceph orch host add ceph-octopus-01
Error EINVAL: Traceback (most recent call last):
  File "/usr/share/ceph/mgr/mgr_module.py", line 1756, in _handle_command
    return self.handle_command(inbuf, cmd)
  File "/usr/share/ceph/mgr/orchestrator/_interface.py", line 171, in handle_command
    return dispatch[cmd['prefix']].call(self, cmd, inbuf)
  File "/usr/share/ceph/mgr/mgr_module.py", line 462, in call
    return self.func(mgr, **kwargs)
  File "/usr/share/ceph/mgr/orchestrator/_interface.py", line 107, in <lambda>
    wrapper_copy = lambda *l_args, **l_kwargs: wrapper(*l_args, **l_kwargs)  # noqa: E731
  File "/usr/share/ceph/mgr/orchestrator/_interface.py", line 96, in wrapper
    return func(*args, **kwargs)
  File "/usr/share/ceph/mgr/orchestrator/module.py", line 356, in _add_host
    return self._apply_misc([s], False, Format.plain)
  File "/usr/share/ceph/mgr/orchestrator/module.py", line 1092, in _apply_misc
    raise_if_exception(completion)
  File "/usr/share/ceph/mgr/orchestrator/_interface.py", line 225, in raise_if_exception
    e = pickle.loads(c.serialized_exception)
TypeError: __init__() missing 2 required positional arguments: 'hostname' and 'addr'

首先先将公钥分发到对应的 CEPH NODE 之上

export CEPH_HOSTNAME=root@ceph-octopus-01
# 获取公钥
ceph cephadm get-pub-key > /etc/ceph/ceph.pub

# 分发公钥到对应 ceph node
ssh-copy-id -f -i /etc/ceph/ceph.pub ${CEPH_HOSTNAME}

# 尝试使用私钥是否可以连接到 ceph node
ceph cephadm get-ssh-config > ssh_config
ceph config-key get mgr/cephadm/ssh_identity_key > ~/cephadm_private_key
chmod 0600 ~/cephadm_private_key
ssh -F ssh_config -i ~/cephadm_private_key ${CEPH_HOSTNAME}

我解决的方式:实际上版本不对,更新版本就恢复了

Reference

[1] install-cephadm

[2] Object Request Broker Architecture

[3] Cooperation for Open Systems Interconnection Networking in Europe

本文发布于Cylon的收藏册,转载请著名原文链接~

链接:https://www.oomkill.com/2023/07/02-1-install-ceph-with-cephadm/

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」 许可协议进行许可。