Consul

整理了一些觉得有用的资料和踩过的坑.

为什么选用consul

1.因为Eureka即将停止维护了

2.Consul要更强大点,带配置中心

  • 每台机都必须运行一个consul agent.
  • consul agent有两种模式,1,server模式 2,client模式.
  • consul server,每个数据中心会有一个leader有server选举出来,故障后会重新选举.
  • consul server,保持数据一致性,维护集群状态,转发查询,转发请求给leader或者远程数据中心,交换wan gossip.
  • consul client用于注册服务,运行健康检查和转发对server的查询.
  • node名字必须在集群中唯一

Consulの初体验

运行一个Consul Server

docker run -d -p 8500:8500 -p 8300-8302:8300-8302 -p 8600:8600 \
--restart=always \
-h node1 \
--name consul  \
consul agent \
-server \
-bootstrap-expect=1 \
-node=node1 \
-rejoin \
-client 0.0.0.0 \
-advertise 192.168.99.100 \
-ui

端口作用不赘述,其它参数作用如下.

  • -h node1 指定hostname
  • -server 以server模式运行,不添加默认以client模式运行.
  • -bootstrap-expect=1 组成集群需要启动的server数量
  • -node=node1 指定节点名,同集群内不能重复
  • -rejoin 在意外断开连接后,会不会自动重新加入集群
  • -client 可以访问的ip
  • -advertise 宣传IP.不写的话,通过registrator注册,服务没有指定IP环境变量的话.consul上默认的是 consul server所在的容器的内网IP.写一个能访问到你服务的IP.
  • -ui 是否启用面板管理

Consul Server是一个有状态的容器,它有两个目录可以挂载本地的目录进去,方便改动配置和数据持久化.

  • /consul/config 配置目录,如果agent可以把json配置放这里,会自动加载
  • /consul/data consul数据目录,存放节点,KV,datacenter等数据

为了consul server能稳定提供服务,一般都建议有3-5个consul server组成集群.

如果有很多台机器,在启动足够的consul server后,其它主机可以都作为client运行.

运行一个Consul Client

docker run -d -p 8500:8500 -p 8300-8302:8300-8302 -p 8600:8600 \
--restart=always \
-h node2 \
--name consul  \
consul agent \
-node=node2 \
-rejoin \
-client 0.0.0.0 \
-join 192.168.99.100 \
-advertise 192.168.99.101

整个命令和运行consul是非常像的,就是少了几个配置.注意 -join到consul server即可

服务发现

consul提供了很多方式来注册,如通过json配置服务,放到相关目录,让agent注册,服务调用相关API注册,Docker容器发现.

由于我们服务都是运行在Docker之中,用Docker容器发现相关技术会方便点,所以优先考虑了这个.

1.可以在不改动代码的同时实现服务发现注册

2.可以和eureka发现同时存在,可以平缓过度.

相关实现的开源可选工具官方推荐了两个ContainerPilotRegistrator.

由于ContainerPilot使用更为复杂点,registrator比较简单,文档多,所以优先考虑了它.

- Docker Registrator主要特点

  • 通过docker socket直接监听容器event,根据容器启动/停止等event来注册/注销服务
  • 每个容器的每个exposed端口对应不同的服务
  • 支持可插拔的registry backend,默认支持Consul, etcd and SkyDNS
  • 自身也是docker化的,可以容器方式启动
  • 用户可自定义配置,如服务TTL(time-to-live)、服务名称、服务tag等

运行registrator

docker run -d \
    --name=registrator \
    --net=host \
    --volume=/var/run/docker.sock:/tmp/docker.sock \
    gliderlabs/registrator:latest \
    -internal \
    -ip 192.168.99.101 \
      consul://192.168.99.101:8500

每台机都要运行一个Registrator,consul地址填同机的consul agent

这时候,你只要在机子上运行任意一个docker容器,只要它暴露端口,就会被当成一个服务注册过去,如果没有指定服务名字之类的,默认取得服务名字作为服务名,服务id则为[hostname+端口].

Registrator服务对象

type Service struct {
    ID    string               // unique service instance ID
    Name  string               // service name
    IP    string               // IP address service is located at
    Port  int                  // port service is listening on
    Tags  []string             // extra tags to classify service
    Attrs map[string]string    // extra attribute metadata
}

可以通过运行docker服务的时候,传入环境变量SERVICE_<属性>=值,Registrator会读取得到它的相关的环境变量.

如:

docker run -d --name redis.0 -p 10000:6379 \
    -e "SERVICE_NAME=db" \
    -e "SERVICE_TAGS=master,backups" \
    -e "SERVICE_REGION=us2" progrium/redis

参考资料

首发于个人博客:https://uublog.com/article/20180802/consul-cluster/

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