ceph-deploy 安装 ceph
ceph-deploy 安装 ceph
该教程适用于 luminous(12) - Octopus(15) 版本
节点规划
主机 | 配置 | 角色 |
---|---|---|
192.168.223.151(ceph1) | 1核1G,20G系统盘,50G数据裸盘 | mon,osd,mgr,admin |
192.168.223.152(ceph2) | 1核1G,20G系统盘,50G数据裸盘 | mon,osd,mgr,mds |
192.168.223.153(ceph3) | 1核1G,20G系统盘,50G数据裸盘 | mon,osd,rgw |
- admin 为 ceph-deploy 节点
- mon 集群元数据奇数个
- osd 节点上添加了几个磁盘,osd 进程就有几个。集群中最少需要 3 个osd,osd 支持添加文件系统(目录)或者裸盘(/dev/sdb等),一般推荐直接添加裸盘,因为文件系统性能比较低
- mgr 的主要功能是提供外部监测和管理系统的接口(dashboard界面与对外restful api),无状态服务,是 12.x(Luminous)版本加入的新组件,启用 mgr 之后集群状态才会是HEALTH_OK。最少一个,建议部署多个做高可用
- mds 为 cephfs 基础组件,如果不需要使用 cephfs 则可以不部署,生产环境成建议部署多个做高可用
- rgw 为对象存储基础组件,如果不需要使用对象存储也可以不部署,生产环境也建议部署多个
- rbd 块存储在 ceph 底层 rados 集群部署完成就自带,无需单独开启其他进程
- 生产环境中建议各组件单独部署到独立的服务器上面
- public 和 cluster 网络都使用 192.168.223.0/24,生产环境中出于性能的考虑,建议使用不同的网络
系统初始化
系统版本
系统 centos 7.9 mininal,7.9 默认内核是 3.x,建议升级内核
升级内核
# 载入公钥
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
# 安装ELRepo
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
# 载入elrepo-kernel元数据
yum --disablerepo=\* --enablerepo=elrepo-kernel repolist
# 查看可用的rpm包
yum --disablerepo=\* --enablerepo=elrepo-kernel list kernel*
# 安装长期支持版本的kernel
yum --disablerepo=\* --enablerepo=elrepo-kernel install -y kernel-lt.x86_64
# 删除旧版本工具包
yum remove kernel-tools-libs.x86_64 kernel-tools.x86_64 -y
# 安装新版本工具包
yum --disablerepo=\* --enablerepo=elrepo-kernel install -y kernel-lt-tools.x86_64
#查看默认启动顺序
awk -F\' '$1=="menuentry " {print $2}' /etc/grub2.cfg
CentOS Linux (5.4.137-1.el7.elrepo.x86_64) 7 (Core)
CentOS Linux (3.10.0-327.10.1.el7.x86_64) 7 (Core) 151
CentOS Linux (0-rescue-c52097a1078c403da03b8eddeac5080b) 7 (Core)
#默认启动的顺序是从0开始,新内核是从头插入(目前位置在0,而4.4.4的是在1),所以需要选择0。
grub2-set-default 0
#重启并检查
reboot
- 当前最新版本内核 5.4.137-1.el7
安装基础软件
yum install -y epel-release lrzsz
设置主机名与 hosts
方法一
151
$ vi /etc/hostname
ceph1
$ vi /etc/hosts
127.0.0.1 ceph1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 ceph1 localhost localhost.localdomain localhost6 localhost6.localdomain6
152,153 操作类似
三台主机 /etc/hosts 均添加以下内容:
192.168.223.151 ceph1
192.168.223.152 ceph2
192.168.223.153 ceph3
方法二
hostnamectl set-hostname hostname
- 这个命令不太熟悉,推荐第一种吧
设置时钟同步
如果节点可访问互联网,可以直接启动 chronyd 系统服务,并设置开机启动。
yum install -y chrony
systemctl start chronyd.service
systemctl enable chronyd.service
不过一般生产环境中不会开放互联网访问权限的,这时候就需要修改节点 /etc/chrony.conf 配置文件,将时间服务器指向内外 ntp 服务器即可,配置格式如下:
server chrony-server-name-or-ip iburst
关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
关闭 selinux
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
优化 ssh 登录速度
sed -i 's/#UseDNS yes/UseDNS no/g' /etc/ssh/sshd_config
systemctl restart sshd
优化最大文件句柄、进程等
略
优化内核参数
略
集群主机添加 ssh 密钥信任
ceph1 主机上面操作即可
# 生成密钥
ssh-keygen -t rsa -P ''
# 拷贝公钥给本机
ssh-copy-id -i .ssh/id_rsa.pub root@localhost
# 拷贝 .ssh 目录所有文件到集群其他节点
scp -rp .ssh/ root@ceph2:/root
scp -rp .ssh/ root@ceph3:/root
完成后,集群中所有主机可以互相免密登录了
部署
配置 ceph 仓库源 repo
所有节点操作:
rpm -ivh http://download.ceph.com/rpm-luminous/el7/noarch/ceph-release-1-1.el7.noarch.rpm
sed -i 's#download.ceph.com#mirrors.aliyun.com/ceph#g' /etc/yum.repos.d/ceph.repo
- 其他版本改变相应路径即可
- 如果不修改为国内源,安装慢如狗
手动安装基础软件包
在所有节点上执行,非必须,ceph-deploy 安装组件时会自动安装相应软件,我们这里提前安装是为了让后面安装过程更快一点
yum install ceph ceph-radosgw -y
安装 ceph-deploy
ceph1 节点操作:
yum install ceph-deploy python-setuptools python2-subprocess32 ceph-common -y
部署 mon 节点
ceph1 节点操作:
mkdir ceph-cluster
cd ceph-cluster
ceph-deploy new ceph1 --cluster-network 192.168.223.0/24 --public-network 192.168.223.0/24
# mon 节点可以写第一个,也可以写多个
操作完成后并没有真正安装,只是在当前目前生成相关配置文件以及keyring集群内部通信的认证文件
$ ls
ceph.conf ceph-deploy-ceph.log ceph.mon.keyring
- 这里就可以根据需求修改集群配置文件 ceph.conf 了
所有节点安装 ceph 软件包
ceph-deploy install --no-adjust-repos ceph1 ceph2 ceph3
- 前面在所有节点以及执行 yum install ceph ceph-radosgw -y 手动安装,此步骤其实可以省略
初始化
ceph-deploy mon create-initial
- 初始化完成后会生成集群需要的 keyring 认证文件
- 注意观察启动组件的命令:systemctl start ceph-mon@ceph1,后面的各组件也类似
推送配置以及密钥到集群主机
ceph-deploy admin ceph1 ceph2 ceph3
- 推送后配置和密钥存放于 ceph 默认配置目录 /etc/ceph 中
- 每次更改 ceph 的配置文件,都可以用这个命令推送到所有节点上
推送完成后可以在推送的节点上面使用 ceph 命令管理集群了
# 查看集群状态
$ ceph -s
cluster:
id: dbeb7a50-c5f0-43c5-ac96-4ca1b7c764bb
health: HEALTH_OK
services:
mon: 1 daemons, quorum ceph1
mgr: no daemons active
osd: 0 osds: 0 up, 0 in
data:
pools: 0 pools, 0 pgs
objects: 0 objects, 0B
usage: 0B used, 0B / 0B avail
pgs:
添加 mon 节点
ceph1 节点操作:
ceph-deploy mon add ceph2
ceph-deploy mon add ceph3
查看mon的quorum状态
$ ceph quorum_status --format json-pretty
{
"election_epoch": 12,
"quorum": [
0,
1,
2
],
"quorum_names": [
"ceph1",
"ceph2",
"ceph3"
],
"quorum_leader_name": "ceph1",
"monmap": {
"epoch": 3,
"fsid": "dbeb7a50-c5f0-43c5-ac96-4ca1b7c764bb",
"modified": "2021-07-30 11:59:12.745386",
"created": "2021-07-30 11:49:32.620344",
"features": {
"persistent": [
"kraken",
"luminous"
],
"optional": []
},
"mons": [
{
"rank": 0,
"name": "ceph1",
"addr": "192.168.223.151:6789/0",
"public_addr": "192.168.223.151:6789/0"
},
{
"rank": 1,
"name": "ceph2",
"addr": "192.168.223.152:6789/0",
"public_addr": "192.168.223.152:6789/0"
},
{
"rank": 2,
"name": "ceph3",
"addr": "192.168.223.153:6789/0",
"public_addr": "192.168.223.153:6789/0"
}
]
}
}
部署 mgr 节点
ceph1 节点操作:
$ ceph-deploy mgr create ceph1
$ ceph -s
cluster:
id: dbeb7a50-c5f0-43c5-ac96-4ca1b7c764bb
health: HEALTH_OK
services:
mon: 3 daemons, quorum ceph1,ceph2,ceph3
mgr: ceph1(active)
osd: 0 osds: 0 up, 0 in
data:
pools: 0 pools, 0 pgs
objects: 0 objects, 0B
usage: 0B used, 0B / 0B avail
pgs:
添加 mgr 节点
ceph1 节点操作:
$ ceph-deploy mgr create ceph2
$ ceph -s
cluster:
id: dbeb7a50-c5f0-43c5-ac96-4ca1b7c764bb
health: HEALTH_WARN
OSD count 0 < osd_pool_default_size 3
services:
mon: 3 daemons, quorum ceph1,ceph2,ceph3
mgr: ceph1(active), standbys: ceph2
osd: 0 osds: 0 up, 0 in
data:
pools: 0 pools, 0 pgs
objects: 0 objects, 0B
usage: 0B used, 0B / 0B avail
pgs:
mgr 启用 dashboard & prometheus
$ ceph mgr module ls # 查看所有支持 module
$ ceph mgr module enable dashboard
$ ceph mgr module enable prometheus
$ ceph mgr services
{
"dashboard": "http://localhost.localdomain:7000/",
"prometheus": "http://localhost.localdomain:9283/"
}
- 高于 luminous 版本开启方式有点不一样,具体查看官方文档
在浏览器访问:http://mgr-server-ip:7000/
提醒:目前 mgr 功能模块可能还存在选举问题,如果多mgr 节点都开启,可能会出现web页面取不到数据,建议只开启一个mgr节点服务,然后关闭其他节点mgr服务。
设置dashboard 端口和IP
ceph config-key set mgr/dashboard/server_port 7000 # 指定集群dashboard的访问端口。可以不用配置,默认7000端口
ceph config-key set mgr/dashboard/server_addr $IP # 指定集群 dashboard的访问IP
服务重启:
systemctl restart ceph-mgr@mon_mgr
添加 osd
ceph1 节点操作:
列出节点磁盘
ceph-deploy disk list ceph1 ceph2 ceph3
- 实际就是执行 fdisk -l
清空节点上面指定的磁盘
ceph-deploy disk zap ceph1 /dev/sdb
ceph-deploy disk zap ceph2 /dev/sdb
ceph-deploy disk zap ceph3 /dev/sdb
- 实际就是执行 dd 命令清空磁盘,生产环境敲错盘符可能要跑路哦
- 如果一个节点上有多个盘,则后面一一列出,空格隔开即可
- 可以直接使用整个盘,也可以使用盘的一个分区,比如 /dev/sdb1,/dev/sdb2
正式添加磁盘到集群
ceph-deploy osd create ceph1 --data /dev/sdb
ceph-deploy osd create ceph2 --data /dev/sdb
ceph-deploy osd create ceph3 --data /dev/sdb
如果节点上面有更多的磁盘,可以使用更高级的方式:
ceph-deploy osd create {node} --data /dev/to/data --block-db /dev/to/db-device --block-wal /dev/to/wal-device
# bluestore(裸设备,文件系统方式为filestore)方式,ceph 会在 osd 里面使用 rocksdb 存放对象的元数据,这时候就会有三类数据Object Data Blobs(对象数据)、SST文件(rocksdb数据文件)、wal文件(rocksdb日志文件,类似redis的aof文件),这时候把 sst 或者 wal 文件放在更快的 ssd 或者 nvme 盘上,会提升 osd 储存性能
# --data 选项指定的是Object Data存放的硬盘
# --block-db 选项指定的是SST文件
# --block-wal 选项指定的是wal文件
# 其中 block-db 大小应该不小于 4% data,也就是说如果 --data 盘 1T,--block-db 应该不小于40G
查看集群状态,应该就正常了
$ ceph -s
cluster:
id: dbeb7a50-c5f0-43c5-ac96-4ca1b7c764bb
health: HEALTH_OK
services:
mon: 3 daemons, quorum ceph1,ceph2,ceph3
mgr: ceph1(active), standbys: ceph2
osd: 3 osds: 3 up, 3 in
data:
pools: 0 pools, 0 pgs
objects: 0 objects, 0B
usage: 3.01GiB used, 147GiB / 150GiB avail
pgs:
其中,osd 有四个状态
up:启动状态
down:停止状态
in:在RADOS集群里面
out:在RADOS集群外边
ceph的客户端是直接与osd进行通信的
ceph的客户端,通过与mon节点进行通信,获取完整的Cluster Map,然后在客户端本地,用CRUSH算法,根据Cluster Map,以及对应存储池的放置组规则,进行计算,获得所需数据存储于哪些osd上面,然后直接与osd建立通信进行读写。
移除 osd
查看 osd id
ceph osd tree
停用相关 osd
ceph osd out {osd-id}
停用相关进程
systemctl stop ceph-osd@{osd-id}
移除设备
ceph osd purge {osd-id} --yes-i-really-mean-it
如果类似如下的 osd 配置信息存在于 ceph.conf 中,需要在 osd 移除后将其删除
[osd.1]
host = {hostname}
不过,对应 Luminous 之前的版本,删除的 osd 方法不太一样:
# 删除 crush 运行图相关数据
ceph osd crush remove {osd-name}
ceph auth del osd.{osd-id}
ceph osd rm {osd-id}
简单测试集群功能
查看认证信息等
ceph auth list
查看集群状态
ceph mon stat
# 检查状态:ceph quorum_status --format json-pretty
# 查看集群详细配置:ceph daemon mon.{CEPH-NODE} config show | more
# 查看mon详细状态:ceph daemon mon.{CEPH-NODE} mon_status
# 查看ceph log所在目录:ceph-conf --name mon.{CEPH-NODE} --show-config-value log_fil
# 查看mon节点的admin socket:ceph-conf --name mon.ceph01 --show-config-value admin_socket
查看osd状态
ceph-deploy osd list compute01
在管理节点查看osd状态等
ceph osd stat
ceph osd tree
在管理节点查看容量及使用情况
ceph df
创建存储池 pool
要想使用ceph的存储功能,必须先创建存储池
$ ceph osd pool create mypool 64 64
pool 'mypool' created
- pool 支持设置 quota 限额(对象个数、容量),具体见官方文档
- pool 默认使用 3 个副本,还支持纠删码方式的(类似 raid5),具体见官方文档
查看存储池状态
ceph osd pool stats mypool
列出当前集群所有存储池 pool
$ ceph osd pool ls
mypool
- rados lspools 也可以
上传一个文件
rados put issue /etc/issue --pool=mypool
获取一个文件
rados get issue my_issue -p mypool
# issue是对象的ID
# my_issue是outfile,即输出文件叫啥名字
# -p指定存储池
列出指定存储池有哪些文件
rados ls --pool=mypool
查看指定文件在Ceph集群内是怎样做映射的
ceph osd map mypool issue
osdmap e16 pool 'mypool' (1) object 'issue' -> pg 1.651f88da (1.1a) -> up ([1,0,2], p1) acting ([1,0,2], p1)
ceph map信息简要说明
osdmap e16 pool 'mypool' (1) object 'issue' -> pg 1.651f88da (1.1a) -> up ([1,0,2], p1) acting ([1,0,2], p1)
# pg 1.651f88da (1.1a),表示第1号存储池的1a号pg
# up Ceph的存储池是三副本存储的,后面的三个数字是存储了此文件的三个osd的编号,p1表示1号osd是主osd
# acting同理
删除一个文件
rados rm issue -p mypool
删除一个存储池 pool
$ ceph osd pool rm mypool mypool --yes-i-really-really-mean-it
Error EPERM: pool deletion is disabled; you must first set the mon_allow_pool_delete config option to true before you can destroy a pool
- 必须加 --yes-i-really-really-mean-it
- 报错是由于没有配置 mon 节点的 mon_allow_pool_delete 字段所致,解决办法就是到mon节点进行相应的设置。
解决方法 2 种:
方法一
修改集群 ceph.conf 文件,添加:
[mon]
mon_allow_pool_delete = true
然后使用 ceph-deploy --overwrite-conf admin 推送配置文件到所有节点
最后在集群种所有 mon 节点重启 mon 进程:systemctl restart ceph-mon@{主机名}
方法二
ceph 可以在运行时更改 ceph-osd 、 ceph-mon 、 ceph-mds 守护进程的配置,此功能在增加/降低日志输出、启用/禁用调试设置、甚至是运行时优化的时候非常有用的。
所以前面两个步骤一样的,只是最后一个步骤使用命令直接动态修改所有 mon 节点配置,无需重启,具体命令查看官方文档。
集群访问接口
rbd 块存储
ceph 搭建好底层 rados 集群后,不需要再单独启动进程就可以直接使用 rdb 。
ceph支持一个非常好的特性,以COW(写时复制)的方式从RBD快照创建克隆,在Ceph中被称为快照分层。分层特性允许用户创建多个CEPH RBD克隆实例。这些特性应用于OpenStack等云平台中,使用快照形式保护ceph RBD 镜像,快照是只读的,但COW克隆是完全可以写 ,可以多次来孵化实例,对云平台来说是非常有用的。
ceph RBD镜像有 format-1 和 format-2 两种类型,RBD支持这两种类型,但是分层特性COW克隆特性只支持format-2镜像,默认RBD创建的镜像是format-1。(这个在克隆的时候特别重要)
先看看自己的Linux内核支不支持rbd块设备
modinfo rbd # 查看
modprobe rbd # 加载
如果有错误信息说明内核不支持,那你就先去升级一下内核吧~
创建一个 rdb 块存储
rbd create mypool/myrbd --size 102400
- rbd 命令也会调用 /etc/ceph/ceph.conf 配置文件以便连接 ceph 集群
- 格式:rbd create (pool_name)/rbd_name) --size xxxxxMB
- 在 mypool 上建立了一个叫 myrbd 的块设备,如果没有斜杠 / 则默认建立在 rbd 这个pool上创建
- 还有一个是这个size的大小,这个大小可以超过你实际pool的大小,这个叫做瘦分配,也叫超卖和按需分配。创建块之后可以通过指令rbd resize test/myrbd1 --size 51200 --allow-shrink来动态的更改
映射 rbd 设备到本机
$ rbd map mypool/myrbd
/dev/rbd0
得到块设备的映射/dev/rbd0,这个时候你就可以像操作本机的块设备一样操作该设备了。
mkfs.xfs /dev/rbd0
mkdir /rbd0
mount /dev/rbd0 /rbd0
创建 rbd 快照
rbd snap create --snap mysnap mypool/myrbd
回滚
umount /dev/rbd0
rbd unmap mypool/myrbd
rbd snap rollback mypool/myrbd@mysnap
rbd map mypool/myrbd
mount /dev/rbd0 /rbd0
- 必须 umount,unmap 后才能回滚
- 重新加载后发现回滚到做快照时的状态了
模板与克隆
模板与克隆使用的是分层技术
先看看该块设备支不支持创建快照模板,image-format 必须为2
$ rbd info mypool/myrbd
rbd image 'myrbd':
size 100GiB in 25600 objects
order 22 (4MiB objects)
block_name_prefix: rbd_data.853e6b8b4567
format: 2
features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
flags:
create_timestamp: Fri Jul 30 17:48:39 2021
- 创建 rbd 设备时可以使用参数指定 1 或者 2 版本: --image-format 2
把该块做成模板,首先要把做成模板的快照做成protect
rbd snap protect mypool/myrbd@mysnap
- 通过rbd snap unprotect mypool/myrbd@mysnap可以去掉这个保护,但是这样的话就 不能克隆了
然后可以利用这个快照来当模板来克隆了,我们克隆一个叫myrbd2的块出来试试
$ rbd clone mypool/myrbd@mysnap mypool/myrbd2
$ rbd -p mypool ls
myrbd
myrbd2
$ rbd info mypool/myrbd2
rbd image 'myrbd2':
size 100GiB in 25600 objects
order 22 (4MiB objects)
block_name_prefix: rbd_data.85656b8b4567
format: 2
features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
flags:
create_timestamp: Fri Jul 30 18:35:30 2021
parent: mypool/myrbd@mysnap
overlap: 100GiB
接下来我们看看这个myrbd2看看和myrbd1有什么不一样。
先映射myrbd2
$ rbd map mypool/myrbd2
/dev/rbd1
因为是克隆myrbd的snap,myrbd上本来就有文件系统,所以myrbd2上也有文件系统,直接挂载就好了
mkdir /rbd1
mount /dev/rbd1 /rbd1
- 如果本机挂载了 /dev/rdb0 的话,必须先 umount /dev/rbd0,否则会 UUID 冲突报错:XFS (rbd1): Filesystem has duplicate UUID a7679463-af36-43fb-949a-3ae94bc5c226 - can't mount
- myrbd2的内容上也是和myrbd是相同的,因为是克隆来的嘛
这个时候的myrbd2还是依赖myrbd的镜像mysnap的,如果myrbd的mysnap被删除或者怎么样,myrbd2也不能够使用了,要想独立出去,就必须将父镜像的信息合并flattern到子镜像中,
$ rbd flatten mypool/myrbd2
Image flatten: 100% complete...done.
$ rbd info mypool/myrbd2
rbd image 'myrbd2':
size 100GiB in 25600 objects
order 22 (4MiB objects)
block_name_prefix: rbd_data.85656b8b4567
format: 2
features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
flags:
create_timestamp: Fri Jul 30 18:35:30 2021
这样myrbd2就独立于myrbd了
可以通过如下方法删除镜像模板了
$ rbd snap ls mypool/myrbd
SNAPID NAME SIZE TIMESTAMP
4 mysnap 100GiB Fri Jul 30 17:59:17 2021
$ rbd snap unprotect mypool/myrbd@mysnap
$ rbd snap rm mypool/myrbd@mysnap
Removing snap: 100% complete...done.
$ rbd snap ls mypool/myrbd
cephfs 文件系统
cephfs 是一个支持 POSIX 接口的文件系统,它使用 ceph 存储集群来存储数据。文件系统对于客户端来说可以方便的挂载到本地使用。cephfs 构建在 RADOS 之上,继承 RADOS 的容错性和扩展性,支持冗余副本和数据高可靠性。
注意:当前,cephfs 还缺乏健壮得像 ‘fsck’ 这样的检查和修复功能。存储重要数据时需小心使用,因为灾难恢复工具还没开发完。
准备 mds 元数据服务
cephfs 文件系统要求 ceph 存储集群内至少有一个 mds 元数据服务。
新增 mds 服务:
ceph-deploy mds create ceph2
创建 cephfs 文件系统
一个 cephfs 文件系统需要至少两个 RADOS 存储池,一个用于数据、一个用于元数据。配置这些存储池时需考虑:
- 为元数据存储池设置较高的副本水平,因为此存储池丢失任何数据都会导致整个文件系统失效。
- 为元数据存储池分配低延时存储器(像 SSD ),因为它会直接影响到客户端的操作延时。
要用默认设置为文件系统创建两个存储池,你可以用下列命令:
比如我们使用 120 个 pg。cephfs_data 和 cephfs_metadata 是两个存储池的名称。
ceph osd pool create cephfs_data 128
ceph osd pool create cephfs_metadata 128
创建好存储池后,你就可以用 fs new 命令创建文件系统了:
ceph fs new cephfs cephfs_metadata cephfs_data
cephfs是文件系统的名称。
使用下面的命令可以查看创建的CephFS
$ ceph fs ls
name: cephfs, metadata pool: cephfs_metadata, data pools: [cephfs_data ]
文件系统创建完毕后, MDS 服务器就能达到 active 状态了,比如在一个单 MDS 系统中,使用命令查看
$ ceph mds stat
cephfs-1/1/1 up {0=ceph2=up:active}
- ceph -s 集群管理也可以查看
服务器挂载 cephfs
要挂载 cephfs 文件系统,首先需要知道 ceph-mon 的地址,并且挂载的服务器需要安装 ceph 客户端:yum install ceph ceph-radosgw -y 或者 ceph-deploy install [server]。挂载命令如下:
mount -t ceph ceph1:6789,ceph2:6789,ceph3:6789:/ /mycephfs
但是 ceph v0.55 及后续版本默认开启了 cephx 认证。这样挂载会报错:
mount error 22 = Invalid argument
- mount error 5 = Input/output error 首先先查mds服务是正常,不存在则添加
- mount error 22 = Invalid argument 密钥不正确,检查密钥
如果启用了cephx认证的Ceph文件系统,挂载时我们必须指定用户名、密钥。
secret在/etc/ceph/ceph.client.admin.keyring可以查到。或者使用命令查询:
ceph auth get-key client.admin
mkdir /mycephfs
mount -t ceph ceph1:6789,ceph2:6789,ceph3:6789:/ /mycephfs -o name=admin,secret=AQDQdgNhzPjLFBAAgveHwiTVmWgQJ4EiKlZ98A==
上述方法会把密码暴露在 bash history 里,建议将密码单独保存在一个文件,然后读取:
mount -t ceph ceph1:6789,ceph2:6789,ceph3:6789:/ /mycephfs -o name=admin,secretfile=./admin.key
启动时挂载,vi /etc/fstab 添加:
ceph1:6789,ceph2:6789,ceph3:6789:/ /mycephfs ceph name=admin,secret=AQDQdgNhzPjLFBAAgveHwiTVmWgQJ4EiKlZ98A==,noatime 0 2
cephfs 用户隔离
上一步已经实现了远程挂载,和文件共享,但如果多个产品同时使用一个 cephfs,如果数据都互相可见,显然是不够安全的,那么就要做隔离,咱们接下来就来看看 cephfs 是如何做到这点的。
一个 ceph 集群只能创建一个 cephfs 文件系统,所以隔离是在用户层面做的,具体的做法是:限定某个用户只能访问某个目录。
下面这个命令创建了一个叫 bruce 的用户,这个用户只能写访问目录 /bruce,数据存储在 pool cephfs_data 中。
$ ceph auth get-or-create client.bruce mon 'allow r' mds 'allow r, allow rw path=/bruce' osd 'allow rw pool=cephfs_data'
[client.bruce]
key = AQAKugNheqsKOBAAPiuElV1oTGbB9QX1qwCAIg==
$ ceph auth get client.bruce
exported keyring for client.bruce
[client.bruce]
key = AQAKugNheqsKOBAAPiuElV1oTGbB9QX1qwCAIg==
caps mds = "allow r, allow rw path=/bruce"
caps mon = "allow r"
caps osd = "allow rw pool=cephfs_data"
如果要做进一步的隔离,想让不通用户的数据存储在不同的 pool,可以用命令将 pool 加入的 cephfs 中,再用命令指定,加入 pool 的命令如下:
$ ceph mds add_data_pool bruce
$ ceph fs ls
.... data pools: [cephfs_data bruce ]
挂载方式和 admin 用户挂载一样:
mount -t ceph ceph1:6789,ceph2:6789,ceph3:6789:/ /mycephfs -o name=bruce,secret=AQAKugNheqsKOBAAPiuElV1oTGbB9QX1qwCAIg==
- 注意:因为 bruce 对根目录没写权限,故不能创建 bruce 目录,需要使用 admin 账号先挂载创建一个 bruce 目录才行
- bruce 用户对其他目录以及文件只有读权限,对 /bruce 目录可读可写可删除
cephfs 挂载为 NFS
利用 NFS-Ganesha 或 ceph-fuse 与 nfsd, 我们可以将 CephFS 通过 NFS 协议对外发布出去,用户可以通过 NFS 客户端挂载 CephFS 文件系统进行访问。具体方法这里不赘述,有兴趣的可以上网搜索。
rgw 对象存储
介绍
通过对象存储,将数据存储为对象,每个对象除了包含数据,还包含数据自身的元数据
对象通过Object ID来检索,无法通过普通文件系统操作来直接访问对象,只能通过API来访问,或者第三方客户端(实际上也是对API的封装)
对象存储中的对象不整理到目录树中,而是存储在扁平的命名空间中,Amazon S3将这个扁平命名空间称为bucket。而swift则将其称为容器
无论是bucket还是容器,都不能嵌套
bucket需要被授权才能访问到,一个帐户可以对多个bucket授权,而权限可以不同
对象存储的优点:易扩展、快速检索
rados 网关介绍
rados 网关也称为ceph对象网关、radosgw、rgw,是一种服务,使客户端能够利用标准对象存储api来访问ceph集群。它支持S3和Swift API
rgw运行于librados之上,事实上就是一个称之为 civetweb 的 web 服务器来响应 restfulapi 请求
客户端使用标准 api 与 rgw 通信,而 rgw 则使用 librados 与 ceph 集群通信
rgw 客户端通过 s3 或者 swift api 使用 rgw 用户进行身份验证。然后 rgw 网关代表用户利用cephx 与 ceph 存储进行身份验证
虽然在设计与实现上有所区别,但大多数对象存储系统对外呈现的核心资源类型大同小异
-
Amazon S3:提供了user、bucket和object分别表示用户、存储桶和对象,其中bucket隶属于user,因此user名称即可做为bucket的名称空间,不同用户允许使用相同名称的bucket
-
OpenStack Swift:提供了user、container和object分别对应于用户、存储桶和对象,不过它还额外为user提供了父级组件account,用于表示一个项目或租户,因此一个account中可包含一到多个user,它们可共享使用同一组container,并为container提供名称空间
-
RadosGW:提供了user、subuser、bucket和object,其中的user对应于S3的user,而subuser则对应于Swift的user,不过user和subuser都不支持为bucket提供名称空间,因此,不同用户的存储桶也不允许同名;不过,自Jewel版本起,RadosGW引入了tenant(租户)用于为user和bucket提供名称空间,但它是个可选组件
-
Jewel版本之前,radosgw的所有user位于同一名称空间,它要求所有user的ID必须惟一,并且即便是不同user的bucket也不允许使用相同的bucket ID
S3和Swift使用了不同的认证机制
-
用户账号是认证(Authentication)、授权(Authorization)及存储配额(Quota)功能的载体,RGW依赖它对RESTfulAPI进行请求认证、控制资源(存储桶和对象等)的访问权限并设定可用存储空间上限
-
S3主要采用的是基于访问密钥(access key)和私有密钥(secret key)进行认证,RGW兼容其V2和V4两种认证机制,其中V2认证机制支持本地认证、LDAP认证和kerberos认证三种方式,所有未能通过认证的用户统统被视为匿名用户
-
Swift结合Swift私有密钥(swift key)使用令牌(token)认证方式,它支持临时URL认证、本地认证、OpenStack Keystone认证、第三方认证和匿名认证等方式
-
通过身份认证后,RGW针对用户的每次资源操作请求都会进行授权检查,仅那些能够满足授权定义(ACL)的请求会被允许执行
-
S3使用bucket acl和object acl分别来控制bucket和object的访问控制权限,一般用于向bucket或object属主之外的其它用户进行授权
-
Swift API中的权限控制则分为user访问控制列表和bucket访问控制列表两种,前一种针对user进行设定,而后一定则专用于bucket及内部的object,且只有read和write两种权限
为了支持通用的云存储功能,Ceph在RADOS集群的基础上提供了RGW(RADOS GateWay)数据抽象和管理层,它是原生兼容S3和SwiftAPI的对象存储服务,支持数据压缩和多站点(Multi-Site)多活机制,并支持NFS协议访问接口等特性。RADOS网关也称为Ceph对象网关、RADOSGW、RGW,是一种服务,使客户端能够利用标准对象存储API来访问Ceph集群。它支持S3和Swift API
-
radosgw的http/https服务由内建的Civeweb提供,它同时也能支持多种主流的Web服务程序以代理的形式接收用户请求并转发至ceph-radosgw进程,这些Web服务程序包括nginx和haproxy等
-
rgw客户端通过s3或者swift api使用rgw用户进行身份验证,S3和Swift是RESTful风格的API,它们基于http/https协议完成通信和数据交换。然后rgw网关代表用户利用cephx与ceph存储进行身份验证
RGW的功能依赖于Ceph对象网关守护进程(ceph-radosgw)实现,它负责向客户端提供RESTAPI接口,并将数据操作请求转换为底层RADOS存储集群的相关操作
-
出于冗余及负载均衡的需要,一个Ceph集群上的ceph-radosgw守护进程通常不止一个,这些支撑同一对象存储服务的守护进程联合起来构成一个zone(区域)用于代表一个独立的存储服务和存储空间
-
在容灾设计的架构中,管理员会基于两个或以上的Ceph集群定义出多个zone,这些zone之间通过同步机制实现冗余功能,并组成一个新的父级逻辑组件zonegroup
rgw 网关部署
添加 rgw 节点
ceph-deploy rgw create ceph3
- 使用 ceph-radosgw 经常中 Citeweb 提供服务,默认端口 7480,http ,可以配置为 https,但是没有必要,因为生产环境一般在前面会加个负载均衡器实现 https
当创建RGW时候默认会创建对应的池信息,不需要人为创建
.rgw.root
default.rgw.control #控制器信息
default.rgw.meta #记录元数据
default.rgw.log #日志信息
default.rgw.buckets.index #为rgw的bucket信息
default.rqw.buckets.data #是实际存储的数据信息
- 本地测试时,如果集群 osd 资源太少,创建上面默认 pool 会失败而导致启动失败,建议删除无用 pool
- 可以使用 ceph df 查看集群中所有 pool 使用情况
修改 rgw 配置,admin 主机 ceph.conf 新增配置:
[client.rgw.ceph3]
rgw_host = ceph3
rgw_frontends = "civetweb port=80"
access_log_file = /tmp/rgw_access.log
error_log_file = /tmp/rgw_error.log
rgw_dns_name = rgw.local
rgw_swift_url = http://rgw.local
- 如果有多个 rgw,配置多段即可
- 然后使用 ceph-deploy --overwrite-conf admin 推送配置文件到所有节点
- ceph3 节点上重启 rgw 服务:systemctl restart ceph-radosgw@rgw.ceph3
S3 方式访问
什么是 S3 存储
S3由Amazon于2006年推出,全称为Simple Storage Service,S3定义了对象存储,是对象存储事实上的标准,从某种意义上说,S3就是对象存储,对象存储就是S3,它对象存储市场的霸主,后续的对象存储都是对S3的模仿
S3的特点
- 跨区域复制
- 事件通知
- 版本控制
- 安全加密
- 访问管理切可编程
rgw 中 s3 的 API 支持
对象存储在bucket中若要利用S3 API访问对象,需要为RADOS网关配置用户每个用户具有一个access key和一个secret key。access key标识用户,secret key验证用户身份
- S3服务的RESTAPI使用用户账号(user)、存储桶(bucket)和对象(object)三个组件来组织存储的数据对象,对象保存于存储桶中,而存储桶则支持授权给特定账号进行读写及创建/删除等操作
- Amazon S3 API授权和身份验证模型具有单层设计。一个用户可以有多个access key和secret key,用于在同一帐户中提供不同类型的访问
- radosgw-admin是用于管理radowgw服务的命令行接口,它有着众多的分别用于不同管理功能的命令,例如user、subuser、key、bucket和object等
创建用户
$ radosgw-admin user create --uid=john --display-name="John Doe" --email=iohn@example.com --access-key=leffss --secret=123456
{
"user_id": "john",
"display_name": "John Doe",
"email": "iohn@example.com",
"suspended": 0,
"max_buckets": 1000,
"auid": 0,
"subusers": [],
"keys": [
{
"user": "john",
"access_key": "leffss",
"secret_key": "123456"
}
],
"swift_keys": [],
"caps": [],
"op_mask": "read, write, delete",
"default_placement": "",
"placement_tags": [],
"bucket_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"user_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"temp_url_keys": [],
"type": "rgw"
}
- -uid 指定用户名
- --display-name 指定备注名
- --email 指定邮箱
- --access-key 指定access key,如果不指定,会自动生成
- --secret 指定secret key如果不指定,会自动生成
用户管理
#修改用户:
radosgw-admin user modify --uid=uid --display-name="John E.Doe" --max-buckets=2000
#禁用用户:
radosgw-admin user suspend --uid=uid
#启用用户:
radosgw-admin user enable --uid=uid
#删除用户:
radosgw-admin user rm --uid=uid [--purge-data] [--purge-keys]
管理用户密钥
#创建一个用户的key
radosgw-admin key create --uid=uid --key-type=s3 [--access-key=key] [--secret=secret]
#删除一个用户的key
radosgw-admin key rm --uid=uid --access-key=key # 在创建密钥时,可以通过--gen-access-key和--gen-secret来生成随机的access key和secret key
设置配额数
#基于用户的配额
radosgw-admin quota set --quota-scope=user --uid=uid [--max-objects=number] [--max-
size=sizeinbytes]
#基于bucket的配额
radosgw-admin quota set --quota-scope=bucket --uid=uid [--max-ob.jects=number] [--max-
size=sizeinbytes]
#启用配额
radosgw-admin quota enable --quota-scope=[user|bucket] --uid=uid
#禁用配额
radosgw-admin quota disable --quota-scope=[user|bucket] --uid=uid
检索用户信息
#查看某个用户信息
radosgw-admin user info --uid=user
#查看所有的用户信息
radosgw-admin user list
统计数据
#用户在具体的时间段写入了多少的数据
radosgw-admin usage show --uid=uid --start-date=start --end-date=end
radosgw-admin usage trim --start-date=start --end-date=end
radosgw-admin usage show --show-log-entries=false
#时间的方式
data表示方式:YYYY-MM-DD hh:mm:ss
配置DNS实现数据传输(一)
配置泛域名解析
-
S3的存储桶是用于存储对象的容器,每个对象都必须储存在一个特定的存储桶中,且每个对象都要直接通过RESTfulAPI基于URL进行访问,URL格式为http(s)://bucket-name.radowgw-host[:port]/key"
-
例如,对于存储在rgw01.test.io上的S3API对象存储系统上eshop存储桶中的名为images/test.ipg的对象,可通过http://eshop.rgw01.test.io/images/test.jpg对其进行寻址
-
因此,radosgw的S3API接口的功能强依赖于DNS的泛域名解析服务,它必须能够正常解析任何
. 格式的名称至radosgw主机 -
另外,还需要配置每个radowgw守护进程的rgw dns name为其DNS名称
#下面是一个在bind中用于泛域名解析的配置示例
IN NS ns
ns IN A 172.29.1.199
rgw01 IN A 172.29.0.11
rgw02 IN A 172.29.0.12
*.rgW01 IN CNAME rgw01
*.rgW02 IN CNAME rgw02
配置DNS实现数据传输(二)
创建bucket和访问资源时需要用到范域名解析功能,能解析如 *.rgw.local 这样的域名,所以需要namd服务,并使用该namd服务为客户端提供解析。
配置named服务:
vim /etc/named.rfc1912.zones
zone "rgw.local" IN {
type master;
file "rgw.local.zone";
};
vim /var/named/rgw.local.zone
$TTL 1D
$ORIGIN rgw.local.
@ IN SOA ns.rgw.local. admin.rgw.local. (
0 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
IN NS ns
ns IN A 192.168.223.1
@ IN A 192.168.223.153
* IN A 192.168.223.153
检查namd配置:如果无错误则重新加载配置。
named-checkconf
rndc reload
解析测试
$ dig -t A 111.rgw.local @192.168.223.1
192.168.223.153
S3 客户端 s3cmd 使用
# 安装
$ yum install -y s3cmd
# 配置
$ s3cmd --configure
Access Key []: leffss
Secret Key []: 123456
Default Region []: default # S3服务的访问端点和默认的Region(Ceph的新版本中称作zonegroup)
S3 Endpoint []: rgw.local # 前面安装 rgw 设置的 dns 域名
DNS-style bucket+hostname:port template for accessing a bucket []: %(bucket)s.rgw.local
Encryption password []: 123456
Path to GPG program [/usr/bin/gpg]:
Use HTTPS protocol []: no
HTTP Proxy server name:
Test access with supplied credentials? [Y/n] y
Save settings? [y/N] y
- 配置文件保存 /root/.s3cfg
修改本机 hosts 文件,添加
192.168.223.153 rgw.local
192.168.223.153 demobucket.rgw.local
- demobucket 代表 bucket 名称,rgw.local 代表 rgw 域名,实际生产中需要搭建 dns 服务使用泛解析,这里只是测试就直接添加 hosts 文件了
命令测试
#创建bucket,相当于访问 http://demobucket.rgw.local
$ s3cmd mb s3://demobucket
Bucket 's3://demobucket/' created
#删除bucket
$ s3cmd rb s3://demobucket
Bucket 's3://demobucket/' removed
#上传文件至bucket
$ s3cmd put --acl-public /tmp/yum.log s3://demobucket/yum.log
upload: '/tmp/yum.log' -> 's3://demobucket/yum.log' [1 of 1]
6 of 6 100% in 0s 218.19 B/s done
Public URL of the object is: http://demobucket.rgw.local/yum.log
#获取文件
$ s3cmd get s3://demobucket/demoobject ./demoobject
download: 's3://demobucket/yum.log' -> './yum.log' [1 of 1]
6 of 6 100% in 0s 468.79 B/s done
# curl 方式获取
$ curl http://demobucket.rgw.local/yum.log
xxx11
# 或者,使用这种 url 指定 bucket 的方式相对于域名的方式最大的好处就是不需要 dns 泛解析了
$ curl http://rgw.local/demobucket/yum.log
xxx11
Swift 方式访问
什么是 Swift
openstack swift是openstack开源云计算项目开源的对象存储,提供了强大的扩展性、冗余和持久性
Swift特性
- 极高的数据持久性
- 完全对称的系统架构
- 无限的可扩展性
- 无单点故障
Swift-API 操作
Swift-API 的上下文中,存储桶以container表示,而非S3中的bucket,但二者在功用上类同,都是对象数据的容器,且对象存储在容器中。Openstack Swift API的用户模型与Amazon S3 API稍有不同。若要使用swift api通过rados网关的身份验证,需要为rados网关用户帐户配置子用户。swift有租户概念,rados网关用户对应swift的租户,而子帐号则对应swift的api用户
Swift 的用户账号对应于 radosgw 中的 subuser(子用户),它隶属于某个事先存在的 user(用户账号)
#创建主账户
$ radosgw-admin user create --uid="swiftuser" --display-name="Swift Testing User"
{
"user_id": "swiftuser",
"display_name": "Swift Testing User",
"email": "",
"suspended": 0,
"max_buckets": 1000,
"auid": 0,
"subusers": [],
"keys": [
{
"user": "swiftuser",
"access_key": "220DSCM8265NTLO21RCB",
"secret_key": "VPN0mvA9DNAIDxuehRIqc297vcoaHLcZWhpAAJev"
}
],
"swift_keys": [],
"caps": [],
"op_mask": "read, write, delete",
"default_placement": "",
"placement_tags": [],
"bucket_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"user_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"temp_url_keys": [],
"type": "rgw"
}
# 创建swift子用户
$ radosgw-admin subuser create --uid="swiftuser" --subuser="swiftuser:swiftsubuser" --access="full"
# --uid 指定现有的 rgw 网关主用户
# --subuser 指定子用户,格式[主用户:子用户]
# --access 指定用户权限
# - r 读取
# - w 写入
# - rw 读写
# - full 完全
{
"user_id": "swiftuser",
"display_name": "Swift Testing User",
"email": "",
"suspended": 0,
"max_buckets": 1000,
"auid": 0,
"subusers": [
{
"id": "swiftuser:swiftsubuser",
"permissions": "full-control"
}
],
"keys": [
{
"user": "swiftuser",
"access_key": "220DSCM8265NTLO21RCB",
"secret_key": "VPN0mvA9DNAIDxuehRIqc297vcoaHLcZWhpAAJev"
}
],
"swift_keys": [
{
"user": "swiftuser:swiftsubuser",
"secret_key": "MLJzEgvLT2SrxusMSFjVB4s5PjdKwFPgNC9my3jC"
}
],
"caps": [],
"op_mask": "read, write, delete",
"default_placement": "",
"placement_tags": [],
"bucket_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"user_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"temp_url_keys": [],
"type": "rgw"
}
Swift 用户管理
#修改子用户
rados-admin subuser modify --subuser=uid:subuserid --access=full
#删除子用户
radosgw-admin subuser rm --subuser=uid:subuserid [--purge-data] [--purge-keys]
#修改子用户密钥
radosgw-admin key create --subuser=uid:subuserid --key-type=swift [--access-key=key] [--secret=secret]
#删除子用户密钥
radosgw-admin key rm --subuser=uid:subuserid
Swift 客户端
- swift 客户端不像s3客户端一样有本地的配置信息文件,所以没有次操作都要带上账号的认证信息
- RADOS 网关支持Swift v1.0以及OpenStack keystone v2.0身份验证
# 安装 swift 客户端
yum install -y python3-pip
pip3 install python-swiftclient
# 创建一个容器
swift -V 1.0 -A http://rgw.local/auth -U swiftuser:swiftsubuser -K MLJzEgvLT2SrxusMSFjVB4s5PjdKwFPgNC9my3jC post testcontainer
# 向容器中上传一个文件
$ swift -A http://rgw.local/auth/v1.0 -U swiftuser:swiftsubuser -K MLJzEgvLT2SrxusMSFjVB4s5PjdKwFPgNC9my3jC upload testcontainer /tmp/yum.log
tmp/yum.log
# 列出容器中的文件
$ swift -A http://rgw.local/auth/v1.0 -U swiftuser:swiftsubuser -K MLJzEgvLT2SrxusMSFjVB4s5PjdKwFPgNC9my3jC list testcontainer
tmp/yum.log
# 查看容器状态
$ swift -A http://rgw.local/auth/v1.0 -U swiftuser:swiftsubuser -K MLJzEgvLT2SrxusMSFjVB4s5PjdKwFPgNC9my3jC stat testcontainer
Account: v1
Container: testcontainer
Objects: 1
Bytes: 6
Read ACL:
Write ACL:
Sync To:
Sync Key:
X-Timestamp: 1627709129.41056
X-Container-Bytes-Used-Actual: 4096
X-Storage-Policy: default-placement
X-Trans-Id: tx000000000000000000020-006104e01b-3747-default
X-Openstack-Request-Id: tx000000000000000000020-006104e01b-3747-default
Accept-Ranges: bytes
Content-Type: text/plain; charset=utf-8
# 列出全部容器
$ swift -A http://rgw.local/auth/v1.0 -U swiftuser:swiftsubuser -K MLJzEgvLT2SrxusMSFjVB4s5PjdKwFPgNC9my3jC list
testcontainer
# 查看swift状态
$ swift -A http://rgw.local/auth/v1.0 -U swiftuser:swiftsubuser -K MLJzEgvLT2SrxusMSFjVB4s5PjdKwFPgNC9my3jC stat
Account: v1
Containers: 1
Objects: 1
Bytes: 6
Containers in policy "default-placement": 1
Objects in policy "default-placement": 1
Bytes in policy "default-placement": 6
Objects in policy "default-placement-bytes": 0
Bytes in policy "default-placement-bytes": 0
X-Timestamp: 1627709922.41707
X-Account-Bytes-Used-Actual: 4096
X-Trans-Id: tx000000000000000000027-006104e1e2-3747-default
X-Openstack-Request-Id: tx000000000000000000027-006104e1e2-3747-default
Accept-Ranges: bytes
Content-Type: text/plain; charset=utf-8
k8s 使用 ceph
cephfs pv 模式
集群必须开启 cephfs。首先把 ceph 用户的密钥以 secret 形式存储起来,获取 admin 用户的密钥,如果使用其他用户,可以把 admin 替换为要使用的用户名即可。
$ ceph auth get-key client.admin | base64
QVFEMDFWVmFWdnp6TFJBQWFUVVJ5VVp3STlBZDN1WVlGUkwrVkE9PQ==
$ cat ceph-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: ceph-secret
data:
key: QVFEMDFWVmFWdnp6TFJBQWFUVVJ5VVp3STlBZDN1WVlGUkwrVkE9PQ==
- k8s 集群 Secret 是保存的 base64 数据
接下来创建 pv:
$ cat cephfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: cephfs-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
cephfs:
monitors:
- <monitor1-id>:6789
- <monitor2-id>:6789
- <monitor3-id>:6789
user: admin
secretRef:
name: ceph-secret
readOnly: false
persistentVolumeReclaimPolicy: Recycle
最后创建 pvc:
$ cat cephfs-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: cephfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
pv 和 pvc 都有以后,使用方式和普通的 pv 和 pvc 无异了。
cephfs storageclass 模式
参考:https://www.cnblogs.com/leffss/p/15630641.html
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 我与微信审核的“相爱相杀”看个人小程序副业
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~