在不同负载的项目中使用Ceph作为网络存储,我们可能会遇到各种乍一看并不简单或琐碎的任务。 例如:
- 将数据从旧 Ceph 迁移到新集群,部分使用新集群中以前的服务器;
- Ceph中磁盘空间分配问题的解决方案。
处理此类问题,我们面临着需要正确删除OSD而不丢失数据,这在处理大量数据时尤其重要。 这将在文章中讨论。
下面描述的方法适用于任何版本的 Ceph。 另外,会考虑到Ceph可以存储大量数据的事实:为了防止数据丢失和其他问题,某些操作将被“拆分”为其他几个操作。
关于 OSD 的前言
由于所讨论的三个配方中有两个专用于 OSD(
首先应该说整个Ceph集群是由很多OSD组成的。 越多,Ceph 中的可用数据量就越大。 从这里就很容易理解了 主要 OSD 功能:它将 Ceph 对象数据存储在所有集群节点的文件系统上,并提供对其的网络访问(用于读取、写入和其他请求)。
在同一级别,复制参数是通过在不同OSD之间复制对象来设置的。 在这里您可能会遇到各种问题,下面将讨论其解决方案。
案例1。 从 Ceph 集群中安全删除 OSD,不会丢失数据
删除 OSD 的需要可能是由于从集群中删除服务器而导致的 - 例如,用另一台服务器替换它 - 这就是我们遇到的情况,从而引发了本文的写作。 因此,操纵的最终目标是提取给定服务器上的所有 OSD 和 mon,以便可以停止它。
为了方便起见,并避免在执行命令时错误指示所需的 OSD,我们将设置一个单独的变量,其值将是要删除的 OSD 的编号。 我们就这样称呼她吧 ${ID}
- 在这里和下面,这样的变量替换了我们正在使用的 OSD 的编号。
我们先来看一下开始工作前的情况:
root@hv-1 ~ # ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-1 0.46857 root default
-3 0.15619 host hv-1
-5 0.15619 host hv-2
1 ssd 0.15619 osd.1 up 1.00000 1.00000
-7 0.15619 host hv-3
2 ssd 0.15619 osd.2 up 1.00000 1.00000
要启动 OSD 删除,您需要顺利执行 reweight
就将其归零。 通过这种方式,我们可以通过平衡其他 OSD 来减少 OSD 中的数据量。 为此,请运行以下命令:
ceph osd reweight osd.${ID} 0.98
ceph osd reweight osd.${ID} 0.88
ceph osd reweight osd.${ID} 0.78
……依此类推,直到为零。
需要平稳平衡以免丢失数据。 如果 OSD 包含大量数据,则尤其如此。 确保执行命令后 reweight
一切顺利,你可以完成它 ceph -s
或在单独的终端窗口中运行 ceph -w
以便实时观察变化。
当 OSD 被“清空”时,您可以继续标准操作将其删除。 为此,请将所需的 OSD 转移到状态 down
:
ceph osd down osd.${ID}
让我们将 OSD 从集群中“拉”出来:
ceph osd out osd.${ID}
让我们停止 OSD 服务并卸载其在 FS 中的分区:
systemctl stop ceph-osd@${ID}
umount /var/lib/ceph/osd/ceph-${ID}
删除 OSD
ceph osd crush remove osd.${ID}
让我们删除 OSD 用户:
ceph auth del osd.${ID}
最后,让我们删除 OSD 本身:
ceph osd rm osd.${ID}
注意:如果您使用的是Ceph Luminous版本或更高版本,那么上面的OSD删除步骤可以减少为两个命令:
ceph osd out osd.${ID}
ceph osd purge osd.${ID}
如果完成上述步骤后,您运行命令 ceph osd tree
,那么应该清楚的是,在执行工作的服务器上不再有执行上述操作的 OSD:
root@hv-1 ~ # ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-1 0.46857 root default
-3 0.15619 host hv-1
-5 0.15619 host hv-2
-7 0.15619 host hv-3
2 ssd 0.15619 osd.2 up 1.00000 1.00000
在此过程中,请注意 Ceph 集群的状态将变为 HEALTH_WARN
,我们还将看到 OSD 数量和可用磁盘空间量的减少。
下面将描述如果您想要完全停止服务器并相应地将其从 Ceph 中删除所需的步骤。 在这种情况下,重要的是要记住 关闭服务器之前,必须删除所有 OSD 在此服务器上。
如果该服务器上不再有 OSD,则在删除它们后,您需要从 OSD 映射中排除该服务器 hv-2
通过运行以下命令:
ceph osd crush rm hv-2
清除 mon
从服务器 hv-2
通过在另一台服务器上运行以下命令(即在本例中,在 hv-1
):
ceph-deploy mon destroy hv-2
此后,您可以停止服务器并开始后续操作(重新部署等)。
案例2。 已创建的 Ceph 集群中的磁盘空间分布
我将从关于PG的序言开始第二个故事(
所以:使用Ceph时常见的问题之一是Ceph中池之间的OSD和PG数量不平衡。
首先,正因为如此,可能会出现在一个小池中指定过多PG的情况,这本质上是集群中磁盘空间的不合理使用。 其次,在实践中存在一个更严重的问题:其中一个OSD的数据溢出。 这需要集群首先转换到状态 HEALTH_WARN
, 接着 HEALTH_ERR
。 原因是 Ceph 在计算可用数据量时(可以通过 MAX AVAIL
在命令输出中 ceph df
分别针对每个池)基于 OSD 中的可用数据量。 如果至少一个 OSD 中没有足够的空间,则无法写入更多数据,直到数据在所有 OSD 之间正确分配为止。
这些问题值得澄清 很大程度上是在Ceph集群配置阶段决定的。 您可以使用的工具之一是
那么,我们想象一下下面的图:集群有一个状态 HEALTH_WARN
由于其中一个 OSD 空间不足。 这将由错误指示 HEALTH_WARN: 1 near full osd
。 下面是摆脱这种情况的算法。
首先,您需要在剩余的 OSD 之间分配可用数据。 当我们“耗尽”节点时,我们已经在第一种情况下执行了类似的操作 - 唯一的区别是现在我们需要稍微减少 reweight
。 例如,最大 0.95:
ceph osd reweight osd.${ID} 0.95
这会释放 OSD 中的磁盘空间并修复 ceph 运行状况中的错误。 然而,正如已经提到的,这个问题主要是由于 Ceph 在初始阶段的配置不正确而导致的:重新配置非常重要,这样以后就不会出现这种情况。
在我们的具体案例中,一切都归结为:
- 价值太高
replication_count
在其中一个水池中, - 一个池中的 PG 太多,而另一个池中的 PG 太少。
让我们使用已经提到的计算器。 它清楚地显示了需要输入的内容,原则上没有什么复杂的。 设置必要的参数后,我们得到以下建议:
注意:如果您要从头开始设置 Ceph 集群,计算器的另一个有用功能是生成命令,这些命令将使用表中指定的参数从头开始创建池。
最后一栏可帮助您导航 - 建议 PG 数。 在我们的例子中,第二个也很有用,其中指示了复制参数,因为我们决定更改复制乘数。
因此,首先您需要更改复制参数 - 这是值得首先做的,因为通过减少乘数,我们将释放磁盘空间。 当命令执行时,您会注意到可用磁盘空间会增加:
ceph osd pool $pool_name set $replication_size
完成后,我们更改参数值 pg_num
и pgp_num
如下所示:
ceph osd pool set $pool_name pg_num $pg_number
ceph osd pool set $pool_name pgp_num $pg_number
这一点很重要:我们必须依次更改每个池中的 PG 数量,并且不要更改其他池中的值,直到警告消失 “数据冗余降级” и “n-数量的 pgs 降级”.
您还可以使用命令输出检查一切是否顺利 ceph health detail
и ceph -s
.
案例3。 将虚拟机从 LVM 迁移到 Ceph RBD
当项目使用租用的裸机服务器上安装的虚拟机时,经常会出现存储容错的问题。 也非常希望这个存储有足够的空间...另一种常见情况:服务器上有一个带有本地存储的虚拟机,需要扩展磁盘,但无处可去,因为没有服务器上剩余的可用磁盘空间。
该问题可以通过不同的方式解决 - 例如,迁移到另一台服务器(如果有)或向该服务器添加新磁盘。 但并不总是能够做到这一点,因此从 LVM 迁移到 Ceph 可以很好地解决这个问题。 通过选择此选项,我们还简化了服务器之间的进一步迁移过程,因为无需将本地存储从一个虚拟机管理程序移动到另一个虚拟机管理程序。 唯一的问题是您必须在工作进行时停止虚拟机。
以下食谱摘自
让我们进入实际部分。 在示例中,我们使用 virsh,并相应地使用 libvirt。 首先,确保数据要迁移到的 Ceph 池已连接到 libvirt:
virsh pool-dumpxml $ceph_pool
池描述必须包含与 Ceph 的连接数据和授权数据。
下一步是将 LVM 映像转换为 Ceph RBD。 执行时间主要取决于图像的大小:
qemu-img convert -p -O rbd /dev/main/$vm_image_name rbd:$ceph_pool/$vm_image_name
转换后,将保留 LVM 映像,如果将 VM 迁移到 RBD 失败并且您必须回滚更改,该映像将非常有用。 另外,为了能够快速回滚更改,让我们对虚拟机配置文件进行备份:
virsh dumpxml $vm_name > $vm_name.xml
cp $vm_name.xml $vm_name_backup.xml
...并编辑原始内容(vm_name.xml
)。 让我们找到一个包含磁盘描述的块(以行开头 <disk type='file' device='disk'>
并以 </disk>
) 并将其简化为以下形式:
<disk type='network' device='disk'>
<driver name='qemu'/>
<auth username='libvirt'>
<secret type='ceph' uuid='sec-ret-uu-id'/>
</auth>
<source protocol='rbd' name='$ceph_pool/$vm_image_name>
<host name='10.0.0.1' port='6789'/>
<host name='10.0.0.2' port='6789'/>
</source>
<target dev='vda' bus='virtio'/>
<alias name='virtio-disk0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</disk>
让我们看一些细节:
- 至协议
source
指示 Ceph RBD 中存储的地址(这是指示 Ceph 池和 RBD 映像名称的地址,在第一阶段确定)。 - 在块
secret
类型已指示ceph
,以及连接到它的秘密的 UUID。 可以使用命令找到它的uuidvirsh secret-list
. - 在块
host
指示了 Ceph 监视器的地址。
编辑配置文件并完成 LVM 到 RBD 转换后,您可以应用修改后的配置文件并启动虚拟机:
virsh define $vm_name.xml
virsh start $vm_name
现在是时候检查虚拟机是否正确启动了:例如,您可以通过 SSH 连接到虚拟机或通过 virsh
.
如果虚拟机工作正常并且您没有发现任何其他问题,那么您可以删除不再使用的LVM映像:
lvremove main/$vm_image_name
结论
我们在实践中遇到了所有描述的案例 - 我们希望这些说明能够帮助其他管理员解决类似的问题。 如果您对使用 Ceph 的经历有任何评论或其他类似的故事,我们将很高兴在评论中看到它们!
PS
另请阅读我们的博客:
- «
我们的双手不是为了无聊:在 K8s 中恢复 Rook 集群 “; - «
去鲁克还是不去鲁克——这是一个问题 “; - «
Rook - Kubernetes 的“自助”数据仓库 “; - «
基于 Ceph 的 Kubernetes 中的配置创建持久存储 “。
来源: habr.com