Docker - 使用Consul

时间:2018-03-01 20:46:10

标签: docker docker-compose consul spring-cloud-consul

我正在运行许多使用Consul进行服务发现的Spring Boot应用程序(使用Actuator)。如果我使用docker-compose启动应用程序,为每个容器指定Host和Container端口,那么它们会与Consul正确注册,并很快被标记为健康。

spring:
  application:
    name: myapp-A
  profiles:
    active: default 
  cloud:
    consul:
      enabled: true
      host: consul
      port: 8500
      discovery:
        prefer-ip-address: true
        healthCheckUrl: http://docker-host:${server.port}/health

" consul"的主机地址值和#34; docker-host"在启动时作为环境变量在docker-compose yml文件中传入,并且简单化术语与docker主机的ip地址相关(我在同一台服务器上运行Consul)。

请注意使用:

${server.port}

变量告诉Consul如何连接回容器以检查其健康状况(在这方面它只使用Actuator)。这需要是一个外部可访问的地址和端口,以便Consul可以检查服务。

当我在容器的docker-compose文件中指定Host和Container端口号时,这一切都正常。

我已经达到了我想要扩展一些容器的程度,但当我尝试执行

docker-compose up -d --scale myapp-A=5

命令它告诉我,由于指定了主机端口,因此无法实现。如果我将docker-compose yml文件更改为仅定义容器端口,并保留主机端口以进行动态分配,那么所有这些都会出错,因为Consul(外部运行)被赋予错误的URL连接并将容器标记为不健康的。

我的问题是我如何动态地告诉Consul"外部"暴露在我的应用程序内部运行的端口号?

有没有办法获取端口号并在创建时将其传递到容器中?

如果可以的话,我想尝试使用Compose来破解它(而不是使用Swarm,或者在同一组合容器中的另一个容器中运行Consul)。

1 个答案:

答案 0 :(得分:0)

单个主机和端口映射的扩展通常不能很好地结合在一起。

如果要支持动态映射的端口,则可能需要为服务发现提供服务发现。由于spring应用程序本身永远不会知道外部映射端口,因此您需要以某种方式从Docker守护程序提供信息。

在Docker方面,由于您已经使用了consul,Registrator可以将容器信息作为服务发布:

→ docker ps -f name=verdaccio
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS                    NAMES
a9f0726027fd        deployable/verdaccio:2.7.3   "node --trace_gc /ap…"   3 days ago          Up 12 hours         0.0.0.0:4873->4873/tcp   verdaccio

最终以领事作为服务:

→ curl -s 10.8.8.8:8521/v1/catalog/service/verdaccio | jq
[
  {
    "ID": "fe50cd37-576f-fbce-cb63-567359c87257",
    "Node": "c8fecf7ed36a",
    "Address": "172.16.231.22",
    "Datacenter": "dc1",
    "TaggedAddresses": {
      "lan": "172.16.231.22",
      "wan": "172.16.231.22"
    },
    "NodeMeta": {
      "consul-network-segment": ""
    },
    "ServiceID": "registrator:verdaccio:4873",
    "ServiceName": "verdaccio",
    "ServiceTags": [
      "mhmb"
    ],
    "ServiceAddress": "",
    "ServicePort": 4873,
    "ServiceEnableTagOverride": false,
    "CreateIndex": 139,
    "ModifyIndex": 139
  }
]

SRV DNS记录中提供了端口:

→ dig @127.0.0.1 -p 8621 verdaccio.service.consul. SRV

; <<>> DiG 9.8.3-P1 <<>> @127.0.0.1 -p 8621 verdaccio.service.consul. SRV
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4713
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 2
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;verdaccio.service.consul.  IN  SRV

;; ANSWER SECTION:
verdaccio.service.consul. 0 IN  SRV 1 1 4873 c8fecf7ed36a.node.dc1.consul.

;; ADDITIONAL SECTION:
c8fecf7ed36a.node.dc1.consul. 0 IN  A   172.16.231.22
c8fecf7ed36a.node.dc1.consul. 0 IN  TXT "consul-network-segment="

;; Query time: 2 msec
;; SERVER: 127.0.0.1#8621(127.0.0.1)
;; WHEN: Thu Mar  1 23:08:15 2018
;; MSG SIZE  rcvd: 142

从那时起,我不确定如何配置Spring Cloud Consul来使用这些信息。 Spring Cloud是否包含一些注入动态属性的功能?如果您可以让Spring在发布服务之前查找SRV记录或发出API请求,那么您将进行排序。或者,Consul需要直接支持健康检查SRV记录,我不相信它。