☰
cephadm实战:Ceph Pacific全功能安装从零到生产可用
2026/10/21 13:36:31 网站建设 项目流程

如果让我给Ceph新人一句建议,我一定会说:跳过手动部署和ceph-deploy那一套,直接学cephadm。原因很简单——Ceph Pacific版本里,cephadm已经从“实验性工具”变成了官方主推的部署方式,它把Ceph这个分布式存储系统从“安装地狱”里彻底拉了出来。这篇就写我怎么用cephadm完成一套Pacific的全功能安装,覆盖多节点、OSD、CephFS、RGW对象网关、NFS导出、监控告警这些组件。标题里的“Pacfic”少了个i,按拼写应该是Pacific,也就是Ceph 16.2.x系列。文章比较长,但每一步都是实打实的命令和流程,照着做基本能复现出一套完整集群。适合刚接触Ceph、或者想从传统部署方式切换到cephadm的人参考。

1. 为什么“全功能安装”先要解决部署工具选型

1.1 传统部署方式的问题

先说点历史。Ceph在我早期折腾的时候,主流部署方式是两套:一套是手动安装,一套是ceph-deploy。手动安装的思路是,把每个节点上的ceph-mon、ceph-mgr、ceph-osd这些rpm包装好,再手工生成配置文件、创建monitor并逐个启动,最后还要手工配osd的keyring和crush map。听起来自动化程度很高,实际做起来极其痛苦。依赖冲突是老朋友,yum源配置错了能让你排查一晚上,更别提不同机器上系统版本不一致时,同一个配置文件和参数表现完全不同。

ceph-deploy算是一次进步,它把手动过程脚本化了,但它的思路依然是“把组件装进操作系统里”,升级和回滚照样麻烦。我记得到了某个阶段,社区官方直接宣布ceph-deploy不再维护,所有人都要去适应新的部署方式。当时很多老运维都懵了,我也差不多,整个集群日常运维习惯都要改。

1.2 cephadm的核心设计思路

cephadm的设计思路和以前完全不一样。它不再“安装”Ceph组件,而是“拉起容器”运行Ceph组件。所有daemon,包括mon、mgr、mds、osd、rgw,都跑在容器里,由systemd管理。每个daemon对应一个systemd unit,比如ceph-mon@node01、ceph-mgr@node01,我们平时管理的对象从“系统里的一个服务进程”变成了“一个容器守护单元”。

这个思路带来的好处非常直观:宿主机环境再脏再乱,只要容器运行时正常,daemon的启动就是干净的。升级的时候无非是换一个镜像,回滚的时候也只需要重新apply旧的镜像版本。这个纪律性和传统部署方式完全不同,它不依赖你手工去改一堆配置文件,而是把集群状态交给orchastrator层管理。你可以理解成,Ceph集群本身变成了一个“被编排的应用程序”,cephadm就是那个编排工具,你不是在“安装”分布式存储,而是在“部署一套自己管理的容器化应用”。

1.3 全功能安装到底要装哪些东西

说完工具,回到标题里的“全功能”。我理解的全功能安装不是把所有daemon一把梭装上去就行,而是让集群具备完整的生产可用能力,至少包括下面这些:

组件作用在cephadm下怎么部署
ceph-mon维护集群状态、提供一致性bootstrap阶段自动部署
ceph-mgr提供Dashboard、prometheus接口、编排入口bootstrap阶段自动部署
ceph-osd存储数据ceph orch apply osd
ceph-mds提供CephFS文件系统元数据服务ceph fs volume create
ceph-rgw提供S3对象存储接口radosgw-admin配realm/zone +ceph orch apply rgw
NFS-Ganesha把CephFS导出为NFSceph orch apply nfs
prometheus/alertmanager/grafana监控采集、告警、可视化bootstrap默认带,可自定义placement
ceph-dashboardWeb管理界面默认启用,可配SSO和TLS

