docker - 生产中每台主机应该存在多少个容器?服务应该如何拆分?

标签 docker containers

我试图更好地了解 Docker 的好处,但我并不真正了解它在生产中的工作方式。

假设我有一个 web 前端、一个 rest api 后端和一个 db。这使 3 个容器。

假设我想要 3 个前端,5 个后端和 7 个数据库。 (小问题:dbs 比后端服务器少有意义吗?)

现在,考虑到上述情况,如果我将它们全部打包在同一台主机上,那么我将获得有效使用主机资源的好处,但是当该机器出现故障或有网络分区时,我就处于 DOA 状态。

如果我将它们分成每台主机 1 个完整的应用程序(即 1 个 FE、1 个 BE 和 1 个 DB),并在它们自己的主机上放置额外的容器,我可以获得一些有效利用资源的优势,但在我看来,我仍然损失惨重当我有一个网络分区时,因为它会关闭多个服务。

因此,我几乎倾向于得出结论,我应该为每个主机放入 1 个容器,但这意味着我使用资源的效率非常低,那么容器在生产中的好处是什么?我的意思是,操作系统可能是每台机器的存储大小额外的几场演出,但大多数云提供商为您提供至少 10 场演出的存储空间。让我们面对现实,rest api 后端或 web 前端甚至不会接近 10 gigs ......甚至包括操作系统。

所以,毕竟,我想弄清楚我是否错过了容器的重点?将应用程序的所有容器保留在 1 台主机上的好处是否主要与测试和开发好处有关?

我知道在不同的供应商/机器之间轻松移动容器有很多好处,但在大多数情况下,我个人并不认为这是一个巨大的 yield ,因为这对图像是可行的......

生产中的容器是否还有其他我所缺少的好处?或者是测试和开发的主要好处? (我是否在考虑生产中的容器错误)?

最佳答案

备注 :这个问题非常广泛,可以写一整本书,但我会解释一些。

容器的好处

关于容器的令人兴奋的部分不是它们在单个主机上的使用,而是它们在连接到大型集群上的主机之间的使用。不要将您的机器视为独立的 docker 主机,而是将其视为托管容器的资源池。

容器本身并不是开创性的(即 Docker 的 CTO 在上届 DockerCon 上表示“没有人关心容器”),但结合最先进的调度程序和容器编排框架,它们成为处理生产级的非常强大的抽象软件。

至于它也适用于虚拟机的论点,是的,确实如此,但是容器比 VM 具有一些技术优势(参见:How is Docker different from a normal virtual machine),这使得它们易于使用。

在单个主机上

在单个主机上,您可以从容器中获得的好处是(除其他外):

  • 用作模拟真实生产集群上的行为的开发环境。
  • 独立于主机的可重现构建(方便共享)
  • 测试新软件,而不会使用您不会每天使用的软件包使您的机器膨胀。

  • 从单个主机扩展到机器池(集群)

    当需要管理生产集群时,有两种方法:
  • 创建几个 docker 主机并通过脚本或使用 docker-compose 之类的解决方案“手动”运行/连接容器。监控服务/容器的生命周期由您负责,您应该准备好处理服务停机。
  • 让容器编排器处理一切并监控服务的生命周期,以更好地应对故障。

  • 有很多容器编排器:Kubernetes、Swarm、Mesos、Nomad、Cloud Foundry,可能还有很多其他的。它们为 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+卷创建单独的 pod。

  • 通常:每种类型的容器使用一种服务。关于容器组,评估是否扩展整个容器组(作为一个原子单元,即一个 pod)比单独管理它们更方便。

    总结

    容器更适合与编排框架/平台一起使用。有很多可用的解决方案来处理容器调度和资源管理。选择一个可能适合您的用例,并学习如何使用它。始终选择合适的复制策略,牢记可能的故障模式。尽可能为您的容器/服务指定资源限制,以避免可能导致主机停机的资源耗尽。

    关于docker - 生产中每台主机应该存在多少个容器?服务应该如何拆分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41214091/

    相关文章:

    java - 使用kubernetes将tomcat conf文件发送到容器

    docker - 动态设置docker容器的JAVA_HOME

    docker - 如何在 docker-compose 中定义 build-args?

    c++ - 为什么 std::map::insert 不能采用键和值而不是 std::pair?

    azure - 无法使用SSL通过Nginx实现与redis容器的安全连接

    amazon-web-services - 解析 ECS Fargate 任务中的服务主机名

    docker - Ansible docker_container 命令失败且没有输出

    mongodb - 如何将运行选项传递给 docker-compose

    linux - 分层文件系统和卷挂载

    html - chrome 移动 View 右下角的空白