具有确定性端口绑定(bind)的 Docker 规模

标签 docker docker-compose

我想扩展一个 wildfly 容器,该容器暴露了多个端口并具有确定性结果。

docker-compose.yml

version: '3'
services:
  wildfly-server:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        admin_user: admin
        admin_password: admin
    deploy:
      resources:
          limits:
            memory: 1.5G
            cpus: "1.5"
    restart: always
    ports:
      - "8000-8099:8080"
      - "8100-8199:9990"
      - "8200-8299:8787"
    expose:
      - "8080"
      - "9990"
      - "8787"

Dockerfile

FROM jboss/wildfly:16.0.0.Final

# DOCKER ENV VARIABLES
ENV WILDFLY_HOME /opt/jboss/wildfly
ENV STANDALONE_DIR ${WILDFLY_HOME}/standalone
ENV DEPLOYMENT_DIR ${STANDALONE_DIR}/deployments
ENV CONFIGURATION_DIR ${STANDALONE_DIR}/configuration

RUN ${WILDFLY_HOME}/bin/add-user.sh ${admin_user} ${admin_password} --silent

# OPENING DEBUG PORT
RUN rm ${WILDFLY_HOME}/bin/standalone.conf
ADD standalone.conf ${WILDFLY_HOME}/bin/

# SET JAVA ENV VARS
RUN rm ${CONFIGURATION_DIR}/standalone.xml
ADD standalone.xml ${CONFIGURATION_DIR}/

启动命令

docker-compose up --build --force-recreate --scale wildfly-server=10

它几乎按照我想要的方式工作,但是存在一些端口差异。当我创建容器时,我希望它们为每个要公开的容器提供增量端口,如下所示:

machine_1 8001, 8101, 82001
machine_2 8002, 8102, 82002
machine_3 8003, 8103, 82003 

但是我得到的结果不是确定性的,看起来像这样:

machine_1 8001, 8102, 82003
machine_2 8002, 8101, 82001
machine_3 8003, 8103, 82002 

问题是,每次运行 compose up 命令时,每个容器的端口都不同。

示例输出:

CONTAINER ID  COMMAND                  CREATED             STATUS              PORTS                                                                    NAMES
0232f24fbca4  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8028->8080/tcp, 0.0.0.0:8231->8787/tcp, 0.0.0.0:8126->9990/tcp   wildfly-server_7
13a6a365a552  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8031->8080/tcp, 0.0.0.0:8230->8787/tcp, 0.0.0.0:8131->9990/tcp   wildfly-server_10
bf8260d9874d  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8029->8080/tcp, 0.0.0.0:8228->8787/tcp, 0.0.0.0:8129->9990/tcp   wildfly-server_6
3d58f2e9bdfe  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8030->8080/tcp, 0.0.0.0:8229->8787/tcp, 0.0.0.0:8130->9990/tcp   wildfly-server_9
7824a73a09f5  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8027->8080/tcp, 0.0.0.0:8227->8787/tcp, 0.0.0.0:8128->9990/tcp   wildfly-server_3
85425462259d  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8024->8080/tcp, 0.0.0.0:8224->8787/tcp, 0.0.0.0:8124->9990/tcp   wildfly-server_2
5be5bbe8e577  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8026->8080/tcp, 0.0.0.0:8226->8787/tcp, 0.0.0.0:8127->9990/tcp   wildfly-server_8
2512fc0643a3  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8023->8080/tcp, 0.0.0.0:8223->8787/tcp, 0.0.0.0:8123->9990/tcp   wildfly-server_5
b156de688dcb  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8025->8080/tcp, 0.0.0.0:8225->8787/tcp, 0.0.0.0:8125->9990/tcp   wildfly-server_4
3e9401552b0a  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8022->8080/tcp, 0.0.0.0:8222->8787/tcp, 0.0.0.0:8122->9990/tcp   wildfly-server_1

问题

有什么办法可以让端口分布具有确定性吗?比如禁用并行运行以对可用端口进行串行检查或任何其他方法?我发现的唯一替代方案是使用 yml 模板并生成所有必要的文件(例如,如果我需要 10 个容器,则生成 10 个文件等)。有其他解决方案吗?

最佳答案

不,您当前(10/14/19)无法在 docker-compose 文件中确定端口选择。 Github 问题 #722 中请求了此行为和 #1247 ,但这些问题在没有实现的情况下就被关闭了。

如果您想像听起来那样半动态地扩展应用程序,那么您需要以另一种方式解决这个问题。在我看来,您的 .yml 模板想法听起来像是最干净的解决方案。

您确定需要端口具有确定性吗?如果您使用像 nginx 这样的反向代理来监听一个主机端口并平衡所有 docker 容器之间的负载,这是否适合您的用例?在 Docker 容器中设置 nginx 负载均衡器非常简单。我建议您研究一下这一点,如果您仍然需要一种确定的方式让调用者了解服务的端口,以便它可以重复向特定服务器发送请求,那么请使用您的 .yml 模板解决方案或某种独立于 docker-compose 配置的服务发现过程。

关于具有确定性端口绑定(bind)的 Docker 规模,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58255971/

相关文章:

laravel - 如何在docker上诊断404未找到错误nginx?

docker - CLion 调试器在 Docker 容器中失败

git - 执行 docker-compose : Building webserver unable to prepare context: unable to 'git clone' to temporary context directory: error fetching 时出错

docker - 如何使用 Docker 开发位于不同存储库中的应用程序

docker - 在 docker swarm 中使用 docker 部署 Jenkins

Docker-Compose YAML : how to populate single-line array from environment variable?

docker - 控制台生产者错误连接到节点 kafka1 :9092 (org. apache.kafka.clients.NetworkClient) java.net.UnknownHostException

docker 多阶段构建 Go 镜像 - x509 : certificate signed by unknown authority

docker - 在 OpenShift 内强制重新启动 Pod

ruby - 如何使用 dockerfile 安装 ruby​​ 和 bundler?