Ceph 是一款开源的分布式存储系统,具备高可用性、高扩展性与高性能等核心优势。它能统一提供块存储(RBD)、文件存储(CephFS)和对象存储(RGW)服务,广泛应用于云计算、大数据分析、企业级存储等场景。部署 Ceph 的核心目标是构建一个稳定、可灵活扩展的集群环境。
其核心特点包括:统一存储、高度可靠、高度可扩展、高性能、无单点故障以及自我修复和自我管理能力。
核心组件解析
无论您是想在云平台中使用 Ceph 对象存储或块设备服务,还是部署 Ceph 文件系统,所有 Ceph 存储集群的部署都始于 Ceph 节点配置、网络规划以及集群初始化。
一个 Ceph 存储集群至少需要以下组件:
- Ceph Monitor
- Ceph Manager
- Ceph OSD(对象存储守护进程)
若使用 Ceph 文件系统(CephFS),则还需要 Ceph 元数据服务器(MDS)。
各个组件的详细功能说明如下:
| 组件 |
说明 |
| Monitor(监视器) |
维护集群状态映射(包含 Monitor、Manager、OSD、MDS 拓扑及 CRUSH 算法配置等),相当于集群的“全局地图”;负责守护进程与客户端的身份合法性校验。基于 Paxos 协议实现多节点共识同步。生产环境通常至少部署 3 个节点实现高可用。 |
| Manager(管理器) |
实时跟踪集群运行时指标与状态,涵盖存储利用率、性能负载、PG 健康状态等;提供 Web 可视化仪表板和 REST API。基于 Raft 协议完成多节点状态同步,通常至少部署 2 个节点。 |
| OSD(对象存储守护进程) |
集群的核心数据存储单元,每个 OSD 对应主机上的一块物理/逻辑磁盘;负责用户数据的写入、读取,同时处理数据副本复制、故障数据恢复、数据再平衡等核心任务。 |
| MDS(元数据服务器) |
专用于 Ceph 文件系统(CephFS)的组件,负责存储文件系统的元数据(包括文件名、目录结构、文件权限等);将元数据与实际数据分离存储,提升 CephFS 响应效率。仅在部署 CephFS 时需要。 |
| PG(Placement Groups,放置组) |
连接用户数据与 OSD 的逻辑中间层;一个 PG 会映射到一组 OSD(主 OSD + 副本 OSD),同一 PG 内的所有用户对象均存储在对应 OSD 组中。引入 PG 可大幅简化“对象-OSD”的映射复杂度。 |
数据存储流程与原理
Ceph 将数据作为对象存储在逻辑存储池中,主要包括两个映射步骤:
- 对象 → PG:通过哈希算法计算对象应归属的 PG。
- PG → OSD:通过 CRUSH 算法决定该 PG 应存储在哪几个 OSD 上。CRUSH 算法支持集群动态扩展、再平衡与恢复。
Ceph 存储集群接收来自客户端的数据,数据最终以 RADOS 对象形式存储,每个对象位于一个 OSD 上。Ceph OSD 守护进程负责在存储驱动器上执行读写和复制操作。
Ceph OSD 将数据以对象形式存储在平面命名空间中,每个对象包含:
- 标识符:在内存中唯一标识对象
- 二进制数据:对象的实际内容
- 属性数据:由键值对组成的元数据,语义由 Ceph 客户端决定
其底层存储机制主要有两种:
- Filestore:每个 RADOS 对象作为单独文件存储在传统文件系统(通常为 XFS)上。由于文件系统元数据区仅能存储基础信息,Ceph 会将额外元数据存入单独的数据库中。这种方式因对象需转为文件形式存储,在元数据读写效率上存在开销。
- BlueStore:在新版 Ceph 中,每个
ceph-osd 守护进程内部维护一个 RocksDB 数据库(基于 Ceph 自研的 BlueFS 文件系统运行),用于存储对象的元数据。BlueStore 直接管理裸设备,避免了文件系统层的开销,显著提升了读写性能与元数据管理效率,这是当前 Ceph 默认的存储后端。
单节点 Ceph 集群部署实战
以下为 Ceph 集群部署的关键步骤摘要,具体细节请参考官方文档 docs.ceph.com/en/latest/install/。
环境概述
本次部署采用单节点 Ceph 集群架构,将 Ceph 所有核心组件集中部署于单一节点上,旨在快速搭建学习环境,重点掌握 Ceph 与 Kubernetes 的存储对接流程。此配置适用于学习验证、功能测试及开发调试场景。该架构不具备高可用与容灾能力,不可用于生产环境。
环境规划如下:
| 主机名 |
角色 |
IP地址 |
| ceph.local |
Ceph 单节点集群(所有组件) |
10.1.1.22 |
| K8s-master |
Kubernetes Master 节点 (v1.27.x) |
10.1.1.100 |
| K8s-node1 |
Kubernetes Node 节点 |
10.1.1.120 |
| K8s-node2 |
Kubernetes Node 节点 |
10.1.1.130 |
在 ceph.local 上准备三块独立磁盘(例如 /dev/sdb, /dev/sdc, /dev/sdd)用于 OSD 存储。
安装与引导集群
-
安装 cephadm 部署工具。
- CentOS/RHEL 系统:
CEPH_RELEASE=18.2.0
curl --silent --remote-name --location https://download.ceph.com/rpm-${CEPH_RELEASE}/el9/noarch/cephadm
chmod +x cephadm
mv cephadm /usr/local/bin
- Debian/Ubuntu 系统:
wget -q -O- ‘https://download.ceph.com/keys/release.asc’ | gpg -o /etc/apt/keyrings/ceph.gpg --dearmor
apt-add-repository ‘deb [signed-by=/etc/apt/keyrings/ceph.gpg] https://mirrors.tuna.tsinghua.edu.cn/ceph/debian-octopus/ buster main’
apt update
apt install cephadm
-
引导初始化 Ceph 集群。
cephadm bootstrap \
--mon-ip 10.1.1.22 \
--log-to-file \
--single-host-defaults \
--allow-fqdn-hostname \
--initial-dashboard-user “admin” \
--initial-dashboard-password “admin123” \
--allow-overwrite \
--dashboard-password-noupdate \
--skip-dashboard-plugins
-
添加软件仓库并安装 ceph-common 客户端工具。
cephadm add-repo --release Squid
yum install -y ceph-common
-
将准备好的磁盘添加为 OSD。
ceph orch daemon add osd ceph.local:/dev/sdb
ceph orch daemon add osd ceph.local:/dev/sdc
ceph orch daemon add osd ceph.local:/dev/sdd
使用 ceph -s 和 ceph orch ps --daemon_type osd 命令查看集群及 OSD 状态。
创建 CephFS 文件系统
为 Kubernetes 存储准备 CephFS 文件系统及必要的子卷组。
# 创建元数据池和数据池
ceph osd pool create metadata_for_k8s
ceph osd pool create data_for_k8s
# 新建 CephFS 文件系统
ceph fs new k8s metadata_for_k8s data_for_k8s
# 部署 2 个 MDS 守护进程
ceph orch apply mds k8s --placement 2
# 创建 CephFS 的子卷组 ‘csi’,ceph-csi 驱动要求使用此名称存放 K8s PVC 对应的子卷
ceph fs subvolumegroup create k8s csi
Ceph 用户管理与权限配置
Ceph 集群管理员可直接在集群内完成用户的创建、更新与删除操作。用户标识格式为 TYPE.ID,例如 client.admin。
核心管理命令
| 命令 |
用途 |
特点 |
ceph auth add |
创建用户并设置权限 |
生成密钥并添加指定 caps |
ceph auth get-or-create |
创建用户或获取现有用户信息 |
返回密钥文件格式的密钥信息 |
ceph auth get-or-create-key |
创建用户或获取现有用户密钥 |
仅返回密钥字符串 |
ceph auth caps |
修改用户权限 |
会覆盖现有 caps |
ceph auth del |
删除用户 |
彻底移除用户 |
ceph auth import |
导入用户 |
从备份文件恢复用户 |
权限配置要点:
- 典型用户至少需要对 Ceph Monitor 具有
allow r (读取) 权限。
- 对 Ceph OSD 通常需要
allow rw (读写) 权限。
- 重要:OSD 权限应通过
pool=<pool_name> 语法限制在特定存储池,否则用户将获得集群中所有存储池的访问权。
用户管理实践示例
-
添加用户:创建普通用户 client.testuser,并配置其对 data_for_k8s 存储池的读写权限。
ceph auth add client.testuser mon ‘allow r’ osd ‘allow rw pool=data_for_k8s’
-
查看用户信息与密钥。
ceph auth get client.testuser
ceph auth print-key client.testuser
-
修改用户权限:为用户增加 MDS 读写权限和 MGR 读权限,并扩展 OSD 权限到另一个存储池。
ceph auth caps client.testuser mon ‘allow r’ mgr ‘allow r’ osd ‘allow rw pool=data_for_k8s, allow rw pool=metadata_for_k8s’ mds ‘allow rw’
-
导出与导入用户(用于备份/迁移)。
# 导出到文件
ceph auth export client.testuser > testuser.file
# 从文件导入
ceph auth import -i testuser.file
-
使用 get-or-create:此命令适用于“不确定用户是否存在”的自动化场景,若用户已存在则返回信息,若不存在则创建。
ceph auth get-or-create client.testuser3 mon ‘allow r’ osd ‘allow rw pool=data_for_k8s’
Kubernetes 集成:部署 CephFS CSI 驱动
在 Kubernetes Master 节点执行以下操作,部署 Ceph CSI 插件以对接 CephFS 存储。
1. 准备资源清单
克隆 ceph-csi 仓库并准备配置目录。
git clone -b release-v3.11 --depth 1 https://github.com/ceph/ceph-csi.git
cd ceph-csi
mkdir /root/cephfs
kubectl create ns cephfs
2. 编辑关键配置文件
A. Secret (secret.yaml)
存储用于连接 Ceph 集群的用户认证信息。需要填入之前创建的 client.testuser 和 client.admin 的密钥。
apiVersion: v1
kind: Secret
metadata:
name: csi-cephfs-secret
namespace: cephfs
stringData:
# 用于静态供应卷
userID: testuser
userKey: AQB4dWNpxEhiIhAAE1cDs94V3Z9oGKbsTcbPyg==
# 用于动态供应卷
adminID: admin
adminKey: AQBUvWBpqRupOBAA/DXPwFQMD7EXf1WXqP1+dA==
# 加密口令
encryptionPassphrase: test_passphrase
B. ConfigMap (csi-config-map.yaml)
Ceph CSI 插件的核心连接配置,是 Kubernetes 与 Ceph 集群之间的“通信配置桥梁”。
apiVersion: v1
kind: ConfigMap
metadata:
name: “ceph-csi-config”
data:
config.json: |-
[
{
“clusterID”: “eb9728e2-ec47-11f0-aac5-000c29b88afc”, # 通过 `ceph -s` 获取
“monitors”: [
“10.1.1.22:6789” # Ceph Monitor 地址,单节点集群只有一个
],
“cephFS”: {
“subvolumeGroup”: “csi”, # 指定使用名为 ‘csi’ 的子卷组
“kernelMountOptions”: “”,
“netNamespaceFilePath”: “”,
“fuseMountOptions”: “”
},
“readAffinity”: {
“enabled”: false,
“crushLocationLabels”: []
}
}
]
C. Ceph 客户端配置 (ceph-conf.yaml)
提供 Ceph 集群的基础认证规则。
apiVersion: v1
kind: ConfigMap
metadata:
name: ceph-config
data:
ceph.conf: |
[global]
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx
keyring: |
---
apiVersion: v1
kind: ConfigMap
metadata:
name: ceph-csi-encryption-kms-config
data:
config.json: |- {}
D. StorageClass (storageclass.yaml)
定义动态供应 CephFS 存储卷的模板。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-cephfs-sc
provisioner: cephfs.csi.ceph.com
parameters:
clusterID: eb9728e2-ec47-11f0-aac5-000c29b88afc
fsName: k8s # CephFS 文件系统名称
pool: data_for_k8s # 数据存储池
csi.storage.k8s.io/provisioner-secret-name: csi-cephfs-secret
csi.storage.k8s.io/provisioner-secret-namespace: cephfs
csi.storage.k8s.io/controller-expand-secret-name: csi-cephfs-secret
csi.storage.k8s.io/controller-expand-secret-namespace: cephfs
csi.storage.k8s.io/node-stage-secret-name: csi-cephfs-secret
csi.storage.k8s.io/node-stage-secret-namespace: cephfs
reclaimPolicy: Delete
allowVolumeExpansion: true
3. 部署 CSI 驱动组件
复制并应用 RBAC、插件及驱动配置。
cp deploy/cephfs/kubernetes/csi-* /root/cephfs/
cp deploy/cephfs/kubernetes/csidriver.yaml /root/cephfs/
cd /root/cephfs/
# 统一修改命名空间为 cephfs
sed -i “s/namespace: default/namespace: cephfs/g” *
# 应用所有配置
kubectl apply -f csi-provisioner-rbac.yaml
kubectl apply -f csi-nodeplugin-rbac.yaml
kubectl apply -f csi-cephfsplugin-provisioner.yaml -n cephfs
kubectl apply -f csi-cephfsplugin.yaml -n cephfs
kubectl apply -f csidriver.yaml -n cephfs
kubectl apply -f csi-config-map.yaml -n cephfs
kubectl apply -f ceph-conf.yaml -n cephfs
kubectl apply -f secret.yaml -n cephfs
kubectl apply -f storageclass.yaml
部署后验证相关资源状态:
kubectl get pods -n cephfs
kubectl get csidrivers.storage.k8s.io
kubectl get storageclass
功能验证:创建并使用 CephFS 持久化存储
1. 创建 PersistentVolumeClaim (PVC)
创建 PVC 声明存储需求,它将由 csi-cephfs-sc 这个 StorageClass 动态供应。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-cephfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: csi-cephfs-sc
应用并查看 PVC 状态,应显示 Bound。
kubectl apply -f pvc.yaml
kubectl get pvc csi-cephfs-pvc
2. 创建 Pod 挂载 PVC
创建一个 Nginx Pod,将上一步创建的 PVC 挂载到容器内的目录。
apiVersion: v1
kind: Pod
metadata:
name: csi-cephfs-demo-pod
spec:
containers:
- name: web-server
image: docker.io/library/nginx:latest
volumeMounts:
- name: mypvc
mountPath: /usr/share/nginx/html
volumes:
- name: mypvc
persistentVolumeClaim:
claimName: csi-cephfs-pvc
readOnly: false
应用 Pod 配置。
3. 测试数据持久化
- 进入 Pod 向挂载卷写入数据。
kubectl exec -it csi-cephfs-demo-pod -- bash
echo $HOSTNAME > /usr/share/nginx/html/index.html
exit
- 获取 Pod IP 并访问服务,应能返回刚刚写入的主机名。
kubectl get pod csi-cephfs-demo-pod -o wide
curl <Pod_IP>
- 在运行该 Pod 的 Kubernetes Node 节点上,可以查看到 CephFS 的实际挂载信息,证明存储卷已成功通过 CSI 驱动挂载。
mount | grep ceph
至此,我们完成了从 Ceph 单节点集群部署、用户权限管理,到与 Kubernetes 通过 CSI 接口集成,并最终实现动态供应和挂载 CephFS 持久化存储卷的全流程实战。这套方案为在 云原生 环境中使用开源分布式存储提供了可靠参考。对于生产环境,需将 Ceph 部署为多节点集群以确保高可用性。
参考资料
[1] Kubernetes 运维 - 基于 Ceph 的持久化存储方案实战(CSI 集成篇), 微信公众号:mp.weixin.qq.com/s/RwM42WK4jRzeTrq13DnEsg
版权声明:本文由 云栈社区 整理发布,版权归原作者所有。