etcd集群之序

序言

1、为什么要用etcd集群?

    集群很好理解,毕竟增加了高可用性了,那为什么要用etcd而不实用zookeeper呢?从运维的角度来看,zk难以维护,而etcd作为后起之秀,则大大减少的运维的成本。

2、etcd是什么?

    etcd主要用来作为共享的服务配置及服务发现,使用的是raft协议来保证在分布式系统下的数据一致性,而raft算法那么容易理解,对于每个过程也是很好处理的。

3、如何使用etcd集群?

    etcd的集群搭建是相当容易的,在使用的时候,使用命令行或者接口都是可以的,而作为一种分布式的kv存储,和redis感觉很相同,都是使用key value的模式,不过在etcd中,使用的树形结构来组织,和linux的目录结构是一致的(具体见后文实例)。

搭建集群

1、集群架构

    在搭建集群中,使用四台机器进行演示,etcd集群为3台机器,1台机器作为备用机器,进行模拟坏的机器。

etcd集群之序

2、 安装etcd

    在centos7系统上自带有etcd,从而只要直接使用yum进行安装即可(在四台机器上均要进行安装)。

etcd集群之序

3、 开启防火墙

[root@centos ~]# firewall-cmd --add-port=2380/tcp --permanent;firewall-cmd --add-port=2379/tcp --permanent;systemctl restart firewalld

success

success

4、 启动etcd

    在新建集群的时候,首先在一台机器上启动etcd服务(测试的时候,注意将ip地址进行修改即可):

[root@docker-ce /]# etcd --name docker-ce --data-dir /etcd --initial-advertise-peer-urls http://192.168.1.222:2380 --listen-peer-urls http://192.168.1.222:2380  --listen-client-urls http://192.168.1.222:2379,http://127.0.0.1:2379   --advertise-client-urls http://192.168.1.222:2379  --initial-cluster-token etcd-cluster-1  --initial-cluster docker2=http://192.168.1.33:2380,docker1=http://192.168.1.32:2380,docker-ce=http://192.168.1.222:2380  --initial-cluster-state new

[root@docker-ce ~]# etcdctl member list(查看节点成员)

client: etcd cluster is unavailable or misconfigured; error #0: client: endpoint http://127.0.0.1:2379 exceeded header timeout

; error #1: dial tcp 127.0.0.1:4001: getsockopt: connection refused

[root@docker-ce ~]# etcdctl cluster-health(检查集群是否健康)

cluster may be unhealthy: failed to list members

Error:  client: etcd cluster is unavailable or misconfigured; error #0: dial tcp 127.0.0.1:4001: getsockopt: connection refused

; error #1: client: endpoint http://127.0.0.1:2379 exceeded header timeout

error #0: dial tcp 127.0.0.1:4001: getsockopt: connection refused

error #1: client: endpoint http://127.0.0.1:2379 exceeded header timeout

[root@docker-ce ~]# netstat -ntlp|grep etcd(查看etcd监听的端口,客户端使用的端口为2379,服务端使用的端口为2380)

tcp        0      0 192.168.1.222:2379      0.0.0.0:*               LISTEN      115537/etcd         

tcp        5      0 127.0.0.1:2379          0.0.0.0:*               LISTEN      115537/etcd         

tcp        0      0 192.168.1.222:2380      0.0.0.0:*               LISTEN      115537/etcd         

[root@docker-ce ~]# ps -ef|grep etcd(查看etcd进程)

root     115537   1347 24 20:29 pts/0    00:00:58 etcd --name docker-ce --data-dir /etcd --initial-advertise-peer-urls http://192.168.1.222:2380 --listen-peer-urls http://192.168.1.222:2380 --listen-client-urls http://192.168.1.222:2379,http://127.0.0.1:2379 --advertise-client-urls http://192.168.1.222:2379 --initial-cluster-token etcd-cluster-1 --initial-cluster docker2=http://192.168.1.33:2380,docker1=http://192.168.1.32:2380,docker-ce=http://192.168.1.222:2380 --initial-cluster-state new

    启动日志中,出现报错信息,也就是无法连接其他机器的通信端口2380.

