Docker 容器版 Ceph 15.2 节点关机 5 天后恢复教程 - 容器化环境故障处理实战

前言

在容器化部署的 Ceph 集群中,当某个节点关机数天后重新启动,恢复流程与传统的物理机/虚拟机部署有所不同。本文基于 Ceph 15.2 (Octopus) Docker 容器版本,详细介绍节点关机 5 天后的完整恢复流程,包括容器管理、数据卷挂载、网络配置和常见问题处理。

Ceph 版本:15.2.x (Octopus)

部署方式:Docker 容器

适用场景:OSD/MON 容器节点意外关机/离线后的恢复

环境要求:Docker 19.03+,Ceph 容器镜像,至少 3 个节点

一、Docker 环境 vs 传统环境差异

1.1 主要区别

项目 传统部署 Docker 容器部署
服务管理 systemctl docker start/stop/restart
配置文件 /etc/ceph/ 挂载卷或 ConfigMap
数据存储 /var/lib/ceph/ Docker Volume/Host Path
日志查看 journalctl /var/log/ceph/ docker logs
网络 主机网络 容器网络/Host 网络
进程管理 systemd 容器进程

1.2 常见 Docker Ceph 部署方案

# 方案 1:官方 ceph/daemon 镜像
docker pull docker.io/ceph/daemon:latest-octopus

# 方案 2:ceph/ceph 镜像
docker pull docker.io/ceph/ceph:v15.2

# 方案 3:使用 Docker Compose 部署
docker-compose -f ceph-compose.yml up -d

# 方案 4:使用 K8s 部署(Rook)
kubectl apply -f rook-ceph-operator.yaml

本文以官方 ceph/daemon 镜像 + Docker Compose 为例,其他部署方式类似。

---

二、故障背景分析

2.1 场景描述

# 集群环境
- Ceph 版本:15.2.15 (Octopus)
- 部署方式:Docker 容器
- 节点数量:3 个节点
- 故障节点:node3 (关机 5 天)
- 容器编排:Docker Compose
- 集群状态:HEALTH_WARN (降级运行)

# 容器信息
- MON 容器:ceph-mon-node3
- OSD 容器:ceph-osd-6, ceph-osd-7, ceph-osd-8
- MGR 容器:ceph-mgr-node3
- 网络模式:host 网络

2.2 节点离线 5 天的影响

影响项 说明 严重程度
容器状态 所有 Ceph 容器已停止 🔴 高
数据卷 数据持久化在宿主机,数据安全 🟢 低
容器网络 容器 IP 可能变化 🟡 中
时间同步 容器时间可能不同步 🟡 中
数据差异 故障节点数据落后 5 天 🟢 低

---

三、恢复前准备工作

3.1 检查集群当前状态

正常节点(node1 或 node2)上执行:

1. 查看集群健康状态

# 进入任意一个正常节点的 MON 容器
docker exec -it ceph-mon-node1 bash

# 查看集群状态
ceph -s

# 查看集群健康详情
ceph health detail

# 查看 OSD 树
ceph osd tree

# 示例输出:
# ID  CLASS  WEIGHT   TYPE NAME      STATUS  REWEIGHT  PRI-AFF
# -7          3.33333      host node3
#  6    hdd  1.11111          osd.6   down        0  1.00000
#  7    hdd  1.11111          osd.7   down        0  1.00000
#  8    hdd  1.11111          osd.8   down        0  1.00000

# 退出容器
exit

2. 查看容器状态

# 在正常节点上查看所有 Ceph 容器
docker ps -a | grep ceph

# 示例输出:
# CONTAINER ID   IMAGE                  STATUS
# abc123456789   ceph/daemon:latest     Exited (0) 5 days ago   ceph-mon-node3
# def234567890   ceph/daemon:latest     Exited (0) 5 days ago   ceph-osd-6
# ghi345678901   ceph/daemon:latest     Exited (0) 5 days ago   ceph-osd-7
# jkl456789012   ceph/daemon:latest     Exited (0) 5 days ago   ceph-osd-8
# mno567890123   ceph/daemon:latest     Up 10 days              ceph-mon-node1
# pqr678901234   ceph/daemon:latest     Up 10 days              ceph-osd-0

