etcd入门和常用操作

概述

etcd 是一个高可用的分布式键值(key-value)数据库,采用了更为简洁的Raft共识算法来实现数据强一致。基于Go语言实现,主要用于共享配置和服务发现。

名称说明

名称 说明
etcd 一种基于 raft 协议的分布式 kv 数据库,特点是数据强一致性常用于保存配置文件,如作为 Kubernetes 的默认数据库(etcd 即 etc distributed,/etc 是操作系统的配置目录)
etcdctl etcd 客户端命令行工具,可以输入命令与 etcd 服务端交互(如同 kubectl同k8s集群交互)
server 服务端
client 客户端
cluster 集群,etcd 是一个分布式数据库,由多个节点构成一个集群,作为一个整体提供数据库能力
member 集群成员,其实就是一个 server 节点,更侧重 raft 集群下各节点相互通信保证数据一致性的角度
peer 在同一个集群中,一个 member 将其他 member 视为 peer
endpoint 服务节点,其实就是一个 server 节点,更侧重向 client 提供 API 调用的角度
leader 主节点,etcd 集群中只有一个主节点,所有写请求都会先到主节点,由主节点同步数据给从节点
follower 从节点,etcd 集群中可以有若干个
revision etcd 全局版本号,从 1 开始,每次操作数据都会增加
snapshot 快照,保存某一时刻下的系统状态数据,以便可以让 etcd 恢复到该时刻(在此之前的 log 都可以删掉了)
wal 预写日志(Write Ahead Log),类似 MySQL 的 redo log,用于保证集群的一致性、可恢复性
lease 租约,是客户端与服务端之间的约定,约定内容是某段时间内数据必须保留,过了这段时间数据可以删掉,起到过期时间的作用
checkpoints 一种保障 lease 的技术手段,leader 定期做 checkpoints,同步给其他 member

理解etcd的特性

etcd 由多个节点组成一个集群,只要成功向集群写入数据,立刻可以读到刚刚写入的数据,即使发生节点异常、网络分区故障。强一致性,不是指集群内的所有节点在任意时刻状态一致,而是指整个集群看起来像是只有一个数据副本,读写操作都是原子的,不用关心数据同步的。

etcd 内部通过 Raft 算法实现,由该算法保证分布式、强一致性,这种算法的原理可以参考:
《Raft Understandable Distributed Consensus》
《Raft 容易理解的分布式共识算法》(汉化版)

  • 主节点选举
    etcd集群中有一个主节点(leader,负责写操作),多个从节点(follower,负责读操作)。主节点会发送心跳包给从节点,从节点进行响应。从节点若超过一定时间(一定范围内的随机值)没有收到主节点的心跳包,则认为主节点已不可用,自身可成为候选主节点(candidate),发起投票,若超过一半节点响应,则可成为新的主节点(可能会有几轮争夺)。在每一轮投票中,参与投票的所有节点,只响应收到的第一个投票请求,对后续请求不作响应。
  • 保证数据强一致性(Raft 实现):
    写操作:只能由主节点操作,主节点将数据同步给从节点,大多数从节点返回成功,主节点认为成功。
    读操作:所有节点均可操作,从节点先获取主节点的版本号,如果版本落后就等,一直等到版本追上,返回数据。

etcd的发展

etcd 于 2013 年由 CoreOS 团队发起,2015 年发布第一个正式稳定版本 2.0,2017 年发布 3.0,这两个版本内部实现不同,v2 写入的数据 v3 查不到。本文采用的版本是 比较新的版本3.3。

这里对比一下两个版本的一些区别,也可以看出v3版本做出了哪些优化:
v3版本使用 gRPC + protobuf 取代 v2版本的http + json 通信,提高通信效率。gRPC 只需要一条连接,http是每个请求建立一条连接,建立连接会耗费大量时间;protobuf 加解密比json加解密速度得到数量级的提升,包体也更小。
v3 使用 lease (租约)替换v2中key ttl自动过期机制,后面会介绍。
v3 是支持事务和多版本并发控制mvcc(解决一致性非锁定读的问题)的磁盘数据库,而 v2 是简单的kv内存数据库
v3 是扁平的kv结构,v2是类型文件系统的存储结构,类似zookeeper的存储结构。v3版本使用__prefix前缀索引的方式实现了以往v2版本实现的文件系统的存储结构。

etcd 服务使用测试

关于etcd集群搭建在这就省略了,大家可以自己搭建单节点的集群测试。我就使用之前搭建kubernetes集群时使用的etcd服务。
为方便使用,先设置一下 etcd_v2/ etcd_v3的别名,大家可以根据自己集群的实际情况设置

cat <<EOF > /etc/profile.d/etcd.sh
alias etcd_v2='etcdctl --cert-file /etc/kubernetes/pki/etcd/healthcheck-client.crt \
              --key-file /etc/kubernetes/pki/etcd/healthcheck-client.key  \
              --ca-file /etc/kubernetes/pki/etcd/ca.crt  \
              --endpoints https://192.168.2.140:2379,https://192.168.2.141:2379,https://192.168.2.142:2379'

alias etcd_v3='ETCDCTL_API=3 \
    etcdctl   \
   --cert /etc/kubernetes/pki/etcd/healthcheck-client.crt \
   --key /etc/kubernetes/pki/etcd/healthcheck-client.key \
   --cacert /etc/kubernetes/pki/etcd/ca.crt \
   --endpoints https://192.168.2.140:2379,https://192.168.2.141:2379,https://192.168.2.142:2379'