2018-02-08 20:33:34.566814 W | rafthttp: health check for peer c9bb018f3490f125 could not connect: dial tcp 192.168.1.33:2380:getsockopt: connection refused

2018-02-08 20:33:34.642930 W | rafthttp: health check for peer f83aa3ff91a96c2f could not connect: dial tcp 192.168.1.32:2380:getsockopt: connection refused

    启动另外一台机器上的etcd进程:

[root@docker1 ~]# etcd --name docker1 --data-dir /etcd  --initial-advertise-peer-urls http://192.168.1.32:2380 --listen-peer-urls http://192.168.1.32:2380  --listen-client-urls http://192.168.1.32:2379,http://127.0.0.1:2379   --advertise-client-urls http://192.168.1.32:2379  --initial-cluster-token etcd-cluster-1  --initial-cluster docker2=http://192.168.1.33:2380,docker1=http://192.168.1.32:2380,docker-ce=http://192.168.1.222:2380  --initial-cluster-state new

[root@docker-ce ~]# etcdctl member list(查看集群成员,发现已经有两个节点)

5d951def1d1ebd99: name=docker-ce peerURLs=http://192.168.1.222:2380 clientURLs=http://192.168.1.222:2379 isLeader=true

c9bb018f3490f125: name=docker2 peerURLs=http://192.168.1.33:2380 clientURLs= isLeader=false

f83aa3ff91a96c2f: name=docker1 peerURLs=http://192.168.1.32:2380 clientURLs=http://192.168.1.32:2379 isLeader=false

[root@docker-ce ~]# etcdctl cluster-health(etcd集群已经能够正常工作,已经完成了选举)

member 5d951def1d1ebd99 is healthy: got healthy result from http://192.168.1.222:2379

member c9bb018f3490f125 is unreachable: no available published client urls

member f83aa3ff91a96c2f is healthy: got healthy result from http://192.168.1.32:2379

cluster is healthy

    启动第三个节点上的etcd进程:

[root@docker2 ~]# etcd --name docker2 --data-dir /etcd  --initial-advertise-peer-urls http://192.168.1.33:2380 --listen-peer-urls http://192.168.1.33:2380  --listen-client-urls http://192.168.1.33:2379,http://127.0.0.1:2379   --advertise-client-urls http://192.168.1.33:2379  --initial-cluster-token etcd-cluster-1  --initial-cluster docker2=http://192.168.1.33:2380,docker1=http://192.168.1.32:2380,docker-ce=http://192.168.1.222:2380  --initial-cluster-state new

[root@docker-ce ~]# etcdctl member list(查看集群成员列表,在其中显示了成员名称,名称和id都是唯一的,并且显示了服务端各个节点之间通信的地址,并且显示这个成员的状态,有的为leader,有的为follower)

5d951def1d1ebd99: name=docker-ce peerURLs=http://192.168.1.222:2380 clientURLs=http://192.168.1.222:2379 isLeader=true

c9bb018f3490f125: name=docker2 peerURLs=http://192.168.1.33:2380 clientURLs=http://192.168.1.33:2379 isLeader=false

f83aa3ff91a96c2f: name=docker1 peerURLs=http://192.168.1.32:2380 clientURLs=http://192.168.1.32:2379 isLeader=false

[root@docker-ce ~]# etcdctl cluster-health(集群状态为健康)

member 5d951def1d1ebd99 is healthy: got healthy result from http://192.168.1.222:2379

member c9bb018f3490f125 is healthy: got healthy result from http://192.168.1.33:2379

member f83aa3ff91a96c2f is healthy: got healthy result from http://192.168.1.32:2379

