在 Docker 中运行 Ceph

还没有读者喜欢这个。
open source button on keyboard

Opensource.com

Ceph 是一个完全开源的分布式对象存储、网络块设备和文件系统,专为可靠性、性能和从 TB 级到 EB 级的可扩展性而设计。Ceph 利用一种新颖的放置算法(CRUSH)、活动存储节点和对等 gossip 协议,以避免与集中式控制器和查找表相关的可扩展性和可靠性问题。Ceph 是一个庞大且不断增长的生态系统的一部分,它集成在虚拟化平台 (Proxmox)、云平台 (OpenStack、CloudStack、OpenNebula)、容器 (Docker) 和大数据 (Hadoop,作为 HDFS 的元数据服务器) 中。

自从我第一次尝试在 Docker 中运行 Ceph 以来,已经过去了将近两年。直到最近,我才真正有时间恢复这项工作。在过去的几个月里,我一直投入一些时间来贡献于在 Docker 中部署 Ceph

(在我们开始之前,我想强调一下,如果没有 Seán C. McCord 的帮助,这项工作是不可能实现的。事实上,当前的 ceph-docker 仓库是基于 Seán 的初步工作。)

现在让我们深入了解一下,看看如何让它运行起来!

理由

在 Docker 中运行 Ceph 有点争议,因为很多人可能认为这样做毫无意义。虽然对于 monitor、metadata server 和 RADOS gateway 来说,容器化并不是什么问题,但当涉及到 OSD(对象存储守护进程)时,事情就变得棘手了。Ceph OSD 针对其运行的机器进行了优化,并且与硬件有着密切的关系。如果 OSD 依赖的磁盘出现故障,OSD 就无法工作,这在容器世界中有点问题。

老实说,有那么一瞬间我发现自己在想:

我不知道我为什么要做这个。我只知道外面的人想要它(是的,他们可能也不知道为什么)。我认为无论如何尝试一下很重要,所以让我们开始吧。

我知道这听起来不是很乐观,但这是事实。不过,我的观点略有改变,所以无论如何,让我解释一下原因。也许它也会改变你的想法。(是的,我的解释会不仅仅是:Docker 很时髦,所以让我们将一切 Docker 化。)

人们已经开始投入大量的工程努力,在其平台上运行容器化的软件。因此,他们一直在使用各种工具来构建和编排他们的环境。我不会惊讶地看到 Kubernetes 成为此事的编排工具。有些人也喜欢在生产环境中使用前沿技术,因为他们可能会觉得其他事情很无聊。因此,通过“容器化一切”的方法,他们会很高兴看到他们最喜欢的开源存储解决方案正在发生一些事情。

yumapt-get 不同,回滚并不总是容易的,容器有点不同。升级和回滚变得更容易,因为你可以轻松地使用 docker stopdocker run 来推出新版本的守护进程。你还可以在同一台机器上以隔离的方式运行不同的集群。这对于开发来说是理想的。

项目

正如前面提到的,一切都始于 Seán C. McCord 的工作,我们围绕他的工作进行了迭代。目前,如果你使用 ceph-docker,你将能够在 Ubuntu 或 CentOS 上运行每个 Ceph 守护进程。我们在 Docker Hub 上有很多可用的镜像。我们使用 Ceph 命名空间,所以我们的镜像以 ceph/<daemon> 为前缀。我们使用自动构建;因此,每次我们合并一个新的补丁,都会触发一个新的构建,并生成一个新版本的容器镜像。由于我们目前正处于重构过程中,你将看到有很多镜像可用。从历史上看,我们曾经(并且直到我们合并这个 补丁 之前仍然如此)每个守护进程一个镜像。因此,monitor、osd、mds 和 radosgw 各一个容器镜像。这并不是很理想,实际上也没有必要。这就是为什么我们 致力于 一个名为 daemon 的单一容器镜像。这个镜像包含所有 Ceph 守护进程,你可以在调用 docker run 命令时使用一个参数来激活你想要的那个。话虽如此,如果你想开始,我鼓励你直接使用 ceph/daemon 镜像。我将在下一节展示如何运行它的示例。

容器化 Ceph

Monitor

鉴于 monitor 无法通过 NAT 网络进行通信,我们需要使用 --net=host 来暴露 Docker 主机机器的网络堆栈

$ sudo docker run -d --net=host \
-v /etc/ceph:/etc/ceph \
-v /var/lib/ceph/:/var/lib/ceph \
-e MON_IP=192.168.0.20 \
-e CEPH_PUBLIC_NETWORK=192.168.0.0/24 \
ceph/daemon mon

以下是可供你选择的选项。

  • MON_IP 是运行 Docker 的主机的 IP 地址。
  • MON_NAME 是你的 monitor 的名称(默认值:$(hostname))。
  • CEPH_PUBLIC_NETWORK 是运行 Docker 的主机的 CIDR。它应该与 MON_IP 在同一个网络中。
  • CEPH_CLUSTER_NETWORK 是运行 Docker 的主机的辅助接口的 CIDR。用于 OSD 复制流量。

对象存储守护进程

当前的实现允许你每个容器运行一个 OSD 进程。遵循 微服务 的理念,我们不应该在我们的容器中运行多个服务。在我们的例子中,在单个容器中运行多个 OSD 进程违反了这条规则,并且可能会引入不良行为。这也将增加解决方案的设置和维护复杂性。