# 记录容器 ID 和名称,后续需要启动

3. 备份当前状态

# 进入 MON 容器备份状态
docker exec -it ceph-mon-node1 bash

# 备份集群状态
ceph -s > /tmp/ceph_status_before.txt
ceph osd tree > /tmp/ceph_osd_tree_before.txt
ceph health detail > /tmp/ceph_health_before.txt

# 导出 OSD map
ceph osd getmap -o /tmp/osd_map_before

# 导出 CRUSH map
ceph osd getcrushmap -o /tmp/crush_map_before

# 退出容器
exit

# 将备份文件复制到安全位置
scp node1:/tmp/ceph_*.txt /backup/
scp node1:/tmp/osd_map_before /backup/
scp node1:/tmp/crush_map_before /backup/

---

3.2 故障节点检查(node3)

登录到故障节点 node3 执行以下检查:

1. 检查 Docker 环境

# 检查 Docker 服务状态
systemctl status docker

# 如果 Docker 未启动,先启动
systemctl start docker
systemctl enable docker

# 检查 Docker 版本
docker --version

# 确保与其他节点版本一致
# node1: docker --version
# node2: docker --version
# node3: docker --version

# 检查 Docker 网络
docker network ls

# 检查 Docker 存储
docker info | grep "Storage Driver"

2. 检查 Ceph 容器状态

# 查看所有 Ceph 相关容器
docker ps -a | grep ceph

# 查看停止的容器
docker ps -a --filter "status=exited" | grep ceph

# 记录容器名称和 ID
# ceph-mon-node3
# ceph-osd-6
# ceph-osd-7
# ceph-osd-8
# ceph-mgr-node3

3. 检查数据卷挂载

# 查看容器挂载信息(从正常节点复制配置)
docker inspect ceph-mon-node1 | grep -A 20 "Mounts"

# 在 node3 上检查数据目录
ls -la /data/ceph/
# 或
ls -la /var/lib/ceph/

# 检查 MON 数据
ls -la /data/ceph/mon-node3/

# 检查 OSD 数据
ls -la /data/ceph/osd-6/
ls -la /data/ceph/osd-7/
ls -la /data/ceph/osd-8/

# 检查配置文件
ls -la /etc/ceph/
cat /etc/ceph/ceph.conf

4. 检查时间同步

# 检查宿主机时间
date

# 与其他节点对比
# node1: date
# node2: date
# node3: date

# 检查 NTP 服务
systemctl status chronyd

# 同步时间
systemctl restart chronyd
chronyc -a makestep

# 验证时间同步
chronyc sources -v

5. 检查网络配置

# 检查宿主机网络
ip addr show

# 检查公共网络
ping <公共网络网关>

# 检查集群网络
ping node1
ping node2

# 检查端口(Ceph MON 端口 6789)
telnet node1 6789
telnet node2 6789

# 检查防火墙
systemctl status firewalld

# 如果需要,临时关闭防火墙
systemctl stop firewalld

6. 检查 Docker 镜像

# 查看本地 Ceph 镜像
docker images | grep ceph

# 检查镜像版本(必须与其他节点一致)
# node1: docker images | grep ceph
# node2: docker images | grep ceph
# node3: docker images | grep ceph

# 如果镜像不存在或版本不一致,拉取正确版本
docker pull docker.io/ceph/daemon:latest-octopus

# 或使用国内镜像加速
docker pull registry.cn-hangzhou.aliyuncs.com/ceph/daemon:latest-octopus

---

四、恢复 Ceph 容器

4.1 恢复策略选择

