一、etcd简介与应用场景
etcd 是一个分布式一致性k-v存储系统,可用于服务注册发现与共享配置,具有以下优点:1、简单 : 相比于晦涩难懂的paxos算法,etcd基于相对简单且易实现的raft算法实现一致性,并通过gRPC提供接口调用;2、安全:支持TLS通信,并可以针对不同的用户进行对key的读写控制;3、高性能:10,000 /秒的写性能。其主要应用于服务注册发现以及共享配置。
1、 服务注册与发现
- 服务启动后向etcd注册,并上报自己的监听的端口以及当前的权重因子等信息,且对该信息设置ttl值。
- 服务在ttl的时间内周期性上报权重因子等信息。
- client端调用服务时向etcd获取信息,进行调用,同时监听该服务是否变化(通过watch方法实现)。
- 当新增服务时watch方法监听到变化,将服务加入代用列表,当服务挂掉时ttl失效,client端检测到变化,将服务踢出调用列表,从而实现服务的动态扩展。
- 另一方面,client端通过每次变化获取到的权重因子来进行client端的加权调用策略,从而保证后端服务的负载均衡。
2、共享配置
一般服务启动时需要加载一些配置信息,如数据库访问地址,连接配置,这些配置信息每个服务都差不多,如果通过读取配置文件进行配置会存在要写多份配置文件,且每次更改时这些配置文件都要更改,且更改配置后,需要重启服务后才能生效,这些无疑让配置极不灵活,如果将配置信息放入到etcd中,程序启动时进行加载并运行,同时监听配置文件的更改,当配置文件发生更改时,自动将旧值替换新值,这样无疑简化程序配置,更方便于服务部署。
二、单机模式运行
默认在centos7的yum源里已集成了etcd包,可以通过yum进行安装。也可以去github上下载二进制包:https://github.com/coreos/etcd/tags,这里我选择的yum直接安装的。启用etcd服务命令如下:
[root@docker-01 ~]# yum -y install etcd
[root@docker-01 ~]# systemctl start etcd
进行如下测试etcd的可用性:
[root@docker-01 ~]# etcdctl set site www.361way.com www.361way.com [root@docker-01 ~]# etcdctl get site www.361way.com
从上面可以看到可以进行k/v值的设置和获取。不过单机模式一般很少使用。
三、集群模式说明
集群搭建有三种方式,分布是静态配置,etcd发现,dns发现。默认配置运行etcd,监听本地的2379端口,用于与client端交互,监听2380用于etcd内部交互。etcd启动时,集群模式下会用到的参数如下:
--name etcd集群中的节点名,这里可以随意,可区分且不重复就行 --listen-peer-urls 监听的用于节点之间通信的url,可监听多个,集群内部将通过这些url进行数据交互(如选举,数据同步等) --initial-advertise-peer-urls 建议用于节点之间通信的url,节点间将以该值进行通信。 --listen-client-urls 监听的用于客户端通信的url,同样可以监听多个。 --advertise-client-urls 建议使用的客户端通信url,该值用于etcd代理或etcd成员与etcd节点通信。 --initial-cluster-token etcd-cluster-1 节点的token值,设置该值后集群将生成唯一id,并为每个节点也生成唯一id,当使用相同配置文件再启动一个集群时,只要该token值不一样,etcd集群就不会相互影响。 --initial-cluster 也就是集群中所有的initial-advertise-peer-urls 的合集 --initial-cluster-state new 新建集群的标志,初始化状态使用 new,建立之后改此值为 existing
搭建集群之前首先准备两台安装了CentOS 7的主机,并在其上安装好Docker。
主机名 | IP | 内核 |
docker-02 | 192.168.1.222 | 3.10.0-693.el7.x86_64 |
docker-01 | 192.168.1.221 | 3.10.0-693.el7.x86_64 |
开放ETCD通信使用的接口
[root@docker-01 ~]# firewall-cmd --zone=public --add-port=2379/tcp --permanent success [root@docker-01 ~]# firewall-cmd --zone=public --add-port=2380/tcp --permanent success [root@docker-01 ~]# firewall-cmd --reload success [root@docker-01 ~]# firewall-cmd --list-ports 2379/tcp 2380/tcp [root@docker-02 ~]# firewall-cmd --zone=public --add-port=2379/tcp --permanent success [root@docker-02 ~]# firewall-cmd --zone=public --add-port=2380/tcp --permanent success [root@docker-02 ~]# firewall-cmd --reload success [root@docker-02 ~]# firewall-cmd --list-ports 2379/tcp 2380/tcp
最后那行代码显示已经打开的所有端口。
首先获取ETCD镜像,两台主机都有(以下简称two)。
该镜像的版本信息:https://hub.docker.com/r/eagle6688/etcd/
[root@docker-01 ~]# docker pull eagle6688/etcd [root@docker-02 ~]# docker pull eagle6688/etcd
创建数据挂载目录
[root@docker-01 ~]# mkdir -p /var/data/etcd [root@docker-02 ~]# mkdir -p /var/data/etcd
在docker-02主机执行:
docker run -it -p 2379:2379 -p 2380:2380 -v /var/data/etcd:/data --name etcd-master eagle6688/etcd --name etcd-master --data-dir /data --listen-peer-urls http://0.0.0.0:2380 --listen-client-urls http://0.0.0.0:2379 --initial-advertise-peer-urls http://192.168.1.221:2380 --initial-cluster etcd-master=http://192.168.1.221:2380 --initial-cluster-state new --initial-cluster-token eagle-cluster --advertise-client-urls http://192.168.1.221:2379
注意,第8行我们给etcd节点起的名字要跟13行的name相同,配置docker-01节点时类似。此外,这里的配置仅仅跟docker-02节点自身有关,此时它还不知道有docker-01的存在。
5. 测试master节点:
分别在master节点和node节点执行下面的语句以测试master节点的有效性:
[root@docker-02 ~]# curl http://192.168.1.221:2379/v2/members {"members":[{"id":"5bd86dc1d02152c4","name":"etcd-master","peerURLs":["http://192.168.1.221:2380"],"clientURLs":["http://192.168.1.221:2379"]}]}
该语句应该返回包含master节点信息的json字符串。
6. 添加dokcer-01节点
在docker-01机调用docker-02的api添加自己
[root@docker-01 ~]# curl http://192.168.1.221:2379/v2/members -XPOST -H "Content-Type: application/json" -d '{"peerURLs":["http://192.168.1.222:2380"]}' {"message":"membership: peerURL exists"}[root@docker-01 ~]#
此时,master节点会暂停下来等待node节点的加入。
启动docker-01节点上的etcd
[root@docker-01 ~]# docker run > -it > -p 2379:2379 > -p 2380:2380 > -v /var/data/etcd:/data > --name etcd-node > eagle6688/etcd > --name etcd-node > --data-dir /data > --listen-peer-urls http://0.0.0.0:2380 > --listen-client-urls http://0.0.0.0:2379 > --initial-advertise-peer-urls http://192.168.1.222:2380 > --initial-cluster etcd-master=http://192.168.1.221:2380,etcd-node=http://192.168.1.222:2380 > --initial-cluster-state existing > --initial-cluster-token eagle-cluster > --advertise-client-urls http://192.168.1.222:2379
注意,initial-cluster要包含所有节点,initial-cluster-state必须是existing。
确认验证
[root@docker-02 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 634ee3d3864b eagle6688/etcd "/bin/etcd --name et…" 23 minutes ago Up 23 minutes 0.0.0.0:2379-2380->2379-2380/tcp etcd-master [root@docker-01 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7636428ee667 eagle6688/etcd "/bin/etcd --name et…" 31 seconds ago Up 25 seconds 0.0.0.0:2379-2380->2379-2380/tcp etcd-node