Kubernetes运维 - Ceph分布式存储CSI对接实战指南

Ceph简介

Ceph是一款开源的分布式存储系统,具备高可用性、高扩展性与高性能等核心优势。它能统一提供块存储、文件存储和对象存储服务,广泛应用于云计算、大数据分析、企业级存储等场景。部署Ceph的核心目标是构建一个稳定、可灵活扩展的集群环境。

软件特点:

ceph特点

基本结构

基本结构

Ceph是一种多版本存储系统,它会将每个待管理的数据流(如一个文件)切分为一个或多个固定大小的对象(Object),并以对象为原子单位进行数据存取。
对象的底层存储服务由多个主机组成的存储集群提供,该集群被称为 RADOS(Reliable Automatic Distributed Object Store),即可靠、自动化、分布式对象存储系统。
librados 是RADOS存储集群提供的API库,支持C、C++、Java、Python、Ruby和PHP等多种编程语言。

应用场景

应用场景


组件解析

无论您是想在云平台中使用Ceph对象存储或块设备服务,还是部署Ceph文件系统,所有Ceph存储集群的部署都始于Ceph节点配置、网络规划以及集群初始化。

一个Ceph存储集群至少需要以下组件:

  • Ceph Monitor
  • Ceph Manager
  • Ceph OSD(对象存储守护进程)
    若使用Ceph文件系统,则还需要 Ceph 元数据服务器(MDS)

组件说明
Monitor(监视器)维护集群状态映射(包含Monitor、Manager、OSD、MDS拓扑及CRUSH算法配置等),相当于集群的“全局地图”;负责守护进程与客户端的身份合法性校验,防止未授权访问。基于Paxos协议实现多节点共识同步,确保集群状态一致。生产环境通常至少部署3个节点实现高可用,支持容忍1个节点故障。
Manager(管理器)实时跟踪集群运行时指标与状态,涵盖存储利用率、IOPS/吞吐量、节点CPU/内存负载、PG健康状态等;提供Web可视化仪表板和REST API,支持运维人员图形化管控及自动化运维集成。基于轻量级Raft协议完成多节点状态同步,通常至少部署2个节点实现高可用,故障时备用节点可无缝接管。
OSD(对象存储守护进程)集群的核心数据存储单元,每个OSD对应主机上的一块物理/逻辑磁盘;负责用户数据的写入、读取,同时处理数据副本复制、故障数据恢复、集群扩容/缩容时的数据再平衡等核心任务;定期向Monitor和Manager上报自身健康状态(如磁盘使用率、IO延迟、故障标识)。生产环境至少部署3个节点实现数据冗余,支持容忍1个节点故障不丢失数据。
MDS(元数据服务器)专用于Ceph文件系统(CephFS)的组件,负责存储文件系统的元数据(包括文件名、目录结构、文件权限、修改时间等);将元数据与实际数据分离存储,使lsfind等POSIX文件系统操作直接调用元数据,避免对OSD存储集群造成额外负担,大幅提升CephFS响应效率。仅在部署CephFS时需要配置,对象存储(RGW)、块设备(RBD)场景无需部署。
PG(Placement Groups,放置组)连接用户数据与OSD的逻辑中间层,无实体进程;一个PG会映射到一组OSD(主OSD+副本OSD),同一PG内的所有用户对象均存储在对应OSD组中。引入PG可大幅简化“对象-OSD”的映射复杂度,配合CRUSH算法实现数据均匀分布与快速定位;数据写入时,会先写入主OSD,再同步至副本OSD完成冗余。规划时建议每OSD对应100-200个PG,平衡集群性能与管理开销。

流程解读

综合效果图

Ceph将数据作为对象存储在逻辑存储池中,主要包括两个映射步骤:

  1. 对象 → PG
    通过哈希算法计算对象应归属的PG。

  2. PG → OSD
    通过CRUSH算法决定该PG应存储在哪几个OSD上。CRUSH算法支持集群动态扩展、再平衡与恢复。

数据存储逻辑


存储原理

存储过程说明

Ceph存储集群接收来自客户端的数据(无论通过块设备、对象存储、文件系统还是自定义librados实现),数据最终以RADOS对象形式存储,每个对象位于一个OSD上。
Ceph OSD守护进程负责在存储驱动器上执行读写和复制操作,其底层存储机制主要有两种:

  • Filestore方式:每个RADOS对象作为单独文件存储在传统文件系统(通常为XFS)上。
  • BlueStore方式:对象以类似数据库的整体方式存储,这是新版Ceph的默认存储方式。