在这种配置中,严格要求使用 --privileged=true,因为我们需要完全访问 /dev/ 和其他内核功能。但是,我们支持另一种基于暴露 OSD 目录的配置,操作员将在其中进行设备的适当准备。然后,他或她将简单地暴露 OSD 目录,并且入口点将完成填充(ceph-osd mkfs)。我现在展示的配置更容易上手,因为你只需要指定一个块设备,入口点将完成剩下的工作。

那些不想使用 --privileged=true 的人可以退回到第二个示例。

$ sudo docker run -d --net=host \
--privileged=true \
-v /etc/ceph:/etc/ceph \
-v /var/lib/ceph/:/var/lib/ceph \
-v /dev/:/dev/ \
-e OSD_DEVICE=/dev/vdd \
ceph-daemon osd_ceph_disk

如果你不想使用 --privileged=true,你总是可以使用你选择的配置管理工具自行准备 OSD。

在没有特权模式的示例中,在此示例中,我们假设你已分区、放置文件系统并挂载了 OSD 分区。要创建你的 OSD,只需运行以下命令:

$ sudo docker exec <mon-container-id> ceph osd create。

然后像这样运行你的容器

docker run -v /osds/1:/var/lib/ceph/osd/ceph-1 -v /osds/2:/var/lib/ceph/osd/ceph-2

$ sudo docker run -d --net=host \
-v /etc/ceph:/etc/ceph \
-v /var/lib/ceph/:/var/lib/ceph \
-v /osds/1:/var/lib/ceph/osd/ceph-1 \
ceph-daemon osd_disk_directory

以下是可供你选择的选项。

  • OSD_DEVICE 是 OSD 设备,即:/dev/sdb
  • OSD_JOURNAL 是将用于存储 OSD 日志的设备,即:/dev/sdz
  • HOSTNAME 是运行 OSD 的容器的主机名(默认值:$(hostname))
  • OSD_FORCE_ZAP 将强制擦除给定设备的内容(默认值:0,1 表示强制擦除)
  • OSD_JOURNAL_SIZE 是 OSD 日志的大小(默认值:100)

元数据服务器

这个非常简单易用。目前唯一的注意事项是我们要求 Ceph 管理员密钥在 Docker 中可用。此密钥将用于创建 CephFS 池和文件系统。

如果你运行的是旧版本的 Ceph(0.87 之前),你不需要这个,但你可能想知道,因为运行最新版本总是最好的!

$ sudo docker run -d --net=host \
-v /var/lib/ceph/:/var/lib/ceph \
-v /etc/ceph:/etc/ceph \
-e CEPHFS_CREATE=1 \
ceph-daemon mds

以下是可供你选择的选项。

  • MDS_NAME 是元数据服务器的名称(默认值:mds-$(hostname))。
  • CEPHFS_CREATE 将为你的元数据服务器创建一个文件系统(默认值:0,1 表示启用它)。
  • CEPHFS_NAME 是元数据文件系统的名称(默认值:cephfs)。
  • CEPHFS_DATA_POOL 是元数据服务器的数据池的名称(默认值:cephfs_data)。
  • CEPHFS_DATA_POOL_PG 是数据池的放置组数量(默认值:8)。
  • CEPHFS_DATA_POOL 是元数据服务器的元数据池的名称(默认值:cephfs_metadata)。
  • CEPHFS_METADATA_POOL_PG 是元数据池的放置组数量(默认值:8)。

RADOS 网关

对于 RADOS 网关,我们默认启用 civetweb 进行部署。但是,可以通过简单地给出远程地址和端口来使用不同的 CGI 前端。

$ sudo docker run -d --net=host \
-v /var/lib/ceph/:/var/lib/ceph \
-v /etc/ceph:/etc/ceph \
ceph-daemon rgw

以下是可供你选择的选项。

  • RGW_REMOTE_CGI 定义是否使用 RADOS 网关的嵌入式 Web 服务器(默认值:0,1 表示禁用它)。
  • RGW_REMOTE_CGI_HOST 是运行 CGI 进程的远程主机。
  • RGW_REMOTE_CGI_PORT 是运行 CGI 进程的主机的远程端口。
  • RGW_CIVETWEB_PORT 是 civetweb 的监听端口(默认值:80)。
  • RGW_NAME 是 RADOS 网关实例的名称(默认值:$(hostname))。

进一步的工作

配置存储后端

默认情况下,ceph.conf 和所有 Ceph 密钥在初始 monitor 引导期间生成。此过程假设要将你的集群扩展到多个节点,你必须在所有节点之间分发这些配置。这不是很灵活,我们想改进这一点。我很快将提出的一个想法是使用 Ansible 生成配置/密钥,并在所有机器上分发它们。

或者,我们希望能够将各种配置文件存储在不同的后端,例如 etcdconsul

编排部署

第一步是使用 ceph-ansible,其中逻辑已经实现。我还需要推送一些更改,但大部分工作已经完成。对于 Kubernetes,关于如何引导 monitor 的预览已经 可用

扩展到 Rocket 及更远

这里没什么可做的,因为你可以简单地将你的 Docker 镜像移植到 Rocket 并启动它们(双关语)。

想了解更多?以下提供了一个流程的视频演示。

标签
User profile image.
Sebastien Han 目前在 Red Hat 担任高级云架构师。自 2011 年以来,他一直参与 OpenStack 和 Ceph,并在这两项技术方面积累了丰富的专业知识。他好奇而充满热情,热爱研究前沿技术,并一直希望找到合适的切入点来整合他最喜欢的两项技术。

评论已关闭。

© . All rights reserved.