进行破坏性实验以确保我们的数据恢复
有时候,你只需要一个有效的存储空间。拥有云提供商的存储类并不总是可行的,你必须自己管理。这是我为我的医疗行业的客户解决的挑战。
在本文中,您将了解为什么以及如何安装 Rook Ceph,为您的 Kubernetes 集群提供易于使用的复制存储等级。
然后我们将部署一个文件共享应用程序,破坏部署它的节点,看看会发生什么。Ceph 是否能让我们的文件再次可访问?

选择存储解决方案
在 Kubernetes 中,存储一直是一个挑战,因为它没有本地提供冗余和分布式存储解决方案。使用原生 Kubernetes,您只能附加一个 hostPath 卷进行持久化存储。
我的客户有自己的本地基础架构,并希望确保其中一个服务器出现故障时不会丢失任何数据。他们大多数的应用是单体架构,并不包括本地的数据复制机制。
因此,我必须从多种存储解决方案中进行选择。我的客户不需要超高的性能,但希望有一个稳定的解决方案。我选择了 Rook Ceph,原因如下:
准备您的集群
我们需要一个至少有 3 个节点和每个节点至少有 1 个空附加磁盘的 Kubernetes 集群。
我建议使用Scaleway Kapsule来轻松创建一个 Kubernetes 集群并为每个节点分配未格式化的磁盘。一旦 Kubernetes 集群启动,我们将为每个节点创建一个附加卷(磁盘):
- 转到“实例”
- 选择您的节点
- 点击“附加卷”选项卡
- 点击“+”(创建卷)并创建一个新的磁盘
下载您的 kubeconf 文件,并将其放置在 ~/.kube/config 中。现在,您应该可以使用您的 kubectl CLI 访问您的集群。
安装 Rook Ceph
1. 这篇博文在GitHub 上有附带的仓库,让我们克隆它以获得我们所需要的所有资源
git clone https://github.com/flavienbwk/ceph-kubernetescd ceph-kubernetes
2. 克隆 Rook 仓库并部署 Rook Ceph operator
git clone --single-branch --branch release-1.11 https://github.com/rook/rook.gitkubectl create -f ./rook/deploy/examples/crds.yamlkubectl create -f ./rook/deploy/examples/common.yamlkubectl create -f ./rook/deploy/examples/operator.yaml
3. 创建 Ceph 集群
kubectl create -f ./rook/deploy/examples/cluster.yaml -n rook-ceph
等待几分钟,让 Ceph 配置磁盘。健康状态应为 HEALTH_OK:
kubectl get cephcluster -n rook-ceph
4. 创建存储类
Rook Ceph可以为您提供两种主要的存储类。一种是RBD,允许您在ReadWriteOnce模式下拥有复制的存储。我们将安装的第二种存储类是CephFS,它允许您在ReadWriteMany模式下拥有复制的存储。RBD代表RADOS块设备,允许您在Kubernetes集群中提供卷的存储类。此项仅支持ReadWriteOnce卷(RWO)。CephFS的功能类似于复制的NFS服务器。这将使我们能够在ReadWriteMany模式(RWX)下创建卷。
kubectl create -f ./rook/deploy/examples/csi/rbd/storageclass.yaml -n rook-cephkubectl create -f ./rook/deploy/examples/filesystem.yaml -n rook-cephkubectl create -f ./rook/deploy/examples/csi/cephfs/storageclass.yaml -n rook-ceph
5. 部署Ceph仪表板
kubectl create -f ./rook/deploy/examples/dashboard-external-https.yaml -n rook-ceph
转发仪表板的HTTP访问:
kubectl port-forward service/rook-ceph-mgr-dashboard -n rook-ceph 8443:8443
使用用户名admin和以下密码连接:
kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath="{['data']['password']}"
您应该通过https://localhost:8443浏览以下页面
部署应用程序
我们将部署一个自托管的文件共享应用程序(psitransfer),以检查我们的卷是否正确绑定。
1. 部署文件共享应用程序(NodePort 30080)
kubectl create -f ./psitransfer-deployment-rwx.yaml
2. 查看它部署在哪个节点上
kubectl get pods -o wide -l app=psitransfer
获取此节点的IP(通过Scaleway界面)并检查该应用程序是否在http://nodeip:30080运行
3. 让我们上传一些文件
从5MB,10MB和20MB文件来自xcal1.vodafone.co.uk网站。
将它们上传到我们的文件传输应用程序。点击屏幕上显示的链接。
现在您应该看到已导入的三个文件树。单击它并将链接保存在浏览器选项卡中,我们稍后会使用它。
上传约400MB的文件后,我们可以看到数据的复制在磁盘之间是一致的。我们看到在上传文件时,3个磁盘同时写入。在以下屏幕截图中,每个磁盘的使用率为1%:虽然我在同一主机上上传,但看起来复制按预期工作,数据均匀保留在3个磁盘(OSD)上。磁盘2有大量的“读取”活动,因为另外2个磁盘从它同步数据。
Ceph的仪表板现在应该如下所示:
图片:
C. 销毁和观察
我们将停止托管 Web 应用程序的节点,以确保数据在其他节点上复制。
- 查看应用程序部署在哪个节点上
kubectl get pods -o wide -l app=psitransfer
2. 从 Scaleway 控制台关闭节点
这将模拟节点的电源故障。几分钟后,它应该变为 NotReady:
$> kubectl get node
NAME STATUS ROLES AGE VERSION
scw-ceph-test-clustr-default-5f02f221c3814b47a Ready 3d1h v1.26.2
scw-ceph-test-clustr-default-8929ba466e404a00a Ready 3d1h v1.26.2
scw-ceph-test-clustr-default-94ef39ea5b1f4b3e8 NotReady 3d1h v1.26.2
此时,在我们的 Ceph 仪表板上,节点 3 不可用:
图片:
Ceph 的仪表板现在应该是这样的:
图片:
3. 重新调度我们的 pod
计划的 pod 节点不可用。然而,我们的 pod 仍然认为它处于活动状态:
$> kubectl get pods -o wide -l app=psitransfer
NAME READY STATUS RESTARTS AGE IP NODE
psitransfer-deployment-8448887c9d-mt6wm 1/1 Running 0 19h 100.64.1.19 scw-ceph-test-clustr-default-94ef39ea5b1f4b3e8
删除它以在另一个节点上重新调度:
kubectl delete pod psitransfer-deployment-8448887c9d-mt6wm
检查新重新启动的 pod 的状态。你的应用程序应该再次在之前保留的链接上可用。
图片:
为了避免在节点变为 “NotReady” 时手动删除要重新调度的 pod,将您的应用程序的副本数默认至少扩展到 3 个。
现在可以重新启动之前关闭的节点。
何时使用 rook-ceph-block 或 rook-cephfs?
如果您的应用程序需要更好的性能,并且需要 RWO 访问模式的块存储,请使用 rook-ceph-block (RBD) 存储类。另一方面,如果您的应用程序需要带有 RWX (CephFS) 访问模式和 POSIX 合规性的共享文件系统,请使用 rook-cephfs 存储类。
如果选择 RBD,并尝试在离线的原始节点上重新调度 pod(与我们在 CephFS 中所做的操作相同),你将从 PVC 得到一个错误:“Volume is already exclusively attached to one node and can’t be attached to another”。在这种情况下,您只需要等待 PVC 再次绑定(我的集群自动将 PVC 重新分配给我的 pod,需要约 6 分钟才能开始)。
尝试此行为,请按照关联的存储库章节。
最后
您已经学会了如何安装和部署带有 Ceph 的应用程序。您甚至证明了数据的复制。恭喜 ✨
所有图片(除非另有说明),均由作者提供。