注意:在Ceph中,每个文件都会被拆分为多个独立的object,再按上述逻辑持久化存储。

Ceph OSD守护进程将“数据”以对象形式存储在平面命名空间中,每个对象包含:

  • 标识符:在内存中唯一标识对象
  • 二进制数据:对象的实际内容
  • 属性数据:由键值对组成的元数据,语义由Ceph客户端决定(例如CephFS用其存储文件所有者、创建时间等属性)

注意:对象ID在整个集群内唯一,不限于本地文件系统。

例如,存储一个16MB文件时,会先将其切分为多个4MB的object,通过哈希映射到对应PG,再经由CRUSH策略分布到不同主机的OSD上。
此时面临一个问题:OSD作为磁盘设备,应如何存储数据?

常见存储实现方式

  1. Filestore
    将OSD格式化为文件系统(如XFS)并挂载到目录使用。此时每个object成为文件系统中的一个文件(或目录),OSD需维护object的属性信息。
    由于文件系统元数据区仅能存储属主、权限等基本信息,Ceph会将额外元数据存入单独数据库(如LevelDB)中。

这种方式称为Filestore,因object需转为文件形式存储,在元数据读写效率上存在一定开销。

  1. BlueStore
    在新版Ceph中,每个ceph-osd守护进程内部维护一个RocksDB数据库,用于存储object的元数据。RocksDB基于Ceph自研的BlueFS文件系统运行。
    RocksDB + BlueFS 共同构成BlueStore存储机制,这也是当前Ceph默认的存储后端。

BlueStore直接管理裸设备,避免了文件系统层的开销,显著提升了读写性能与元数据管理效率。


集群部署

以下为Ceph集群部署的关键步骤摘要,具体细节请参考官方文档或完整部署指南。

https://docs.ceph.com/en/latest/install/

环境概述

本次部署采用单节点Ceph集群架构,将Ceph所有核心组件集中部署于单一节点上,旨在快速搭建学习环境,重点掌握Ceph与Kubernetes的存储对接流程。此配置适用于学习验证、功能测试及开发调试场景,能够以最小资源开销实现全流程实践。请注意:该架构不具备高可用与容灾能力,不可用于生产环境;生产部署需采用多节点集群,以确保服务的可靠性与数据的安全性。

主机名角色IP地址
ceph.localCeph单节点集群(所有组件)使用centos-910.1.1.22
K8s-masterK8s Master 节点 k8s 版本v1.27.x10.1.1.100
K8s-node1K8s Node 节点10.1.1.120
K8s-node2K8s Node 节点10.1.1.130

ceph.local上准备三块盘

安装cephadm工具

根据不同操作系统选择安装方式,如CentOS使用curl下载,Debian/Ubuntu通过apt安装。

安装cephadm工具

CentOS/RHEL

1
2
3
4
5
6
7
# 下载cephadm
CEPH_RELEASE=18.2.0 # replace this with the active release
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

1
2
3
4
5
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

引导初始化集群

1
2
3
4
5
6
7
8
9
10
cephadm bootstrap \
--mon-ip 10.1.1.22 \ # Monitor节点IP
--log-to-file \ # 日志输出到文件
--single-host-defaults \ # 单主机环境默认配置
--allow-fqdn-hostname \ # 允许使用FQDN作为主机名
--initial-dashboard-user "admin" \ # dashboard管理员账号
--initial-dashboard-password "admin123" \ # dashboard密码
--allow-overwrite \ # 覆盖已存在的集群配置(若有)
--dashboard-password-noupdate \ # 避免密码被自动重置
--skip-dashboard-plugins # 跳过Grafana/Prometheus等插件部署

添加 Ceph(Squid 版本)仓库并安装ceph-common

1
2
3
4
# 添加Reef版本仓库
cephadm add-repo --release Squid
# 安装ceph-common(提供ceph命令行工具)
yum install -y ceph-common

查看 Ceph 集群状态(后续操作示例)

1
2
3
4
# 查看集群健康状态
ceph status
# 查看集群组件状态
ceph orch status

添加OSD

1
2
3
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

查看OSD

1
ceph orch ps --daemon_type osd

查看集群状态

1
ceph -s

创建cephfs文件系统(用于k8s存储)

1
2
3
4
5
6
7
8
9
10
# 创建元数据池和数据池
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 的子卷组
ceph fs subvolumegroup create k8s csi
ceph fs subvolumegroup ls k8s

ceph-csi 驱动默认要求使用csi子卷组来存放 K8s PVC 对应的 CephFS 子卷,如果这个子卷组不存在,就会报 “subvolume group ‘csi’ does not exist” 错误,导致 PVC 创建失败。

用户管理

Ceph集群管理员可直接在集群内完成用户的创建、更新与删除操作。需注意:创建用户时,可能需要将生成的密钥分发至客户端,并添加到客户端的密钥环中,确保客户端能正常接入集群。

核心命令

  • 列出集群所有用户:命令为 ceph auth list

    • 用户标识格式: TYPE.ID
      例如:osd.0 表示 OSD 类型的用户,其 ID 为 0;client.admin 表示客户端类型的 admin 用户。
  • 检索特定用户信息:可通过 ceph auth get TYPE.IDceph auth export TYPE.ID 命令实现,前者直接输出用户详情,后者可导出用户密钥信息。

  • 列出特定用户密钥:命令为 ceph auth print-key TYPE.ID,仅输出目标用户的密钥字符串,适用于快速获取密钥的场景。

用户管理实践

常用命令解析

命令用途特点
ceph auth add创建用户并设置权限生成密钥并添加指定 caps
ceph auth get-or-create创建用户或获取现有用户信息返回密钥文件格式的密钥信息
ceph auth get-or-create-key创建用户或获取现有用户密钥仅返回密钥字符串
ceph auth import导入用户从备份文件恢复用户
ceph auth caps修改用户权限会覆盖现有 caps
ceph auth del删除用户彻底移除用户

权限配置要点:

  • 典型用户至少需要对 Ceph Monitor 具有读取权限
  • 对 Ceph OSD 通常需要读写权限
  • 重要:OSD 权限应限制在特定存储池,否则用户将获得集群中所有存储池的访问权

修改权限时的注意事项:
使用 ceph auth caps 命令会完全覆盖用户现有权限。建议先通过 ceph auth get TYPE.ID 查看当前权限,再进行修改。

简单实践:完整用户操作流程

添加用户(创建普通用户)

先通过帮助命令了解auth模块的完整用法,再创建带权限限制的普通用户:

1
2
3
4
5
6
# 查看auth命令帮助
$ ceph auth --help

# 创建普通用户client.testuser,配置权限:mon读取、osd对data_for_k8s池读写
$ ceph auth add client.testuser mon 'allow r' osd 'allow rw pool=data_for_k8s'
added key for client.testuser

验证新创建用户信息

1
2
3
4
5
6
7
8
9
10
11
# 查看用户完整信息
$ ceph auth get client.testuser
[client.testuser]
key = AQB4dWNpxEhiIhAAE1cDs94V3Z9oGKbsTcbPyg==
caps mon = "allow r"
caps osd = "allow rw pool=data_for_k8s"
exported keyring for client.testuser

# 单独查看用户密钥
$ ceph auth print-key client.testuser
AQB4dWNpxEhiIhAAE1cDs94V3Z9oGKbsTcbPyg==

修改用户权限

将client.testuser的MDS的权限添加:允许读 + 写(read+write),MGR添加读(read)权限,OSD权限增加至data_for_k8smetadata_for_k8s池:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 修改权限
$ 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'
updated caps for client.testuser

# 验证修改结果
$ ceph auth get client.testuser
[client.testuser]
key = AQB4dWNpxEhiIhAAE1cDs94V3Z9oGKbsTcbPyg==
caps mds = "allow rw"
caps mgr = "allow r"
caps mon = "allow r"
caps osd = "allow rw pool=data_for_k8s, allow rw pool=metadata_for_k8s"
exported keyring for client.testuser

导出用户信息(备份/迁移)

可直接输出用户信息,或导出至文件保存(适用于备份或迁移到其他集群):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 直接输出导出信息
$ ceph auth export client.testuser
[client.testuser]
key = AQB4dWNpxEhiIhAAE1cDs94V3Z9oGKbsTcbPyg==
caps mds = "allow rw"
caps mgr = "allow r"
caps mon = "allow r"
caps osd = "allow rw pool=data_for_k8s, allow rw pool=metadata_for_k8s"
$ export auth(key=AQB4dWNpxEhiIhAAE1cDs94V3Z9oGKbsTcbPyg==)

# 导出到备份文件testuser.file
$ ceph auth export client.testuser > testuser.file

