UU Blog

Centos7+Docker部署Consul集群

[TOC]

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

1
2
3
4
5
6
7
8
9
10
11
12
13
docker run -d -p 8500:8500 -p 8300-8302:8300-8302 -p 8600:8600 \
--restart=always \
-h node1 \
--name consul \
-v /data/consul:/consul/data \
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

1
2
3
4
5
6
7
8
9
10
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
-

1
2
3
4
5
6
7
8
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服务对象
-

1
2
3
4
5
6
7
8
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会读取得到它的相关的环境变量.

如:

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

参考资料

给作者打一针鸡血