介绍 Cephadm

2020年3月25日 sage

多年来,出现了各种各样的 Ceph 部署工具,旨在使 Ceph 更易于安装和管理。 其中大多数利用现有的工具,如 Ansible、Puppet 和 Salt,从而带来现有的用户生态系统,并有机会与组织对特定工具的现有投资保持一致。 然而,这导致 Ceph 社区的投资分散在许多不同的努力中,新用户在开始时面临着难以选择工具的困境,并且简化体验和与 Ceph 本身集成的尝试一直很困难。

像许多其他人一样,我个人坚持使用过时的 ceph-deploy 工具,它具有易于使用和理解的优点(至少对于熟悉 Ceph 的人而言),并且具有不需要最初投资于安装和学习另一种工具的优点。 然而,如今 ceph-deploy 已不再维护,甚至无法与一些较新的发行版(如 RHEL/CentOS 8)一起工作。

然而,最重要的是,这些工具都没有很好地解决核心问题:使 Ceph 对于新用户来说非常容易安装,并通过与 Ceph CLI 和 GUI 的无缝集成来长期维护 Ceph 集群。 Ceph Nautilus 中首次引入了一个新的编排 API,旨在提供一种通用的方法,让 Ceph(CLI 和仪表板)与其部署环境交互,无论它是 Rook 还是 ceph-ansible 还是 DeepSea,但只有在 Octopus 中,它才达到了提供跨多个后端有意义的抽象的成熟度:Rook 用于 Kubernetes 环境,Cephadm 用于其他所有人。

Cephadm 进入

Cephadm 的目标是提供一个功能齐全、健壮且维护良好的安装和管理层,可供所有未在 Kubernetes 中运行 Ceph 的用户使用。 我们设定的目标包括

  • 以容器部署所有组件。 使用 容器 可简化不同发行版之间的依赖项管理和打包负担。 当然,我们仍在构建 RPM 和 Deb 包,但随着越来越多的用户过渡到 cephadm(或 Rook),以及容器构建,我们将看到更少的特定于操作系统的错误。
  • 与编排 API 紧密集成。 Ceph 的编排接口在 cephadm 的开发过程中得到了广泛的演进,以便与实现匹配,并清晰地抽象出 Rook 中存在的(略有不同的)功能。 最终结果是看起来、感觉和行为都像是 Ceph 的一部分。
  • 无需依赖管理工具。 像 Salt 和 Ansible 这样的系统在大型组织中跨多个规模部署时非常出色,但让 Ceph 依赖于这样的工具意味着用户需要学习的软件又多了一项。 更重要的是,由此产生的部署将更加复杂、更难调试,并且(最重要的是)比专门为管理 Ceph 而构建的部署速度慢。
  • 最小的操作系统依赖项。 Cephadm 需要 Python 3、LVM 和容器运行时——Podman 或 Docker。 任何现代 Linux 发行版都可以。
  • 隔离彼此的集群。 在同一主机上同时存在多个 Ceph 集群在历史上是一个利基场景,但它确实会出现,并且拥有一个健壮、通用的方法来隔离集群可以使测试和重新部署集群对于开发人员和用户来说都是一个安全且自然的过程。
  • 自动升级。 一旦 Ceph “拥有”了自己的部署,它就可以负责以安全且自动化的方式 升级 Ceph
  • 轻松从“遗留”部署工具迁移。 我们需要允许现有的 Ceph 部署从现有的工具(如 ceph-ansible、ceph-deploy 和 DeepSea)无痛迁移到 cephadm

所有这些目标是集中 Ceph 开发人员和用户社区的注意力在两个平台上用于部署和管理 Ceph——cephadm 用于“裸机”部署,Rook 用于在 Kubernetes 中运行 Ceph——并为两者提供相似的管理体验。

引导

cephadm 模型是有一个简单的“引导”步骤,该步骤从命令行启动,并在本地主机上启动一个最小的 Ceph 集群(单个监视器和管理器守护程序)。 然后使用“第二天”编排命令部署集群的其余部分,以添加其他主机、使用存储设备和部署集群服务的守护程序。

引导集群就像这样简单

curl --silent --remote-name --location https://github.com/ceph/ceph/raw/octopus/src/cephadm/cephadm chmod +x cephadm mkdir -p /etc/ceph ./cephadm bootstrap --mon-ip

30 到 60 秒后,一个最小的 Ceph 集群将启动并运行,cephadm 将打印出访问 Ceph CLI(通过容器化 shell)和访问仪表板的 URL

INFO:cephadm:Ceph Dashboard is now available at

