简体   繁体   English

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

[英]Why multi-container docker apps are built?

Can somebody explain it with some examples?有人可以用一些例子来解释吗? Why multi-container docker apps are built?为什么要构建多容器 docker 应用程序? while you can contain your app in a single docker container.而您可以将您的应用程序包含在单个 docker 容器中。 When you make a multi-container app you have to do networking.当您制作多容器应用程序时,您必须进行网络连接。 Is not it easy to run a single image of a single container rather than two images of two containers?运行单个容器的单个图像而不是两个容器的两个图像不是很容易吗?

There are several good reasons for this:这有几个很好的理由:

It's easier to reuse prebuilt images.重用预建图像更容易。 If you need MySQL, or Redis, or an Nginx reverse proxy, these all exist as standard images on Docker Hub, and you can just include them in a multi-container Docker Compose setup. If you need MySQL, or Redis, or an Nginx reverse proxy, these all exist as standard images on Docker Hub, and you can just include them in a multi-container Docker Compose setup. If you tried to put them into a single image, you'd have to install and configure them yourself.如果您尝试将它们放入单个映像中,则必须自己安装和配置它们。

The Docker tooling is built for single-purpose containers. Docker 工具专为单一用途容器而设计。 If you want the logs of a multi-process container, docker logs will generally print out the supervisord logs, which aren't what you want;如果你想要多进程容器的日志, docker logs一般会打印出supervisord日志,这不是你想要的; if you want to restart one of those containers, the docker stop; docker rm; docker run如果要重新启动其中一个容器,则docker stop; docker rm; docker run docker stop; docker rm; docker run docker stop; docker rm; docker run sequence will delete the whole thing. docker stop; docker rm; docker run顺序将删除整个内容。 Instead with a multi-process container you need to use debugging tools like docker exec to do anything, which is harder to manage.相反,对于多进程容器,您需要使用诸如docker exec之类的调试工具来做任何事情,这更难管理。

You can upgrade one part without affecting the rest.您可以升级一个部件而不影响 rest。 Upgrading the code in a container usually involves building a new image, stopping and deleting the old container, and running a new container from the new image.升级容器中的代码通常涉及构建新镜像、停止和删除旧容器以及从新镜像运行新容器。 The "deleting the old container" part is important, and routine; “删除旧容器”部分很重要,而且是例行公事; if you need to delete your database to upgrade your application, you risk losing data.如果您需要删除数据库以升级应用程序,则可能会丢失数据。

You can scale one part without affecting the rest.您可以缩放一个零件而不影响 rest。 More applicable in a cluster environment like Docker Swarm or Kubernetes.更适用于集群环境,如 Docker Swarm 或 Kubernetes。 If your application is overloaded (especially in production) you'd like to run multiple copies of it, but it's hard to run multiple copies of a standard relational database.如果您的应用程序过载(尤其是在生产中),您希望运行它的多个副本,但很难运行标准关系数据库的多个副本。 That essentially requires you to run these separately, so you can run one proxy, five application servers, and one database.这实质上需要您单独运行它们,因此您可以运行一个代理、五个应用程序服务器和一个数据库。

Setting up a multi-container application shouldn't be especially difficult;设置多容器应用程序应该不是特别困难; the easiest way is to use Docker Compose, which will deal with things like creating a network for you.最简单的方法是使用 Docker Compose,它将为您处理诸如创建网络之类的事情。

For the sake of simplification, I would say you can run only one application with a public entry point (like API) in a single container.为了简化起见,我想说您只能在单个容器中运行一个具有公共入口点(如 API)的应用程序。 Actually, this approach is recommended by Docker official documentation .实际上,这种方法是Docker 官方文档推荐的

Microservices微服务

Because of this single constraint, you cannot run microservices that require their own entry points in a single docker container.由于这一单一约束,您无法在单个 docker 容器中运行需要自己的入口点的微服务。 It could be more a discussion on the advantages of Monolith application vs Microservices .这可能是关于单体应用程序与微服务的优势的更多讨论。

Database数据库

Even if you decide to run the Monolith application only, still you need to connect some database there.即使您决定只运行 Monolith 应用程序,您仍然需要在那里连接一些数据库。 As you noticed, Docker has an additional network-configuration layer, so if you want to run Database and application locally, the easiest way is to use docker-compose to run both images (Database and your Application) inside one, automatically configured network.如您所见,Docker 有一个额外的网络配置层,因此如果您想在本地运行数据库和应用程序,最简单的方法是使用docker-compose在一个自动配置的网络中运行两个映像(数据库和您的应用程序)。

# Application definition
application: <your app definition>

# Database definition
database:
  image: mysql:5.7

In my example, you can just connect to your DB via https://database:<port> URL from your main app (plus credentials eventually) and it will work.在我的示例中,您可以通过https://database:<port> URL 从您的主应用程序(最终加上凭据)连接到您的数据库,它将起作用。

Scalability可扩展性

However, why we should split images for the database from the application?但是,为什么我们应该从应用程序中拆分数据库的图像? One word - scalability .一个词——可扩展性 For development purposes, you want to have your local DB, maybe with docker because it is handy.出于开发目的,您希望拥有本地数据库,可能使用 docker,因为它很方便。 For production purposes, you will put the application image to run somewhere (Kubernetes, Docker-Swarm, Azure App Services, etc.).出于生产目的,您会将应用程序映像放在某个地方(Kubernetes、Docker-Swarm、Azure App Services 等)运行。 To handle multiple requests at the same time, you want to run multiple instances of your application.要同时处理多个请求,您需要运行应用程序的多个实例。 However what about the database?但是数据库呢? You cannot connect to the internal instance of DB hosted in the same container, because other instances of your app in other containers will have a completely different set of data (without synchronization).您无法连接到托管在同一容器中的数据库的内部实例,因为您的应用程序在其他容器中的其他实例将具有完全不同的数据集(没有同步)。 db-inside-same-container Most often you are electing to use a separate Database server - no matter if running it on the container or fully manged databases (like Azure CosmosDB or Mongo Atlas), but with your own configuration, scaling, and synchronization dedicated for DB only.大多数情况下,您选择使用单独的数据库服务器 - 无论是在容器上运行它还是在完全托管的数据库(如 Azure CosmosDB 或 Mongo Atlas)上运行它,但您自己的配置、扩展和同步仅用于 DB。 Your app just needs to worry about the proper URL to that.您的应用程序只需要担心正确的 URL 即可。 Most cloud providers are exposing such services out of the box, so you are not worrying about the configuration by yourself.大多数云提供商都开箱即用地公开此类服务,因此您不必担心自己的配置。
外部数据库

Easy to change易于更改

Last but not least argument is about changing the initial setup overtime.最后但并非最不重要的争论是关于改变初始设置加班。 You might change the database provider, or upgrade the version of the image in the future (such things are required from time to time).您可能会更改数据库提供程序,或者将来升级映像的版本(这些事情是不时需要的)。 When you separate images, you can modify one without touching others.当您分离图像时,您可以修改其中的一个而无需触及其他图像。 It is decreasing the cost of maintenance significantly.它显着降低了维护成本。

Also, you can add additional services very easy - different logging aggregator?此外,您可以非常轻松地添加其他服务 - 不同的日志聚合器? No Problem, additional microservice running out-of-the-box?没问题,额外的微服务开箱即用? Easy.简单的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM