一、使用Docker部署Ceph分布式存储的准备
1.1、环境说明
创建三台虚拟机,采用的Linux是Almalinux9.3版本,Docker的版本是29.6.1,Ceph的版本是v20.2.2,【最少要求2核CPU,4G内存】。三台虚拟机的情况如下:
| 主机名 | IP地址 | 系统 | Ceph版本 | 备注 |
|---|---|---|---|---|
| ceph01 | 192.168.1.66 | Almalinux9.3 | v20.2.2 | 容器主节点(Dashbaord、mon、mds、rgw、mgr、osd) |
| ceph02 | 192.168.1.67 | Almalinux9.3 | v20.2.2 | 容器子节点(mon、mds、rgw、mgr、osd) |
| ceph03 | 192.168.1.68 | Almalinux9.3 | v20.2.2 | 容器子节点(mon、mds、rgw、mgr、osd) |
1.2、系统环境配置
bash
#Ceph服务器的环境配置
#1-关闭selinux
getenforce
sed -i 's/enforcing/disabled/' /etc/selinux/config
setenforce 0
#2-关闭防火墙【也可将ceph所需的端口放开】
systemctl stop firewalld
systemctl disable firewalld
#3-设置主机名称
hostnamectl set-hostname ceph01
systemctl restart systemd-hostnamed
exec bash
#4-配置本地的域名解析
cat>>/etc/hosts<<EOF
192.168.1.66 ceph01
192.168.1.67 ceph02
192.168.1.68 ceph03
EOF
#5-关闭交换分区
swapoff -a
sed -i '/swap/s/^/#/' /etc/fstab
#6-配置系统免密登录【在主节点ceph01配置(可选)】
ssh-keygen -t ed25519 -C "cephcluster"
cd ~/.ssh/
ls -al
ssh-copy-id ceph02
ssh-copy-id ceph03
| 必须开放端口 / 端口段 | 协议 | 服务进程 | 作用说明(官网原文依据) | 开放范围 |
|---|---|---|---|---|
| 3300 | TCP | ceph-mon | Messenger v2 新型协议,IANA 标准分配端口,集群、客户端默认优先通信端口 | Mon/OSD/MGR/MDS/RGW/ 客户端全互通 |
| 6789 | TCP | ceph-mon | Messenger v1 旧兼容协议,兼容低版本客户端 / 旧集群 | Mon/OSD/MGR/MDS/RGW/ 客户端全互通 |
| 6800--7568 | TCP | ceph-osd、ceph-mgr、ceph-mds | OSD 副本 / 回填 / 心跳;MGR 集群交互;MDS 元数据同步;客户端直连 OSD 读写 | 集群所有存储 / 管理节点、客户端 |
| 按需开放端口 | 协议 | 组件服务 | 用途 |
|---|---|---|---|
| 7480 | TCP | RGW(Civetweb) | 对象存储 S3/Swift 网关默认 HTTP 端口 |
| 80/443 | TCP | RGW | 自定义标准 HTTP/HTTPS 端口(替换 7480) |
| 8080 | TCP | Ceph Dashboard | 面板 HTTP 访问 |
| 8443 | TCP | Ceph Dashboard | 面板 HTTPS 访问 |
| 8003 | TCP | MGR Restful API | 集群 REST 接口 |
| 3260 | TCP | RBD iSCSI Gateway | iSCSI 块存储导出 |
| 2049 | TCP/UDP | NFS Ganesha | CephFS NFSv4 共享主端口 |
| 875 | TCP/UDP | NFS Ganesha | NFS 配额服务端口 |
实现Linux的ssh免密登录实操保姆级教程
https://blog.csdn.net/xiaochenxihua/article/details/152375722
1.3、系统参数配置
bash
#系统参数配置
#1-内核参数优化
cat >>/etc/sysctl.conf <<EOF
vm.swappiness=0
vm.dirty_background_ratio=5
vm.dirty_ratio=10
net.ipv4.tcp_keepalive_time = 60
EOF
sysctl -p
#2-设置数据预读机制
echo "8192" > /sys/block/sda/queue/read_ahead_kb
#I/O Scheduler,关于I/O Scheculder的调整,简单说【SSD/NVMe高速固态,无机械寻道开销要用none(noop)】【SATA/SAS使用mq-deadline(deadline)】二选一即可。
echo "mq-deadline" > /sys/block/sda/queue/scheduler
#echo "none" > /sys/block/sda/queue/scheduler
#3-设置系统时间同步【chrony服务作用:集群多节点统一时间,Ceph对时钟偏移敏感,差值超50ms会引发集群异常】
#查看系统当前日期与时间
date
#查看chronyd运行状态,inactive=未启动,active(running)=正常运行
systemctl status chronyd
#启动chrony服务
systemctl start chronyd
#设置开启自启动chrony服务
systemctl enable chronyd
#立即强制同步一次系统时间
chronyc -a makestep
#将同步后的系统时间写入硬件时钟,重启不丢失时间
hwclock -w
#校验NTP时间源是否正常同步
chronyc sources -v
#查看本地时钟偏移量(重点看System time : X seconds fast/slow)
chronyc tracking
#4-将容器内的ceph命令alias到本地,方便使用【其他ceph的相关命令也可参考添加】(以ceph01为例)
echo 'alias ceph="docker exec ceph-mon-ceph01 ceph"' >> /etc/profile
source /etc/profile
| 调度器 | 适用场景 |
|---|---|
| mq-deadline (deadline) | 数据库、Ceph OSD、RBD 块存储、低延迟业务(推荐) |
| kyber | 普通桌面、云虚拟机通用 |
| none(noop) | SSD/NVMe 高速固态,无机械寻道开销 |
注意:deadline:老式单队列调度器(4.10 + 内核已移除,仅保留多队列版);
1.4、安装部署Docker环境与配置加速器
Docker容器实践------docker的安装与加速器配置
https://blog.csdn.net/xiaochenXIHUA/article/details/160057920
bash
#使用yum在线安装docker------以AlmaLinux9为例
#1-安装docker-ce的依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2
#2-国内直接添加阿里云的docker-ce的yum源
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#3-安装docker-ce
yum makecache
yum install docker-ce -y
#4-启动docker-ce并设置开机自启
systemctl start docker
systemctl enable docker
#5-查看版本
docker -v
bash
#国内的docker镜像加速器配置
mkdir /etc/docker
vim /etc/docker/daemon.json
#【daemon.json】文件的完整内容
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://proxy.1panel.live",
"https://docker.xuanyuan.me",
"https://docker.m.daocloud.io",
"https://docker.rainbond.cc",
"https://docker.1panel.live"
]
}
#重载docker-ce的配置与服务
systemctl daemon-reload
systemctl restart docker
#查看docker的信息(若底部能够正常显示我们配置的【/etc/docker/daemon.json】文件的镜像加速地址则表示配置成功)
docker info
#测试拉取镜像是否正常(能正常拉取镜像下来则表示正常,若长时间等待没有反应或者拉取失败报错,则可考虑将DNS设置为:223.5.5.5、8.8.8.8)
docker pull nginx:1.28.3
基于Docker安装部署Ceph分布式存储有两种方法【使用Docker手动部署Ceph分布式存储(该方法可用于学习了解ceph的部署细节)】、****【使用cephadm一键式部署cephs分布式存储(官方推荐)】。
二、使用Docker手动部署Ceph分布式存储
2.1、在Docker宿主机创建Ceph目录并授权
在宿主机上创建Ceph目录与容器建立映射,便于直接操纵管理Ceph配置文件,以root身份依次在三台节点上创建/usr/local/ceph/{admin,data,etc,lib,logs}目录:
| Ceph目录 | 说明 |
|---|---|
| admin | admin文件夹下用于存储启动脚本 |
| data | data文件夹用于挂载文件 |
| etc | etc文件夹下存放了ceph.conf、集群密钥环(admin.keyring、mon.keyring )等配置文件,只在 ceph01 初始化生成,之后把整个 etc 目录同步到 ceph02、ceph03;(对应容器内/etc/ceph) |
| lib | 持久化 mon、mgr、osd、mds 容器数据(对应容器内 /var/lib/ceph)【bootstrap 引导密钥、集群元数据】 |
| logs | logs文件夹下存放了ceph的集群日志文件 |
bash
#配置Ceph所需的内容
#1-在Docker宿主机创建Ceph目录
mkdir -p /usr/local/ceph/{admin,data,etc,lib,logs}
#2-对docker内用户进行授权【167是docker内用户的id号,这里是进行授权,以便docker进程可以操作这些目录】
chown -R 167:167 /usr/local/ceph/
#3-配置密钥目录权限必须700,安全规范
chmod -R 700 /usr/local/ceph/etc
#4-验证权限
ls -ld /usr/local/ceph/*
2.2、创建OSD磁盘
若没有独立磁盘,可以在Linux下创建一个虚拟磁盘进行挂载【Ceph01、Ceph02、Ceph03三个节点都需要创建】【Ceph OSD 需要裸磁盘 / 裸分区,禁止使用系统盘分区;三台虚拟机各自新增至少 1 块空白磁盘(如 /dev/sdb),无分区表、无文件系统】,
这里以Ceph01节点操作:
bash
#创建OSD磁盘【若没有独立磁盘,则可如下一样创建虚拟磁盘挂载操作】
#1-初始化一个10G的镜像文件
mkdir -p /data/ceph-disk
dd if=/dev/zero of=/data/ceph-disk/ceph-disk-01 bs=1G count=10
#2-将镜像文件虚拟为块设备
losetup -f /data/ceph-disk/ceph-disk-01
##3-格式化虚拟磁盘【不用执行】
#mkfs.xfs -f /dev/loop0
##4-将虚拟磁盘挂载【将loop0磁盘挂载到/usr/local/ceph/data/osd/目录下】
#mount /dev/loop0 /usr/local/ceph/data/osd/
bash
#创建OSD磁盘【有独立磁盘,则可如下一样挂载操作】
lsblk
mkdir -p /usr/local/ceph/data/osd/
mkfs.ext4 /dev/sdb
mount /dev/sdb /usr/local/ceph/data/osd/
#获取到/dev/sdb的UUID持久挂载到系统中(如:获取到/dev/sdb的UUID="7e695a54-dc9c-4d87-bfc7-b59a822d012b")
blkid
vi /etc/fstab
UUID="7e695a54-dc9c-4d87-bfc7-b59a822d012b" /usr/local/ceph/data/osd defaults 0 0



2.3、部署Ceph的Mon容器并启动
一个 Ceph 存储集群至少需要一个 Ceph mon(监视器)、Ceph mgr(管理) 和 Ceph OSD(对象存储守护进程)。本文这里还增加Ceph mds、 Ceph rgw两个组件。为了便于后期维护管理,将docker命令写成了脚本形式。
2.3.1、在主节点(ceph01)执行集群初始化与启动mon容器
bash
#部署Ceph
#《1》仅在主节点ceph01执行集群初始化(生成 fsid、密钥、ceph.conf)与启动mon容器
#1-拉取官方镜像
docker pull quay.io/ceph/ceph:v20.2.2
#2-生成集群唯一FSID
FSID=$(uuidgen)
echo $FSID > /usr/local/ceph/etc/cluster-fsid
cat /usr/local/ceph/etc/cluster-fsid
#3-生成 mon. 密钥
docker run --rm \
-v /usr/local/ceph/etc:/etc/ceph \
quay.io/ceph/ceph:v20.2.2 \
ceph-authtool --create-keyring /etc/ceph/ceph.mon.keyring \
--gen-key -n mon. \
--cap mon 'allow *'
#4-生成 client.admin 密钥
docker run --rm \
-v /usr/local/ceph/etc:/etc/ceph \
quay.io/ceph/ceph:v20.2.2 \
ceph-authtool --create-keyring /etc/ceph/ceph.client.admin.keyring \
--gen-key -n client.admin \
--cap mon 'allow *' \
--cap osd 'allow *' \
--cap mds 'allow *' \
--cap mgr 'allow *'
#5-合并 keyring(mon 必需)
docker run --rm \
-v /usr/local/ceph/etc:/etc/ceph \
quay.io/ceph/ceph:v20.2.2 \
ceph-authtool /etc/ceph/ceph.mon.keyring \
--import-keyring /etc/ceph/ceph.client.admin.keyring
#6-生成标准ceph.conf
cat > /usr/local/ceph/etc/ceph.conf <<EOF
[global]
fsid = ${FSID}
mon initial members = ceph01,ceph02,ceph03
mon host = 192.168.1.66,192.168.1.67,192.168.1.68
auth cluster required = cephx
auth service required = cephx
auth client required = cephx
public network = 192.168.1.0/24
cluster network = 192.168.1.0/24
osd pool default size = 3
osd pool default min size = 2
osd pool default pg num = 32
osd pool default pgp num = 32
[mon]
mon data = /var/lib/ceph/mon/ceph-\$id
mon clock drift allowed = 0.5
mon clock drift warn backoff = 30
[mon.ceph01]
mon addr = 192.168.1.66:6789
[mon.ceph02]
mon addr = 192.168.1.67:6789
[mon.ceph03]
mon addr = 192.168.1.68:6789
[mgr]
mgr modules = dashboard
[dashboard]
dashboard ssl enabled = false
EOF
chown -R 167:167 /usr/local/ceph
#7-仅在ceph01上执行mon mkfs 初始化(初始化完成后会在【/usr/local/ceph/lib】目录下生成【mon/ceph-ceph01】目录及其该目录下有内容生成)
docker run -it --rm --net=host \
-v /etc/localtime:/etc/localtime \
-v /usr/local/ceph/etc:/etc/ceph \
-v /usr/local/ceph/lib:/var/lib/ceph \
quay.io/ceph/ceph:v20.2.2 \
sh -c "mkdir -p /var/lib/ceph/mon/ceph-ceph01 && ceph-mon \
--cluster ceph \
--id ceph01 \
--mkfs \
--mon-data /var/lib/ceph/mon/ceph-ceph01 \
--keyring /etc/ceph/ceph.mon.keyring \
-c /etc/ceph/ceph.conf"
ll /usr/local/ceph/lib/mon/ceph-ceph01/
chown -R 167:167 /usr/local/ceph
#8-启动ceph01的mon容器
docker run -d \
--name ceph-mon-ceph01 \
--net=host \
--restart=always \
-v /etc/localtime:/etc/localtime \
-v /usr/local/ceph/etc:/etc/ceph \
-v /usr/local/ceph/lib:/var/lib/ceph \
-v /usr/local/ceph/logs:/var/log/ceph \
quay.io/ceph/ceph:v20.2.2 \
ceph-mon -f \
--cluster ceph \
--id ceph01 \
--keyring /etc/ceph/ceph.mon.keyring \
-c /etc/ceph/ceph.conf
docker ps
docker logs ceph-mon-ceph01
docker exec -it ceph-mon-ceph01 ceph -s
#9-同步 ceph01 配置文件到 ceph02、ceph03
#9.1-同步配置+密钥
scp -p /usr/local/ceph/etc/* root@ceph02:/usr/local/ceph/etc/
scp -p /usr/local/ceph/etc/* root@ceph03:/usr/local/ceph/etc/
#9.2-同步后从节点重新授权权限
ssh root@ceph02 "chown -R 167:167 /usr/local/ceph/;chmod 700 /usr/local/ceph/etc"
ssh root@ceph03 "chown -R 167:167 /usr/local/ceph/;chmod 700 /usr/local/ceph/etc"






2.3.2、在其余节点配置与启动mon容器
bash
#ceph02 节点部署 Mon 服务
#1-初始化 ceph02 mon 数据目录
docker run -it --rm --net=host \
-v /etc/localtime:/etc/localtime \
-v /usr/local/ceph/etc:/etc/ceph \
-v /usr/local/ceph/lib:/var/lib/ceph \
quay.io/ceph/ceph:v20.2.2 \
sh -c "mkdir -p /var/lib/ceph/mon/ceph-ceph02 && ceph-mon \
--cluster ceph \
--id ceph02 \
--mkfs \
--mon-data /var/lib/ceph/mon/ceph-ceph02 \
--keyring /etc/ceph/ceph.mon.keyring \
-c /etc/ceph/ceph.conf"
ll /usr/local/ceph/lib/mon/ceph-ceph02/
chown -R 167:167 /usr/local/ceph
#2-启动ceph02 mon容器
docker run -d \
--name ceph-mon-ceph02 \
--net=host \
--restart=always \
-v /etc/localtime:/etc/localtime \
-v /usr/local/ceph/etc:/etc/ceph \
-v /usr/local/ceph/lib:/var/lib/ceph \
-v /usr/local/ceph/logs:/var/log/ceph \
quay.io/ceph/ceph:v20.2.2 \
ceph-mon -f \
--cluster ceph \
--id ceph02 \
-c /etc/ceph/ceph.conf
docker ps
docker logs ceph-mon-ceph02
docker exec -it ceph-mon-ceph02 ceph -s
#3-配置交互命令
echo 'alias ceph="docker exec ceph-mon-ceph02 ceph"' >> /etc/profile
source /etc/profile
ceph -s



bash
#ceph03 节点部署 Mon 服务
#1- 初始化 ceph03 mon 数据目录
docker run -it --rm --net=host \
-v /etc/localtime:/etc/localtime \
-v /usr/local/ceph/etc:/etc/ceph \
-v /usr/local/ceph/lib:/var/lib/ceph \
quay.io/ceph/ceph:v20.2.2 \
sh -c "mkdir -p /var/lib/ceph/mon/ceph-ceph03 && ceph-mon \
--cluster ceph \
--id ceph03 \
--mkfs \
--mon-data /var/lib/ceph/mon/ceph-ceph03 \
--keyring /etc/ceph/ceph.mon.keyring \
-c /etc/ceph/ceph.conf"
ll /usr/local/ceph/lib/mon/ceph-ceph03/
chown -R 167:167 /usr/local/ceph
#2-启动ceph03 mon容器
docker run -d \
--name ceph-mon-ceph03 \
--net=host \
--restart=always \
-v /etc/localtime:/etc/localtime \
-v /usr/local/ceph/etc:/etc/ceph \
-v /usr/local/ceph/lib:/var/lib/ceph \
-v /usr/local/ceph/logs:/var/log/ceph \
quay.io/ceph/ceph:v20.2.2 \
ceph-mon -f \
--cluster ceph \
--id ceph03 \
-c /etc/ceph/ceph.conf
docker ps
docker logs ceph-mon-ceph03
docker exec -it ceph-mon-ceph03 ceph -s
#3-配置交互命令
echo 'alias ceph="docker exec ceph-mon-ceph03 ceph"' >> /etc/profile
source /etc/profile
ceph -s



2.4、部署Ceph的OSD容器
Linux的磁盘存储管理实操------(中)------逻辑卷管理实战
https://coffeemilk.blog.csdn.net/article/details/149471808
bash
#部署Ceph的OSD容器操作步骤【如下以ceph01节点为例说明操作;其余两个节点也是一样的操作】
#1-mon 容器导出 bootstrap 密钥
docker exec ceph-mon-ceph01 bash -c "mkdir -p /var/lib/ceph/bootstrap-osd && ceph auth get client.bootstrap-osd -o /var/lib/ceph/bootstrap-osd/ceph.keyring"
chown -R 167:167 /usr/local/ceph
#2-宿主机手动清空指定磁盘并创建逻辑卷
lsblk
#2.1-彻底清空磁盘
wipefs -af /dev/sdb
dmsetup remove_all
udevadm trigger --subsystem-match=block
udevadm settle
sleep 5
#2.2-查看磁盘是否干净无占用
lsblk /dev/sdb
lsof /dev/sdb
fuser /dev/sdb
#2.3-预创建逻辑卷管理(LVM)
pvcreate /dev/sdb
vgcreate ceph-osd-vg /dev/sdb
lvcreate -l 100%FREE -n osd-0 /dev/ceph-osd-vg
udevadm settle
sleep 3
#3-临时特权 OSD 容器执行 ceph-volume 预处理磁盘【设置磁盘为OSD、激活磁盘OSD】(操作完后必须删除)
chown -R 167:167 /usr/local/ceph
ls -al /usr/local/ceph/lib/bootstrap-osd/
ls -al /usr/local/ceph/lib/
docker run -it --rm \
--name temp-osd \
--privileged=true \
--pid=host \
--cap-add=SYS_ADMIN \
-v /dev:/dev \
-v /run/udev:/run/udev \
--tmpfs /run/lvm \
--tmpfs /etc/lvm/devices \
-v /etc/localtime:/etc/localtime \
-v /usr/local/ceph/etc:/etc/ceph \
-v /usr/local/ceph/lib:/var/lib/ceph \
-v /usr/local/ceph/logs:/var/log/ceph \
quay.io/ceph/ceph:v20.2.2 sh -c "
ceph-volume lvm create --data /dev/ceph-osd-vg/osd-0;
echo '===== OSD创建完成,列出OSD =====';
ceph-volume lvm list;
echo '===== 激活所有OSD =====';
ceph-volume lvm activate --all;
cd /var/lib/ceph;
tar -zcvf osd.tar.gz osd;
echo '打包/var/lib/ceph目录下的osd.tar.gz文件完成'
"
cd /usr/local/ceph/lib/
tar -zxvf osd.tar.gz
chown -R 167:167 /usr/local/ceph
#4-启动OSD容器(id后的数字必须是OSD创建完成后的编号)
docker run -d \
--name ceph-osd \
--net=host \
--privileged=true \
--pid=host \
--cap-add=SYS_ADMIN \
--restart always \
-v /dev:/dev \
-v /run/udev:/run/udev \
--tmpfs /run/lvm \
--tmpfs /etc/lvm/devices \
-v /etc/localtime:/etc/localtime \
-v /usr/local/ceph/etc:/etc/ceph \
-v /usr/local/ceph/lib:/var/lib/ceph \
-v /usr/local/ceph/logs:/var/log/ceph \
quay.io/ceph/ceph:v20.2.2 \
ceph-osd -f --cluster ceph --id 12
#5-验证 OSD 是否真正就绪
docker ps
docker logs ceph-osd
ceph -s
ceph osd tree
docker exec -it ceph-osd ps aux | grep ceph-osd








2.5、部署Ceph的mgr容器
bash
#部署ceph的mgr容器步骤【如下以ceph01节点为例说明操作;其余两个节点也是一样的操作】
#1-创建mgr容器所需的身份密钥
docker exec ceph-mon-ceph01 sh -c "ceph auth get-or-create mgr.ceph01 mon 'allow profile mgr' osd 'allow *' mds 'allow *' > /etc/ceph/ceph.mgr.ceph01.keyring"
chmod 600 /usr/local/ceph/etc/ceph.mgr.ceph01.keyring
chown -R 167:167 /usr/local/ceph
ls -al /usr/local/ceph/etc
mkdir -p /usr/local/ceph/lib/mgr/ceph-ceph01
cp /usr/local/ceph/etc/ceph.mgr.ceph01.keyring /usr/local/ceph/lib/mgr/ceph-ceph01/keyring
chown -R 167:167 /usr/local/ceph
ls -al /usr/local/ceph/lib/mgr/ceph-ceph02/
#2-创建mgr容器
docker run -d \
--net=host \
--name=ceph-mgr \
--restart=always \
--privileged \
--cap-add=SYS_MODULE \
--cap-add=SYS_ADMIN \
-v /etc/localtime:/etc/localtime:ro \
-v /usr/local/ceph/etc:/etc/ceph \
-v /usr/local/ceph/lib:/var/lib/ceph \
-v /usr/local/ceph/logs:/var/log/ceph \
quay.io/ceph/ceph:v20.2.2 \
ceph-mgr -f --cluster ceph -i ceph01
#3-验证mgr容器是否正常启动
docker ps -a
docker logs ceph-mgr
ceph -s







2.6、部署Ceph的rgw容器
Ceph PG 完整算法、计算公式、分配逻辑:
| Ceph PG核心概念 | 说明 |
|---|---|
| PG(Placement Group) | 放置组,Ceph 把对象哈希到 PG,再把 PG 映射到 OSD 副本集 |
| Pool PG_num | 单个存储池总 PG 数量;pgp_num = 参与数据分片的 PG(一般等于 pg_num) |
| size(副本数) | min_size:最小可读写副本数; |
| mon_max_pg_per_osd | 总 PG 压力上限(单 OSD 最多承载多少 PG) |
单个 Pool 推荐 PG 计算公式(官方标准):PG_num=(OSD总数x100)/副本数; 结果向上取最接近的2 的幂次(2、4、8、16、32、64、128、256、512、1024...)

目前本文的环境计算:【当前集群:OSD=3,size=3】;PG_num=(3x100)/3=100,离 100 最近的 2 次幂:128(64 太小,128 是 2^7)因此 单池推荐 PG = 128
为什么必须是 2 的幂?
因为Ceph 使用 CRUSH 哈希、分片迁移、扩容重平衡底层依赖二进制位运算,非 2 次幂会导致 PG 分布极度不均、OSD 负载倾斜。
对象哈希到 PG 算法(简单版)
-
对对象名称 + pool ID 做哈希(CRUSH hash)
-
哈希值取模
pg_num,得到 PG ID:PG_ID=hash(object_name)modpg_num
同一对象永远落在同一个 PG,扩容 PG 时只会少量迁移。
PG 映射到 OSD 副本集(CRUSH 算法)
- 根据 PG ID、CRUSH 规则、副本数 size,算出一组 OSD 列表(主 OSD + 副本 OSD);
- 遵循机房 / 机架 / 主机隔离规则,尽量分散副本;
- 当 OSD 上下线、扩容缩容,仅少量 PG 重新映射,数据迁移量最小。
pg_num /pgp_num 关系算法
-
pg_num:该池总 PG 数量; -
pgp_num:有效参与对象分配的 PG;扩容流程:
-
先调大 pg_num(新增空 PG)
-
等待数据迁移平衡
-
再调大 pgp_num 等于 pg_num
日常稳定环境必须满足:
pgp_num = pg_num
多池总 PG 计算示例(本文的 RGW 场景)
- RGW 默认 5 个独立 pool:rgw.root/rgw.control/rgw.data/rgw.meta/rgw.log
- 若单池 PG=128;
- 总 PG 数量 = 5 × 128 = 640;
- 副本总负载 = 640 × 3 = 1920;
- 远低于 200000 上限,完全安全。
bash
#部署Ceph的rgw容器步骤【如下以ceph01节点为例说明操作;其余两个节点也是一样的操作】
#0-查看osd情况,若有不在线(down)的则直接清理下线
ceph osd tree
docker exec -it ceph-mon-ceph01 sh -c '
# 逐个移除下线无效OSD
ceph osd out 0;ceph osd rm 0;ceph osd crush remove osd.0
ceph osd out 1;ceph osd rm 1;ceph osd crush remove osd.1
ceph osd out 2;ceph osd rm 2;ceph osd crush remove osd.2
'
#1-创建rgw容器所需的身份密钥
docker exec -it ceph-mon-ceph01 ceph auth del client.rgw.ceph01
docker exec -it ceph-mon-ceph01 sh -c "
ceph auth get-or-create client.rgw.ceph01 \
mon 'allow rwx' \
osd 'allow rwx' \
mgr 'allow rwx' \
mds 'allow *';
ceph auth get client.rgw.ceph01 -o /etc/ceph/ceph.client.rgw.ceph01.keyring
"
docker exec -it ceph-mon-ceph01 ceph auth get client.rgw.ceph01
chmod 600 /usr/local/ceph/etc/ceph.client.rgw.ceph01.keyring
mkdir -p /usr/local/ceph/lib/radosgw/ceph-rgw.ceph01
cp /usr/local/ceph/etc/ceph.client.rgw.ceph01.keyring /usr/local/ceph/lib/radosgw/ceph-rgw.ceph01/keyring
chown -R 167:167 /usr/local/ceph
ls -al /usr/local/ceph/lib/radosgw/ceph-rgw.ceph01/
cat /usr/local/ceph/etc/ceph.client.rgw.ceph01.keyring
cat /usr/local/ceph/lib/radosgw/ceph-rgw.ceph01/keyring
#2-登录mon容器执行池创建
docker exec -it ceph-mon-ceph01 sh -c "
# 强制删除旧池
for p in $(ceph osd pool ls | grep default.rgw);do
ceph osd pool rm $p $p --yes-i-really-really-mean-it
done
# 指定副本最大3,最小2【单个存储池总 PG 数量pg_num=(OSD总数x100)/副本数;结果向上取最接近的2 的幂次(2、4、8、16、32、64、128、256、512、1024...)pg_num=(3x100)/3=100,向上取接近2的次幂就是128】
# 忽略不存在报错强制删
radosgw-admin zone delete --rgw-zone default --rgw-zonegroup default 2>/dev/null
radosgw-admin zonegroup delete --rgw-zonegroup default 2>/dev/null
radosgw-admin realm delete --rgw-realm default 2>/dev/null
"
#查看集群的完整配置是否一致
docker exec -it ceph-mon-ceph01 ceph config dump
#3-执行 v20 标准 realm/zone 初始化
docker exec -it ceph-mon-ceph01 sh -c "
# 1. 创建默认realm
radosgw-admin realm create --rgw-realm default --default
# 2. 创建默认zonegroup
radosgw-admin zonegroup create --rgw-zonegroup default --master --default
# 3. 创建zone并归属zonegroup
radosgw-admin zone create --rgw-zone default --rgw-zonegroup default --master --default
# 4. 设置zonegroup默认zone
radosgw-admin zonegroup default --rgw-zone default
# 5. 提交配置变更
radosgw-admin period update --commit
# 6.创建admin用户
radosgw-admin user create --uid=admin --display-name='RGW Admin User' --access-key=admin --secret-key=qwer1234
"
# 校验zone配置是否生效
docker exec -it ceph-mon-ceph01 ceph osd pool ls | grep rgw
docker exec -it ceph-mon-ceph01 radosgw-admin zone get --rgw-zone default
#4-创建ceph01的rgw容器
docker run -d \
--name ceph-rgw \
--restart always \
--net=host \
--privileged=true \
-v /etc/localtime:/etc/localtime:ro \
-v /usr/local/ceph/etc:/etc/ceph \
-v /usr/local/ceph/lib:/var/lib/ceph \
-v /usr/local/ceph/logs:/var/log/ceph \
quay.io/ceph/ceph:v20.2.2 \
radosgw -n client.rgw.ceph01 --rgw-frontends="civetweb port=7480"
注意:该rgw容器在初始化的时候总是会报34错误,手动这里部署不上,可忽略。

2.7、部署Ceph的mds容器
bash
#ceph的mds容器配步骤【如下以ceph01节点为例说明操作;其余两个节点也是一样的操作】
#1-生成ceph的mds容器所需的权限密钥
docker exec -it ceph-mon-ceph01 ceph auth del mds.ceph01
docker exec -it ceph-mon-ceph01 sh -c "
# 创建/获取mds.ceph01身份并授权
ceph auth get-or-create mds.ceph01 \
mon 'allow rwx' \
osd 'allow rwx' \
mgr 'allow rwx'
# 正确导出对应身份密钥
ceph auth get mds.ceph01 -o /etc/ceph/ceph.mds.ceph01.keyring
"
# 创建mds实例目录
chmod 600 /usr/local/ceph/etc/ceph.mds.ceph01.keyring
mkdir -p /usr/local/ceph/lib/mds/ceph-ceph01
# 复制密钥环到mds数据目录
cp /usr/local/ceph/etc/ceph.mds.ceph01.keyring /usr/local/ceph/lib/mds/ceph-ceph01/keyring
# ceph镜像内部运行用户uid/gid=167,必须修改权限,否则容器读不到
chown -R 167:167 /usr/local/ceph
cat /usr/local/ceph/lib/mds/ceph-ceph01/keyring
cat /usr/local/ceph/etc/ceph.mds.ceph01.keyring
ls -al /usr/local/ceph/lib/mds/ceph-ceph01/
ls -al /usr/local/ceph/etc/
#2-创建ceph的mds容器
docker run -d \
--net=host \
--name=ceph-mds \
--restart=always \
--privileged=true \
-v /etc/localtime:/etc/localtime \
-v /usr/local/ceph/etc:/etc/ceph \
-v /usr/local/ceph/lib:/var/lib/ceph \
-v /usr/local/ceph/logs:/var/log/ceph \
-e CEPHFS_CREATE=0 \
quay.io/ceph/ceph:v20.2.2 \
ceph-mds -f --cluster ceph -i ceph01
#3-查看mds容器
docker ps -a
docker logs -f ceph-mds
#查看ceph-mds容器的实际日志信息【需要查看包含mds.1.34 recovery_done -- successful recovery!字符串则表示成功】
tail -n 50 -f /usr/local/ceph/logs/ceph-mds.ceph01.log
#4-创建两个存储池(元数据池 + 数据池)【只用在ceph01上执行一次就行,其他节点不用执行】
docker exec -it ceph-mon-ceph01 sh -c "
## 清理旧池绑定(需要时才启用)
#ceph osd pool application disable cephfs_data cephfs --yes-i-really-mean-it
#ceph osd pool application disable cephfs_metadata cephfs --yes-i-really-mean-it
# 不存在才创建元数据池与数据池
ceph osd pool ls | grep -q cephfs_metadata || ceph osd pool create cephfs_metadata 512
ceph osd pool ls | grep -q cephfs_data || ceph osd pool create cephfs_data 512
# 新版本CephFS要求数据池开启bulk标记
ceph osd pool set cephfs_data bulk true
# 不存在才创建文件系统
ceph fs ls | grep -q cephfs || ceph fs new cephfs cephfs_metadata cephfs_data
# 设置2个活跃MDS(2个干活一个备用)
ceph fs set cephfs max_mds 2
"
#5-健康检查
ceph fs ls
ceph mds stat
ceph fs status
ceph -s





pool 标记应用类型(常见三种):
- 块设备:
rbd - 文件存储:
cephfs - 对象存储:
rgw
bash
#设置池为制定的类型
#1-先查看所有的池
ceph osd pool ls
#2-给这里的cephfs_metadata、cephfs_data标记为cephfs
#.mgr 是 Ceph 自带管理池,一般不用手动添加标记
ceph osd pool application enable cephfs_metadata cephfs
ceph osd pool application enable cephfs_data cephfs
#3-查看所有池的标记信息
ceph osd pool ls detail

2.8、开启ceph的dashboard管理面板
bash
#开启ceph的dashboard管理面板【找到mgr主节点后的命令都在主节点宿主机操作】
#0-需要确定ceph集群的主节点(通过【ceph -s】命令查看集群状态,找到mgr后为active的节点)
#如:【mgr: ceph02(active, since 113s), standbys: ceph01, ceph03】表示ceph02为主节点
ceph -s
#1-在mgr的主节点(ceph02)正式开启dashboard功能并设置【之后就可以在浏览器:ceph02对应的ip是192.168.1.67【https://192.168.1.67:8443】访问】
docker exec ceph-mgr sh -c '
# 1. 启用dashboard模块
ceph mgr module enable dashboard;
# 2. 生成自签名SSL证书(默认HTTPS 8443)
ceph dashboard create-self-signed-cert;
# 3. 监听0.0.0.0允许外部访问
ceph config set mgr mgr/dashboard/server_addr 0.0.0.0;
# 4. 创建admin管理员,administrator超级角色,管道传密码不落地文件
echo "qwer1234" | ceph dashboard ac-user-create admin -i /dev/stdin administrator;
# 5. 查看dashboard服务地址
ceph mgr services;
# 6. 查看创建的用户
ceph dashboard ac-user-show admin
'
#2-生产环境替换为 CA 签发证书
#2.1-上传crt/key到容器后执行
ceph dashboard set-ssl-certificate -i /tmp/dashboard.crt
ceph dashboard set-ssl-certificate-key -i /tmp/dashboard.key
#3-内网测试关闭 SSL(HTTP 访问,不推荐生产)
#3.1-如需用http://IP:8080访问,追加关闭 SSL 配置
docker exec ceph-mgr ceph config set mgr mgr/dashboard/ssl false
# 自定义端口(可选)
docker exec ceph-mgr ceph config set mgr mgr/dashboard/server_port 8080
# 重启mgr容器生效
docker restart ceph-mgr





到这里恭喜你,基于Docker部署Ceph的分布式存储完全部署成功了!
三、使用cephadm一键式部署ceph分布式存储【官方推荐】
注意:cephadm 默认使用 podman,如何永久固定 docker【即每次 bootstrap 必须加 --container-engine docker】;
若集群已创建,修改 orch 全局配置:
bash
#cephadm操作的ceph集群永久固定 docker
ceph config set mgr mgr/cephadm/container_image_base quay.io/ceph/ceph
ceph config set mgr mgr/cephadm/container_engine docker
# 重启mgr生效
ceph orch daemon restart mgr
bash
#Docker 权限不足报错
# 将root加入docker组(默认root已有权限,普通用户需加)
usermod -aG docker root
newgrp docker
bash
#AlmaLinux9 containerd 与 docker 冲突
#不要同时启用 podman.socket,关闭 podman 避免端口占用
systemctl stop podman
systemctl disable podman
3.1、初始化ceph集群
bash
#直接使用cephadm在宿主机上初始化ceph集群(生成主节点192.168.1.66的配置与各种密钥)
curl -o cephadm https://download.ceph.com/rpm-20.2.2/el9/noarch/cephadm
chmod +x cephadm
# 安装依赖、cephadm 工具
./cephadm add-repo --release quincy
./cephadm install
# 初始化ceph主节点
./cephadm bootstrap --mon-ip 192.168.1.66 --container-engine docker --allow-fqdn-hostname
#命令执行完成后【/etc/ceph】目录下存在【ceph.conf、ceph.client.admin.keyring】文件
cp -p /etc/ceph/ceph.conf /etc/ceph/ceph.client.admin.keyring /usr/local/ceph/etc
#命令执行完成后【/var/lib/ceph/fa9625dc-7428-11f1-87ee-000c299ebdac/mon.ceph01】目录下的【keyring】文件
cp -p /var/lib/ceph/fa9625dc-7428-11f1-87ee-000c299ebdac/mon.ceph01/keyring /usr/local/ceph/etc
3.2、添加其他节点到集群中
bash
#添加其余节点到集群(ceph01 执行)
ceph orch host add ceph02 192.168.1.67 --allow-fqdn-hostname
ceph orch host add ceph03 192.168.1.68 --allow-fqdn-hostname
#2-查看主机列表
ceph orch host ls
3.3、部署集群服务(MON、MGR、OSD)
bash
#部署集群服务(MON、MGR、OSD)
#1-扩展 MON 服务到 3 个节点
# 自动部署mon到所有节点【集群 MON 总数建议奇数:1/3/5 个,保证仲裁机制;单节点测试可用 1 个,生产最少 3 个分布不同服务器。】
#还可手动指定安装的ceph镜像(仅特殊临时场景使用)【如:ceph orch daemon add mon ceph01 --image quay.io/ceph/ceph:v20.2.2】
ceph orch daemon add mon ceph01
ceph orch daemon add mon ceph02
ceph orch daemon add mon ceph03
# 查看mon状态
ceph mon stat
#2-部署双 MGR 高可用
ceph orch daemon add mgr ceph01
ceph orch daemon add mgr ceph02
ceph orch daemon add mgr ceph03
# 查看mgr状态
ceph mgr stat
#3-部署 OSD(裸盘方式,推荐)
#自动发现磁盘批量创建 OSD
# 告知orch使用所有未挂载裸盘
ceph orch device ls
ceph orch daemon add osd host:disk
# 示例单节点两块盘
ceph orch daemon add osd ceph01:/dev/sdb
ceph orch daemon add osd ceph01:/dev/sdc
ceph orch daemon add osd ceph02:/dev/sdb
ceph orch daemon add osd ceph02:/dev/sdc
ceph orch daemon add osd ceph03:/dev/sdb
ceph orch daemon add osd ceph03:/dev/sdc
#4-进入指定容器命令
#4.1-ceph orch 封装方式(推荐)
ceph orch daemon shell mon.ceph01
#4.2-原生docker方式
docker exec -it ceph-xxxx-mon.ceph01 bash
#5- 重启 / 删除服务
ceph orch daemon restart mon.ceph01
ceph orch daemon rm osd.0
#6-指定镜像版本重装服务【仅特殊的临时场景使用】
ceph orch daemon redeploy mon.ceph01 --image quay.io/ceph/ceph:v20.2.2
3.4、查看集群的整体状态与常用运维命令
bash
#1-查看集群的整体状态
#1.1-集群健康状态
ceph -s
#1.2-所有容器服务
ceph orch ps
#1.3-磁盘与OSD
ceph osd tree
#1.4-docker查看ceph容器
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}"
#2-常用运维命令
#2.1-查看所有 Ceph 容器(docker)
docker ps | grep ceph
#2.2-进入指定服务容器(如 mon)
#2.2.1-ceph orch 封装方式(推荐)
ceph orch daemon shell mon.ceph01
#2.2.2-原生docker方式
docker exec -it ceph-xxxx-mon.ceph01 bash
#2.3-重启 / 删除服务
ceph orch daemon restart mon.ceph01
ceph orch daemon rm osd.0
#2.4-指定镜像版本重装服务
ceph orch daemon redeploy mon.ceph01 --image quay.io/ceph/ceph:v20.2.2
3.5、启用 Dashboard 可视化(可选)
bash
#启用 Dashboard 可视化(可选)
# 开启dashboard模块
ceph mgr module enable dashboard
# 绑定0.0.0.0允许外部访问
ceph dashboard set-server-url https://0.0.0.0:8443
# 创建自签名证书
ceph dashboard create-self-signed-cert
3.6、部署 MDS 服务并启用 CephFS
块存储是【RBD】;文件存储是【CephFS】。
bash
#部署 MDS 服务并启用 CephFS 文件存储
ceph orch daemon add mds ceph01
ceph fs volume create cephfs
##若想使用 RBD 块存储池则进行如下操作:
#ceph osd pool create rbdpool 128
#rbd pool init rbdpool
3.7、部署RGW 服务
bash
#部署RGW服务
#1-站点统一为 default(也可自定义站点,如区分机房:ceph01.shanghai、ceph02.beijing),多节点扩容【三台节点均运行 RGW 容器,前端可搭配 Nginx/HAProxy 做 7 层负载均衡】
ceph orch daemon add rgw ceph01.default
ceph orch daemon add rgw ceph02.default
ceph orch daemon add rgw ceph03.default
#2-创建 S3 访问用户
#2.1-创建 rgw 用户
# 格式:radosgw-admin user create --uid=用户名 --display-name="展示名"
radosgw-admin user create \
--uid=coffeemilk \
--display-name="S3 Test User"
#2.2-查看指定用户的 access_key /secret_key
radosgw-admin user info --uid=coffeemilk
#2.3-给用户配置读写权限
radosgw-admin caps add --uid=coffeemilk --caps="users=*;buckets=*"
#3-常用的RGW运维命令
#3.1-查看所有 RGW 实例
ceph orch ps --service rgw
#3.2-重启 / 重部署 RGW 容器(Docker 重建)
# 重启单个实例
ceph orch daemon restart rgw.ceph01.default
# 重新拉镜像重建容器
ceph orch daemon redeploy rgw.ceph01.default
#3.3-删除 RGW 实例
ceph orch daemon rm rgw.ceph03.default
#3.4-进入 RGW 容器调试(Docker exec)
#3.4.1-cephadm封装(推荐)
ceph orch daemon shell rgw.ceph01.default
#3.4.2-原生docker方式
docker exec -it $(docker ps --filter name=rgw.ceph01.default -q) bash
#3.5-查看 RGW 日志
# 实时日志
ceph orch daemon logs -f rgw.ceph01.default
# docker原生日志
docker logs -f $(docker ps --filter name=rgw.ceph01.default -q)
#4-自定义 RGW 配置(修改监听端口、HTTPS、缓存等)
#4.1-修改 RGW 监听端口为 8080
ceph config set rgw default rgw_frontends "beast port=8080"
ceph orch daemon restart rgw.*.default
#4.2-开启 HTTPS(443 端口)
# 上传证书到集群配置库
ceph orch cert import rgw /root/rgw.crt /root/rgw.key
# 修改前端配置启用ssl
ceph config set rgw default rgw_frontends "beast ssl_port=443 ssl_certificate=/etc/ceph/rgw.crt ssl_private_key=/etc/ceph/rgw.key"
ceph orch daemon restart rgw.*.default
3.8、彻底销毁现有ceph分布式存储集群【慎用】
bash
#集群的销毁重装【慎用】
#1-主节点 ceph01 执行,强制销毁集群编排元数据
#1.1-查看当前集群FSID,替换下方命令中的ID
ceph fsid
#1.2-强制删除集群(仅主节点执行)
./cephadm rm-cluster --force --fsid fa9625dc-7428-11f1-87ee-000c299ebdac
#2-三台节点(ceph01、ceph02、ceph03)全部执行全套清理脚本
#2.1-停止删除所有ceph容器
docker rm -f $(docker ps -a | grep ceph | awk '{print $1}')
#2.2-清理ceph容器镜像(可选,需要纯净环境执行)
docker rmi $(docker images | grep ceph | awk '{print $3}')
#2.3-清空集群持久化数据、mon/mgr/osd密钥目录
rm -rf /var/lib/ceph
#2.4-删除客户端配置、admin密钥(重装不删会bootstrap冲突)
rm -rf /etc/ceph
#2.5-删除自定义备份配置目录(你之前备份用的)
rm -rf /usr/local/ceph
#2.6- 6. 清理cephadm本地缓存(可选)
rm -rf /var/lib/cephadm