【问题标题】:Container cannot connect other container容器无法连接其他容器
【发布时间】:2021-11-21 02:42:01
【问题描述】:

我想与两个 docker 容器通信。我是 Docker 新手,我尝试了很多不同的方法。

首先我制作了 2 个不同的 Dockerfile

myJavaAPI Dockerfile:

FROM java:8
WORKDIR /app
COPY . .
EXPOSE 4016:23503
CMD java -jar myJavaServerApi.jar

java API 监听 localhost:4016 并提供来自 127.0.0.1:23503 的数据

其他 Dockerfile:

FROM python:3.8

WORKDIR /app

COPY requirements.txt requirements.txt

RUN pip install -r requirements.txt

COPY . .

EXPOSE 23503:23503

CMD ["python","./myDaemonServer.py"]

myDaemonServer 从 23503 获得连接并做一些工作。

我尝试在我的机器上运行这 2 个文件,一切正常。但是当我创建 Docker 这两个容器无法通信时,myDaemonServer 看不到我的 Java API。

我使用这些命令构建了我的图像:

docker build -t dockerjava .

docker build -t dockerdaemon .

并通过以下方式运行它:

docker run -d <ImageID>

首先我运行 dockerjava,然后我运行 dockerdaemon

另外,我尝试了这个命令,没有任何改变:

docker run -p --net=host <DockerImageIDs>

我该如何解决这个问题?

编辑:守护进程(python 文件)监听 127.0.0.1:23503 并从 5002 端口提供服务。

【问题讨论】:

    标签: docker dockerfile containers


    【解决方案1】:

    你可以通过两种方式解决这个问题,

    1. 一种方法是创建一个 docker-compose.yml 文件,您可以在其中指定 networks 为您的应用提供以下示例 docker-compose 文件。
    version: "3.3"
    services:
    
      #  Java API
      myJavaAPI:
        image: "dockerjava"
        ports:
          - "4016:23503"
        restart: "no"
        networks:
          - localnetwork
    
      # Python Daemon
      myDaemonServer:
        image: "dockerdaemon"
        ports:
          - "23503:23503"
        restart: "no"
        depends_on:
          - myJavaAPI
        networks:
          - localnetwork
    
    networks:
      localnetwork:
    
    1. 第二种方法是在调用 java api 的 Python 代码中使用 http://host.docker.internal:23503 代替 localhost:23503

    但我建议您使用第一种方法,因为这是使容器相互连接的更简洁的方法。

    【讨论】:

    • 问题仍然存在。我尝试了您的解决方案,但没有任何改变。
    【解决方案2】:

    两个 Docker 容器可以通过 TCP 进行通信。

    为了简单的配置,您可以使用单个 docker-compose.yml:

    version: '3.6'
    
    services:
    
      myJavaServer:
        container_name: myJavaServer
        restart: always
        image: ...
        ports:
          - 80:80
          - 443:443
       
      myDaemonServer:
        container_name: myDaemonServer
        restart: always
        image: ...
        
    networks:
      default:
        driver: bridge
        name: mynetwork
        
    

    如果您想使用单独的 docker-compose.yml 文件,您必须使用外部网络:

    version: '3.6'
    
    services:
    
      myJavaServer:
        container_name: myJavaServer
        restart: always
        image: ...
        ports:
          - 80:80
          - 443:443
        networks:
          - mynetwork
    
    networks:
      mynetwork:
      external: true
    

    对于守护进程:

    version: '3.6'
    
    services:
    
      myDaemonServer:
        container_name: myDaemonServer
        restart: always
        image: ...
        networks:
          - mynetwork
    
    networks:
      mynetwork:
      external: true
    

    如果你使用两个 docker-compose.yml 文件,可以使用命令docker network create ...:https://docs.docker.com/engine/reference/commandline/network_create/创建外部网络

    在您的容器中,您现在可以使用以下名称进行简单的交流:ping myJavaServer。或 http://myJavaServer:1234 无需为同一网络内的通信映射端口(端口 1234)。 端口映射仅用于将您的服务器暴露给外部单词(例如端口 80/443)。

    要启动两个容器,您可以在 docker-compose.yml 文件的目录中运行命令 docker-compose up

    【讨论】:

    • 我应该更改我的配置文件吗?我的配置文件的 IP 地址为 127.0.0.1:23503
    • 另外,您没有添加“networks”标签来描述特定的网络(mynetwork)。你为什么这样做?
    • 当你给你的网络一个名字时,你也可以启动其他容器并使用同一个网络。我将调整我的答案以更详细地解释这一点。
    • Compose 为您提供了一个名为 default 的网络,并默认将容器附加到该网络。为了简单起见,我建议删除所有 networks: 块和 container_name: 行,特别是在单 Compose 文件的情况下。 Docker 文档中的Networking in Compose 有更多详细信息。
    • 你当然可以使用默认网络。但是,当您为不同目的运行多个容器时,隔离网络是有意义的。我也会使用container_name 选项来避免冲突。
    猜你喜欢
    • 2021-05-22
    • 2020-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    相关资源
    最近更新 更多