URL: https://gnit:8443/ User: admin Password: 07j394z550

INFO:cephadm:You can access the Ceph CLI with

sudo ./cephadm shell --fsid 2d2fd136-6df1-11ea-ae74-002590e526e8 -c /etc/ceph/ceph.conf -k /etc/ceph/ceph.client.admin.keyring

INFO:cephadm:Bootstrap complete.

访问 Ceph CLI

由于 Ceph 完全容器化(检查 podman psdocker ps),因此主机上没有安装任何软件,并且通常的 ceph 命令将无法工作(至少目前是这样)。 有几种方法可以与新集群交互。

一种方法是使用 cephadm shell 命令。 用于引导的 cephadm 也可以启动一个容器化 shell,其中安装了所有 Ceph 软件(包括 CLI)。 由于引导程序默认将 ceph 配置文件和管理员密钥环放入 /etc/ceph 中,并且 shell 命令默认查找那里,因此您只需使用以下命令即可启动一个工作 shell 并使用 CLI

./cephadm shell ceph status

cephadm 命令还使在主机上安装“传统”Ceph 包变得容易。 要将 Ceph CLI 命令和 cephadm 命令安装在标准位置,

./cephadm add-repo --release octopus ./cephadm install cephadm ceph-common

这支持几个常见的 Linux 发行版(CentOS/RHEL、Debian/Ubuntu、OpenSUSE/SLE),并且可以轻松扩展以支持新的发行版。

扩展集群

任何真实的 Ceph 集群都跨多个主机。 Cephadm 通过使用 SSH 连接到集群中的主机来管理集群,以检查环境、监视 Ceph 守护程序以及部署或删除守护程序。 每个 Ceph 集群都会生成一个唯一的 SSH 身份和密钥,用于连接到主机。 引导过程会将此密钥添加到本地主机的 root 用户的 authorized_keys 文件中。 但是,添加其他主机需要几个手动步骤。

首先,我们需要集群密钥的公共部分副本。 默认情况下,引导程序将其放在 /etc/ceph/ceph.pub 中,或者您可以使用 ceph cephadm get-ssh-pub-key 从集群中获取副本。

对于每个主机,我们首先需要在远程系统上安装密钥。 这最容易使用包含任何最新版本 SSH 的 ssh-copy-id 命令完成

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

如果您的当前用户尚未设置无密码 SSH 访问,则此命令可能会提示输入 root 密码。

接下来,我们需要告诉 Ceph 关于新主机。 我们假设这里所有主机都具有唯一的 hostname,该 hostname 与主机上配置的 hostname 匹配。 如果您的本地环境也没有配置 DNS,以便我们连接到这些 hostname,或者如果您想避免对 DNS 的依赖,您可以为每个主机提供 IP 地址

ceph orch host add[]

您可以使用以下命令查看集群中的所有主机

ceph orch host ls

管理 Ceph 监视器、管理器和其他守护程序

Cephadm 中的每个服务或守护程序集合都与相关的放置规范相关联,该规范描述了守护程序应该部署在何处以及数量。 默认情况下,使用 cephadm 的新 Ceph 集群知道集群应该有 5 个监视器、2 个管理器以及一些其他服务(如崩溃转储收集器)部署在每个主机上。 一旦将其他主机添加到集群,就会自动部署新的监视器和管理器。 您可以使用 ceph orch lsceph orch ps 命令查看新的集群服务和已部署的守护程序

# ceph orch ls NAME RUNNING REFRESHED AGE PLACEMENT IMAGE NAME IMAGE ID
alertmanager 1/1 71s ago 22m count:1 docker.io/prom/alertmanager:latest 0881eb8f169f
crash 1/1 71s ago 23m * docker.io/ceph/ceph:v15 204a01f9b0b6
grafana 1/1 71s ago 22m count:1 docker.io/ceph/ceph-grafana:latest 87a51ecf0b1c
mgr 1/2 71s ago 23m count:2 docker.io/ceph/ceph:v15 204a01f9b0b6
mon 1/5 71s ago 23m count:5 docker.io/ceph/ceph:v15 204a01f9b0b6
node-exporter 1/1 71s ago 22m * docker.io/prom/node-exporter:latest e5a616e4b9cf
prometheus 1/1 71s ago 22m count:1 docker.io/prom/prometheus:latest e935122ab143

ceph orch ps

