etcd集群节点数量的说明
etcd 是基于 raft算法的分布式键值数据库,生来就为集群化而设计的,由于Raft算法在做决策时需要超半数节点的投票,所以etcd集群一般推荐奇数节点,如3、5或者7个节点构成一个集群。
对于具有 n 个成员的集群,仲裁为
(n/2)+1,
ETCD 集群高可用允许 (N-1)/2 的节点出现临时性故障,3台etcd集群允许宕机一台;超过(N-1)/2节点,那集群将暂时不可用,直到节点个数恢复到超过 (N-1)/2.
etcd官方推荐3、5、7个节点,虽然raft算法也是半数以上投票才能有 leader,但奇数只是推荐,其实偶数也是可以的。如 2、4、8个节点。下面分情况说明:
- 1 个节点:就是单实例,没有集群概念,不做讨论
- 2 个节点:是集群,但没人会这么配,尽管双节点的etcd能启动,启动时也能有主,可以正常提供服务,但是一台挂掉之后,就选不出主了,因为存活的节点只能拿到1票,剩下的那台也无法提供服务,也就是双节点无容错能力,不要使用。
- 3 节点:标准的3 节点etcd 集群只能容忍1台机器宕机,挂掉 1 台此时等于2个节点的情况,如果再挂 1 台,就和 2节点的情形一致了,一直选,一直增加任期,但就是选不出来,服务也就不可用了
- 4 节点:最大容忍1 台 服务器宕机
- 5 节点:最大容忍 2 台 服务器宕机
- 6 节点:最大容忍 2 台 服务器宕机
- 7和8个节点,最大容忍3台 服务器宕机
以此类推,9和10个节点,最大容忍4台 服务器宕机,总结以上可以得出结论:偶数节点虽然多了一台机器,但是容错能力是一样的,也就是说即便设置偶数节点,但没增加什么能力,还浪费了一台机器。同时etcd 是通过复制数据给所有节点来达到一致性,因此偶数的多一台机器增加不了性能,反而会拉低写入速度。
etcd集群节点数越多越好吗?
etcd 集群是一个 Raft Group,没有 shared。所以它的极限有两部分,一是单机的容量限制,内存和磁盘;二是网络开销,每次 Raft 操作需要所有节点参与,每一次写操作需要集群中大多数节点将日志落盘成功后,Leader 节点才能修改内部状态机,并将结果返回给客户端。因此节点越多性能越低,并且出错的概率会直线上升,并且是呈现线性的性能下降,所以扩展很多 etcd 节点是没有意义的,其次,如果etcd集群超过7个达到十几个几十个,那么,对运维来说也是一个不小的压力了,并且集群的配置什么的也会更加的复杂,而不是简单易用了。因此,etcd集群的数量一般是 3、5、7, 3 个是最低标准,7个也就是最高了。
扩容
1、新增节点部署etcd
部署新节点配置需要包含集群节点信息。
$ wget https://github.com/etcd-io/etcd/releases/download/v3.4.27/etcd-v3.4.27-linux-amd64.tar.gz
$ tar xvf etcd-v3.4.27-linux-amd64.tar.gz
$ mv etcd-v3.4.27-linux-amd64/etcd* /usr/local/bin/ ##复制etcd命令文件
$ mkdir -p /var/lib/etcd/ ##创建数据存放目录
$ mkdir -p /etc/etcd ##创建配置文件存放目录
配置:
$ cat /etc/etcd/etcd.conf
ETCD_NAME=etcd-4
ETCD_DATA_DIR="/var/lib/etcd"
ETCD_LISTEN_PEER_URLS="http://10.0.19.128:2380"
ETCD_LISTEN_CLIENT_URLS="http://127.0.0.1:2379,http://10.0.19.128:2379"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.220.43.206:2380"
ETCD_INITIAL_CLUSTER="etcd-2=https://10.0.19.129:2380,etcd-4=https://10.0.19.128:2380,etcd-1=https://10.0.19.127:2380,etcd-3=https://10.0.19.130:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="singless"
ETCD_ADVERTISE_CLIENT_URLS="http://10.0.19.128:2379"
2、集群添加新节点
#add 增加新节点
[root@k8s-master1 etcd]# ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://10.0.19.127:2379" member add etcd-4 --peer-urls=https://10.0.19.128:2380
Member 1e1a799fc9c59a7b added to cluster 983f3fe4681bf439#list 查看节点状态
[root@k8s-master1 etcd]# ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://10.0.19.127:2379" member list --write-out=table
+------------------+-----------+--------+--------------------------+--------------------------+
| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS |
+------------------+-----------+--------+--------------------------+--------------------------+
| db5a2c24a8bf7a | started | etcd-2 | https://10.0.19.129:2380 | https://10.0.19.129:2379 |
| 1e1a799fc9c59a7b | started | | https://10.0.19.128:2380 | |
| 318ff80236db7a1e | started | etcd-1 | https://10.0.19.127:2380 | https://10.0.19.127:2379 |
| ee6138446f578296 | started | etcd-3 | https://10.0.19.130:2380 | https://10.0.19.130:2379 |
+------------------+-----------+--------+--------------------------+--------------------------+
3、修改所有etcd配置并重启
[root@k8s-master1 etcd]# cat /etc/etcd/etcd.conf|grep ETCD_INITIAL_CLUSTER
ETCD_INITIAL_CLUSTER="etcd-2=https://10.0.19.129:2380,etcd-4=https://10.0.19.128:2380,etcd-1=https://10.0.19.127:2380,etcd-3=https://10.0.19.130:2380"
[root@k8s-master1 etcd]# systemctl restart etcd
[root@k8s-master1 ~]# etcdctl endpoint health
member db5a2c24a8bf7a is healthy: got healthy result from https://10.0.19.129:2379
member 1e1a799fc9c59a7b is healthy: got healthy result from https://10.0.19.128:2379
member 318ff80236db7a1e is healthy: got healthy result from https://10.0.19.127:2379
member ee6138446f578296 is healthy: got healthy result from https://10.0.19.130:2379
缩容
1、故障节点停服
在故障节点上停止etcd服务,以防止数据写入。
systemctl stop etcd
2 移除故障或不需要的成员
首先需要确定要移除的etcd成员的ID。可以通过以下命令查看集群成员列表:
etcdctl --endpoints=${existing-advertise-peer-urls} member list
然后,使用member remove
命令移除指定的成员:
etcdctl --endpoints=${existing-advertise-peer-urls} member remove ${cluster_id}
这里的${cluster_id}
是要移除的成员的ID。
3 确认成员已被移除
再次使用member list
命令确认成员已被成功移除:
etcdctl --endpoints=${existing-advertise-peer-urls} member list
注意事项
以上步骤提供了一个基本的etcd集群缩容流程。请根据具体环境和需求调整步骤和命令。