ETCD使用手册

在这里插入图片描述

etcd简介

etcd是一个分布式、开源的key-value键值对数据存储系统,具有一致性、支持高并发、高可用性。

相比zookeeper特点

zookeeper可以实现的功能etcd均可以实现,etcd从zookeeper得到启发作为后起之秀,弥补了zookeeper的一些不足,有不少公司逐步用etcd替代zookeeper,随着k8s的兴起etcd越来越受到关注。

  1. 语言优势:zookeeper采用java编写,部署zookeeper实例需要依赖响应版本的jdk环境,软件目录结构复杂繁琐;而etcd使用go开发编写,源码编译生成的二进制文件可灵活部署,配置文件简介。zookeeper启动的java运行需要设置jvm相关运行参数进行调优,所以维护复杂,并且java应用相对重型;而etcd继承了go语言特点轻巧灵活。
  2. 高并发性:etcd更适合高并发场景,可支持百万级并发请求,相对于java的zookeeper有很大优势。
  3. 接口:etcd客户端访问接口api和自身节点同步机制都采用了HTTP协议和Resful风格,用户可以采用curl、postman等工具访问。相对zookeeper的api只支持java和c语言的客户端更加灵活。
  4. 一致性性算法:etcd采用了raft算法可以维护分布式节点的数据一致性,相比zookeeper的Paxos强一致性算法理解更加简单,zookeeper一致性算法业界出名难以理解。
  5. 更好的安全性:zookeeper默认没有开启用户认证机制,如果要开启需要配置acl认证权限,而etcd有更加规范的认证和权限体系,采用用户和角色机制控制节点访问权限,支持用户对每个节点的读、写、读写权限。
    采用SSL认证加密体系,支持HTTPS访问协议,数据传输安全有保证。
  6. 数据结构:etcd的数据结构和zookeeper类似采用目录节点形式,但etcd支持对每个节点的value的多版本机制,而且可以是设置节点过期机制。
使用场景

以下总结etcd组件在各大企业常见的使用场景,基本和zookeeper使用场景一致。

  • 服务发现和注册:应用微服务兴起,大型的应用按功能被分为各个微服务。各种服务之间相互调用通过服务注册和发现的方式实现。服务注册组件有zookeeper/etcd/eureka。

      服务提供方:在etcd中注册服务,将服务在etcd中创建目录,并且把服务每个节点ip,在该目录下添加。当服务提供方有变化随时更新状态。

      服务调用方:从etcd中获取服务提供方信息,ip和端口等信息,然后直连服务,同时watch服务节点变化,如果服务新增、挂掉,ttl失效等,客户端及时添加服务或踢掉服务。

      这种服务调用方式可设置策略权重,实现负载均衡。
  • 配置中心:etcd和zookeeper类似可以作为分布式配置中心。服务运行依赖的数据库连接信息、redis连接信息等可以写入etcd集群中,服务启动时从etcd中获取配置,同时利用watch机制实现类似消息发布订阅原理,实现配置动态改变。同时分布式特性免去了新建多分配置文件的操作。
  • 分布式锁(分布式消息队列):etcd组件特性可以很方便实现一个分布式锁的逻辑。实现原理和zookeeper类似,zk是利用了自身的临时节点特性。

      分布式锁实现的效果:当多个客户端请求过来的时候,只能有一个客户端去访问资源或者执行,并上锁,其余客户端等待释放锁,再竞争资源,是一种悲观锁。

      利用ETCD实现分布式锁的思路:
  • 定义一个锁 /lock/business_lock这个前缀命名的一个全局唯一key为我们的锁。
  • 设计客户端连接的session 每个客户端连接请求过来从etcd申请锁的时候,在锁下面定义一个key,例如客户端1,/lock/business_lock/client_uuid1,第二个客户端为/lock/business_lock/client_uuid2。每个客户端的锁要设置租约,例如为10s,这样如果客户端奔溃,key到期自动删除,相当于退出申请锁竞争,而且客户端每秒要设置“心跳”,租约到期客户端还要等待锁,则更新租约不要过期。
  • 获取锁的逻辑实现etcd的中有一个维护全局事务的ID为revision,每次对key的操作,这个全局id就会加一。当每个申请锁的请求过来后,完成维护自己的key之后,要为自己创建的key来put一个值,并且获取操作的revision。同时客户端获取/lock/business_lock/前缀下面所有的key列表,其中包含每个key的revision信息,每个客户端比较
    自己的revision是否为最小的,最小的客户端定义为获取锁,这个客户端可以执行自己的业务代码。同时其他客户端监听最小的revision对应的key,获取锁的客户端执行业务代码之后会释放锁,(如果客户端奔溃,租约到期也会释放锁),监听到释放锁则进行每个客户端再次比较是否获取锁,依次类推。

