在 Docker 中启动你的 Ceph 集群

自从我第一次尝试 在 Docker 中运行 Ceph 以来,已经过去了将近两年。时间流逝,直到最近我才真正有时间恢复这项工作。在过去的几个月里,我一直在投入三分之一的时间来贡献 Ceph 在 Docker 中 的部署。在开始之前,我想强调的是,如果没有 Seán C. McCord 的帮助,这项工作都不可能实现。事实上,当前的 ceph-docker 仓库是基于 Seán 的初始工作。让我们看看如何让它运行!
原理
在 Docker 中运行 Ceph 有点争议,很多人可能认为这样做没有意义。对于 Monitors、Metadata Server 和 Rados Gateway 来说,容器化并不是什么问题,但对于 OSD 来说就比较棘手了。Ceph OSD 与其运行的机器紧密相关,这种与硬件的紧密关系并非所有软件都具备。考虑到 OSD 无法在依赖的磁盘发生故障时工作,这在容器化世界中是一个问题。
老实说,在某个时候,我一直在思考这个问题
我不知道我为什么要这样做。我只是知道那里的人们想要它(而且他们可能不知道为什么)。我能感觉到这样做很重要,所以让我们去做吧。
我知道这听起来不太乐观,但某种程度上这就是事实。我的愿景已经略有改变,所以就我而言,让我解释一下原因。看看你是否会改变主意。是的,我的解释不仅仅是:Docker 很流行,所以让我们 Docker 化一切。
人们已经投入了大量的工程精力来在他们的平台上运行容器化软件。因此,他们一直在使用各种工具来构建和编排他们的环境。而且我不会惊讶地看到 Kubernetes 成为这种编排工具。有些人也喜欢在生产环境中运行最前沿的技术,因为他们可能会觉得其他事情很无聊(对吧 Seán?)。因此,有了 *容器化一切* 的方法,他们会很高兴地看到他们最喜欢的开源存储解决方案上发生了一些事情 :).
与 yum 或 apt-get 相比,回滚并不容易,而容器则不然。升级和回滚变得更容易,因为你可以轻松地 docker stop 和 docker 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
Monitors ¶
由于 monitors 无法通过 NATed 网络进行通信,我们需要使用 --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) OSD 将由入口点完成。我现在呈现的配置更容易上手,因为你只需要指定一个块设备,而入口点将完成其余的工作。
对于那些不想使用 --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/sdbOSD_JOURNAL是将用于存储 OSD 日志的设备,例如:/dev/sdzHOSTNAME是 OSD 运行的容器的主机名 (默认: $(hostname))OSD_FORCE_ZAP将强制擦除给定设备的内容 (默认: 0 和 1 以强制擦除)OSD_JOURNAL_SIZE是 OSD 日志的大小 (默认: 100)
元数据服务器 ¶
这很简单,很容易启动。目前唯一的限制是,我们需要在 Docker 中提供 Ceph admin 密钥。此密钥将用于创建 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 生成配置/密钥并在所有机器上分发它们。
或者,我们希望能够将各种配置文件存储在不同的后端 kv 存储中,例如 etcd 和 consul。
编排部署 ¶
一个非常重要的步骤是使用 ceph-ansible,其中逻辑已经实现。我只需要进行一些更改,但大部分工作已经存在。
Kubernetes,一个关于如何引导 monitors 的预览已经 可用。
扩展到 Rocket 和其他 ¶
这里没什么可做的,你可以简单地将你的 Docker 镜像移植到 Rocket 并启动它们 (这里是双关语)。
奖励视频
再次,我想借此机会感谢 Seán C. McCord,他使这一切成为可能。Seán 是一个很好合作的人,我期待着与他一起为 ceph-docker 做出贡献!