【问题标题】:docker-compose: no connection between containersdocker-compose:容器之间没有连接
【发布时间】:2019-09-24 10:16:20
【问题描述】:

我有 3 个微服务,我使用 docker 运行它们。

他们每个人的 Dockerfile。 前端:

FROM node:alpine
LABEL maintainer="2262288@gmail.com"
WORKDIR /usr/app/front
EXPOSE 3000
COPY ./ ./
RUN npm install
CMD ["npm", "start"]

后端1(后退):

FROM openjdk:8-jdk-alpine
LABEL maintainer="2262288@gmail.com"
VOLUME /tmp
EXPOSE 8099
ARG JAR_FILE=build/libs/auth-0.0.3.jar
ADD ${JAR_FILE} digital.jar
ENTRYPOINT ["java","-jar","/digital.jar"]

后端 2(消息):

FROM openjdk:8-jdk-alpine
LABEL maintainer="2262288@gmail.com"
VOLUME /tmp
EXPOSE 8082
ARG JAR_FILE=build/libs/sender-0.0.1.jar
ADD ${JAR_FILE} sender.jar
ENTRYPOINT ["java","-jar","/sender.jar"]

前端向后端1发送REST请求,然后后端1向后端2发送REST请求(消息)。

我在集线器上发布它并在 docker-compose 中的外部服务器上运行:

版本:'3.7'

services:
  web:
    image: account/front:0.0.1
    restart: on-failure
    ports:
      - 80:3000
  back:
    image: account/back:0.0.3
    restart: on-failure
    ports:
      - 8099:8099
  message:
    image: account/message:0.0.1
    restart: on-failure
    ports:
      - 8082:8082

后端服务在端口上运行:

message_1_e8eb3b2d2477 | 2019-09-24 09:34:00.882  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8082 (http) with context path ''

back_1_1982cc6e57f7 | 2019-09-24 09:34:07.403  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8099 (http) with context path ''

正如我们所见,每个服务都在自己的端口上运行。

然后,我尝试将请求发送到前面 -> 后面 -> 消息。将请求返回到消息并接收答案:

java.net.ConnectException: Operation timed out (Connection timed out)

然后,对消息服务的请求无法到达。

当我直接使用 Postman 发送请求时,它可以工作。

怎么了?

UPD。 从前到后的请求:

http://81.100.122.90:8099/auth/register
body:
{"username":"ksgcf","password":"123","firstName":"John","lastName":"Doe","email":"398456234785@gmail.com"}

从返回到消息的请求(IP 已更改):

String url = "http://81.100.122.90:8082/email";
        EmailMessageDto request = new EmailMessageDto(
                dto.getEmail(),
                "slava_rossii@list.ru",
                "Email confirmation",
                "Press link: http://dig.lamb.ru/confirm?username="
                        + registrationToken.getUsername() + "&token=" + registrationToken.getToken()
        );

所以,我在第一次运行 docker-compose 时看到了这条消息:

Creating network "project_default" with the default driver

【问题讨论】:

  • 发送请求时能否具体分享一下代码?
  • 我敢打赌,从 compose 访问服务时,您应该使用 docker-compose 服务名称作为主机。例如,要访问它的 backend1 url 将是 back:8099。要确认这一点,您应该显示用于访问正面 -> 背面和背面 -> 消息的链接,因为我认为它们设置为 localhost
  • michalk 是对的;请注意,容器内的localhost 指的是 container,而不是容器运行所在的主机。当您使用 docker-compose 时,不同的容器可以通过使用 docker-compose.yml 文件中的容器名称(在您的情况下为主机名“back”、“front”和“message”)来相互看到。
  • @michalk 我添加了发帖请求

标签: java docker docker-compose dockerfile


【解决方案1】:

首先,当您使用 docker-compose 时,所有服务都可以通过那里的名称获得。所以你可以像这样从后面访问消息

$ docker-compose exec back ping message
PING message (172.24.0.3) 56(84) bytes of data.
64 bytes from message (172.24.0.3): icmp_seq=1 ttl=64 time=0.078 ms
64 bytes from message (172.24.0.3): icmp_seq=2 ttl=64 time=0.068 ms

其次,检查端口绑定。您必须绑定 0.0.0.0(不是大多数服务和框架默认的 localhost)才能通过网络从其他容器访问服务。你得到普通的虚拟机是一样的。 您可以使用 telnet 检查端口可用性

例如,我正在检查 5432 上的 postresql 是否可以从名为 superset 的容器中获取

$ docker-compose exec superset telnet postgres 5432
Trying 172.24.0.3...
Connected to postgres.
Escape character is '^]'.

【讨论】: