注意:这个问题非常广泛,可能会写满整本书,但我会阐明一些观点。
容器的好处
关于容器的令人兴奋的部分不是关于它们在单个主机上的使用,而是它们在连接在大型集群上的主机之间的使用。不要将您的机器视为独立的 docker 主机,而应将其视为托管容器的资源池。
容器本身并不是开创性的(ie. Docker 的 CTO 在最后的 DockerCon 上声明“没人关心容器”),但与最先进的调度程序和容器编排框架相结合,它们成为处理生产级软件的非常强大的抽象。
关于它也适用于虚拟机的论点,是的,但容器比虚拟机具有一些技术优势(参见:How is Docker different from a normal virtual machine),这使得它们更易于使用。
在单个主机上
在单个主机上,您可以从容器中获得的好处是(以及许多其他好处):
- 用作模仿真实生产集群行为的开发环境。
- 独立于主机的可重现构建(方便共享)
- 测试新软件时不会使用您不会每天使用的软件包使您的计算机膨胀。
从单个主机扩展到机器池(集群)
当需要管理生产集群时,有两种方法:
- 通过脚本或使用 docker-compose 等解决方案“手动”创建几个 docker 主机并运行/连接容器。监控服务/容器的生命周期由您负责,您应该准备好处理服务停机时间。
- 让容器编排器处理所有事情并监控服务的生命周期,以更好地应对故障。
有很多容器编排器:Kubernetes、Swarm、Mesos、Nomad、Cloud铸造厂,可能还有很多其他的。他们为许多大型公司和基础设施(如 Ebay)提供动力,因此他们肯定发现使用这些设施有好处。
选择正确的复制策略
容器最好用作一次性资源,这意味着您可以独立停止和重新启动数据库,并且它不应该影响后端(除了因为数据库关闭而引发错误)。因此,只要您的服务在多个主机之间正确复制,您应该能够处理任何类型的网络分区。
您需要选择适当的复制策略,以确保您的服务保持正常运行。例如,您可以跨云提供商可用区复制您的数据库,这样当整个可用区出现故障时,您的数据仍然可用。
以 Kubernetes 为例,您可以将每个容器(1 个 FE、1 个 BE 和 1 个 DB)放在一个 pod 中。 Kubernetes 将处理在许多主机上复制此 pod 并监控这些 pod 是否始终处于启动和运行状态,如果没有,将创建一个新的 pod 来应对故障。
如果您想减轻网络分区的影响,请指定节点关联性,提示调度程序将容器放置在同一机器子集上并在适当数量的主机上进行复制。
每台主机有多少个容器?
这实际上取决于您使用的机器数量和它们拥有的资源。
规则是,如果您不指定任何资源限制(在 CPU 或内存方面),则不应使用太多容器使主机膨胀。否则,您可能会危及主机并耗尽其资源,进而影响机器上的所有其他服务。良好的复制策略不仅在单个服务级别很重要,而且对于确保共享主机的服务池的健康状况也很重要。
应根据工作负载的类型处理资源限制:数据库可能会使用比前端容器更多的资源,因此您应该相应地调整大小。
例如,使用 Swarm,您可以明确指定给定服务所需的 CPU 或内存数量(请参阅docker service documentation)。尽管有很多可能性,您也可以根据 CPU 或内存使用情况给出上限/下限。根据选择的值,调度程序会将服务固定到具有可用资源的正确机器上。
Kubernetes 的工作方式几乎相同,您可以为 pod 指定限制(请参阅 documentation)。
Mesos 具有更细粒度的资源管理策略,包括框架(针对特定工作负载,如 Hadoop、Spark 等)和过度提交功能。 Mesos 对于大数据类型的工作负载特别方便。
服务应该如何拆分?
这真的取决于编排解决方案:
- 在 Docker Swarm 中,您将为每个组件(FE、BE、DB)创建一个服务,并为每个服务设置所需的复制数。
- 在 Kubernetes 中,您可以创建一个包含整个应用程序(FE、BE、DB 和附加到 DB 的卷)的 pod,也可以为 FE、BE、DB+volume 创建单独的 pod。
通常:每种类型的容器使用一项服务。关于容器组,评估扩展整个容器组(作为一个原子单元,即一个 pod)是否比单独管理它们更方便。
总结
容器更适合与编排框架/平台一起使用。有很多可用的解决方案来处理容器调度和资源管理。选择一个可能适合您的用例,并学习如何使用它。始终选择适当的复制策略,牢记可能的故障模式。尽可能为您的容器/服务指定资源限制,以避免可能导致主机停机的资源耗尽。