为什么要构建多容器 docker 应用程序?

Why multi-container docker apps are built?

有人可以举例说明吗?为什么要构建多容器 docker 应用程序?而您可以将您的应用包含在单个 docker 容器中。 当您制作多容器应用程序时,您必须进行联网。 运行 单个容器的单个图像而不是两个容器的两个图像不是很容易吗?

为了简单起见,我会说在一个容器中您只能 运行 一个具有 public 入口点(如 API)的应用程序。其实这个做法就是recommended by Docker official documentation.

微服务

由于这个单一的约束,您不能 运行 在单个 docker 容器中需要自己的入口点的微服务。 它可能更多地讨论 .

的优点

数据库

即使您决定 运行 仅使用 Monolith 应用程序,您仍然需要在那里连接一些数据库。正如您所注意到的,Docker 有一个额外的网络配置层,所以如果您想在本地 运行 数据库和应用程序,最简单的方法是同时使用 docker-compose 和 运行图像(数据库和您的应用程序)在一个自动配置的网络中。

# Application definition
application: <your app definition>

# Database definition
database:
  image: mysql:5.7

在我的示例中,您只需通过 https://database:<port> URL 从您的主应用程序(最终加上凭据)连接到您的数据库即可。

可扩展性

但是,为什么我们要从应用程序中拆分数据库的图像?一个词 - 可扩展性。出于开发目的,您希望拥有本地数据库,也许 docker 因为它很方便。出于生产目的,您会将应用程序映像放在 运行 某个地方(Kubernetes、Docker-Swarm、Azure App Services 等)。要同时处理多个请求,您需要 运行 应用程序的多个实例。但是数据库呢?您无法连接到同一容器中托管的数据库的内部实例,因为其他容器中的应用程序的其他实例将具有完全不同的数据集(没有同步)。 大多数情况下,您会选择使用单独的数据库服务器——无论 运行 将其放在容器或完全托管的数据库(如 Azure CosmosDB 或 Mongo Atlas)上,但使用您自己的配置、缩放、和同步专用于数据库。您的应用程序只需要担心正确的 URL 即可。大多数云提供商都开箱即用地公开此类服务,因此您不必担心自己的配置。

易于更改

最后但并非最不重要的争论是关于超时更改初始设置。您可能会更改数据库提供程序,或者将来升级图像的版本(有时需要这样的事情)。当您分离图像时,您可以在不接触其他图像的情况下修改一个图像。它显着降低了维护成本。

此外,您可以非常轻松地添加其他服务 - 不同的日志聚合器?没问题,额外的微服务 运行 开箱即用?简单。

这有几个很好的理由:

重用预建镜像更容易。如果你需要MySQL,或者Redis,或者Nginx反向代理,这些都作为标准镜像存在于Docker Hub,您可以将它们包含在多容器中 Docker Compose 设置。如果您尝试将它们放入单个映像中,则必须自己安装和配置它们。

Docker工具是为单用途容器构建的。如果你想要多进程容器的日志,docker logs通常会打印输出 supervisord 日志,这不是您想要的;如果你想重新启动其中一个容器,docker stop; docker rm; docker run 序列将删除整个容器。取而代之的是多进程容器,你需要使用像 docker exec 这样的调试工具来做任何事情,这更难管理。

你可以升级一个部分而不影响其余部分。 升级容器中的代码通常涉及构建新镜像、停止和删除旧容器以及运行从新图像中创建一个新容器。 “删除旧容器”部分很重要,也是例行公事;如果您需要删除数据库来升级您的应用程序,您可能会丢失数据。

您可以扩展一部分而不影响其余部分。更适用于 Docker Swarm 或 Kubernetes 等集群环境。如果您的应用程序过载(尤其是在生产中),您希望 运行 它的多个副本,但很难 运行 标准关系数据库的多个副本。这基本上需要您分别 运行 这些,因此您可以 运行 一个代理、五个应用程序服务器和一个数据库。

设置多容器应用程序应该不是特别困难;最简单的方法是使用 Docker Compose,它将处理诸如为您创建网络之类的事情。