后面我整个安装流程就是围绕这张表展开的。注意一个关键点:bootstrap之后,你只是有了一个“能用的最小集群”,离“全功能”还差得远。这也是很多人装了cephadm后觉得“怎么这么简单”,结果要用RGW时发现一堆坑的原因。

2. 环境准备:决定集群生死的隐藏细节

2.1 节点规划与网络拓扑设计

我先说节点规划。生产环境至少三台机器,我这里演示也用三节点。每一台节点我都规划好角色和IP,避免后面再做调整。

节点IP角色数据盘
node01192.168.30.10mon, mgr, osd, mds, rgw, nfs/dev/sdb, /dev/sdc
node02192.168.30.11mon, mgr, osd, rgw/dev/sdb
node03192.168.30.12mon, osd, rgw/dev/sdb

很多人喜欢把mon都集中在前三个节点,这没问题。但有个容易忽略的细节:每个mon所在的主机名必须能互相解析,否则monica会不断重试。我是直接在/etc/hosts里写死的,DNS解析如果配置不干净,后面故障排查会让你怀疑人生。

网络这块,我习惯把public_network和cluster_network分开。public网络走客户端和监控流量,cluster网络走OSD之间的数据同步和心跳。如果测试环境条件有限,可以都在一个网段,但生产环境强烈建议分离。cephadm bootstrap阶段只需要指定mon地址和cluster网络,后面的daemon会自动拾取配置。

2.2 系统基础配置项清单

这部分是很多教程里的“一句话带过”,但恰恰是集群不稳定的大部分根因。我在所有节点上依次做这些操作:

  • 设置主机名,确保和规划完全一致
  • 在每台节点的/etc/hosts写入所有节点的主机名和IP对应关系
  • 关闭防火墙或专门放行Ceph端口
  • 开启NTP时间同步,并确认chrony状态为active
  • 安装容器运行时,推荐使用docker或containerd

给几个关键命令:

hostnamectl set-hostname node01 cat >> /etc/hosts <<EOF 192.168.30.10 node01 192.168.30.11 node02 192.168.30.12 node03 EOF timedatectl set-ntp true timedatectl status

这里我踩过一个特别典型的坑:NTP同步配置好了,但timedatectl status显示NTP synchronized: yes,结果CePH仍然报时钟漂移。原因是宿主机内核时钟和NTP服务的校准时间存在微小差异,容器内的daemon取的是宿主机内核时钟,如果NTP服务才刚启动几分钟,时钟差还没校准掉。所以启动NTP之后,我建议先等一两分钟,再用ceph -s看clock skew告警是否消失。

容器运行时安装上,用docker还是containerd都不影响cephadm工作,但要注意docker和cephadm的兼容性,别装太老的版本。我这次用docker,因为排障工具生态更熟悉。

2.3 bootstrap引导:给集群建立第一块地基

在三台节点准备好之后,我回到node01进行操作。先获取cephadm脚本:

curl -fsSL https://download.cephadm.ceph.com/api/v1/cephadm/16.2.15/cephadm -o /usr/local/bin/cephadm chmod +x /usr/local/bin/cephadm

然后执行bootstrap,这一步会生成集群的第一个mon、第一个mgr,同时部署监控stack和Dashboard:

cephadm bootstrap \ --mon-ip 192.168.30.10 \ --cluster-network 192.168.32.0/24 \ --initial-dashboard-password StrongPassw0rd \ --allow-fqdn-hostname

几个参数说明一下。--mon-ip是必填参数,它告诉集群monitor监听的IP,千万别让它自己在多网卡环境下猜,猜错一次你就得重新初始化集群。--cluster-network指定OSD数据流量的网络,如果和public网络重叠,可以省略。--allow-fqdn-hostname允许主机名带域名,很多云环境的默认主机名是带域的,不加这个参数bootstrap会报错。

bootstrap结束后,一行关键输出格式大概是:

Ceph Dashboard is now available at https://192.168.30.10:8443/

这个地址就是Dashboard入口,初始账号是admin,密码就是我刚刚--initial-dashboard-password设置的。如果设置时没有指定,它会在bootstrap日志里给你一串随机密码,千万别丢。

