问题1:ip问题
使用容器方式在主机上部署后,consul节点的ip为容器IP,如上图所示,主机外不能访问到该服务,需要配置内网或公网IP。
使用docker
使用docker run命令启动consul只需要在run后增加 --net = "host"
,这相当于使用主机上的IP。
#注意1是要指定net为host,2是网卡为主机上的网卡,该网卡主机外服务能访问到,可以使用ifconfig看看网卡具体的名字
docker run --net = "host" --name ** -e CONSUL_BIND_INTERFACE='eth0' ....(省略)
使用docker-compose
使用docker-compose
启动docker,需要指定network_mode
为host
#原本配置,eth0为容器内网卡
consul_server_2:
container_name: consul_server_2
image: consul:1.6.0
networks:
consul:
ipv4_address: 172.20.0.3
volumes:
- /docker/consul/server2/config:/consul/config
- /docker/consul/server2/data:/consul/data
environment:
- CONSUL_BIND_INTERFACE=eth0
- TZ=Asia/Shanghai
- CONSUL_HTTP_TOKEN=db98c304-4d38-8660-fafe-6a4be56a40d0
restart: always
command: [
'agent'
]
#优化后,映射端口不需要了,因为是直接使用主机ens33网卡了
consul_server_1:
container_name: consul_server_1
image: consul:1.6.0
network_mode: host
volumes:
- /docker/consul/server1/config:/consul/config
- /docker/consul/server1/data:/consul/data
environment:
- CONSUL_BIND_INTERFACE=ens33
- TZ=Asia/Shanghai
- CONSUL_HTTP_TOKEN=db98c304-4d38-8660-fafe-6a4be56a40d0
restart: always
command: [
'agent'
]
这样启动后consul服务的ip会变成主机的ip,外面的服务可以访问,跨机器部署consul集群通信也不会有问题了
但是以上办法一台机器只能启动一个consul容器,多了会有端口占用的问题,如果想要单机部署多个consul节点,可以考虑修改consul端口。
//新增ports.json放到consul的配置目录下即可。配置目录下所有.json配置都会加载
//默认端口参考官网:https://www.consul.io/docs/agent/options.html#ports
{
"ports": {
"dns":9600,
"http":9500,
"serf_lan":9301,
"serf_wan":9302,
"server":9300
}
}
启动后同一台机器上两个consul都启动了,占用不同端口,类似可以继续增加consul节点数量,他们的IP都是一样的
问题2:跨机器加入集群报错
#client
2019/10/11 03:48:01 [INFO] agent: (LAN) joining: [192.168.41.128]
consul_client_2 | ==> 1 error occurred:
consul_client_2 | * Failed to join 192.168.41.128: No installed keys could decrypt the message
#server端
consul_server_1 | 2019/10/11 03:48:18 [ERR] memberlist: failed to receive: No installed keys could decrypt the message from=192.168.41.129:48362
consul_server_1 | 2019/10/11 03:48:18 [ERR] memberlist: failed to receive: No installed keys could decrypt the message from=192.168.41.129:48364
consul_server_1 | 2019/10/11 03:48:31 [ERR] memberlist: failed to receive: No installed keys could decrypt the message from=192.168.41.129:48438
consul_server_1 | 2019/10/11 03:48:31 [ERR] memberlist: failed to receive: No installed keys could decrypt the message from=192.168.41.129:48440
consul_server_1 | 2019/10/11 03:48:57 [ERR] memberlist: failed to receive: No installed keys could decrypt the message from=192.168.41.129:48598
consul_server_1 | 2019/10/11 03:48:57 [ERR] memberlist: failed to receive: No installed keys could decrypt the message from=192.168.41.129:48600
所有consul节点加入配置
"encrypt":"Cwqvm4elg0SIaF6xanFxZ3OFYadEiQtZ71xY1mJTUbk="
此encrypt官方解释是用与集群通信加密的,生成方式 consul keygen
依然报错不能解决
//所有节点加入以下配置,删除encrypt,下面的配置字面意思,出入的通信都不在验证,问题解决,不在报错
"encrypt_verify_incoming":false
"encrypt_verify_outgoing":false
上面的配置是把验证功能关掉了,有安全隐患,官网还有另一个配置disable_keyring_file
,(https://github.com/hashicorp/consul/issues/4163
)有人可以解决,但是我尝试没有成功,后面继续研究有没有两全其美的办法。。
start_join、retry_join的格式
-join-启动时要加入的另一个代理的地址。可以多次指定,以指定要加入的多个代理。如果Consul无法加入任何指定地址,则代理启动将失败。默认情况下,代理在启动时不会加入任何节点。请注意,retry_join在Consul群集部署自动化时,使用 更为合适的方法有助于减轻节点启动竞争条件。
-retry-join-与类似,-join但如果第一次尝试失败,则允许重试连接。在您知道该地址最终可用的情况下,这很有用。该列表可以包含IPv4,IPv6或DNS地址。在Consul 1.1.0及更高版本中,可以将其设置为 go-sockaddr 模板。如果Consul在非默认的Serf LAN端口上运行,则也必须指定此端口。IPv6必须使用“括弧式”语法。如果给出了多个值,则按照列出的顺序尝试并重试它们,直到第一个成功。这里有些例子:
# Using a DNS entry
$ consul agent -retry-join "consul.domain.internal"
# Using IPv4,只有IP
$ consul agent -retry-join "10.0.4.67"
# Using IPv6,带端口
$ consul agent -retry-join "[::1]:8301"
#配置文件中格式
"start_join":[
"192.168.41.128:8301"
],
"retry_join":[
"192.168.41.128:8301"
],
问题:No installed keys could decrypt the message 报错解决
新加入的consul节点需要配置encrypt
,这个值是需要跟server端一样的,值保存在/consul/data/serf/local.keyring
文件中,如果文件中已存在内容,是不是会更新的,需要删掉,或者手动填入,然后重启服务。如果文件中已经有了,那么启动配置中encrypt参数就可以删了,不会产生影响。-disable-keyring-file
这个参数作用是是否持久化这个encrypt
,默认持久化,可以选择不持久化,缺点是就要在启动配置里显式填写,优点是更好的排查所有节点是否一样。例如文件中和你启动参数中不一样,问题就出来了。
可以先在原有的集群中找到local.keyring
文件中找到该encrypt
,所有节点保持一致即可。