策略 适用场景 操作步骤
方案 A
直接启动容器
容器配置未变
数据卷完整
网络配置一致
docker start
自动加入集群
方案 B
重建容器
容器配置丢失
需要更新配置
网络环境变化
删除旧容器
用原配置重建
方案 C
完全重新部署
数据卷损坏
节点配置大改
版本升级
清理所有数据
重新部署节点

本例选择方案 A(直接启动容器),因为数据卷完整,容器配置未变。

---

4.2 恢复 MON 容器

步骤 1:启动 MON 容器

# 在 node3 上执行

# 方法 1:如果容器配置还在,直接启动
docker start ceph-mon-node3

# 方法 2:如果使用 Docker Compose
cd /opt/ceph  # Compose 文件所在目录
docker-compose up -d mon

# 方法 3:如果容器已删除,需要重建
docker run -d --name ceph-mon-node3     --net=host     --restart=always     -v /etc/ceph:/etc/ceph     -v /data/ceph/mon-node3:/var/lib/ceph/mon     -v /var/log/ceph:/var/log/ceph     -e MON_IP=     -e CEPH_PUBLIC_NETWORK=<公共网络 CIDR>     --privileged=true     docker.io/ceph/daemon:latest-octopus     mon

步骤 2:验证 MON 状态

# 查看容器状态
docker ps | grep ceph-mon

# 查看容器日志
docker logs -f ceph-mon-node3

# 进入容器检查
docker exec -it ceph-mon-node3 bash

# 检查 MON 状态
ceph mon_status

# 检查 quorum
ceph quorum_status

# 预期输出应包含 node3
# "quorum_names": ["node1","node2","node3"]

# 退出容器
exit

---

4.3 恢复 OSD 容器

步骤 1:将 OSD 标记为 in

正常节点的 MON 容器中执行:

# 进入 MON 容器
docker exec -it ceph-mon-node1 bash

# 将 node3 的 OSD 标记为 in
for osd_id in 6 7 8; do
    ceph osd in osd.$osd_id
    echo "osd.$osd_id 已标记为 in"
done

# 验证状态
ceph osd tree | grep node3

# 退出容器
exit

步骤 2:设置恢复参数

# 进入 MON 容器
docker exec -it ceph-mon-node1 bash

# 设置保守的恢复参数
ceph config set mon osd_recovery_max_active 3
ceph config set mon osd_recovery_max_single_start 1
ceph config set mon osd_recovery_max_chunk 1048576
ceph config set mon osd_recovery_sleep 0.1

# 退出容器
exit

步骤 3:启动 OSD 容器

# 在 node3 上执行

# 方法 1:直接启动现有容器
docker start ceph-osd-6
docker start ceph-osd-7
docker start ceph-osd-8

# 方法 2:使用 Docker Compose
cd /opt/ceph
docker-compose up -d osd

# 方法 3:重建容器(如果容器已删除)
# 启动 OSD 6
docker run -d --name ceph-osd-6     --net=host     --restart=always     -v /etc/ceph:/etc/ceph     -v /data/ceph/osd-6:/var/lib/ceph/osd     -v /var/log/ceph:/var/log/ceph     -e OSD_ID=6     -e OSD_DEVICE=/dev/sdb     --privileged=true     docker.io/ceph/daemon:latest-octopus     osd

# 启动 OSD 7(修改 OSD_ID 和设备)
docker run -d --name ceph-osd-7     --net=host     --restart=always     -v /etc/ceph:/etc/ceph     -v /data/ceph/osd-7:/var/lib/ceph/osd     -v /var/log/ceph:/var/log/ceph     -e OSD_ID=7     -e OSD_DEVICE=/dev/sdc     --privileged=true     docker.io/ceph/daemon:latest-octopus     osd

# 启动 OSD 8
docker run -d --name ceph-osd-8     --net=host     --restart=always     -v /etc/ceph:/etc/ceph     -v /data/ceph/osd-8:/var/lib/ceph/osd     -v /var/log/ceph:/var/log/ceph     -e OSD_ID=8     -e OSD_DEVICE=/dev/sdd     --privileged=true     docker.io/ceph/daemon:latest-octopus     osd