原理

raft协议
  • etcd工作原理推荐:《ETCD技术内幕》百里燊

    raft协议是etcd维护分布式集群一致性的协议。主要内容为以下几个方面:
ldeader节点选举

相关参数:

  • heartbeat timeout: 心跳超时时间,也称之为广播时间,50ms。
  • election timeout: 选举超时时间,每个节点为150ms ~ 300ms的随机数
  • Term: 任期,从开始选举新的leader节点为下一个任期开始,到接收不到leader节点心跳时间到了election timeout。

  etcd集群是一主多从的结构。etcd集群节点分为leaderfollower,candidate(竞选状态)三个状态。

  etcd之间的角色转换过程:集群初始化后所有节点状态为follower节点状态。leader节点会发出心跳信息到follower节点。初始化节点没有leader节点,其中一个follower节点率先等到election timeout后,角色转换为cadidate节点,Term为过期状态,开始进入下一个任期,重置election timer。

  角色为cadidate节点会发起leader选举,vote for,其他followe节点收到term较大的任期投票,会投票给cadidate节点当选为leader节点,并更新election timer,更新term。cadidate节点收到一般以上的投票更新为leader节点,广播其他follower节点心跳信息。

  cadidate节点未能选为leader节点或者发现leeder节点会转换为follower。

  如果故障leader节点恢复后接收到任期较高的leader节点的心跳广播信息后会更新为follower节点。

  如果网络分区少数节点部分没有主节点,发起投票时,preVote检查不足半数节点则不会出现无限投票状况。

etcd写入过程

leader节点处理每一次更新操作,都会记录一个全局的reversion记录。

etcd主节点接受用户请求,其他节点收到写入请求重定向到主节点。
leader节点处理每一次更新操作,都会记录一个全局的reversion。

相关参数:
每个节点本地都有日志文件,记录写入操作。

  • commitIndex #本地日志提交的最大索引
  • lastAppend #应用到状态机最大索引
  • nextIndex[] #数组,主节点记录向follower节点发送吓一条消息的索引。
  • matchIndex[] #数组,主节点已经向follower节点发送消息的最大索引。

主节点收到更新操作,写入本地日志,向其他节点广播append entries消息。收到消息的follower节点,写入本地日志,返回消息,leader节点收到半数以上节点返回,将日志记录为commit状态,并应用自身状态机,返回客户端消息,并广播消息提交信息,其他follower节点更新状态机。

综上:flowwer节点本地日志最大索引大于等于nextInex,leader节点向follower同步消息时,如果返回失败,减小nextIndex,知道匹配成功。如果leader节点切换会丢失nextIndex/matchIndex数据,新leader会从当前日志索引以上方法重试matchIndex重置为0。

综上:选举投票时,cadidate的日志索引没有自己的大则拒绝投票。

raft的linearizable语义:客户端为每个请求进行唯一编号,服务端为每个客户端设置唯一session,如果请求在集群中被执行,没有响应客户端则客户端重试请求带相同的编号,服务端不会重新执行,并返回客户端。

快照和日志持久化策略

和zookeeper类似,etcd持久化采用快照日志策略,每个节点维护自身快照和日志。

日志生成快照策略详见配置。

如果follower节点宕机比较久,leader节点会发送快照。

只读请求

leader节点处理只读请求,leader节点处理请求之前检查自己是否时最新leader节点,如果不是交付最新leader节点。如果时新任期的leader节点则提交一条空记录使之前日志全部提交,再相应只读请求。

ETCD客户端访问

ETCDCTL

etcdctl是etcd自带的客户的那工具,支持v2,v3的api

key操作

  • 连接
    开启https,需要ca证书/证书/公钥,(客户端/服务端都可以)

    开启认证:用户

    endpoints会连接机器列表,如果不通选择下一个。默认http协议/2379端口。
