基于Docker Compose编排Ceph分布式存储集群:从单机到高可用

📅 2026/7/13 13:53:21
基于Docker Compose编排Ceph分布式存储集群:从单机到高可用
1. 为什么选择Docker Compose部署Ceph集群第一次接触Ceph部署时我像大多数运维人员一样被复杂的多节点配置劝退——手动配置monitor、OSD、manager的服务依赖关系反复检查网络端口和存储路径稍有不慎就会遇到集群无法启动的诡异报错。直到发现用Docker Compose编排Ceph集群这个作弊技巧部署时间从半天缩短到15分钟。传统部署的三大痛点依赖管理复杂MON节点必须先于OSD启动MGR需要MON就绪手工启动容易顺序错乱配置易出错每个节点的ceph.conf需手动同步网络参数稍有偏差就会导致节点失联扩容不灵活增加OSD需要重新配置认证密钥人工操作容易破坏现有数据而Docker Compose通过声明式YAML文件完美解决了这些问题。比如下面这个最小化的docker-compose.yml就能启动基础集群version: 3.7 services: mon1: image: ceph/daemon:v4.0.3-stable-4.0-nautilus-centos-7-x86_64 command: mon environment: - MON_IP192.168.1.101 - CEPH_PUBLIC_NETWORK192.168.1.0/24 volumes: - /data/ceph/mon1:/var/lib/ceph networks: ceph-net: ipv4_address: 192.168.1.101 osd1: image: ceph/daemon:v4.0.3-stable-4.0-nautilus-centos-7-x86_64 command: osd_directory depends_on: - mon1 volumes: - /data/ceph/osd1:/var/lib/ceph/osd - /dev/sdb:/var/lib/ceph/osd/block这个配置实现了三个关键能力服务依赖自动化通过depends_on确保OSD在MON启动后运行网络精准控制自定义子网避免端口冲突数据持久化宿主机目录映射保证存储安全2. 集群规划与基础环境准备2.1 硬件资源建议根据我的踩坑经验测试环境最低配置如下节点类型CPU内存磁盘数量MON2核2GB10GB系统盘3OSD4核4GB50GB数据盘3MGR2核2GB10GB系统盘2生产环境特别注意每个OSD对应一块独立磁盘不要用LVM万兆网络是性能底线否则恢复数据时会卡死MON节点务必使用SSD盘2.2 关键目录规划在宿主机创建统一的目录结构所有节点mkdir -p /ceph/{etc,lib,logs,osd} chmod 777 /ceph/*这个结构对应容器内的关键路径/etc/ceph集群配置文件/var/lib/ceph元数据存储/var/log/ceph日志文件/var/lib/ceph/osd实际数据存储2.3 内核参数调优编辑/etc/sysctl.conf增加# 提高网络吞吐量 net.ipv4.tcp_rmem 4096 87380 16777216 net.ipv4.tcp_wmem 4096 16384 16777216 # Ceph专用参数 kernel.pid_max 4194303 fs.file-max 26234859执行sysctl -p生效。这些参数能避免大规模IO时的连接中断问题。3. 编写Docker Compose核心配置3.1 网络定义首先创建专用网络避免端口冲突networks: ceph-net: driver: bridge ipam: config: - subnet: 172.20.0.0/24关键点使用bridge模式而非host方便端口管理固定子网防止容器重启IP变化生产环境建议用macvlan获得真实IP3.2 Monitor服务配置三节点MON配置示例mon1为例services: mon1: image: ceph/daemon:v4.0.3 command: mon hostname: mon1 environment: - MON_NAMEmon1 - MON_IP172.20.0.11 - CEPH_PUBLIC_NETWORK172.20.0.0/24 volumes: - /ceph/etc:/etc/ceph - /ceph/lib/mon1:/var/lib/ceph/mon networks: ceph-net: ipv4_address: 172.20.0.11 healthcheck: test: [CMD, ceph, -s] interval: 30s参数解析MON_NAME必须与hostname一致healthcheck自动检测MON状态数据卷挂载到不同宿主机路径防止冲突3.3 OSD服务配置使用独立磁盘的OSD配置osd1: image: ceph/daemon:v4.0.3 command: osd_directory depends_on: mon1: condition: service_healthy environment: - OSD_FORCE_ZAP1 - OSD_DEVICE/dev/sdb volumes: - /ceph/etc:/etc/ceph - /ceph/lib/osd1:/var/lib/ceph/osd - /dev/sdb:/dev/sdb devices: - /dev/sdb:/dev/sdb注意事项depends_on的service_healthy确保MON就绪必须映射物理设备路径/dev/sdb首次启动需设置OSD_FORCE_ZAP清除磁盘3.4 Manager与RGW服务高可用MGR配置mgr1: image: ceph/daemon:v4.0.3 command: mgr depends_on: mon1: condition: service_healthy volumes: - /ceph/etc:/etc/ceph - /ceph/lib/mgr1:/var/lib/ceph/mgr对象存储网关RGW配置rgw1: image: ceph/daemon:v4.0.3 command: rgw ports: - 7480:7480 depends_on: mon1: condition: service_healthy4. 集群初始化与高可用验证4.1 一键启动集群docker-compose up -d mon1 mon2 mon3 # 先启动MON docker-compose up -d osd1 osd2 osd3 # 再启动OSD docker-compose up -d mgr1 mgr2 # 最后启动MGR通过docker-compose logs -f mon1观察日志出现mon.mon1 is running表示成功。4.2 集群健康检查进入任意MON容器执行ceph -s # 查看集群状态 ceph osd tree # 检查OSD分布健康状态应显示health: HEALTH_OK pgmap: activeclean4.3 模拟节点故障测试高可用性docker stop mon1 # 停掉一个MON ceph -s # 观察集群自动恢复正常情况30秒内会选举出新MON期间客户端可能有短暂卡顿。5. 生产环境优化技巧5.1 性能调优参数在docker-compose.yml中添加OSD优化参数environment: - OSD_OPTS--osd-opts-threads4 --osd-disk-threads4 - BLUESTORE_BDB_CACHE_SIZE2147483648 # 2GB缓存5.2 监控配置启用Prometheus监控docker exec mgr1 ceph mgr module enable prometheus访问http://mgr_ip:9283/metrics获取指标。5.3 备份与恢复使用ceph-volume备份OSD元数据docker exec osd1 ceph-volume lvm backup --data /dev/sdb --path /backup/osd1.db恢复时只需挂载备份文件volumes: - /backup/osd1.db:/var/lib/ceph/osd/backup.db environment: - OSD_RESTORE/var/lib/ceph/osd/backup.db6. 常见问题排错指南问题1OSD启动报错 permission denied解决方案chown -R 167:167 /ceph/lib/osd* # Ceph容器内UID固定为167问题2RGW无法上传大文件调整docker-compose.ymlenvironment: - RGW_FRONTEND_PORT7480 - RGW_REMOTE_CGI1 - RGW_REMOTE_CGI_HOST0.0.0.0 - DEBUGverbose问题3MON容器不断重启检查宿主机时间同步ntpdate pool.ntp.org timedatectl set-ntp true最后分享一个真实案例某次升级后集群突然出现OSD离线最终发现是Docker默认的iptables规则阻断了节点间通信。解决方法是在docker-compose.yml中显式声明端口ports: - 6789:6789/tcp # MON端口 - 6800-7300:6800-7300/tcp # OSD通信范围