2.4 bootstrap后的状态检查:确认地基是稳的

很多教程到bootstrap结束就完事了,实际上这一步只是“启动完成”,必须马上做状态检查。

ceph -s

正常输出应该是HEALTH_OK,mon和mgr都是active。然后确认编排器工作正常:

ceph orch status ceph orch ps

ceph orch ps会列出所有在跑的daemon容器,从这里能看到mon、mgr、prometheus、grafana、alertmanager已经就绪。我还会看一眼ceph osd tree,这时候还没有OSD,tree应该是空的,这正常。

如果bootstrap阶段出现daemon反复重启,先查两处:一是你指定的--mon-ip是否真的绑定在这台机器上,二是systool里确认时间同步没问题。排查命令我常用:

journalctl -u ceph-mon@node01 -n 200 cephadm logs --fsid $(cat /etc/ceph/ceph.conf | grep fsid | awk '{print $NF}')

从bootstrap到这一步,核心思想就一句话:先把地基搞干净,后面加复杂组件才不容易被环境问题干扰。

3. 横向扩展:从单节点到一套真正的存储集群

3.1 向集群添加主机:SSH免密与cephadm install

node01上的bootstrap集群只是单节点,要变成一套真正的存储集群,必须把node02和node03加进来。添加主机之前,最重要的是让cephadm管理的节点能通过SSH免密访问其他节点。bootstrap默认会生成一对新的SSH密钥放在/etc/ceph/ceph.ssh下。

步骤是这样的:先导出cephadm需要的SSH配置,再把公钥拷贝到其他节点:

ceph cephadm get-ssh-config > ~/ceph.ssh.config ssh-copy-id -i /etc/ceph/ceph.ssh/id_rsa.pub -F ~/ceph.ssh.config root@node02 ssh-copy-id -i /etc/ceph/ceph.ssh/id_rsa.pub -F ~/ceph.ssh.config root@node03

注意,-F指定了cephadm自己的ssh config文件,因为cephadm默认不会使用root用户下默认的ssh config。这个细节很多教程不写,如果你直接用ssh-copy-id root@node02,后面ceph orch host add大概率会连接失败。

然后到node02和node03上安装cephadm命令行工具:

cephadm install

这个命令会生成/usr/bin/cephadm和/usr/bin/ceph软链,方便每个节点直接执行ceph相关命令。

回到node01,正式把主机加入集群:

ceph orch host add node02 --labels _admin ceph orch host add node03 --labels _admin

--labels _admin是给节点打标签,_admin标签意味着cephadm可以把某些管理daemon调度到这台节点上。如果你不想让所有节点都成为admin,可以去掉这个标签。

3.2 为节点划分标签与OSD设备规划

加入主机后,我习惯先把主机列表和标签看清楚:

ceph orch host ls

标签的作用后面会体现出来。比如我打算让rgw只跑在带rgw标签的节点上,让nfs只跑在node03上,就可以用标签控制daemon的部署位置,而不是让orchastrator随便调度。

数据盘规划同样重要。ceph orch device ls会列出所有节点上可用的裸盘信息。这一步必须先做,别急着创建OSD。我看到很多人直接执行ceph orch apply osd --all,结果把系统盘也给做成OSD了,那是真的灾难。好一点的策略是:先给每个节点上需要用作OSD的盘打上标签,或者直接在osd spec里指定设备路径。

我这里演示时,node01上有/dev/sdb和/dev/sdc,node02有/dev/sdb,node03有/dev/sdb。我会写成osd spec来管理:

cat <<EOF > /tmp/osd.yaml service_type: osd service_id: all_osds placement: hosts: - node01 - node02 - node03 spec: data_devices: paths: - /dev/sdb - /dev/sdc EOF ceph orch apply -i /tmp/osd.yaml

如果你喜欢一键全自动,也可以:

ceph orch apply osd --all

