从Ceph Pacific开始官方其实已经把安装方式收敛得比较死传统的手工装包、写systemd、一个个配mon这种路子基本只适合定制化极高的场景。日常部署、测试环境、以及大多数生产起步阶段我更推荐直接用cephadm把整个集群“管起来”。这篇文章就把我用cephadm完整装一套Ceph Pacific的过程写透从环境准备到bootstrap再到加OSD、起MDS/RGW、配Dashboard、挨个踩坑排查。内容偏实操命令可以直接复制但我也尽量把每个关键参数背后为什么这么设讲清楚这样你改起来也有依据。1. 先说清楚为什么用cephadm装Pacific1.1 传统安装方式到底痛点在哪早几年装Ceph主流路径是先在每个节点上装一堆依赖包然后手动生成mon、mgr的配置再用ceph-deploy推配置。后来ceph-deploy不维护了官方转向cephadm很多人还没反应过来。我自己早期被坑得最多的就是三件事。第一包版本漂移。每个节点都要保证librados、ceph-mon、ceph-osd这些rpm包版本完全一致稍微差个构建号集群起不来排查起来非常痛苦。第二systemd单元文件自己维护。机器重启以后某个服务没设开机自启OSD虽然盘还在但进程一直不来ceph health一查一堆down。第三证书和keyring管理手动做。加个节点、改个ip权限文件错一个字符整个集群告警。cephadm把所有这些东西全都装进容器并且用一套编排逻辑来管理。核心组件以容器方式跑镜像版本统一不会出现节点间包不一致服务实例的启停、重启、扩缩容都由cephadm接管config和keyring由mgr的orchestrator模块统一分发。对于多数人来说这才是Ceph Pacific的正确打开方式。1.2 cephadm的工作原理和优势cephadm并不是一个简单的“启动脚本”它本身是一个基于SSH和容器运行时来执行任务的管理工具。bootstrap的时候它在第一个节点上拉取官方ceph容器镜像然后启动mon和mgr并且把自己的SSH能力纳入到mgr的orchestrator接口里。之后你执行ceph orch相关的命令本质上都是让mgr调度模块通过SSH到目标节点再调用容器运行时把对应服务拉起来。这套机制的优点很直接服务容器化镜像里自带匹配版本的所有二进制规避包冲突。升级路径简单换镜像tag就是升级。增加服务实例、标记维护、自动拉取OSD这些都是声明式操作。自带cephadm shell不用在宿主机上装ceph-common也能执行ceph、rbd等命令。当然也有代价必须接受容器化SSH权限和容器运行时稳定性的要求更高。但相对于它解决的问题这个代价在绝大多数场景下都值得。2. 安装前的准备工作2.1 节点规划、系统要求与网络注意事项我自己装的时候用的是一台管理节点加三台存储节点的拓扑。管理节点只跑命令行工具和dashboard存储节点跑mon/mgr/osd。如果你的机器不多也可以让一台机器同时承担所有角色但至少要保证总内存不小于8G毕竟Ceph本身的服务加上容器开销都不算小。系统方面Pacific要求还是比较友好的。CentOS 7往上、Rocky/RHEL 8、Ubuntu 18.04/20.04都可以。注意hostname必须能解析不能是localhostCeph对节点名要求比较严格最好规划成短域名。另外每个节点的/etc/hosts要把所有节点的IP和hostname写全这个是老生常谈但真的很多人漏。网络方面存储集群强烈建议有独立的cluster网络与public网络分开。如果环境条件有限只有一张网卡也能跑但性能和稳定性差距明显。我在实际配置里至少要求把public网段和cluster网段分开规划就算前期条件不允许至少要把IP地址留好后续能改。还有个很容易忽略的点就是时间同步。Ceph内部对时间偏移容忍度比较低mon节点之间时间差超过一定阈值就会互相不认。建议所有节点都配置NTP或chrony并保证开机自启。2.2 容器运行时Podman还是Dockercephadm默认优先用Podman没有的话也会去找Docker。从我实际经验看两者都能跑差别主要在细节上。Podman的优势在于无守护进程、rootless能力、systemd集成度好像RHEL系系统里装了podman之后基本不用额外配。Docker则更通用很多人对它的日志和网络更熟悉。如果你用的是CentOS 7官方推荐装Docker因为老系统上用podman容易遇到cgroup和存储驱动的兼容问题。这里提醒一句千万不要在同一个节点上同时启用Podman和Docker容易导致网络栈冲突cephadm检测到多个容器运行时之后可能会行为异常。装完容器运行时最好自己先跑个hello-world确认没问题别等到集群都搭一半了才发现容器起不来。2.3 SSH免密、hosts解析和防火墙端口cephadm从管理节点SSH到各存储节点是核心机制所以我习惯先把管理节点到所有节点包括它自己的SSH免密配好。注意不只是登录用户要免密还要保证时区一致、sudo权限可用。如果你用非root用户部署那用户必须加入docker组或者具备sudo权限否则容器管理命令会执行失败。防火墙方面最小化开放规则是这样的端口用途3300mon和mgr的grpc通信6789mon默认端口6800-7300OSD、MDS、RGW等各类服务端口8080某些rgw默认端口如果用8443dashboard Web UI端口22SSH用于cephadm管理我实际部署时直接先按“最小规则放行测试不过再收紧”的顺序来。先把集群内部各节点之间这些端口全放开客户端访问再按需要限制来源IP。很多问题排查到最后发现根本不是Ceph的问题而是防火墙没放行非常浪费时间。3. 用cephadm完成bootstrap3.1 获取cephadm脚本Ceph Pacific的cephadm脚本可以有两个来源。如果你有一台能访问外网的机器直接curl -fsSL https://download.ceph.com/rpm-pacific/el8/noarch/cephadm -o cephadm chmod x cephadm如果是在内网环境也可以找一台已经装过cephadm的机器把脚本拷过去或者用源码仓库里的脚本。这个脚本本身只是个Python程序不依赖其他工具包所以拷贝到目标机器后直接就能用。拿到脚本后先用./cephadm add-repo --release pacific把对应版本的软件源配置好再把容器运行时装好。脚本还有个install命令会自动安装需要的依赖和容器运行时但如果公司网络策略严格我建议还是手动控制环境准备这一步。3.2 bootstrap命令详解与关键参数bootstrap是搭建集群的第一道关卡它的作用就是初始化mon、mgr并让cephadm进入可管理状态。我用的命令类似这样./cephadm bootstrap \ --mon-ip 192.168.10.10 \ --ssh-user root \ --ssh-private-key /root/.ssh/id_rsa \ --ssh-public-key /root/.ssh/id_rsa.pub \ --allow-fqdn-hostname \ --output-config /etc/ceph/ceph.conf \ --output-keyring /etc/ceph/ceph.client.admin.keyring \ --skip-monitoring-stack你可能注意到我加了--skip-monitoring-stack。这是因为我暂时不想让prometheus和grafana容器一起启动先把核心服务起来监控后面再补。如果你内存不富裕这个参数能省不少资源。如果内存有16G以上也可以不跳直接让监控栈一步到位。--mon-ip必须是本机可达的IP不能填localhost否则后续mon服务注册的时候会对不上。--ssh-user指定cephadm往其他节点登录用的用户名。我记得第一次装的时候没指定--ssh-user导致cephadm尝试用当前用户名登录其他节点结果权限不够后来又重新bootstrap一遍。还有一个我今天特别想强调的参数是--allow-fqdn-hostname。如果你节点的hosts文件里写的是完整域名或者本身希望用FQDN来标识节点这个参数必须加上。不加的话cephadm会拒绝继续。如果你在海外镜像拉取慢的区域可以指定--image参数指向一个镜像仓库镜像。比如./cephadm bootstrap \ --mon-ip 192.168.10.10 \ --image docker.io/ceph/ceph:v16.2.12我实际测试中用docker.io/ceph/ceph:v16.2.12加载就比较稳quay.io在某些网络环境里容易超时所以看情况选镜像源。3.3 验证bootstrap结果bootstrap结束会把一串配置贴出来包括dashboard地址、用户名、密码以及帮你生成的ceph.conf和admin keyring路径。第一次执行完我建议先做三个检查。第一个检查是容量状态ceph -s正常情况下你会看到一个包含单个mon、单个mgr的集群状态可能是HEALTH_WARN因为还没有OSD这是正常的。第二个检查是看容器运行情况cephadm ps如果mon和mgr容器都在运行第一阶段就算成功。第三个检查是把admin密钥和配置文件拷贝到每一台节点上方便后续所有节点都能执行ceph命令。拷的时候注意权限ceph.client.admin.keyring一般设置成600权限否则客户端连接时会报权限过宽。4. 给集群加机器、加盘部署OSD4.1 把其他节点加入集群一个单节点的集群没有实际意义所以bootstrap完成后第一件事就是把其他存储节点加进来。执行ceph orch host add命令ceph orch host add node02 192.168.10.11 ceph orch host add node03 192.168.10.12执行的时候mgr orchestrator会通过SSH连接新节点检查容器运行时、拉取所需镜像再准备该节点相关角色。如果你之前没配置好SSH免密这里会直接报错报错信息一般就是“Permission denied”。所以我在环境准备阶段反复强调SSH免密这是cephadm模式下的核心依赖。加完节点后用ceph orch host ls查看节点状态。如果你发现节点处于维护模式或者label不对可以通过ceph orch host label add来补充。给节点打label的好处是后续部署服务时可以直接指定目标。我通常会给不同节点加上_admin的label方便cephadm知道哪些节点可以放置管理类服务。4.2 查看可用设备并添加OSDOSD的加入主要有两种思路。第一种是完全手动我就想要某个节点上的某块盘成为OSD。第二种是让Ceph自动发现所有未使用的设备并统一加进来。先看当前集群识别的未使用设备ceph orch device ls这个命令会列出所有节点上“无分区、无文件系统”的原始设备比如裸的SSD或者HDD。如果列表为空大概率是磁盘上还有残留分区表用wipefs -a /dev/sdX清一下再执行ceph orch device zap让Ceph重新扫描。手动添加单个OSDceph orch daemon add osd node02:/dev/sdb自动批量添加所有可用设备ceph orch apply osd all-available-devices我用自动方式部署的时候建议配合ceph orch osd status看进度。Ceph会先对磁盘做一些检查然后起OSD容器再把该盘注册为OSD。第一次看到设备数量很多的时候会觉得这个过程比手动装节省时间太多但也要注意自动方式会把所有无分区磁盘都吞掉万一机器上有保存数据的数据盘也会被格式化。所以如果环境不是纯测试还是手动逐台指定设备更安全。4.3 OSD部署的几个注意点第一尽量不要混合使用不同规格的磁盘作为同一存储池的后端如果你的SSD和HDD混在一个池子里性能会被拉低。可以给HDD打上hdd的label给SSD打上ssd的label然后通过ceph osd pool set或crush rule让不同池落在不同设备上。第二OSD数量的规划要参照副本数。三副本情况下OSD至少要大于等于三台机器否则数据分布会不均。我见过有人一台机器上塞了4个OSD然后只做了2副本结果一张盘坏了就丢数据这种方案完全不可取。第三还没加OSD之前Cluster状态是HEALTH_WARN这个不用慌。但一旦加了OSD要持续盯一下ceph -s中的PG状态PG数会先进入creating然后慢慢变成activeclean。数据均衡需要时间不要中途为了加速去手动调整很多参数容易引发backfill风暴。5. 补齐MDS、RGW和Dashboard5.1 部署CephFS需要的MDS假如你希望给客户端提供文件存储接口那CephFS是标准选择而CephFS需要MDS服务作为元数据进程。cephadm部署MDS非常简单ceph fs volume create cephfs这条命令会自动完成三件事创建CephFS需要的两个数据池和一个元数据池生成MDS服务并启动MDS实例。如果你要手动精细控制MDS所在节点先把节点打label然后指定placementceph orch apply mds cephfs --placementlabel:mds我测试时发现MDS最小1个实例能跑但为了保证性能至少部署2个MDS。当元数据访问量上来以后单MDS会变成明显瓶颈。创建好以后用ceph fs ls确认文件系统存在用ceph mds stat看MDS状态。如果MDS一直failed多半是元数据池没有正确激活或者创建volume时网络抖动导致可以直接ceph fs volume create重新执行一次Ceph的幂等性做得还是不错的。5.2 部署RGW对象网关对象存储走RGWcephadm下的部署也是声明式ceph orch apply rgw rgw01 \ --placementlabel:rgw \ --port 8080这里的意思是要创建一个名为rgw01的RGW服务放在打上rgw标签的节点上监听8080端口。RGW启动的时候会自动创建default区域的存储池比如default.rgw.buckets.data、default.rgw.meta等。部署完以后验证一下端口能通curl -I http://192.168.10.10:8080正常会返回HTTP/1.1 200 OK。如果是403或者404先看看RGW容器是不是起来了再检查防火墙和负载均衡配置。我这里有个经验尽量不要改rgw_frontends参数除非你非常清楚自己在干什么。默认的beast前端在大多数场景下表现够用乱改civetweb之类参数反而引入额外问题。5.3 Dashboard启用告警和其他功能模块cephadm bootstrap的时候已经默认启用dashboard并且生成了自签名证书和密码。登录地址在bootstrap日志里能看到通常是https://mon-ip:8443。第一次用admin账号登录进去之后建议立刻改密码ceph dashboard ac-user-set-password admin 新密码如果你bootstrap时用了--skip-monitoring-stack那dashboard里关于性能监控的图表会空白因为prometheus没有部署。要补齐监控栈可以直接ceph orch apply prometheus ceph orch apply grafana ceph orch apply alertmanager这里注意监控组件会占用一些内存如果服务器资源紧张我建议只装prometheus和grafanaalertmanager可以后面需要告警再接。另外dashboard的rgw管理功能默认是关闭的需要手动把RGW的密钥配置填进去ceph dashboard set-rgw-api-access-key access-key ceph dashboard set-rgw-api-secret-key secret-key但前提是你先在RGW里创建好用户和管理员角色。这块操作不算难但顺序容易搞混我的建议是先把RGW的S3接口验证通了再回来配dashboard。6. 存储池创建和客户端接入6.1 RBD存储池与客户端接入Ceph块存储的接入路径是创建pool启用rbd应用然后创建镜像最后映射到客户端。先创建poolceph osd pool create rbdpool 128 128 ceph osd pool application enable rbdpool rbdPG数量这里我给的是128具体数值取决于你集群OSD总数。经验公式是每个OSD上PG数量控制在100到200之间比如10个OSD那所有池PG总量控制在1000左右。128 * 3副本分到10个OSD上大约是38个PG/OSD偏保守但没毛病。PG太少会导致分布不均PG太多会占用不少内存所以别乱配。接着创建块设备镜像rbd create rbdpool/image01 --size 20G rbd map rbdpool/image01rbd map之后会生成一个/dev/rbd*设备客户端可以像普通块设备一样分区、格式化、挂载。我在测试中经常忽略一点就是linux内核需要加载rbd模块。如果lsmod | grep rbd没有输出先modprobe rbd一下。如果你的客户端是KVM虚拟机直接让libvirt使用rbd存储池也行。这个场景下存储池的rbd应用类型必须启用否则虚拟机创建会报“no applicable application”之类的错误。6.2 CephFS的客户端挂载CephFS客户端挂载前确认拿到了admin keyring。手动挂载命令mkdir -p /mnt/cephfs mount -t ceph 192.168.10.10:/ /mnt/cephfs -o nameadmin,secretfile/etc/ceph/admin.secret其中admin.secret是从keyring里提取的密钥部分。更推荐的方式是直接用ceph-fuseapt install -y ceph-fuse ceph-fuse -m 192.168.10.10:6789 /mnt/cephfs内核原生挂载速度更快但兼容性上ceph-fuse更好可以根据你的内核版本来选。如果挂载时出现no fs found先检查ceph fs ls确认文件系统已经存在。还有个小坑挂载机上的/etc/hosts必须能解析mon节点hostname否则ceph客户端根据配置文件里的hostname找不到mon。6.3 RGW的S3接口验证RGW服务起来以后我一般先拿radosgw-admin建一个测试用户radosgw-admin user create --uidtestuser --display-nameTest User命令执行完会输出一个包含access_key和secret_key的JSON把它们记下来。然后用任何S3客户端工具如s3cmd、aws cli验证s3cmd --host192.168.10.10:8080 \ --host-bucket192.168.10.10:8080/%(bucket) \ --access_keyxxx --secret_keyyyy \ mb s3://testbucket注意host-bucket这个参数很多工具默认会把bucket名作为子域名去解析内网没有DNS的情况下就会失败所以要让客户端使用路径风格寻址。Pacific本身默认支持path-style访问所以只要客户端配置正确一般都能通。7. 踩过的坑和排查速查7.1 典型故障现场先说一个我印象最深的坑。bootstrap的时候因为网络抖动mon容器起了但mgr一直没起来ceph -s显示mon有mgr没有。第一反应是重新执行bootstrap但实际上可以单独补cephadm deploy --name mgr.$(hostname)这条命令能让cephadm尝试重新创建mgr实例。如果你遇到mon进程反复重启先看日志cephadm logs --fsid fsid --name mon.hostname大多数情况是时间偏差或者网络不通少数情况是容器镜像被标记为损坏需要cephadm rm-daemon --name mon.hostname --fsid fsid再重新部署。再有就是OSD起不来。我碰到过一次磁盘明明显示available但ceph orch apply osd all-available-devices就是不加日志里说是Device is being used后来查到是磁盘上残留了LVM元数据。用wipefs -a清理之后重新ceph orch device zap问题就解决了。还有一次是dashboard登录不进去报502原因是grafana和prometheus没有部署。我当时bootstrap用了--skip-monitoring-stackdashboard部分功能依赖grafana反向代理后来把监控栈补上页面就正常了。7.2 常用巡检和运维命令合集整理一套我在日常运维中基本每次都会用的命令帮助你快速定位问题场景命令查看集群整体状态ceph -s查看OSD树和权重ceph osd tree查看所有主机ceph orch host ls查看服务实例列表ceph orch ps查看后台任务状态ceph orch job list查看设备清单ceph orch device ls查看cephadm日志cephadm logs --fsid fsid --name daemon重启某个服务ceph orch restart service-name进入cephadm容器内cephadm shell如果你要修改某个daemon的参数比如增加OSD内存分配可以用ceph orch daemon add带参数重新创建实例。改完以后记得ceph orch redeploy让所有节点同步配置。7.3 备份、升级和维护的思路Ceph Pacific的升级路径也比较简单假设要从v16.2.7升到v16.2.12只需要保证所有节点能拉取新镜像然后ceph orch upgrade start --image docker.io/ceph/ceph:v16.2.12升级过程会自动控制“先mon再mgr再osd”的顺序。执行完成后用ceph versions确认所有组件版本一致。这里有个经验是升级前一定先做一次ceph balancer status检查和ceph health detail校验不要在集群处于degraded状态时触发升级。备份方面ceph.conf、admin keyring、monstore这三个东西是最重要的。比如要备份monstore可以在mon容器里打一个快照cephadm enter --name mon.hostname -- ceph-mon --mon-data /var/lib/ceph/mon/ceph-hostname --extract-monstore /tmp/monstore把导出的/tmp/monstore目录拷走就行。维护思路不要贪多求全先把“容器配置密钥”备份好遇到极端情况重建比硬修更省时间。最后再分享一点点个人心得Ceph Pacific搭配cephadm其实把安装门槛降得非常低了。但门槛低不等于风险低你要想在生产里用环境准备、网络规划、磁盘规划这三块一定不能省。我见过太多人图省事直接自动apply结果后面因为设备误识别或者网络分区栽跟头。多花一小时确认基础环境后面能省下好几个加班的晚上。