共计 2605 个字符,预计需要花费 7 分钟才能阅读完成。
导读 | Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。 |
本文介绍了利用 Docker 和 Kubernetes 搭建一套具有冗余备份集合的 MongoDB 服务,从容器对 CI 和 CD 引发的改变入手,讨论了容器技术对 MongoDB 带来的挑战和机会,然后实战如何部署一套稳定的 MongoDB 服务,非常的干货~
想尝试在笔记本电脑上运行 MongoDB 么? 希望通过执行一个简单的命令,然后就有一个轻量级、自组织的沙盒么? 并可再通过一条命令就可以移除所有的痕迹么?
需要在多个环境中运行相同的应用程序栈? 创建自己的容器镜像,使得开发、测试、操作和支持团队启动一份完全相同的环境。
容器正在改变整个软件生命周期; 它覆盖了从最初的技术试验到通过开发、测试、部署和支持的概念证明。
阅读微服务:容器和编排白皮书(https://www.mongodb.com/collateral/microservices-containers-and-orchestration-explained)。
编排工具管理着多个容器如何创建、升级和高可用。编排同样管理着容器如何连接,并利用多个微服务容器创建稳定的应用服务。
丰富的功能、简单的工具、强大的 API 让容器和编排得到 DevOps 团队的青睐。DevOps 工程师将它们整合到持续集成 (CI) 和持续交付 (CD) 工作流中。
本篇文章将探索在尝试运行和编排 MongoDB 容器时遇到的问题,并描述如何克服这些问题。
采用容器和编排运行 MongoDB 带来了一些新的思考:
MongoDB 数据库节点是有状态的。若一个容器挂了,并且被重新编排,数据丢失是不能接受的 (虽然它可以从其他节点中恢复数据,但是很费时)。为解决这个问题,Kubernetes 中的卷抽象(Volume abstraction) 特性将用于映射 MongoDB 数据文件夹到一个持久化地址,避免容器的失败或重编排。
同一组 MongoDB 数据库备份节点之间需要通信,即使是在重编排之后。同一冗余备份集合的节点必须知道全部其他节点的地址,但是当某个容器重编排之后,它的 IP 地址会变化。例如,所有 Kubernetes 内的容器共享一个 IP 地址,当 pod 被重编排之后这个地址就会改变。在 Kubernetes 中,这个问题可以通过联系 Kubernetes 服务与 MongoDB 节点来解决,采用 Kubernetes 的 DNS 服务提供主机名给重编排之后的服务。
一旦每个独立的 MongoDB 节点 (每个节点在单独容器中) 启动起来,备份集合必须初始化,并把每个节点加入进来。这需要编排工具提供额外的逻辑。特别是备份集合中只有一个 MongoDB 节点时,必须执行 rs.initiate 和 rs.add 命令。
如果编排框架提供自动化重编排容器功能(如 Kubernetes 的特性),那么这可以提高 MongoDB 的容灾性,节点会在挂掉之后自动重新创建,恢复到完整冗余水平且不需要人工干预。
当编排框架掌控所有容器的状态时,它并不管理容器内的应用或者备份数据。这就意味着采用一个有效的管理和备份方案很重要,如 MongoDB Cloud Manager,包括 MongoDB Enterprise Advanced 和 MongoDB Professional 两部分。考虑到需要创建镜像,可采用你倾向的 MongoDB 版本和 MongoDB Automation Agent。
如前一节所述,MongoDB 这类分布式数据库在利用编排框架 (如 Kubernetes) 进行部署时需要额外考虑。本节将对这部分细节进行分析,并介绍如何实现。
首先,我们在一个单独的 Kubernetes 集群 (同一个数据中心内,并不存在物理上的冗余备份) 中创建整个 MongoDB 冗余集合。如果跨多个数据中心进行创建,其步骤也差异不大,后续将会介绍。
备份中的每个成员都运行在独自的 pod 中,只暴露其 IP 地址和端口。固定的 IP 地址对于外部应用和其他冗余备份节点非常重要,它决定了哪些 pod 将被重新部署。
下图展示了其中一个 pod 与关联的冗余控制器和服务的关系。
深入这些配置中描述的资源,内容如下:
下图展示了冗余备份及中的另一个成员信息:
90% 的配置是相同的,只有几处不同:
第三个冗余备份成员的配置仿照上述的模式进行,下图展示了完整的冗余配置集合:
注意,即使配置如图 3 一样,在一个三个或者多个节点的 Kubernetes 集群上,Kubernetes 可能会调度两个或者多个 MongoDB 冗余备份成员在同一个宿主机上。这是因为 Kubernetes 将三个 pod 视为三个独立的服务。
为了增加冗余,需要创建一个额外的 headless 服务。该服务不具备提供外部服务的能力,甚至没有外部 IP 地址,但是它用于通知 Kubernetes 这三个 MongoDB Pod 是属于同一个服务,于是 Kubernetes 会将它们调度在不同的节点上。
具体的配置文件和相关操作命令可以从《启动微服务:容器 & 调度说明白皮书》中找到。其中包含了三个特殊的步骤确保合并三个 MongoDB 到一个功能中,即本文中描述的冗余备份。
所有冗余部件均运行在同一个 GCE 集群上时具有很高的风险,在同一个 zone 的集群也一样。如果发生一个重大事件导致可用 zone 离线,那么 MongoDB 冗余集合也就不可用。如果需要地理上的冗余备份,那么三个 pod 需要运行在不同的 zone 内。
只需要很少的改动就可以创建这样一个冗余备份集合。每一个集群需要独自的 Kubernetes YAML 文件来定义 pod、冗余控制器和服务。然后,就可以完成一个 zone 的集群创建、持久化存储和 MongoDB 节点。
下图展示了运行在不同 zone 上的冗余结合:
![post-qrcode](https://www.xgss.net/wp-content/uploads/2023/07/二维码-微信公众号256x256.jpg)