步骤 4:验证 OSD 状态

# 在 node3 上检查容器状态
docker ps | grep ceph-osd

# 查看 OSD 容器日志
docker logs -f ceph-osd-6

# 在正常节点上验证 OSD 状态
docker exec -it ceph-mon-node1 bash

# 查看 OSD 树
ceph osd tree

# 预期输出:
# ID  CLASS  WEIGHT   TYPE NAME      STATUS  REWEIGHT  PRI-AFF
# -7          3.33333      host node3
#  6    hdd  1.11111          osd.6      up   1.00000  1.00000
#  7    hdd  1.11111          osd.7      up   1.00000  1.00000
#  8    hdd  1.11111          osd.8      up   1.00000  1.00000

# 查看集群状态
ceph -s

# 退出容器
exit

---

4.4 恢复 MGR 容器(如果有)

# 在 node3 上执行

# 启动 MGR 容器
docker start ceph-mgr-node3

# 或使用 Docker Compose
docker-compose up -d mgr

# 验证 MGR 状态
docker exec -it ceph-mon-node1 bash
ceph mgr stat
ceph mgr dump

# 退出容器
exit

---

五、数据同步和平衡

5.1 监控数据恢复进度

# 进入 MON 容器
docker exec -it ceph-mon-node1 bash

# 实时查看恢复进度
watch -n 5 'ceph -s'

# 查看 PG 恢复状态
ceph pg dump | grep -E "recovering|backfill"

# 查看恢复详情
ceph pg ls recovering

# 查看数据平衡进度
ceph osd df

# 查看恢复速度
ceph -w | grep -E "recover|backfill"

# 退出容器
exit

5.2 查看容器资源使用

# 查看容器资源使用
docker stats ceph-osd-6 ceph-osd-7 ceph-osd-8

# 查看容器网络流量
docker inspect ceph-osd-6 | grep -i network

# 查看容器日志(实时)
docker logs -f ceph-osd-6 --tail 100

5.3 加速恢复(可选)

# 进入 MON 容器
docker exec -it ceph-mon-node1 bash

# 在业务低峰期,可以临时提高恢复速度
ceph config set mon osd_recovery_max_active 10
ceph config set mon osd_recovery_max_single_start 5
ceph config set mon osd_recovery_max_chunk 8388608
ceph config set mon osd_recovery_sleep 0
ceph config set mon osd_max_backfills 10

# 恢复完成后,改回保守值
ceph config set mon osd_recovery_max_active 3
ceph config set mon osd_recovery_max_single_start 1
ceph config set mon osd_recovery_max_chunk 1048576
ceph config set mon osd_recovery_sleep 0.1

# 退出容器
exit

---

六、验证和收尾

6.1 验证集群健康

# 进入 MON 容器
docker exec -it ceph-mon-node1 bash

# 检查集群健康状态
ceph health
# 预期输出:HEALTH_OK

ceph health detail
# 应该没有警告或错误

# 检查集群状态
ceph -s
# 预期输出:
#   health: HEALTH_OK
#   osd: 30 osds: 30 up, 30 in

# 检查 PG 状态
ceph pg stat
# 预期输出:
#   X PGs: Y active+clean

# 检查所有 OSD 状态
ceph osd tree
# 所有 OSD 应该是 up 和 in 状态

# 退出容器
exit

6.2 恢复 Docker 容器自启

# 确保容器设置了 --restart=always
# 如果没有,更新容器
docker update --restart=always ceph-mon-node3
docker update --restart=always ceph-osd-6
docker update --restart=always ceph-osd-7
docker update --restart=always ceph-osd-8
docker update --restart=always ceph-mgr-node3

# 验证
docker inspect ceph-mon-node3 | grep -i restart

6.3 保存恢复后的状态

# 进入 MON 容器
docker exec -it ceph-mon-node1 bash