但我强烈建议生产环境不要这么做,至少你得先确认每台机器上系统盘是哪个设备,并用device filter把它们排除掉。我在测试机上吃过一次亏,那台机器的系统盘也叫/dev/sda,还好当时是环境,重新初始化代价也不大,要是生产环境早就炸了。

3.3 创建OSD:自动发现设备与部署状态观察

osd spec提交后,cephadm会按照spec要求的placement去各节点扫描设备,发现匹配的设备后自动创建OSD。观察部署情况:

ceph orch osd ls ceph osd tree

正常情况下,osd树里会出现osd.0到osd.4,分别对应三台节点的物理盘。这一步要注意观察OSD状态是up还是down。如果出现down且ceph -s报osd.0 is down,多半是设备路径冲突、盘被占用,或者节点systemd服务没起来。我用得最多的排查命令是:

cephadm osd activate --device /dev/sdb

但更快的办法是先看对应节点的日志:

ssh node02 "journalctl -u ceph-osd@osd.1 -n 100"

OSD创建完成后,ceph -s应该从HEALTH_OK变成可能有HEALTH_WARN,因为此时monHost可能有nearly full的pg warning? 实际上只要有OSD,pg会自动分配,但集群PG数如果很少,可能看到PG unavailable的告警。这是因为刚刚创建的OSD还需要时间做backfill和peering,等一小会儿就好。

3.4 创建CephFS:MDS实例和双Active配置

CephFS是Ceph的传统强项,cephadm下创建非常简单:

ceph fs volume create cephfs

这一条命令会自动创建poolcephfs.cephfs.meta和cephfs.cephfs.data,同时自动部署所需的MDS daemon到合适的节点上。检查一下:

ceph fs ls ceph mds stat ceph orch ps --daemon-type mds

默认情况下单个MDS就够基本使用了。生产环境想要双active MDS,需要设置cephfs max_mds和ceph fs set cephfs max_mds 2,然后让cephadm把MDS扩展到至少两个节点:

ceph fs set cephfs max_mds 2 ceph orch apply mds cephfs --placement="2"

需要注意,CephFS的pool数量不建议手动调整,除非你知道自己在做什么。max_mds大于1时,MDS之间的元数据负载均衡是自动的,不用手工干预。

到这里,集群已经有OSD和CephFS了,一个基本可用块存储/文件存储集群已经成型。但全功能安装当然还要把对象存储和NFS补上。

4. 补齐对象、网关与管理面板

4.1 Dashboard的进阶配置与密码重置技巧

bootstrap后Dashboard已经处于可用状态,但我仍然要补两件事:重置密码和配置TLS证书。

如果忘记初始密码,最直接的办法是:

ceph dashboard reset-dashboard-password

这个命令会提示输入新密码。如果只想看当前用户名,ceph dashboard ac-user-show也可以查看。

TLS证书方面,默认是自签名证书,浏览器会报不安全。为了后面避免各种告警,我建议直接配置一个可信证书,路径可以放在/etc/ceph/dashboard.crt和key:

ceph dashboard set-ssl-certificate /etc/ceph/dashboard.crt /etc/ceph/dashboard.key ceph dashboard set-ssl-server-certificate /etc/ceph/dashboard.crt

这里的set-ssl-certificate会替换默认证书。如果是内网环境不方便拿到可信CA,至少要确认证书不过期,以及浏览器可以导入根CA。Dashboard本身还能做主机的健康检查、查看OSD性能、管理RGW,非常实用。

4.2 RGW对象网关部署与S3访问验证

RGW是Ceph提供S3对象存储的核心组件。这里的坑比前面多,我一步步说。

首先要创建RGW需要的realm、zonegroup和zone。记住,realm是一个逻辑概念,它对应独立的API网关;zonegroup是realm下的可用区分组;zone是实际的网关实例。创建顺序不能乱:

radosgw-admin realm create --rgw-realm=realm1 radosgw-admin zonegroup create --rgw-zonegroup=rgw1 --master radosgw-admin zone create --rgw-zone=zone1 --rgw-zonegroup=rgw1 --master radosgw-admin period update --commit

