2016-05-19 67 views
2

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

内嵌我这个dockerfile此示例应用程序(从http://rpi-cloud.com/apigatewaypattern/电影应用程序):

# 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"] 

然后从下面的码头工人,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本身嵌入到电影容器中,我已将consul主机(ip)绑定到电影容器的本地主机(使用docker网络功能)。

它适用于服务发现:consul ui告诉我,电影应用程序能够注册自身,但它不能以另一种方式工作:当consul服务试图达到/电影服务的健康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 

其中重演无限期。 我不明白为什么?任何想法 ?

编辑 当使用泊坞窗,撰写版本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中提供的嵌入式DNS服务器提供。这打破了localhost的伎俩。

EDIT2

如果我明确地为第2版(带领事IP)额外的主机正常工作。

version: '2' 

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

EDIT3

这是在/ etc /不添加extra_hosts通过用版本2的电影容器看到主机:在版本1

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 

而:

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

如何在保持网络功能的同时自动执行并重新创建版本1的行为?

Edit4 - 结论

=>这似乎是不可行的本地主机技巧。所以我会在Docker中使用 不同的配置(如建议)。

这终究不是一个大问题,因为默认的consul主机可以在Dockerfile的CMD内的命令行上覆盖,然后我可以使用consular作为主机名。 (见春超载机制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"] 

泊坞版本

我使用泊坞窗1.11.1与泊坞窗机

泊坞版本1.11.1窗口,建立5604cbe

码头构成版本1.7.0,构建0d7bf73

回答

1

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

Consul执行定期运行状况检查以确保服务已启动并正在运行,因此需要访问应用程序运行状况检查服务。 这是“http://ca676cad169e:9000/health

服务工程的注册,因为您已经定义了从应用程序容器到consul容器的链接。应用程序出现时向应用程序注册。

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

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

这里是链接到文件 https://docs.docker.com/compose/compose-file/#net

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

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


我试图与码头工人撰写第2版,并可能访问容器两种方式,网络应该让你无论是沟通方式..我的样品中,我从与领事容器下载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 
+0

我试过第2版,但我不能够连接到领事在这种模式下。在我的情况下,使用net = host并不是一个选项:因为我希望有一个独立的网络与api-gateway。 – yves

+0

尝试在注册时为Movie应用程序配置healtcheck http://cloud.spring.io/spring-cloud-consul/spring-cloud-consul.html – Shibashis

+0

是的,我知道可以更改弹簧默认设置,但我想避免在Docker内部或外部具有相同的配置。我现在得到的问题似乎与“链接”在版本2中表现不一样(请参阅我的编辑)。 – yves