consul【多台机器docker部署】


问题1:ip问题

consul
使用容器方式在主机上部署后,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_modehost

#原本配置,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节点,可以考虑修改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都是一样的

consul
consul

问题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,所有节点保持一致即可。


文章作者: wuzhiyong
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 wuzhiyong !
评论
 上一篇
k8s常用命令整理 k8s常用命令整理
用途 命令 查看集群状态 kubectl cluster-info 查看集群详细状态 kubectl cluster-info dump 查看节点 kubectl get nodes 查看节点更多信息 kubectl
2019-10-14
下一篇 
consul【结合spring cloud使用consul配置中心并自动刷新】 consul【结合spring cloud使用consul配置中心并自动刷新】
重点: consul的配置需要全部写在resource目录下bootstrap.yml文件中,写在application.yml中不能生效! consul config配置#bootstrap.yml配置 spring: cloud:
2019-10-10
  目录