看到有同学直接快进到ceph orch apply rgw,结果报一堆rgw无法启动,多半就是漏了realm/zone创建。zone创建后,再让cephadm去部署RGW实例:

ceph orch apply rgw realm1.zone1 --placement="3"

这会创建一个服务名为realm1.zone1的RGW服务,placement是3,表示在3个节点各起一个RGW容器。查看状态:

ceph orch ps --daemon-type rgw

RGW默认监听7480端口,公网访问一般会挂在Nginx或者负载均衡后面。我习惯先用curl验证S3端点是否通了:

curl http://192.168.30.10:7480

返回一段XML说明服务正常。只是这样还不够,我还会用s3cmd或aws cli做一次实际读写。

aws --endpoint-url http://192.168.30.10:7480 s3api create-bucket --bucket test-bucket aws --endpoint-url http://192.168.30.10:7480 s3 ls

看到test-bucket出现,RGW才算真正可用。

4.3 NFS导出:让客户端直接挂载

CephFS默认是POSIX文件系统,但很多业务环境习惯用NFS对外提供共享。Ceph的NFS导出是基于NFS-Ganesha实现,cephadm下部署NFS也比较顺:

ceph orch apply nfs cephfs-nfs --placement="2"

cephfs-nfs是自定义的cluster_id。部署完成之后,创建导出:

ceph nfs export create cephfs \ --cluster-id cephfs-nfs \ --pseudo-path /cephfs \ --fsname cephfs

列出导出确认:

ceph nfs export ls cephfs-nfs

这样客户端就能通过NFS挂载了:

mount -t nfs -o port=2049 192.168.30.10:/cephfs /mnt

NFS这个组件的隐藏坑在于:placement要至少给两个节点,否则高可用无法保证;客户端挂载时用的NFS版本、端口要对得上,防火墙放行也很关键。如果export创建失败,多半是cluster_id和pseudo-path格式不对,可以先看ceph nfs export info cephfs-nfs的输出。

4.4 监控告警组件的一并确认与自定义

bootstrap默认会把prometheus、alertmanager、grafana都部署起来,但“全功能安装”要求我们对这些组件有掌控权,而不是只能被动看默认版本。

查看当前状态:

ceph orch ps --daemon-type prometheus ceph orch ps --daemon-type alertmanager ceph orch ps --daemon-type grafana

如果某个组件挂了或被误删,重新部署很简单:

ceph orch apply prometheus ceph orch apply alertmanager ceph orch apply grafana

这几个apply命令不指定placement时,会按照默认规则调度到适合的节点。我建议把prometheus和grafana放在mgr节点上,因为mgr本身会暴露prometheus metrics接口:

ceph orch apply prometheus --placement="label:mgr" ceph orch apply grafana --placement="label:mgr"

Grafana默认的初始密码是admin/admin,第一次登录后会要求修改。Ceph Dashboard里也直接有Prometheus数据源的集成,能在仪表盘里看到告警页面,这个功能比单独登录Grafana方便很多。

5. 升级、回滚与踩坑实录:这些坑我替你趟过了

5.1 同版本小版本升级的正确姿势

集群跑起来之后,升级是绕不开的运维动作。cephadm下升级集群非常简单:

ceph orch upgrade start --ceph-version 16.2.15

这个命令会让cephadm依次停止每个节点上的daemon,拉取新镜像,再启动新daemon。观察升级进度:

ceph orch upgrade status

如果中途有daemon升级失败,升级并不会中断,但状态会一直卡在那里。这时候优先把失败节点对应的daemon日志翻出来:

cephadm logs --fsid <fsid> --name mon.$(hostname)

我遇到过升级到一半容器镜像仓库tag拼错的情况,cephadm会把ImagePullError打满日志,整个升级暂停。解决方式是:

ceph orch upgrade stop

然后重新执行正确的升级命令,cephadm会基于当前状态续传,不用重头来。

