docker服务注册到领事,但健康检查失败

我想在docker集装箱内放置一个弹簧启动应用程序。 它使用了@EnableDiscoveryClient,它将它与consul =>注册整合在一起,健康检查在docker之外完美运行。

我将这个示例应用程序(来自http://rpi-cloud.com/apigatewaypattern/的电影应用程序)embedded到这个dockerfile中:

# VERSION 1.0 FROM java:8 ADD ./movie-0.0.1-SNAPSHOT.jar / # server port EXPOSE 9000 WORKDIR / CMD ["java", "-jar", "/movie-0.0.1-SNAPSHOT.jar"] 

然后从以下docker-compose.yml运行它:

 # service discovery consul: image: consul ports: - "8500:8500" # 8500 (HTTP) command: agent -server -bootstrap-expect 1 -ui -data-dir /tmp -client=0.0.0.0 ## test service movie: build: ./movie ports: - "9000:9000" links: - consul:localhost # for consul registry and configuration 

正如你所看到的,我试图变得聪明:为了避免将consul本身embedded到电影容器中,我已经将consul主机(ip)绑定到了电影容器的本地主机(使用dockernetworkingfunction)。

这对于服务发现是非常有效的:consul ui告诉我,电影应用程序能够注册自己,但是不能以另一种方式工作:当领事服务试图达到/电影服务的健康api时,健康检查失败。 以下是领事日志的输出:

  2016/05/19 15:50:38 [INFO] agent: Synced service 'movie-9000' 

和后者:

 2016/05/19 15:50:43 [WARN] agent: http request failed 'http://ca676cad169e:9000/health': Get http://ca676cad169e:900 0/health: dial tcp: lookup ca676cad169e on 10.0.2.3:53: server misbehaving 

无限重复。 我不明白为什么? 任何想法 ?

编辑使用docker-compose版本2时:

 version: '2' services: consul: ... (unchanged) movie: ... (unchanged) links: - consul:localhost # for consul registry and configuration 

领事开头很好,但电影服务不能注册本身=>连接被拒绝。 链接在v2中似乎没有效果。 因为https://github.com/docker/compose/issues/3127

链接不再由/ etc / hosts提供,它们现在由Docker 1.10.x中提供的embedded式DNS服务器提供。 这打破了本地主机的伎俩。

EDIT2

如果我明确地设置版本2的附加主机(与领事IP)它工作正常。

 version: '2' services: movie: # removed link keyword and replaced by extra_hosts: - "localhost:172.19.0.2" # specifying consul ip 

EDIT3

这是不带extra_hosts的版本2的电影容器看到的/ etc / hosts:

 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.19.0.3 45210c319110 

而在版本1中:

 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback ... # same + 172.17.0.2 localhost 88a07a35f228 ci_consul_1 

我该如何自动化并重新创build版本1的行为,同时保持networkingfunction?

编辑4 – 结论

=>这似乎是不可行的本地伎俩。 所以我在Docker中使用不同的configuration(如build议)。

这终究不是一个大问题,因为默认的consul主机可以在Dockerfile的CMD中的命令行上重写,然后我可以使用consul作为主机名。 (请参阅spring overload mechanism http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html )

 # in movie Dockerfile CMD ["java", "-jar", "/movie-0.0.1-SNAPSHOT.jar", "--spring.cloud.consul.host=consul"] 

docker版本

我使用docker-machine在窗口上使用docker 1.11.1

Docker版本1.11.1,build 5604cbe

docker-compose 1.7.0版,build 0d7bf73

由于您不使用撰写版本2.两个容器不共享相同的networking。

Consul执行定期健康检查以确保服务已启动并运行,因此需要访问应用程序健康检查服务。 哪个是“ http:// ca676cad169e:9000 / health ”

由于您已经定义了从应用程序容器到领事容器的链接,所以服务工作的注册。 应用程序出现时,该应用程序向领事注册。

您可以定义由容器共享的networking,也可以在主机networking上运行容器。

你将需要使用net: "host"选项

以下是文档链接https://docs.docker.com/compose/compose-file/#net

使用现有泊坞窗组合版本的泊坞窗,您可以更新电影应用程序的健康检查端点。 它将不会使用默认值,并将在外部端口上查询应用程序。

spring: cloud: consul: discovery: healthCheckPath: localhost:9000/health healthCheckInterval: 15s


我试图用docker组合版本2,并可以访问容器两种方式,networking应该允许你沟通任何方式..在我的示例中,我从consul容器下载nginx页面。

 version: "2" services: app: image: nginx ports: - "9000:80" discovery: image: consul ports: - "8500:8500" command: agent -server -bootstrap-expect 1 -ui -data-dir /tmp -client=0.0.0.0 docker version Client: Version: 1.10.3 API version: 1.22 Go version: go1.5.3 Git commit: 8acee1b Built: OS/Arch: linux/amd64 Server: Version: 1.10.3 docker-compose version docker-compose version 1.7.1, build 0a9ab35 docker-py version: 1.8.1 CPython version: 2.7.11 OpenSSL version: OpenSSL 1.0.2e 3 Dec 2015