arm32v6/consulConsul 1.16版本起,我们将停止发布官方Dockerhub镜像,仅发布Verified Publisher镜像。Docker镜像用户应从hashicorp/consul拉取镜像,而非consul。Verified Publisher镜像可在[***]
维护者:
HashiCorp
获取帮助:
Docker社区Slack、Server Fault、Unix & Linux或Stack Overflow
Dockerfile链接无支持的标签
问题提交地址:
[***]
支持的架构:(更多信息)
无支持的架构
已发布镜像制品详情:
repo-info仓库的repos/consul/目录(历史记录)
(镜像元数据、传输大小等)
镜像更新:
official-images仓库的library/consul标签
official-images仓库的library/consul文件(历史记录)
本描述的来源:
docs仓库的consul/目录(历史记录)
Consul是一个分布式、高可用且支持多数据中心的工具,用于服务发现、配置和编排。Consul支持大规模服务导向架构的快速部署、配置和维护。更多信息请参见:
!logo
Consul包含多个组件,我们先简要介绍Consul的架构,再详细说明其与Docker的交互。更多概念细节请参见Consul架构指南。
Consul集群中的每个主机运行Consul代理(一个长期运行的守护进程),可在客户端或服务器模式下启动。每个集群至少有1个服务器模式的代理,通常为3个或5个以实现高可用。服务器代理参与共识协议,维护集群状态的集中视图,并响应集群中其他代理的查询。其余客户端模式的代理通过gossip协议发现其他代理并检查其故障状态,同时将集群查询转发给服务器代理。
主机上运行的应用程序仅与其本地Consul代理通信,使用HTTP API或DNS接口。主机上的服务也注册到本地Consul代理,代理将信息同步到Consul服务器。使用Consul进行最基本的基于DNS的服务发现时,应用程序查询foo.service.consul,会获得提供"foo"服务的所有主机的随机子集。这使应用程序无需中间代理即可定位服务并平衡负载。Consul还提供多个HTTP API,供应用程序与服务发现功能及其他特性(如键/值存储)进行深度集成。
这些概念同样适用于在Docker中运行Consul。通常,每个主机运行一个Consul代理容器,与Docker守护进程一起运行。还需将部分代理配置为服务器(基本高可用设置至少需要3个)。Consul在Docker中应始终使用--net=host运行,因为Consul的共识和gossip协议对延迟和丢包敏感,其他网络类型涉及的额外层通常不可取且不必要。下文将详细说明。
本文不涉及Consul的多数据中心功能,但只要使用--net=host,Docker环境无需特殊考虑。
我们选择Alpine作为轻量级基础镜像,具有较小的安全***面,同时具备足够功能用于开发、交互式调试以及在容器中运行Consul的健康检查、监控和执行脚本。从Consul 0.7开始,镜像还包含curl,因为它常用于健康检查。
Consul始终在dumb-init下运行,dumb-init处理僵尸进程的回收,并将信号转发给容器中运行的所有进程。我们还使用gosu以非root用户"consul"运行Consul,提高安全性。这些二进制文件均由HashiCorp构建并用其GPG密钥签名,可验证用于构建特定基础镜像的签名包。
不带参数运行Consul容器将以开发模式启动Consul服务器。提供的入口点脚本会查找Consul子命令,并以正确的用户身份运行consul及该子命令。例如,执行docker run consul members将在容器内运行consul members命令。入口点在运行agent子命令时还会添加下文详述的一些特殊配置选项。其他命令将在dumb-init下exec到容器中。
容器公开VOLUME /consul/data,Consul将在此路径放置持久化状态。开发模式下不使用此路径。对于客户端代理,此路径存储集群信息和客户端健康检查,以便容器重启时使用。对于服务器代理,此路径存储客户端信息以及快照、共识算法相关数据、键/值存储和目录等状态。对于服务器,重启容器时保留此卷数据以从故障场景恢复非常重要。如果绑定挂载此卷,容器启动时所有权将更改为consul用户。
容器在/consul/config设置了Consul配置目录,代理将加载通过绑定卷放置或通过组合新镜像添加的配置文件。或者,可通过环境变量CONSUL_LOCAL_CONFIG传递配置JSON。如果绑定挂载此目录,容器启动时所有权将更改为consul用户。
由于Consul在Docker中几乎总是使用--net=host运行,配置Consul的IP地址时需注意。Consul有集群地址和客户端地址的概念。集群地址是其他Consul代理可联系给定代理的地址。客户端地址是主机上其他进程联系Consul以发出HTTP或DNS请求的地址。启动时通常需要告知Consul其集群地址,使其绑定到正确的接口并向其他Consul代理广播可用接口。下文示例中会看到-bind=<external ip>参数传递给Consul。
入口点还包含一个小工具,可通过接口名查找客户端或绑定地址。要使用此功能,设置环境变量CONSUL_CLIENT_INTERFACE和/或CONSUL_BIND_INTERFACE为所需接口名称,启动时将计算并传递-client=<interface ip>和/或-bind=<interface ip>参数给Consul。
console$ docker run -d --name=dev-consul -e CONSUL_BIND_INTERFACE=eth0 consul
这将启动一个完全基于内存的Consul服务器代理,使用默认桥接网络,不在主机上暴露服务,适用于开发但不应在生产中使用。例如,如果该服务器运行在内网地址172.17.0.2,可启动另外两个实例并让它们加入第一个节点,形成三节点开发集群。
console$ docker run -d -e CONSUL_BIND_INTERFACE=eth0 consul agent -dev -join=172.17.0.2 ... 服务器2启动 $ docker run -d -e CONSUL_BIND_INTERFACE=eth0 consul agent -dev -join=172.17.0.2 ... 服务器3启动
然后可在第一个容器中运行Consul CLI命令查询集群中的所有成员:
console$ docker exec -t dev-consul consul members Node Address Status Type Build Protocol DC 579db72c1ae1 172.17.0.3:8301 alive server 0.6.3 2 dc1 93fe2309ef19 172.17.0.4:8301 alive server 0.6.3 2 dc1 c9caabfd4c2a 172.17.0.2:8301 alive server 0.6.3 2 dc1
注意,此模式下Consul不使用数据卷——容器停止后所有状态将被清除,因此请勿在生产中使用此模式。在桥接网络上完全运行开发服务器有助于在单台机器上测试多个Consul实例,这通常因端口冲突而难以实现。
开发模式还会在8500端口启动Consul Web UI。可通过在命令行向Consul提供-ui选项将其添加到其他Consul配置中。Web资源捆绑在容器内的Consul二进制文件中。
console$ docker run -d --net=host -e 'CONSUL_LOCAL_CONFIG={"leave_on_terminate": true}' consul agent -bind=<external ip> -retry-join=<root agent ip> ==> Starting Consul agent... ==> Starting Consul agent RPC... ==> Consul agent running! Node name: 'linode' Datacenter: 'dc1' Server: false (bootstrap: false) Client Addr: 127.0.0.1 (HTTP: 8500, HTTPS: -1, DNS: 8600, RPC: 8400) Cluster Addr: <external ip> (LAN: 8301, WAN: 8302) Gossip encrypt: false, RPC-TLS: false, TLS-Incoming: false Atlas: <disabled> ...
这将运行共享主机网络的Consul客户端代理,并向集群其他节点广播外部IP地址。注意,代理默认将客户端接口绑定到127.0.0.1(主机的回环接口)。如果主机上的其他容器也使用--net=host,此配置非常适用,同时也将代理暴露给直接在主机上运行的进程(如HashiCorp的Nomad)。
-retry-join参数指定集群中另一个代理的外部IP,用于启动时加入集群。有多种方式控制代理加入集群,详见代理配置指南中的-join、-retry-join和-atlas-join选项。
还需注意,我们使用CONSUL_LOCAL_CONFIG环境变量设置了leave_on_terminate。这是客户端推荐的配置,Consul 0.7及更高版本将默认设为true,因此未来无需再设置。
启动时,代理将从/consul/config读取配置JSON文件。数据将持久化在/consul/data卷中。
以下是外部IP为66.175.220.234的主机上的查询示例:
console$ curl http://localhost:8500/v1/health/service/consul?pretty { "Node": { "Node": "linode", "Address": "66.175.220.234", ...
console$ dig @localhost -p 8600 consul.service.consul ; <<>> DiG 9.9.5-3ubuntu0.7-Ubuntu <<>> @localhost -p 8600 consul.service.consul ; (2 servers found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61616 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; WARNING: recursion requested but not available ;; QUESTION SECTION: ;consul.service.consul. IN A ;; ANSWER SECTION: consul.service.consul. 0 IN A 66.175.220.234 ...
如果要通过其他网络(如桥接网络)向其他容器暴露Consul接口,使用Consul的-client选项:
consoledocker run -d --net=host consul agent -bind=<external ip> -client=<bridge ip> -retry-join=<root agent ip> ==> Starting Consul agent... ==> Starting Consul agent RPC... ==> Consul agent running! Node name: 'linode' Datacenter: 'dc1' Server: false (bootstrap: false) Client Addr: <bridge ip> (HTTP: 8500, HTTPS: -1, DNS: 8600, RPC: 8400) Cluster Addr: <external ip> (LAN: 8301, WAN: 8302) Gossip encrypt: false, RPC-TLS: false, TLS-Incoming: false Atlas: <disabled> ...
此配置下,Consul的客户端接口将绑定到桥接IP,对该网络上的其他容器可用,但不在主机网络上。注意,我们仍将集群地址保留在主机网络以提高性能。Consul也接受-client=0.0.0.0选项绑定到所有接口。
console$ docker run -d --net=host -e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}' consul agent -server -bind=<external ip> -retry-join=<root agent ip> -bootstrap-expect=<number of server agents>
这将运行共享主机网络的Consul服务器代理。上文客户端代理的所有网络注意事项和行为同样适用于服务器代理。单个服务器无法形成法定人数,将等待其他服务器加入。
与客户端代理一样,-retry-join参数指定集群中另一个代理的外部IP,用于启动时加入集群。有多种方式控制代理加入集群,详见[代理配置指南中的-join、-retry-join和-atlas-join选项。服务器代理还使用-bootstrap-expect选项,指定首次引导集群前要等待的服务器代理数量。这提供了一种轻松实现新集群有序启动的方式。详见代理配置指南中的-bootstrap和-bootstrap-expect选项。
还需注意,我们使用CONSUL_LOCAL_CONFIG环境变量设置了skip_leave_on_interrupt。这是服务器推荐的配置,Consul 0.7及更高版本将默认设为true,因此未来无需再设置。
启动时,代理将从/consul/config读取配置JSON文件。数据将持久化在/consul/data卷中。
集群引导并达成法定人数后,必须注意保持最少数量的服务器运行,以避免集群进入故障状态。共识指南中的部署表概述了不同配置所需的服务器数量。还有添加/删除服务器指南描述该过程,也适用于Docker配置。故障恢复指南提供了服务器永久丢失时的恢复步骤。通常,最好一次重启或替换一台服务器,确保服务器健康后再继续下一台。
默认情况下,Consul的DNS服务器暴露在8600端口。由于在resolv.conf等工具中配置此端口不便,可能需要将DNS暴露在53端口。Consul 0.7及更高版本支持通过设置环境变量对Consul二进制文件运行setcap,使其能够绑定到特权端口。注意,并非所有Docker存储后端都支持此功能(特别是AUFS)。
示例如下:
console$ docker run -d --net=host -e 'CONSUL_ALLOW_PRIVILEGED_PORTS=' consul -dns-port=53 -recursor=8.8.8.8
此示例还包含递归器配置,使用Google的DNS服务器处理非Consul查询。可根据具体

manifest unknown 错误
TLS 证书验证失败
DNS 解析超时
410 错误:版本过低
402 错误:流量耗尽
身份认证失败错误
429 限流错误
凭证保存错误
来自真实用户的反馈,见证轩辕镜像的优质服务