• 认识etcd


    etcd是CoreOS基于Raft开发的分布式key-value存储,可用于服务发现、共享配置以及一致性保障,在分布式系统中,如何管理节点间的状态的一致性一直是一个难题,而etcd很适合在集群环境下提供服务发现功能,他提供了数据的TTL失效、数据改变监视、多值、目录监听、分布式锁原子操作等功能,可以方便跟踪和管理集群节点状态。etcd的很适合进行服务注册和发现以及消息发布和订阅。
    服务注册与发现
    基于Raft算法的etcd天生就是一个强一致性、高可用的服务存储目录,用户可在etcd中注册服务,并对注册的服务配置key TTL(Time to Live),定时保持服务的心跳以达到健康检查的效果。
    消息发布与订阅
    在分布式系统中,最实用的一种组件件通行方式就是消息发布与订阅,即构建一个配置共享中心,数据提供者在这个配置中心发布消息,数据使用者订阅他们关心的主题,一旦主题有消息发布,就会实时通知订阅者,通过这种方式可以实现分布式系统配置的集中管理的动态更新。将一些配置信息放到etcd上,应用在启动的时候从etcd上一次性获取全部配置信息,同时在etcd上注册一个watcher并等待,后续如果配置有更新,etcd就能实时通知订阅者,从而能及时获取到最新的配置信息。

    选举机制

    Etcd是基于Raft协议实现的,为了了解etcd工作原理,需要先了解下Raft协议原理。先来看看Raft中的选举机制。初始启动时,节点都处于Follower状态,并设定了一个选举超时时间(election timeout),如果这段时间内没有手动来自Leader的heartbeat,节点将主动发起选举,将自己切换成candidate,向集群中其他Follower发送请求,询问是否同意自己成为Leader,如果收到来自集群过半节点数的同意后,节点即成为Leader,开始接受client的数据并向其他Follower节点同步日志,如果未达成一致,candidate会随机选择一个等待时间间隔(150ms-300ms)后再次发起投票。故为了避免冲突,一般情况下节点数据保持奇数,而非偶数。每成功选取一次新Leader的任期Term会比之前Leader的任期大1,且Leader为了保持自己的地位会持续给Follower发heartbeat。

    日志复制机制

    当Leader接受到client的数据请求后,是如何保持各个节点的数据同步的呢?是通过日志复制机制。当Leader收到客户端的请求后,会把日志追加到本地Log中,然后通过hearbeat把该信息同步给其他Follower,Follower接收到日志后记录日志然后向Leader发送ACK,当Leader收到半数以上的Follower的ACK信息后,将该日志设置为已提交并追加到本地磁盘中,通知客户端已经写入数据,且在下一次heartbeat中Leader通知所有Follower将该日志存储到自己的本地磁盘中。

    安全保障机制

    除了完成数据同步外,为了在Leader切换过程中数据不丢失,Raft还设置了一些安全保障机制。
    第一:选举安全性:每个任期只能选取出一个Leader,保证来自客户端的所有请求一定会经过唯一的这个Leader,然后同步Leader的日志同步给Follower
    第二:当Log在Term1被coomit后,后续任期Term2、Term3的Leader必须包含该Log,否则不会被选举为Leader。
    第三:Leader失效处理,如果Leader失效,其他Follower会自动发起选举,Leader恢复后由于Term小,会自动变成Follower,自身的日志也会被新的Leader的日志进行覆盖。
    第四:Follower节点不可用,如果发现Follower节点不可用,当Follower节点恢复后,因为能从心跳包获取到Leader的日志,故能获取到最新的全量数据
    另外,由于etcd非常消耗资源,故不建议存放太多的数据,单个对象不建议超过1.5M,默认容量是2G,不建议超过8G。
    下面通过小实验来看看etcd如何工作。
    1.安装etcd请查看这里   

    2.安装完成后通过如下命令启动etcd

    1. etcd --listen-client-urls 'http://localhost:12379' \
    2. --advertise-client-urls 'http://localhost:12379' \
    3. --listen-peer-urls 'http://localhost:12380' \
    4. --initial-advertise-peer-urls 'http://localhost:12380' \
    5. --initial-cluster 'default=http://localhost:12380'

    etcd中常用参数含义如下,更多参数含义可查看这里

    listen-client-url:用于监听客户端通讯的URL列表。这个标记告诉 etcd 在特定的 scheme://IP:port 组合上从客户端接收进来的请求.

    listen-peer-url:用于监听伙伴通讯的URL列表。这个标记告诉 etcd 在特定的 scheme://IP:port 组合上从它的伙伴接收进来的请求.

    3.写入/获取/查看etcd的数据

     上面演示了如何启动etcd,并进行数据写入和查看,接下来看看如果要通过https访问etcd应该如何实现,如果要通过https访问需要签发证书,目前能制作根证书和服务器证书常用工具有cfssl和Openssl,这里演示如何cfssl签发生成证书,然后通过https访问访问etcd。

    第一:安装cfssl,如果是mac,可使用命令brew install cfssl进行安装。更多安装细节可查看这里

    第二:编写ca的证书请求配置文件ca-csr.json,内容如下所示

    1. {
    2. "CN": "Autogenerated CA",
    3. "key": {
    4. "algo": "rsa",
    5. "size": 2048
    6. },
    7. "names": [
    8. {
    9. "O": "Certificates",
    10. "OU": "Hastily-Generated Values Divison",
    11. "L": "Chengdu",
    12. "ST": "Chengdu",
    13. "C": "CN"
    14. }
    15. ]
    16. }

    第三:通过命令生成证书签发机构CA的私有key的证书

    cfssl gencert -initca ca-csr.json | cfssljson -bare ca

    执行命令后会生成ca.csr文件(证书请求文件,属于中间文件,后续不会用到),ca-key.pem文件,私有密钥文件,ca.pem文件即ca的证书文件,后续会用到。

    第四:为需要签发证书的服务编写服务证书请求配置文件和CA的配置文件,内容如下所示

    服务证书请求的配置文件req-csr.config,hosts里面存放需要签发证书的IP地址或者域名

    1. req-csr.json
    2. {
    3. "CN": "etcd",
    4. "hosts": [
    5. "localhost",
    6. "127.0.0.1"
    7. ],
    8. "key": {
    9. "algo": "rsa",
    10. "size": 2048
    11. },
    12. "names": [
    13. {
    14. "O": "autogenerated",
    15. "OU": "etcd cluster",
    16. "L": "the internet"
    17. }
    18. ]
    19. }

    CA的配置文件ca-config.json,内容如下所示,里面设置了证书的实效时间

    1. {
    2. "signing": {
    3. "default": {
    4. "usages": [
    5. "signing",
    6. "key encipherment",
    7. "server auth",
    8. "client auth"
    9. ],
    10. "expiry": "876000h"
    11. }
    12. }
    13. }

     第五:通过命令给服务签发证书,会生成服务的私有key的pem证书文件

    cfssl gencert -ca ca.pem -ca-key ca-key.pem -config ca-config.json req-csr.json  | cfssljson -bare server

    修改生成的文件prefix为peer,再次执行命令生成peer-key.pem,peer.pem以及中间的证书请求文件peer.csr

    第六:证书生成后,通过如下命令启动etcd,启动etcd过程中需要传入ca.pem,server.pem,key.pem.

    1. ./etcd --listen-client-urls 'https://localhost:12379' \
    2. --data-dir=/tmp/etcd/data \
    3. --advertise-client-urls 'https://localhost:12379' \
    4. --listen-peer-urls 'https://localhost:12380' \
    5. --initial-advertise-peer-urls 'https://localhost:12380' \
    6. --initial-cluster 'default=https://localhost:12380' \
    7. --client-cert-auth --trusted-ca-file=/tmp/certs/ca.pem \
    8. --cert-file=/tmp/certs/server.pem \
    9. --key-file=/tmp/certs/server-key.pem \
    10. --peer-client-cert-auth --peer-trusted-ca-file=/tmp/certs/ca.pem \
    11. --peer-cert-file=/tmp/certs/peer.pem \
    12. --peer-key-file=/tmp/certs/peer-key.pem

    etcd成功启动后,尝试通过https方式向etcd写入、输出。

    1. ./etcdctl --endpoints=https://localhost:12379 \
    2. --cert /tmp/certs/server.pem \
    3. --key /tmp/certs/server-key.pem \
    4. --cacert /tmp/certs/ca.pem put key1 value1

    实验结果如下图所示,可以看到写入、查看数据成功,说明签发证书正确,能通过https的方式访问启动的etcd服务。

    除了进行写入查看数据外,还可以对etcd中的数据进行备份和恢复,磁盘碎片整理等。

    1. ./etcdctl --endpoints=https://localhost:12379 \
    2. --cert /tmp/certs/server.pem \
    3. --key /tmp/certs/server-key.pem \
    4. --cacert /tmp/certs/ca.pem snapshot save snapshot.db
    1. ./etcdctl --endpoints=https://localhost:12379 \
    2. --cert /tmp/certs/server.pem \
    3. --key /tmp/certs/server-key.pem \
    4. --cacert /tmp/certs/ca.pem snapshot restore snapshot.db
  • 相关阅读:
    Android数据存储
    如何使用Linux DataEase数据可视化分析工具结合内网穿透实现远程办公
    Ubuntu Pycharm安装
    SpringCloud下关于SWAGGER2的部署,包含JWT+GATEWAY鉴权
    C# EF框架增加和查询
    分布式系统可观测性之应用业务指标监控
    施密特正交化
    python编程题——如何求一组数的全排列
    Spring Boot + shiro 去除Redis缓存
    Node的模块化管理
  • 原文地址:https://blog.csdn.net/qiaotl/article/details/125561638