NAME HOST STATUS REFRESHED AGE VERSION IMAGE NAME IMAGE ID CONTAINER ID
alertmanager.gnit gnit running (21m) 96s ago 22m 0.20.0 docker.io/prom/alertmanager:latest 0881eb8f169f 15ceff5ae935
crash.gnit gnit running (22m) 96s ago 23m 15.2.0 docker.io/ceph/ceph:v15 204a01f9b0b6 0687711365e4
grafana.gnit gnit running (21m) 96s ago 22m 6.6.2 docker.io/ceph/ceph-grafana:latest 87a51ecf0b1c fa1db4647c4c
mgr.gnit.xmfvjy gnit running (24m) 96s ago 24m 15.2.0 docker.io/ceph/ceph:v15 204a01f9b0b6 6a29bc868357
mon.gnit gnit running (24m) 96s ago 24m 15.2.0 docker.io/ceph/ceph:v15 204a01f9b0b6 072f5926faa8
node-exporter.gnit gnit running (22m) 96s ago 22m 0.18.1 docker.io/prom/node-exporter:latest e5a616e4b9cf eb5f715005fc
prometheus.gnit gnit running (22m) 96s ago 22m 2.16.0 docker.io/prom/prometheus:latest e935122ab143 6ee6de1b3cc1

在上面的示例输出中,您会注意到部署了许多非 Ceph 守护程序:Prometheus、Grafana、alertmanager 和 node-exporter。 这些提供了一个基本但功能齐全的监控堆栈,允许 Ceph 仪表板的所有指标和图形开箱即用。 如果您已经有一个现有的 Prometheus 部署想要 Ceph 使用,您可以告诉 cephadm 跳过所有这些,方法是在 bootstrap 命令中传递 --skip-monitoring-stack

对于大多数用户来说,这种默认行为就是您所需要的。 对于想要精确控制监视器部署在哪些主机上或选择哪些 IP 的高级用户,需要采取一些额外的步骤来定制这些守护程序的放置。 甚至可以完全禁用特定服务(如监视器)的自动放置,尽管应该很少有理由这样做。

一旦集群启动并运行,可以获取一个最小但足够的 ceph.conf 文件,用于访问集群的主机,方法是

# ceph config generate-minimal-conf

添加存储

将 OSD 添加到 Ceph 集群通常是部署中最棘手的部分。 HDD 和 SSD 可以以各种方式组合以平衡性能和成本,并且告诉 Ceph 使用哪些设备可能很棘手。

对于许多用户,我们希望以下命令就足够了

ceph orch apply osd --all-available-devices

这将使用集群中任何主机上的任何设备(HDD 或 SSD),只要它通过所有安全检查,这意味着没有分区、没有 LVM 卷、没有文件系统等。 每个设备将获得一个 OSD 部署,这是适用于许多(如果不是大多数)用户的最简单的情况。

对于我们其他人,我们有几种工具可以使用。 我们可以枚举所有主机上的所有设备(以及上述安全检查的状态),方法是

ceph orch device ls

可以显式地在单个设备上创建一个 OSD,方法是

ceph orch daemon add osd host-foo:/dev/foo

但是,对于更高级的自动化,编排 API 引入了 驱动组 的概念,允许根据设备属性(SSD 与 HDD、型号名称、大小、主机名称模式)描述 OSD 部署,并以半自动化的方式部署“混合”OSD(例如,SSD 用于元数据,HDD 用于数据)。

部署存储服务

其他 Ceph 守护进程是无状态的,这意味着它们不会在本地存储任何数据,并且可以轻松地在任何主机上重新部署。这些对于 cephadm 来说很容易……并且在 CephFS 的情况下,它们的部署是完全自动化的。例如,要创建一个名为 foo 的 CephFS 文件系统

ceph fs volume create foo

将创建一个必要的数据和元数据池,并一步到位地部署 MDS 守护进程。可以通过 ceph orch lsceph orch apply mds ... 命令检查和调整守护进程的数量和位置,或者可以将可选的放置参数传递给 volume create 命令。

对于使用 RGW 的对象存储,事情还不完全那么简化(目前),但是编排器和 cephadm 基础设施都在那里来管理底层的守护进程。对于独立的存储集群,

radosgw-admin realm create --rgw-realm=myorg --default radosgw-admin zonegroup create --rgw-zonegroup=default --master --default radosgw-admin zone create --rgw-zonegroup=default --rgw-zone=us-east-1 --master --default ceph orch apply rgw myorg us-east-1

对于现有的(多站点或独立)部署,部署守护进程可以像 ceph orch apply rgw <realmname> <zonename> 一样简单,前提是 RGW 配置选项已经存储在集群的配置数据库中(ceph config set client.rgw.$realmname.$zonename ...),而不是存储在 ceph.conf 文件中。