# 保存状态
ceph -s > /tmp/ceph_status_after.txt
ceph osd tree > /tmp/ceph_osd_tree_after.txt
ceph health detail > /tmp/ceph_health_after.txt

# 退出容器
exit

# 复制备份文件
scp node1:/tmp/ceph_status_after.txt /backup/
scp node1:/tmp/ceph_osd_tree_after.txt /backup/
scp node1:/tmp/ceph_health_after.txt /backup/

# 记录恢复过程
cat > /var/log/ceph/node3_recovery_$(date +%Y%m%d).log << EOF
恢复时间:$(date)
故障节点:node3
离线时长:5 天
恢复容器:ceph-mon-node3, ceph-osd-6/7/8
恢复耗时:约 XX 分钟
恢复后状态:HEALTH_OK
操作人员:XXX
EOF

---

七、Docker Compose 完整示例

7.1 Docker Compose 配置文件

# ceph-compose.yml
version: '3'

services:
  mon:
    image: docker.io/ceph/daemon:latest-octopus
    container_name: ceph-mon-node3
    network_mode: host
    restart: always
    volumes:
      - /etc/ceph:/etc/ceph
      - /data/ceph/mon-node3:/var/lib/ceph/mon
      - /var/log/ceph:/var/log/ceph
    environment:
      - MON_IP=192.168.1.13
      - CEPH_PUBLIC_NETWORK=192.168.1.0/24
      - CEPH_DAEMON=MON
    privileged: true

  mgr:
    image: docker.io/ceph/daemon:latest-octopus
    container_name: ceph-mgr-node3
    network_mode: host
    restart: always
    volumes:
      - /etc/ceph:/etc/ceph
      - /var/log/ceph:/var/log/ceph
    environment:
      - CEPH_DAEMON=MGR
    privileged: true
    depends_on:
      - mon

  osd-6:
    image: docker.io/ceph/daemon:latest-octopus
    container_name: ceph-osd-6
    network_mode: host
    restart: always
    volumes:
      - /etc/ceph:/etc/ceph
      - /data/ceph/osd-6:/var/lib/ceph/osd
      - /var/log/ceph:/var/log/ceph
      - /dev/sdb:/dev/sdb
    environment:
      - OSD_ID=6
      - OSD_DEVICE=/dev/sdb
      - CEPH_DAEMON=OSD
    privileged: true
    depends_on:
      - mon

  osd-7:
    image: docker.io/ceph/daemon:latest-octopus
    container_name: ceph-osd-7
    network_mode: host
    restart: always
    volumes:
      - /etc/ceph:/etc/ceph
      - /data/ceph/osd-7:/var/lib/ceph/osd
      - /var/log/ceph:/var/log/ceph
      - /dev/sdc:/dev/sdc
    environment:
      - OSD_ID=7
      - OSD_DEVICE=/dev/sdc
      - CEPH_DAEMON=OSD
    privileged: true
    depends_on:
      - mon

  osd-8:
    image: docker.io/ceph/daemon:latest-octopus
    container_name: ceph-osd-8
    network_mode: host
    restart: always
    volumes:
      - /etc/ceph:/etc/ceph
      - /data/ceph/osd-8:/var/lib/ceph/osd
      - /var/log/ceph:/var/log/ceph
      - /dev/sdd:/dev/sdd
    environment:
      - OSD_ID=8
      - OSD_DEVICE=/dev/sdd
      - CEPH_DAEMON=OSD
    privileged: true
    depends_on:
      - mon

7.2 使用 Docker Compose 管理

# 启动所有服务
cd /opt/ceph
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f mon
docker-compose logs -f osd-6

# 重启服务
docker-compose restart osd-6

# 停止服务
docker-compose stop osd-6

# 删除容器(不删除数据卷)
docker-compose rm -f osd-6

# 重新创建容器
docker-compose up -d osd-6

---

八、常见问题和故障排查