etcdctl --cacert=ca.pem --cert=client.pem --key=client-key.pem --endpoints=ip1:2379,ip2:2379,ip3:2379  --user root:123456
  • 版本:v3,如果报错请检查是否添加版本环境变量。
export ETCDCTL_API=3
  • 查询
    get --help显示所有查询参数,下面写常用的
etcdctl get /example 
--prefix #按前缀查所有key以及值,默认精确匹配
--limit 10 #显示10个
--keys-only #只显示key
--print-value-only #只显示值
-w json #可以显示key的创建reversion/修改reversion等信息。
  • 信息显示:
etcdctl member list  #成员列表
etcdctl endpoint status #集群状态/数据量等 -w json 可以显示当前reversion
etcdctl endpoint health #集群健康

ETCD配置

详细参考github/中文官网手册。

集群配置要保证每个节点一致。

配置可盈使用命令行/环境变量/配置文件

ETCD的搭建

生成pem的安全证书

ETCD支持https协议需要生成pem安全证书,自签TLS证书。

https协议也是是在tcp协议和http协议增加ssl协议加密http内容,是由一对公私钥组成。公钥交给公开的有资质证书管理机构,由客户端获取,私钥服务端保留。公约加密只能由私钥解密,私钥加密只能由公钥解密。也可以自签ca证书,不用交给证书管理机构。

生成证书过程参考:

生成证书

1.下载cfssl工具:

mkdir ~/bin
curl -s -L -o ~/bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
curl -s -L -o ~/bin/cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
chmod +x ~/bin/{cfssl,cfssljson}
export PATH=$PATH:~/bin

2.初始化证书颁发机构:

(1)生成默认ca配置:

mkdir ~/cfssl
cd ~/cfssl
cfssl print-defaults config > ca-config.json
cfssl print-defaults csr > ca-csr.json

(2) 修改ca证书配置:

ca-config.json,注意超时时间默认为8760h(365天),添加证书类型:server/client/peer

{
    "signing": {
        "default": {
            "expiry": "43800h"
        },
        "profiles": {
            "server": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth"
                ]
            },
            "client": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "client auth"
                ]
            },
            "peer": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ]
            }
        }
    }
}

ca-csr.json,C国家,L城市,O公司,OU组织/部门,采用rsa加密方式。

{
    "CN": "My own CA",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "SH",
            "O": "My Company Name",
            "ST": "Shanghai",
            "OU": "Org Unit 1",
            "OU": "Org Unit 2"
        }
    ]
}

生成ca, ca.pem/ca.csr为证书,ca-key为私钥。

cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
ls -rlt 
ca-key.pem
ca.csr
ca.pem

(3) 生成服务端证书和私钥

生成默认配置文件并修改:注意访问服务端的所有hosts和命名CN

cfssl print-defaults csr > server.json
...
    "CN": "etcd cluster name",
    "hosts": [
        "192.168.128.96",
        "192.168.128.97",
        "192.168.128.98",
        "node1.example.com",
        "node2.example.com",
        "node3.example.com",
        "127.0.0.1",
        "localhost"
    ]
...

生成server端证书和私钥(peer)

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=peer server.json | cfssljson -bare server

或者一步生成

echo '{"CN":"coreos1","hosts":[""],"key":{"algo":"rsa","size":2048}}' | cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server -hostname="192.168.122.68,ext.example.com,coreos1.local,coreos1" - | cfssljson -bare server

文件内容

server-key.pem
server.csr
server.pem

(4)生成客户端证书:客户端证书不需要hosts

cfssl print-defaults csr > client.json
...
    "CN": "etcd cluster name",
    "hosts": [""],
...

生成证书:

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client.json | cfssljson -bare client

或者一步生成

echo '{"CN":"client","hosts":[""],"key":{"algo":"rsa","size":2048}}' | cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client - | cfssljson -bare client
#
client-key.pem
client.csr
client.pem

验证证书:

openssl x509 -in ca.pem -text -noout
openssl x509 -in server.pem -text -noout
openssl x509 -in client.pem -text -noout
启动etcd服务端

go程序直接启动etcd,加载配置可以通过环境变量/命令行/配置文件。建议用systemd管理。

etcd --config-file=/etc/etcd/etcd.conf.yml
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值