cluster is healthy

    启动参数说明如下:

    --name:节点的名称,唯一标识这个节点;

    --data-dir:存储数据的目录,当没有指定wal-dir的时候,日志文件也会存储在这个目录下,主要用来存储节点的信息和集群的信息,还有快照文件;

    --initial-advertise-peer-urls:告知集群其他节点的这个成员的url信息,可以有多个;

    --listen-peer-urls:监听其他节点的url,主要用来和其他的节点进行通信;

    --listen-client-urls:监听客户端的url,主要用来接受客户端的信息;

    --advertise-client-urls:对外的监听的客户端的url,用来接受客户端的信息,不过是public的;

    --initial-cluster-tocken:集群启动的时候的tocken信息,相当于集群id;

    --initial-cluster:集群启动时候的配置信息(也就是集群的所有member节点);

    --initial-cluster-state:初始化的时候集群的状态(new或者existing)。

5、 为何要用奇数个节点

    在组建集群的时候,我们总是可以看到使用奇数个节点,例如,3,5,7,9等节点的数量。

    主要是在选主leader的时候,不会发生脑裂的情况。一般情况是如果有3个,那么可以容许一个挂掉;如果有五个,那么容许2个挂掉;也就是N/2+1个活着就行。

    节点数量看起来越多越好,但是在通信的时候,首先是leader要发送很多信息给follower,从而导致网络可能有压力;另外就是写的时候,必须全部首先写到leader之中,然后从leader进行同步,这样会造成写的性能下降。

6、 测试

    测试的时候,最简单的方式就是使用命令客户端,etcdctl来使用,如下:

etcd集群之序

    在这里mkdir主要是创建一个目录,树形结构,而set则是设置一个kv值,而get则是取出这个值,从而达到配置共享的目的,也实现了分布式系统中的强一致性。

运维视角看问题

1、 一台机器进程崩溃

etcd集群之序

    直接关闭一台follower的进程模拟宕机,发现集群是健康的,依旧是可以工作的。

    在恢复的时候,直接使用原来的启动程序启动即可,无须修改任何东西。

etcd集群之序

    当一个leader的进程挂了的时候,集群在短时间内会完成选举,选举之后,正常工作,当进程恢复启动之后,原来的leader会向新的leader进行同步信息,从而达到一致性的目的。

2、 主机迁移

    有的时候,物理机需要下线维修,从而需要将数据拷贝到其他的机器上,从而在这里使用第三台机器来进行迁移。

    在这里进行恢复的时候,必须按照步骤进行恢复,首先停止需要停止的机器的etcd进程,然后将数据拷贝到新机器的数据目录中

etcd集群之序

    更新集群中的信息,然后在新机器上启动etcd进程。

etcd集群之序

    测试:

etcd集群之序

3、 扩容

    当发现集群的能力跟不上的时候,那么就需要扩容。

    首先进行注册新的节点:

etcd集群之序

    然后进行启动etcd进程,但是需要注意的是,启动的时候需要三个值,也就是ETCD_NAME,ETCD_INITIAL_CLUSTER,ETCD_INITIAL_CLUSTER_STATE,表示新加入一个集群。

etcd --name docker22 --data-dir /etcd  --initial-advertise-peer-urls http://192.168.1.33:2380 --listen-peer-urls http://192.168.1.33:2380  --listen-client-urls http://192.168.1.33:2379,http://127.0.0.1:2379   --advertise-client-urls http://192.168.1.33:2379  --initial-cluster-token etcd-cluster-1  --initial-cluster docker-ce=http://192.168.1.222:2380,docker22=http://192.168.1.33:2380,docker2=http://192.168.1.22:2379,docker1=http://192.168.1.32:2380  --initial-cluster-state existing

4、 缩容

    当集群需要缩小规模的时候,主要直接移除节点,那么节点上etcd进程会被停止。

etcd集群之序



待续。。。。。

etcd集群之序


上一篇:如何落地全球最大 Kubernetes 生产集群


下一篇:etcd集群之常见问题