docker-compose容器间通讯

时间:2018-10-02 12:41:24

标签: docker spring-boot docker-compose

我目前正在尝试基于Spring Boot的微服务,并开始使用docker,但是遇到了麻烦。

基本上,我想做的是将2个小型服务容器化:spring cloud config服务和spring cloud eureka服务(发现服务)。 eureka服务从config服务获取其配置。

两个服务都是具有自己的Dockerfile的独立项目:

Dockerfile-cloud-config-service:

FROM openjdk:10.0.2-13-jre-sid
ENV APP_FILE cloud-config-service.jar
ENV APP_HOME /usr/apps
EXPOSE 8888
COPY target/$APP_FILE $APP_HOME/
WORKDIR $APP_HOME
ENTRYPOINT ["sh", "-c"]
CMD ["exec java -jar $APP_FILE"]

Dockerfile-discovery-service:

FROM openjdk:10.0.2-13-jre-sid
ENV APP_FILE discovery-service.jar
ENV APP_HOME /usr/apps
EXPOSE 8761
COPY target/$APP_FILE $APP_HOME/
WORKDIR $APP_HOME
ENTRYPOINT ["sh", "-c"]
CMD ["exec java -jar $APP_FILE"]

使用docker-compose,我尝试使用以下 docker-compose.yml将它们绑在一起:

version: '3.7'
services:
  cloud-config-service:
    container_name: cloud-config-service
    build:
      context: cloud-config-service
      dockerfile: Dockerfile-cloud-config-service
    image: cloud-config-service:latest
    ports:
      - 8888:8888
    networks:
      - emp-network

  discovery-service:
    container_name: discovery-service
    build:
      context: discovery-service
      dockerfile: Dockerfile-discovery-service
    image: discovery-service:latest
    ports:
      - 8761:8761
    networks:
      - emp-network
    links:
      - cloud-config-service

networks:
  emp-network:
    driver: bridge

首先,我将发现服务配置为从 http://localhost:8888 获取其配置,但是经过一番挖掘后,我发现容器中的localhost引用了容器本身,并在Docker中找到了服务可以使用其名称相互引用的文档。因此,我更改了发现服务的属性,以从 http://cloud-config-service:8888 获取其配置。那行不通,因此这篇文章。

两个Dockerfile都可以正常构建和运行,除了发现服务无法在 http://cloud-config-service:8888 上获取配置服务这一事实。

如果我使用host网络驱动程序和 http://localhost:8888 端点,它确实可以工作,但是这种“感觉”很骇人,而不是应该怎么做。 / p>

我可能缺少一些琐碎的东西,但恐怕找不到。

编辑: 发现服务的控制台日志的小片段:

discovery-service       | 2018-10-02 13:14:26.798  INFO 1 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://cloud-config-service:8888
cloud-config-service    | 2018-10-02 13:14:26.836  INFO 1 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$8a18e3b3] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
discovery-service       | 2018-10-02 13:14:27.129  INFO 1 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Connect Timeout Exception on Url - http://cloud-config-service:8888. Will be trying the next url if available
discovery-service       | 2018-10-02 13:14:27.129  WARN 1 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Could not locate PropertySource: I/O error on GET request for "http://cloud-config-service:8888/discovery-service/default": Connection refused (Connection refused); nested exception is java.net.ConnectException: Connection refused (Connection refused)

3 个答案:

答案 0 :(得分:0)

听起来像您走上正轨...我将引入depends_on的概念,以告诉容器discovery-service在容器cloud-config-service启动之前等待

  discovery-service:
    container_name: discovery-service
    build:
      context: discovery-service
      dockerfile: Dockerfile-discovery-service
    image: discovery-service:latest
    depends_on:
      - cloud-config-service
    ports:
      - 8761:8761
    networks:
      - emp-network
    links:
      - cloud-config-service

有一个有限的时间来启动容器,容器才能主动处理流量,因此很高兴参加这个启动过程,尤其是在处理数据库容器时,其他人应该depends_on

答案 1 :(得分:0)

我无法发表评论,所以我正在写一个新答案。

您是否尝试运行类似docker exec -it myconatiner1 curl myconatiner2:port

查看是否看到它或ping,如果没有,是什么错误?

答案 2 :(得分:0)

首先,泊坞窗容器之间的通信是分布式服务中普遍存在的一个更大问题的子集-您不知道什么服务(因此their dependencies)随时会中断,因此您应该采取在构建应用程序时会考虑到此类故障。

您面临的问题是常见的,尤其是在Docker容器中,我相信容器间的通信是Docker中的一个主要部分,并且在频繁的开发变更中。

为解决您的问题,首先,我想提出几点-

    容器中的
  1. localhost将引用该容器本身。
  2. localhost实际上是指您的本地主机,并且将与ports文件中每个服务的通过docker-compose配置映射的服务映射。 / li>
  3. depends_on仅等待容器启动,而不等待实际进程开始运行-这可能意味着您正在等待的服务不一定已启动并正在运行,因此导致超时依赖服务。

您需要的是等待服务开始运行,而不仅仅是容器启动。有两种方法可以完成此任务-

  1. 根据故障为您的restart指定discovery-service策略。对于您而言,故障将是在连接到cloud-config-service时超时。类似restart: on-failure:10之类的东西,这意味着您要让docker在discover-service失败时重新启动,最大重试次数为10。这样,您将有合理的时间让其他容器(服务)启动并运行,并确保具有重启策略最终的容器连接到该容器。

  2. 使用其他类似dockerize的工具,使您可以wait在启动容器之前使用其他服务。

此外,为确保正确调试问题,请务必检查容器的日志以查看问题的根源-docker logs -f --tail=100 <container_name/container_id>

希望这会有所帮助。