Docker-使用 Consul 组合动态分配的端口
Docker-Compose dynamically assigned ports with Consul
我是 运行 一些使用 Consul 进行服务发现的 Spring 启动应用程序(带有 Actuator)。如果我使用 docker-compose 启动应用程序,为每个容器指定主机和容器端口,然后它们会正确注册到 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" 和 "docker-host" 的主机地址值在启动时作为环境变量传入 docker-compose yml 文件,简单来说与 ip 地址相关docker 主机(我是同一台服务器上的 运行 Consul)。
请注意使用:
${server.port}
告诉 Consul 如何连接回容器以检查其健康状况的变量(在这方面它只是使用 Actuator)。这需要是一个外部可访问的地址和端口,以便 Consul 可以检查服务。
当我在容器的 docker-compose 文件中指定主机和容器端口号时,一切正常。
我已经到了想要扩展一些容器的地步,但是当我尝试执行
docker-compose up -d --scale myapp-A=5
command 它告诉我这是不可能的,因为已经指定了主机端口。如果我将 docker-compose yml 文件更改为仅定义容器端口,并让主机端口动态分配,那么一切都会出错,因为 Consul(运行 外部)得到错误的 URL 连接到容器并将其标记为不健康。
我的问题是如何告诉 Consul 动态和 "externally" 暴露的端口号,以便从我的应用程序 运行 容器内使用?
有什么方法可以获取端口号并在创建时将其传递到容器中吗?
如果可以的话,我想尝试使用 Compose 来破解它(而不是使用 Swarm,或者通过 运行 Consul 在同一组容器中的另一个容器中)。
单个主机上的缩放和端口映射通常不能很好地结合在一起。
如果您想支持动态映射的端口,那么您可能需要服务发现来进行服务发现。由于 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
最终在 consul as a service 中:
→ 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 记录,我认为它不会。
我是 运行 一些使用 Consul 进行服务发现的 Spring 启动应用程序(带有 Actuator)。如果我使用 docker-compose 启动应用程序,为每个容器指定主机和容器端口,然后它们会正确注册到 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" 和 "docker-host" 的主机地址值在启动时作为环境变量传入 docker-compose yml 文件,简单来说与 ip 地址相关docker 主机(我是同一台服务器上的 运行 Consul)。
请注意使用:
${server.port}
告诉 Consul 如何连接回容器以检查其健康状况的变量(在这方面它只是使用 Actuator)。这需要是一个外部可访问的地址和端口,以便 Consul 可以检查服务。
当我在容器的 docker-compose 文件中指定主机和容器端口号时,一切正常。
我已经到了想要扩展一些容器的地步,但是当我尝试执行
docker-compose up -d --scale myapp-A=5
command 它告诉我这是不可能的,因为已经指定了主机端口。如果我将 docker-compose yml 文件更改为仅定义容器端口,并让主机端口动态分配,那么一切都会出错,因为 Consul(运行 外部)得到错误的 URL 连接到容器并将其标记为不健康。
我的问题是如何告诉 Consul 动态和 "externally" 暴露的端口号,以便从我的应用程序 运行 容器内使用?
有什么方法可以获取端口号并在创建时将其传递到容器中吗?
如果可以的话,我想尝试使用 Compose 来破解它(而不是使用 Swarm,或者通过 运行 Consul 在同一组容器中的另一个容器中)。
单个主机上的缩放和端口映射通常不能很好地结合在一起。
如果您想支持动态映射的端口,那么您可能需要服务发现来进行服务发现。由于 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
最终在 consul as a service 中:
→ 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 记录,我认为它不会。