升级

cephadm 的一个最佳特性之一,一旦你部署了新的集群(或现有集群 升级并转换),就是它能够 自动化升级。在大多数情况下,这就像

ceph orch upgrade start --ceph-version 15.2.1

可以从 ceph status 视图监控升级进度,它将包含一个进度条,例如

升级到 docker.io/ceph/ceph:v15.2.1 (3m) [===.........................] (剩余: 21m)

深入了解

能够更仔细地查看 cephadm 在后台所做的事情来在远程主机上运行服务,这很有帮助(而且对我来说,令人安心)。你可以首先查看正在运行的容器,使用 podman psdocker ps。你会注意到所有容器的名称中都有集群 fsid UUID,以便可以在同一主机上存在多个集群而不会发生冲突。(这在很大程度上是正确的,除非守护进程使用固定的端口,例如 Ceph 监控器,或像 prometheus node-exporter 这样的服务。)

文件也是分开的。在 /var/lib/ceph/var/log/ceph 中,你会发现它们按集群 fsid 分开。并且在每个守护进程目录中,你将看到一个名为 unit.run 的文件,其中包含启动守护进程的 docker 或 podman 命令——这是 systemd 单元执行的内容。

虽然你可能记得引导步骤将文件写入 /etc/ceph,但它只是为了方便起见,以便在主机上只有一个集群的常见情况下,只需安装 ceph-common 包就可以使 ceph CLI 正常工作。将 --output-dir .(或类似)传递给 bootstrap 会将这些文件写入其他位置。

事实上,主机 OS 中存在的唯一其他更改是

  • 为每个集群写入到 /etc/systemd/system 的 systemd 单元文件(每个集群的 ceph-$fsid.target,所有守护进程共享的 ceph-$fsid@.service
  • 一个总体的 ceph.target 单元,用于启动/停止所有 Ceph 服务
  • 一个 logrotate 文件位于 /etc/logrotate.d/ceph-$fsid,以防 启用写入文件的日志。(默认情况下,cephadm 守护进程将日志写入 stderr,并且日志由容器运行时捕获。)

与此同时,更改正由在 ceph-mgr 守护进程中运行的 cephadm 模块驱动。服务通过编排器接口进行配置,可以通过内部 Python 接口(例如,供仪表板使用)或通过 CLI 访问该接口。要查看所有可用命令,请尝试 ceph orch -h。特别是 ceph orch ls 将描述当前配置的服务。

在后台,cephadm 具有一个“协调循环”,类似于 Kubernetes,它将当前状态与所需状态进行比较,如配置的服务所指定。要监控其活动,ceph -W cephadm 将跟踪日志,因为它进行更改,或者 ceph log last cephadm 将显示最近的消息。可以使用 ceph orch pause 随时暂停此后台工作,并使用 ceph orch resume 恢复。

展望未来

有了最初的 Octopus 版本,cephadm 对核心 Ceph 服务具有坚实的支持:RADOS、CephFS、RBD 和 RGW。许多辅助服务正在积极开发中,包括 NFS 和 iSCSI 网关支持,并且预计 CIFS 支持(通过 Samba)将在之后推出。所有这些更改都将回移植到 Octopus,一旦它们完成。

与此同时,我们还希望改进“调度”算法的稳健性和智能性,该算法决定在哪里运行服务。现在 cephadm 只是将服务守护进程跨主机传播,但(默认情况下)随机选择这些主机。我们希望通过为守护进程容器设置资源限制(例如 CPU 和内存),并根据每个主机上可用的资源智能地选择守护进程的位置来改进这一点。

最后,我们预计将在下一个开发周期中花费大量时间,通过 Ceph 仪表板公开更多编排器功能,以简化整体用户体验,特别是对于初始部署、集群扩展和更换故障存储设备等常见操作。

欢迎反馈!

最后但并非最不重要:Cephadm 是全新的,我们正在寻找来自真实用户在现实世界中首次部署它的反馈,以了解哪些有效,哪些无效,以及我们可以做些什么来改进!

有关 Cephadm 的更多信息,请参阅 在线文档

衷心感谢使 cephadm 成为可能的团队:Sebastian Wagner、Joshua Schmidt、Michael Fritch、Daniel Pivonka、Paul Cuzner、Kristoffer Grönlund、Kiefer Chang、Patrick Seidensal 和 Volker Theile;感谢 Noah Watkins,他编写了“ssh 编排器”的第一个版本;以及感谢 John Spray,他早在 Nautilus 中就启动了整个编排器抽象。