EOF
source /etc/profile.d/etcd.sh

然后测试读写

[root@k8s-m1 tmp]# etcd_v3  put aaa 111
OK
[root@k8s-m1 tmp]#  etcd_v3  get aaa 
aaa
111

etcd 保存的数据有版本号,可以指定版本读取历史数据(如果不压缩清除历史版本的数据),如果不指定,默认读取最大版本的数据:
写数据

[root@k8s-m1 tmp]#  etcd_v3  put aaa 222 -w json
{"header":{"cluster_id":9189981678766318811,"member_id":7409550525054359918,"revision":89481299,"raft_term":267804}}
[root@k8s-m1 tmp]#  etcd_v3  put aaa 333  -w json
{"header":{"cluster_id":9189981678766318811,"member_id":1864273196654539866,"revision":89481333,"raft_term":267804}}

指定版本读取读数据

[root@k8s-m1 tmp]#  etcd_v3  get aaa --rev=89481299
aaa
222
[root@k8s-m1 tmp]#  etcd_v3  get aaa --rev=89481333
aaa
333
#默认最新
[root@k8s-m1 tmp]#  etcd_v3  get aaa 
aaa
333

查看数据

插入一些测试数据

[root@k8s-m1 tmp]#  etcd_v3  put bbb 444
[root@k8s-m1 tmp]#  etcd_v3  put ccc 555
[root@k8s-m1 tmp]#  etcd_v3  put ddd 666
[root@k8s-m1 tmp]#  etcd_v3  put eee 777
[root@k8s-m1 tmp]#  etcd_v3  put fff 888
[root@k8s-m1 tmp]#  etcd_v3  put aa1 999
[root@k8s-m1 tmp]#  etcd_v3  put aa2 1010
[root@k8s-m1 tmp]#  etcd_v3  put cc1 1111
[root@k8s-m1 tmp]#  etcd_v3  put dd2 1212

按key前缀查看

[root@k8s-m1 tmp]# etcd_v3 get --prefix aa
aa1
999
aa2
1010
aaa
333

按key的字节排序的前缀查找>=

[root@k8s-m1 tmp]# etcd_v3 get --from-key aaa
aaa
333
bbb
444
cc1
1111
ccc
555
compact_rev_key
89481477
dd2
1212
ddd
666
eee
777
fff
888
foo
bar2

按key的字节排序区间查找<= value <

[root@k8s-m1 tmp]# etcd_v3 get ccc eee
ccc
555
compact_rev_key
89481477
dd2
1212
ddd
666

查找所有key

#key太多,查看起来很不方便
[root@k8s-m1 tmp]# etcdctl get --from-key ""

删除数据

删除指定key

#返回1 代表正常删除key的数量
[root@k8s-m1 tmp]# etcd_v3 del aa1
1

删除key时并返回被删除的键值对

[root@k8s-m1 tmp]# etcd_v3 del aa2 --prev-kv
1
aa2
1010

删除指定前缀的key

#删除了2个
[root@k8s-m1 tmp]# etcd_v3 del --prefix cc
2

删除所有数据

#危险操作,谨慎
[root@k8s-m1 tmp]# etcd_v3 del --prefix ""

更新数据

[root@k8s-m1 tmp]# etcd_v3 get  aaa
aaa
333
[root@k8s-m1 tmp]# etcd_v3 put  aaa  test
OK
[root@k8s-m1 tmp]# etcd_v3 get  aaa
aaa
test

更多常用操作

#只查看所有的key
[root@k8s-m1 tmp]# etcd_v3  get / --prefix --keys-only
#查看节点
[root@k8s-m1 tmp]# etcd_v3 member list
19df3a9852e0345a, started, etcd0, https://192.168.2.140:2380, https://192.168.2.140:2379
3bb3629d60bef3f6, started, etcd2, https://192.168.2.142:2380, https://192.168.2.142:2379
66d402f1ef2c996e, started, etcd0, https://192.168.2.141:2380, https://192.168.2.141:2379
#查看节点状态
[root@k8s-m1 tmp]# etcd_v3 endpoint health
https://192.168.2.141:2379 is healthy: successfully committed proposal: took = 3.200938ms
https://192.168.2.140:2379 is healthy: successfully committed proposal: took = 3.421955ms
https://192.168.2.142:2379 is healthy: successfully committed proposal: took = 1.915926ms

记不住命令的可以通过etcd_v3 -h查看帮助选项

备份恢复

#备份,只需要在一台上执行
ETCDCTL_API=3     etcdctl      --cert /etc/kubernetes/pki/etcd/healthcheck-client.crt    --key /etc/kubernetes/pki/etcd/healthcheck-client.key    --cacert /etc/kubernetes/pki/etcd/ca.crt    --endpoints https://192.168.2.140:2379,https://192.168.2.141:2379,https://192.168.2.142:2379 snapshot save test.db

#恢复,三个节点都需要执行
ETCDCTL_API=3   etcdctl  --name k8s-m1 --initial-advertise-peer-urls https://192.168.2.140:2380 	--initial-cluster k8s-m1=https://192.168.2.140:2380,k8s-m2=https://192.168.2.141:2380,k8s-m3=https://192.168.2.142:2380 snapshot restore /root/test.db --data-dir=/var/lib/etcd/

更多关于kubernetes的知识分享,请前往博客主页。编写过程中,难免出现差错,敬请指出

你可能感兴趣的:(Kubernetes,kubernetes,etcd)