8.1 容器无法启动

# 问题 1:权限问题
# 症状:容器启动失败,日志显示权限错误
# 解决:
chown -R 64045:64045 /data/ceph/osd-6/
chmod 755 /data/ceph/osd-6/
docker start ceph-osd-6

# 问题 2:设备被占用
# 症状:容器启动失败,日志显示设备 busy
# 解决:
# 检查设备是否被其他容器占用
docker ps | grep sdb
# 释放设备或更换设备

# 问题 3:网络问题
# 症状:容器启动后无法加入集群
# 解决:
# 检查网络模式
docker inspect ceph-mon-node3 | grep -i network
# 确保使用 host 网络或正确的网络配置

8.2 容器启动后立即退出

# 查看容器日志
docker logs ceph-osd-6 --tail 200

# 查看容器退出码
docker inspect ceph-osd-6 | grep -i exit

# 常见原因:
# 1. 配置文件错误 - 检查 /etc/ceph/ceph.conf
# 2. 数据目录损坏 - 检查 /data/ceph/osd-6/
# 3. 网络不通 - 检查 ping 和 telnet
# 4. 时间不同步 - 检查 chronyc sources

# 重新创建容器(保留数据卷)
docker rm -f ceph-osd-6
docker-compose up -d osd-6

8.3 PG 长时间处于 recovering 状态

# 进入 MON 容器
docker exec -it ceph-mon-node1 bash

# 查看卡住的 PG
ceph pg dump_stuck recovering -f plain

# 查看具体 PG 详情
ceph pg 1.2 query

# 尝试修复
ceph pg repair 1.2

# 退出容器
exit

8.4 容器网络问题

# 检查容器网络
docker exec -it ceph-mon-node3 ip addr show

# 测试容器网络连通性
docker exec -it ceph-mon-node3 ping node1

# 检查端口
docker exec -it ceph-mon-node3 telnet node1 6789

# 如果网络有问题,重建容器(使用 host 网络)
docker rm -f ceph-mon-node3
docker run -d --name ceph-mon-node3     --net=host     --restart=always     -v /etc/ceph:/etc/ceph     -v /data/ceph/mon-node3:/var/lib/ceph/mon     docker.io/ceph/daemon:latest-octopus     mon

---

总结

Docker 容器版 Ceph 15.2 节点关机 5 天后的恢复流程主要包括以下步骤:

  1. 恢复前准备 - 检查集群状态、备份配置、确认 Docker 环境正常
  2. 节点检查 - 时间同步、网络配置、Docker 镜像、数据卷挂载
  3. 恢复容器 - 启动 MON、OSD、MGR 容器
  4. 数据同步 - 监控恢复进度、调整恢复参数、数据平衡
  5. 验证收尾 - 验证集群健康、设置容器自启、文档记录
  6. 故障排查 - 处理容器启动问题、网络问题、数据同步问题

关键注意事项:

  • ✅ 确保 Docker 版本一致
  • ✅ 确保容器镜像版本一致
  • ✅ 确保时间同步(NTP)正常
  • ✅ 确保数据卷挂载正确
  • ✅ 确保网络配置(host 网络或容器网络)正确
  • ✅ 恢复前备份集群状态
  • ✅ 在业务低峰期执行恢复
  • ✅ 设置容器--restart=always 保证自启

通过正确的恢复流程,可以确保 Docker 容器版 Ceph 集群在节点故障后快速、安全地恢复正常状态。🚀


注:本文基于 Ceph 15.2.15 (Octopus) Docker 容器版本编写。不同部署方式(Docker Compose、K8s、Rook)可能在配置和管理上略有差异,请根据实际情况调整。

参考资料:

  • Ceph 官方文档:https://docs.ceph.com/en/octopus/
  • Ceph Docker 镜像:https://hub.docker.com/r/ceph/daemon
  • Ceph 容器部署指南:https://docs.ceph.com/en/octopus/start/containerized/

发表回复

后才能评论