i386/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是一个分布式、高可用且支持多数据中心的工具,用于服务发现、配置和编排。它支持大规模面向服务架构的快速部署、配置和维护。更多信息请参见:
!logo
Consul包含多个组件,我们先简要介绍其架构,再详细说明与Docker的交互。更多细节请参见Consul架构指南。
Consul集群中的每个主机运行Consul代理(agent),这是一个长期运行的守护进程,可在客户端或服务器模式下启动。每个集群至少有1个服务器模式代理,通常为3个或5个以实现高可用。服务器代理参与共识协议,维护集群状态的集中视图,并响应集群中其他代理的查询。其余客户端模式代理通过gossip协议发现其他代理并检查其故障,同时将集群查询转发给服务器代理。
主机上运行的应用仅与本地Consul代理通信,使用HTTP API或DNS接口。主机上的服务也注册到本地Consul代理,代理将信息同步到Consul服务器。使用Consul进行最基本的基于DNS的服务发现时,应用查询foo.service.consul会获得提供"foo"服务的所有主机的随机子集,使应用无需中间代理即可定位服务并平衡负载。还提供多个HTTP API,供应用与Consul的服务发现功能及其他特性(如键/值存储)进行深度集成。
在Docker中运行Consul时,这些概念同样适用。通常,每个主机运行一个Consul代理容器,与Docker守护进程并行。还需将部分代理配置为服务器(至少3个用于基本高可用设置)。Consul在Docker中应始终使用--net=host运行,因为Consul的共识和gossip协议对延迟和丢包敏感,其他网络类型的额外层通常不可取且不必要,下文将详细说明。
本文不涉及Consul的多数据中心功能,但只要使用--net=host,Docker环境无需特殊考虑。
我们选择Alpine作为轻量级基础镜像,具有较小的安全***面,同时具备足够功能用于开发、交互式调试,以及在容器中运行Consul的健康检查、监控和执行脚本。从Consul 0.7起,镜像还包含curl,因为它常用于健康检查。
Consul始终在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_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查询。可根据具体DNS配置调整。若Consul客户端接口绑定到主机回环地址,可将主机resolv.conf配置为将DNS请求路由到Consul,方法是将"127.0.0.1"作为主DNS服务器。这会将Consul的DNS暴露给主机上所有应用,但由于Docker内置DNS服务器,容器内无法直接指向回环地址,Docker会报错。必须将Consul配置

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