1

Docker 容器的主要应用之一是负载均衡。例如,在 Web 应用程序的情况下,我们不是只有一个实例处理所有请求,而是有许多容器做完全相同的事情,但是请求被拆分到所有这些实例。

但它可以用来做同样的服务,但使用不同的“参数”吗?

例如,假设我想创建一个平台来存储来自不同交易平台(Bitfinex、Bittrex 等)的加密货币数据。

许多这些平台都在处理 Web 套接字。所以为了为每个平台创建一个套接字,我会在“代码层”做一些事情,比如(与语言无关):

foreach (platform in platforms)
    client = createClient(platform)
    socket = client.createSocket()
    socket.GetData()

现在当然,这个循环会卡在第一次迭代中,因为 websocket 正在等待(尽管我可以使用异步,无论如何)。为了避免这种情况,我可以使用多处理,例如:

foreach (platform in platforms)
    client = createClient(platform)
    socket = client.createSocket()
    process = new ProcessWhichGetData(socket)
    process.Launch()

有没有办法在“Docker 层”做到这一点,我的意思是使用 Docker 使不同的容器处理不同的平台?我会有一个用于 Bittrex 的 Docker 容器,一个用于 Bitfinex 的 Docker 容器,等等。

我知道这意味着不同的容器将相互通信(谁负责 Bitfinex?谁负责 Bittrex?),或者容器编排器(Docker Swarm / Kubernete)将自己处理这个“重新分区”。

这是我们可以做的事情,最重要的是,这是我们想要的吗?

4

3 回答 3

2

Docker 容器化只是在常规用户端进程周围添加了各种隔离层。它本身并没有引入多个进程之间的协调,尽管它当然可以用于构建一个多进程系统,其中每个进程执行一些工作,无论这些工作是冗余的还是互补的。

如果您可以设计您的解决方案,以便为每个“平台”启动一个进程(例如,传递实例应作为命令行参数处理的特定平台),那么实际上,这在技术上可以在 Docker 中完成。

但是我应该指出,不清楚为什么要在不同的容器中运行每个进程。出于安全原因,隔离是否相关?对于资源会计?将每个进程分派到不同的主机以便获得更多的处理能力?此外,除了必须最初确定哪个进程处理哪个平台之外,这些进程之间是否需要协调?如果是这样,他们是否需要访问共享存储,或者能够相互发送信号?这些问题将帮助您决定如何处理解决方案的 docker 化。

在最简单的情况下,假设您只想让整个进程与系统的其余部分隔离,但不要求这些进程彼此隔离,那么最简单的策略就是拥有一个单一的包含入口点 shell 脚本的容器,该脚本将简单地为每个平台启动一个进程。

entrypoint.sh (inside your docker image):

#!/bin/bash

platforms=Bitfinex Bittrex
for platform in ${platforms} ; do
    ./myprogram "${platform}" &
done

如果您确实需要为每个平台使用不同的容器,那么您将使用类似的脚本,但这一次,它将直接在主机上运行(即在容器之外),并将每个进程封装在 docker 中容器。

launch.sh (directly on the host):

#!/bin/bash

for platform in ${platforms} ; do
    docker  -name "program_${platform}" my_program_docker \
        /usr/local/bin/myprogram "$platform"
done

或者,您可以使用docker-compose定义要启动的 docker 容器列表,但目前我不会讨论更多此选项(只是询问这是否与您的情况相关)。

如果您需要将容器分布在多台主机之间,则可以使用相同的循环,但这次将使用docker-machine. 或者,如果使用docker-compose,则可以使用 Swarm 分发进程。

于 2018-09-29T13:12:45.570 回答
1

假设您将其重组为一个长时间运行的程序,一次只处理一个平台,并通过命令行选项或环境变量控制它是哪个平台。您可以编写一个 shell 脚本,而不是在代码中“启动所有平台”循环

#!/bin/sh
for platform in $(cat platforms.txt); do
  ./run_platform $platform &
done

这种设置很容易移植到 Docker 中。

您不应该计划动态启动 Docker 容器的进程。这很难设置并且具有重大的安全隐患(我的意思是“容器启动器中的错误可以轻松地使您的主机成为根”)。

如果各个处理任务都可以完全独立运行(也许它们使用共享数据库来存储数据),那么您基本上就完成了。你可以用列出所有容器的 Docker Compose YAML 文件替换那个 shell 脚本;如果你想在多个主机上运行它,你可以使用 Ansible、Docker Swarm 或 Kubernetes 等工具来分散容器(具有不同级别的基础设施复杂性)。

于 2018-09-29T12:41:22.753 回答
0

您可以将不同的 docker 容器捆绑在一个堆栈中,还可以配置网络,以便 docker 容器可以与外界保持隔离,但可以相互通信。

更多信息在这里Docker 堆栈

于 2018-09-29T15:18:50.437 回答