# 验证导出文件内容
$ cat testuser.file
[client.testuser]
key = AQB4dWNpxEhiIhAAE1cDs94V3Z9oGKbsTcbPyg==
caps mds = "allow rw"
caps mgr = "allow r"
caps mon = "allow r"
caps osd = "allow rw pool=data_for_k8s, allow rw pool=metadata_for_k8s"

删除用户

删除无用用户,释放集群资源并保障安全:

1
2
3
4
5
6
7
# 删除client.testuser
$ ceph auth del client.testuser
updated

# 验证删除结果(删除后无法查询到用户信息)
$ ceph auth get client.testuser
Error ENOENT: failed to find client.testuser in keyring

导入用户(从备份恢复)

通过之前导出的密钥环文件,恢复已删除的用户:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 从testuser.file导入用户
$ ceph auth import -i testuser.file
imported keyring

# 验证导入结果
$ ceph auth get client.testuser
[client.testuser]
key = AQB4dWNpxEhiIhAAE1cDs94V3Z9oGKbsTcbPyg==
caps mds = "allow rw"
caps mgr = "allow r"
caps mon = "allow r"
caps osd = "allow rw pool=data_for_k8s, allow rw pool=metadata_for_k8s"
exported keyring for client.testuser

特殊场景:get-or-create命令使用

该命令适用于“不确定用户是否存在”的场景,避免重复创建或漏创建:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 尝试创建已存在的用户client.testuser
$ ceph auth get-or-create client.testuser
[client.testuser]
key = AQB4dWNpxEhiIhAAE1cDs94V3Z9oGKbsTcbPyg==
# 结果:返回现有用户信息,不覆盖权限

# 创建新用户client.testuser2,指定权限
$ ceph auth get-or-create client.testuser2 mon 'allow r' osd 'allow rw pool=data_for_k8s'
[client.testuser2]
key = AQAwPDBjHPByABAA+nMEvAXztrzE8FSCZkNGgg==

# 验证新用户
$ ceph auth get client.testuser2
[client.testuser2]
key = AQAwPDBjHPByABAA+nMEvAXztrzE8FSCZkNGgg==
caps mon = "allow r"
caps osd = "allow rw pool=data_for_k8s"
exported keyring for client.testuser2

结果说明:若用户已存在,get-or-create仅返回信息;若不存在,则直接创建并返回配置,适合自动化脚本中的用户创建场景。

部署Ceph-csi

下载 ceph-csi 资源清单(在 K8s Master 节点执行)

1
2
3
4
5
6
7
8
9
# 克隆ceph-csi仓库(指定v3.11版本分支)
git clone -b release-v3.11 --depth 1 https://github.com/ceph/ceph-csi.git
cd ceph-csi

# 准备cephfs配置文件夹
mkdir /root/cephfs

# 创建cephfs命名空间
kubectl create ns cephfs

查看认证用户信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ ceph auth get client.admin
client.admin
key: AQBUvWBpqRupOBAA/DXPwFQMD7EXf1WXqP1+dA==
caps: [mds] allow *
caps: [mgr] allow *
caps: [mon] allow *
caps: [osd] allow *
$ ceph auth get client.testuser
[client.testuser]
key = AQB4dWNpxEhiIhAAE1cDs94V3Z9oGKbsTcbPyg==
caps mds = "allow rw"
caps mgr = "allow r"
caps mon = "allow r"
caps osd = "allow rw pool=data_for_k8s, allow rw pool=metadata_for_k8s"

编辑资源配置清单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ cp examples/cephfs/secret.yaml /root/cephfs/
$ vim /root/cephfs/secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: csi-cephfs-secret
namespace: cephfs
stringData:
# Required for statically provisioned volumes
userID: testuser
userKey: AQB4dWNpxEhiIhAAE1cDs94V3Z9oGKbsTcbPyg== # 使用创建的testuser用户。

# Required for dynamically provisioned volumes
adminID: admin
adminKey: AQBUvWBpqRupOBAA/DXPwFQMD7EXf1WXqP1+dA==

# Encryption passphrase
encryptionPassphrase: test_passphrase

ceph-csi-configCeph CSI(Container Storage Interface)插件 的核心配置资源,主要用于向 Kubernetes 集群中的 Ceph CSI 插件提供连接后端 Ceph 集群的关键信息,让 CSI 插件能够和 Ceph 集群建立通信,从而实现 KubernetesCephFS 存储的生命周期管理(比如创建 / 删除 CephFS 卷、挂载 / 卸载卷、管理 CephFS 子卷组等)。简单来说,它是 K8s 和 Ceph 集群之间的 “通信配置桥梁”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
cp /root/ceph-csi/deploy/cephfs/kubernetes/csi-config-map.yaml /root/cephfs/
cat /root/cephfs/csi-config-map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: "ceph-csi-config"
data:
config.json: |-
[
{
"clusterID": "xxx-81a1-40f6-97b7-xx",
"monitors": [
"10.1.x.x:6789",
"10.1.x.x:6789",
"10.1.x.x:6789"
],
"cephFS": {
"subvolumeGroup": "csi",
"kernelMountOptions": "",
"netNamespaceFilePath": "",
"fuseMountOptions": ""
},
"readAffinity": {
"enabled": false,
"crushLocationLabels": [
]
}
}
]

各配置项的注释说明

以下是移除的注释对应的配置项解释,按层级梳理:

1. 顶层配置(Ceph 集群连接基础)

配置项说明
clusterID【必填】Ceph 集群的唯一标识;获取方式:在 Ceph 集群节点执行 ceph -s,输出中找 “id: xxx-81a1-40f6-97b7-xx”
monitors【必填】Ceph Monitor 节点的地址列表;ceph-csi 通过这些地址连接 Ceph 集群

2. cephFS 子配置(CephFS 存储专属规则)

配置项说明
subvolumeGroup【关键】指定 ceph-csi 创建子卷时使用的子卷组(对应提前创建的 csi 子卷组)
kernelMountOptions内核挂载 CephFS 时的额外参数(比如 ro= 只读,默认空即可)
netNamespaceFilePath网络命名空间文件路径;设置为空避免 “找不到网络命名空间” 的报错,非特殊网络场景留空是最佳实践
fuseMountOptionsFUSE 方式挂载 CephFS 的额外参数(默认空即可)

3. readAffinity 子配置(读性能优化)

配置项说明
enabled是否启用读亲和性;false= 关闭,适合单节点 / 小规模集群
crushLocationLabels用于读亲和性的 CRUSH 位置标签;启用时需配置(比如 ["host", "rack"]),关闭时留空

修改ceph-conf配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$ cp /root/ceph-csi/deploy/cephfs/ceph-conf.yaml /root/cephfs/
$ cat /root/cephfs/ceph-conf.yaml
---
# ceph-config:提供 Ceph 集群的基础认证规则和日志调试配置,是 CSI 插件与 Ceph 集群交互的核心客户端配置;
apiVersion: v1
kind: ConfigMap
data:
ceph.conf: |
[global]
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx
# enable ceph librbd,librados logs in rbd/cephfs/nfs container logs
# log_to_stderr = true
# debug_rbd = 30 # enable debug rbd logs
# debug_rados = 30 # enable debug rados logs
# debug_rbd_mirror = 30 # enable debugging logs for rbd mirroring daemon

# keyring is a required key and its value should be empty
keyring: |
metadata:
name: ceph-config
# 需要添加下面配置。
# ceph-csi-encryption-kms-config:为 Ceph CSI 的卷加密功能提供密钥管理系统(KMS)的占位配置,满足插件对该配置的存在性要求。
---
apiVersion: v1
kind: ConfigMap
metadata:
name: ceph-csi-encryption-kms-config
data:
config.json: |-
{}
1
2
3
4
5
6
7
8
9
10
11
12
# 复制RBAC和provisioner配置
cp /root/ceph-csi/deploy/cephfs/kubernetes/csi-cephfsplugin-provisioner.yaml /root/cephfs/
cp /root/ceph-csi/deploy/cephfs/kubernetes/csi-cephfsplugin.yaml /root/cephfs/
cp /root/ceph-csi/deploy/cephfs/kubernetes/csi-nodeplugin-rbac.yaml /root/cephfs/
cp /root/ceph-csi/deploy/cephfs/kubernetes/csi-provisioner-rbac.yaml /root/cephfs/
cp /root/ceph-csi/deploy/cephfs/kubernetes/csidriver.yaml /root/cephfs/
cd /root/cephfs/

# 替换命名空间为cephfs
sed -i "s/namespace: default/namespace: cephfs/g" *
# 修改镜像源(解决国内拉取失败问题)
sed -i "s#registry.k8s.io/sig-storage#wangxiansen#g" *
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
cp /root/ceph-csi/examples/cephfs/storageclass.yaml /root/cephfs/
cat /root/cephfs/storageclass.yaml
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-cephfs-sc
provisioner: cephfs.csi.ceph.com
parameters:
# (必填) Ceph 集群的唯一标识;获取方式:在 Ceph 集群节点执行 ceph -s
clusterID: eb9728e2-ec47-11f0-aac5-000c29b88afc

# (必填) CephFS文件系统名称;获取方式:在 Ceph 集群节点执行 ceph fs ls
# eg: fsName: myfs
fsName: k8s

# (可选) 存储卷数据的Ceph池
pool: data_for_k8s

# 认证密钥配置:指定不同操作使用的Secret名称和命名空间
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/controller-publish-secret-name: csi-cephfs-secret
csi.storage.k8s.io/controller-publish-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 # 是否允许卷扩容

应用资源配置清单

1
2
3
4
5
6
7
8
9
10
cd /root/cephfs/
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

验证:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
root@k8s-master:~# kubectl get -n cephfs secrets    
NAME TYPE DATA AGE
csi-cephfs-secret Opaque 5 6d20h
root@k8s-master:~# kubectl get -n cephfs configmaps
NAME DATA AGE
ceph-config 2 5d
ceph-csi-config 2 6d19h
ceph-csi-encryption-kms-config 1 5d
kube-root-ca.crt 1 6d20h
root@k8s-master:~# kubectl get -n cephfs csidrivers.storage.k8s.io
NAME ATTACHREQUIRED PODINFOONMOUNT STORAGECAPACITY TOKENREQUESTS REQUIRESREPUBLISH MODES AGE
cephfs.csi.ceph.com true false false <unset> false Persistent 6d19h
root@k8s-master:~# kubectl get pods -n cephfs
NAME READY STATUS RESTARTS AGE
csi-cephfsplugin-dgh4b 3/3 Running 0 4d14h
csi-cephfsplugin-nskzx 3/3 Running 0 4d14h
csi-cephfsplugin-provisioner-74f9d5c5bb-5mct9 0/6 Pending 0 4d14h
csi-cephfsplugin-provisioner-74f9d5c5bb-8hj2d 6/6 Running 0 4d14h
csi-cephfsplugin-provisioner-74f9d5c5bb-dgjnf 6/6 Running 0 4d14h
csi-cephfsplugin-tlq27 3/3 Running 0 4d14h

验证cephfs使用

  1. 创建pvc

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # pvc.yml
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
    name: csi-cephfs-pvc
    spec:
    accessModes:
    - ReadWriteMany
    resources:
    requests:
    storage: 1Gi
    storageClassName: csi-cephfs-sc
  2. 应用pvc:kubectl apply -f pvc.yaml

  3. 查看绑定信息 kubectl get pvc csi-cephfs-pvckubectl describe pvc csi-cephfs-pvc

  4. 创建pods进行pvc绑定

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    # pod.yml
    ---
    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
  5. 修改nginx 的首页信息

    1
    2
    kubectl exec -it csi-cephfs-demo-pod -- bash
    echo $HOSTNAME > /usr/share/nginx/html/index.html
  6. 访问nginx页面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ kubectl get pod -o wide
    NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
    csi-cephfs-demo-pod 1/1 Running 0 4d14h 172.17.220.118 k8s-node01.local <none> <none>
    $ curl 172.17.220.118
    csi-cephfs-demo-pod

    # 在k8s-node01.local 查看挂着信息
    mount |grep ceph
    testuser@eb9728e2-ec47-11f0-aac5-000c29b88afc.k8s=/volumes/csi/csi-vol-58d8d81f-1a3a-494e-a87f-f86cae16c6d1/2b67bb5b-0ae9-435c-806a-883f8d92d90f on /var/lib/kubelet/plugins/kubernetes.io/csi/cephfs.csi.ceph.com/849761e041befc33136d68dc18a637394d7dc0bfdd2d199e61f38061d5765551/globalmount type ceph (rw,relatime,name=testuser,secret=<hidden>,acl,mon_addr=10.1.1.200:6789)
    testuser@eb9728e2-ec47-11f0-aac5-000c29b88afc.k8s=/volumes/csi/csi-vol-58d8d81f-1a3a-494e-a87f-f86cae16c6d1/2b67bb5b-0ae9-435c-806a-883f8d92d90f on /var/lib/kubelet/pods/cf503833-3f10-436b-aa84-724cf2f9f282/volumes/kubernetes.io~csi/pvc-9580f87e-9c32-45f8-8fbf-107a08b092f2/mount type ceph (rw,relatime,name=testuser,secret=<hidden>,acl,mon_addr=10.1.1.200:6789,_netdev)