5.2 daemon容器日志跟踪与systemd机制

cephadm把每个daemon都用systemd管理,这是好事也是坑。好处是可以单独操作某个daemon,坏处是很多人下意识会用docker ps去找容器,结果发现容器名全是ceph-<fsid>-mon-node01这种长名字,根本分不清对应关系。

其实不用折腾docker命令,直接用:

systemctl status ceph-mon@node01 systemctl status ceph-osd@0 journalctl -u ceph-osd@0 -f

如果你只是想重启某个daemon,也直接用systemctl,比如把node03上的rgw重启:

ssh node03 "systemctl restart ceph-rgw@realm1.zone1.node03"

这个操作比ceph orch daemon restart更精确,但要注意,cephadm会把节点上的unit文件放在/etc/systemd/system下,不要轻易手动修改这些unit,否则下轮orch reconcile时会被覆盖。

5.3 典型案例复盘:时钟漂移、设备误zap、配置遗漏

我挑三个实实在在的踩坑现场,给各位打个预防针。

第一个是时钟漂移。集群起来了但ceph -s一直HEALTH_WARN,提示clock skew is 2.3s。原因是其中一台节点NTP服务其实没起来。表面上看timedatectl没问题,实际chronyc sources显示无同步源。修复办法是重新指向可用的NTP服务器并等待校准,但更要紧的是,你必须提前在所有节点的chrony.conf里配置正确的上游源,别依赖默认源,尤其是离线环境。

第二个是设备误zap。我在测试机上返回设备列表时,系统盘/dev/sda也在列表里,当时图省事用了ceph orch apply osd --all,结果系统盘和两块数据盘一起被做成OSD,系统直接卡死。后来恢复之后,我改成用explicit spec指定数据盘路径,并在osd spec里排除系统盘:

cat <<EOF > /tmp/osd-exclude.yaml service_type: osd service_id: excluded_osd placement: hosts: - node01 spec: data_devices: paths: - /dev/sdb - /dev/sdc EOF ceph orch apply -i /tmp/osd-exclude.yaml

生产环境千万要对设备列表做双确认,宁可多花五分钟核对设备序列号。

第三个是bootstrap时漏加了--allow-fqdn-hostname。我拿到一台云主机,默认hostname是带域名的,结果bootstrap直接报主机名解析失败。加上参数重来才解决。这说明一个问题:cephadm很多细节看起来不起眼,但都是前人踩过的坑的沉淀,参数别乱省略。

5.4 删除不需要的组件与服务收缩

全功能不等于全都留着,如果某个组件没有业务需求,删掉也干净。删除服务的方法统一走orch remove:

ceph orch remove rgw.realm1.zone1 ceph orch remove nfs.cephfs-nfs ceph orch remove grafana

注意,ceph orch remove只会移除对应的daemon,不会删除CephFS的pool或者RGW的realm配置。想要清理数据的话,还得到radosgw-admin层面操作,这个流程比较长,我这里不展开。关键提醒是:删除之前确认业务没有正在使用,因为daemon被移除后,客户端连接会直接失败。

回滚场景也类似。如果你升级后发现某个组件有明显问题,可以用ceph orch upgrade stop暂停升级,然后重新执行ceph orch upgrade start指向旧版镜像。但OSD的数据格式升级一般是不可逆的,升级前务必确认所有PGS都是active+clean,并做好快照或数据备份方案。

最后说点实际操作层面的体会。用cephadm做全功能安装,最重要的不是记命令,而是理解它背后“声明式编排”的思路:你告诉它期望的最终状态,它负责把状态对齐。所以遇到问题别急着手改配置文件,先看一眼ceph orch ps和journalctl,判断是desired state和actual state之间的偏差,再决定是调整placement还是重新apply。这套方法比埋头翻日志靠谱得多。我自己的经验是,把节点规划、设备清单、标签策略这三样东西提前写清楚,后面安装过程就会非常顺。希望这篇能把你在cephadm和Ceph Pacific上想踩的坑提前挡住。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询