关于etcd:Etcd-监控

重点监控指标指标分类 衰弱状态USE 办法(零碎) 使用率饱和度谬误RED 办法(利用) 申请速率错误率提早指标分类指标释义衰弱状态实例衰弱状态etcd是一个分布式系统,由多个成员节点组成。监控etcd成员节点的状态能够帮忙你理解集群中节点的健康状况,发现掉线或者异样节点。衰弱状态主从状态 衰弱状态etcd leader切换统计频繁的领导者变更会重大影响 etcd 的性能。这也意味着领导者不稳固,可能是因为网络连接问题或对 etcd 集群施加的过载负荷导致的。衰弱状态心跳etcd集群中的节点通过发送心跳来放弃彼此之间的连贯。监控失落的心跳能够帮忙你发现etcd节点之间的通信问题或者网络提早。RED 办法QPS RED 办法申请错误率监控etcd的错误率能够帮忙你发现etcd操作中的潜在问题。高错误率可能表明集群遇到了故障或其余异常情况。RED 办法申请提早监控etcd的申请提早能够帮忙你理解API申请的解决工夫。较高的提早可能表明etcd正面临负载压力或性能问题。RED 办法磁盘同步(WAL/DB fsync)耗时高磁盘操作提早(wal_fsync_duration_seconds或backend_commit_duration_seconds)通常示意磁盘问题。它可能会导致高申请提早或使群集不稳固。RED 办法同步提早如果集群失常运行,已提交的提案应该随着工夫的推移而减少。重要的是要在集群的所有成员中监控这个指标;如果单个成员与其领导节点之间存在继续较大的滞后,这表明该成员运行迟缓或存在异样。RED 办法提案失败次数失败的提案通常与两个问题相干:与领导选举相干的暂时性故障或因为集群丢失法定人数而导致的较长时间的停机。RED 办法快照解决工夫etcd定期创立快照以备份数据。监控快照解决工夫能够帮忙你理解etcd备份的性能,确保备份工作可能及时实现。RED 办法watcher 数量监控etcd集群以后连贯到etcd的客户端数量。如果连接数过高,可能须要调整etcd的配置或者减少集群的容量。USE 办法CPU 使用率 USE 办法内存使用量 USE 办法关上文件数 USE 办法存储空间使用率监控etcd存储空间的使用率能够帮忙你确保etcd有足够的空间存储配置数据。如果使用率靠近或达到下限,可能须要思考扩大存储容量或者清理无用的数据。应用 kube-prometheus 收集 etcd 指标http 模式(举荐)批改--listen-metrics-urls #- --listen-metrics-urls=http://127.0.0.1:2381 - --listen-metrics-urls=http://127.0.0.1:2381,http://ip:2381部署 helm install monitoring -n cattle-prometheus --set kubeEtcd.service.port=2381 --set kubeEtcd.service.targetPort=2381 --set prometheusOperator.admissionWebhooks.patch.image.sha=null ./https 模式新增 etcd secret kubectl create secret generic etcd-certs -n cattle-prometheus --from-file=/etc/kubernetes/pki/etcd/ca.crt --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.crt --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.key部署 helm install monitoring -n cattle-prometheus --set kubeEtcd.serviceMonitor.scheme=https --set kubeEtcd.serviceMonitor.caFile=/etc/prometheus/secrets/etcd-certs/ca.crt --set kubeEtcd.serviceMonitor.certFile=/etc/prometheus/secrets/etcd-certs/healthcheck-client.crt --set kubeEtcd.serviceMonitor.keyFile=/etc/prometheus/secrets/etcd-certs/healthcheck-client.key --set prometheus.prometheusSpec.secrets={etcd-certs} --set prometheusOperator.admissionWebhooks.patch.image.sha=null ./大盘展现Grafana 大盘: https://github.com/clay-wangzhi/grafana-dashboard/blob/master/etcd/etcd-dash.json导入即可 ...

June 21, 2023 · 1 min · jiezi

关于etcd:Etcd-高可用故障演练

目标本次演练旨在测试 Kubernetes 的 etcd 高可用性,测验是否可能在其中一个 etcd 节点产生故障的状况下,其余 etcd 节点可能接管其工作,确保集群仍能失常运行。 集群架构 演练场景在一个三节点的 Kubernetes 集群中,咱们将模仿其中一个 etcd 节点的故障,察看残余的 etcd 节点是否可能失常运行。 演练过程确认集群以后衰弱状态 kubectl get componentstatuses # 确认所有组件状态均为失常kubectl -n kube-system get endpoints | grep etcd # 确认 etcd Endpoints 列表kubectl -n kube-system get pods | grep etcd # 确认 etcd Pod 的数量# 确认etcd 集群状态ETCD_CA_CERT="/etc/kubernetes/pki/etcd/ca.crt"ETCD_CERT="/etc/kubernetes/pki/etcd/server.crt"ETCD_KEY="/etc/kubernetes/pki/etcd/server.key"ETCDCTL_API=3 /usr/local/bin/etcdctl --endpoints=https://127.0.0.1:2379 \ --cacert="${ETCD_CA_CERT}" --cert="${ETCD_CERT}" --key="${ETCD_KEY}" member listETCDCTL_API=3 /usr/local/bin/etcdctl --endpoints=${HOST1},${HOST2},${HOST3} \ --cacert="${ETCD_CA_CERT}" --cert="${ETCD_CERT}" --key="${ETCD_KEY}" endpoint health进行 M3 节点 etcd 服务 ...

June 19, 2023 · 1 min · jiezi

关于etcd:分布式注册服务中心etcd在云原生引擎中的实践

作者:王雷etcd是什么etcd是云原生架构中重要的根底组件,由CNCF孵化托管。ETCD是用于共享配置和服务发现的分布式,一致性的KV存储系统,是CoreOS公司发动的一个开源我的项目,受权协定为Apache。etcd 基于Go语言实现,次要用于共享配置,服务发现,集群监控,leader选举,分布式锁等场景。在微服务和 Kubernates 集群中不仅能够作为服务注册发现,还能够作为 key-value 存储的中间件。 提到键值存储系统,在大数据畛域利用最多的当属ZOOKEEPER,而ETCD能够算得上是后起之秀了。在我的项目实现,一致性协定易了解性,运维,平安等多个维度上,ETCD相比Zookeeper都占据劣势。 ETCD vs ZK ETCDZK一致性协定Raft协定ZAB(类Paxos协定)运维方面不便运维难以运维我的项目活跃度沉闷没有etcd沉闷APIETCD提供HTTP+JSON, gRPC接口,跨平台跨语言ZK须要应用其客户端拜访平安方面ETCD反对HTTPS拜访ZK在这方面不反对etcd的架构etcd 是一个分布式的、牢靠的 key-value 存储系统,它用于存储分布式系统中的要害数据,这个定义十分重要。 通过上面这个指令,理解一下etcd命令的执行流程,其中etcdctl:是一个客户端,用来操作etcd。 etcdctl put key test通常etcd都是以集群的形式来提供服务的,etcdctl操作命令的时候,会对应到leader当中的gRPC Server gRPC Server 用来接管客户端具体的申请进行解决,然而不仅仅是解决客户端的连贯,它同时负责解决集群当中节点之间的通信。 wal: Write Ahead Log(预写式日志) etcd 的数据存储形式。除了在内存中存有所有数据的状态以及节点的索引以外,etcd 就通过 WAL 进行长久化存储。WAL 中,所有的数据提交前都会当时记录日志。实现事务日志的规范办法;执行写操作前先写日志,跟mysql中redo相似,wal实现的是程序写。 当执行put操作时,会批改etcd数据的状态,执行具体的批改的操作,wal是一个日志,在批改数据库状态的时候,会先批改日志。put key test会在wal记录日志,而后会进行播送,播送给集群当中其余的节点设置key的日志。其余节点之后会返回leader是否批准数据的批改,当leader收到一半的申请,就会把值刷到磁盘中。 snapshot etcd 避免 WAL 文件过多而设置的快照,用于存储某一时刻etcd的所有数据。Snapshot 和 WAL 相结合,etcd 能够无效地进行数据存储和节点故障复原等操作。 boltdb 相当于mysql当中的存储引擎,etcd中的每个key都会创立一个索引,对应一个B+树。 etcd重要的个性•存储:数据分层存储在文件目录中,相似于咱们日常应用的文件系统; •Watch 机制:Watch 指定的键、前缀目录的更改,并对更改工夫进行告诉; •平安通信:反对 SSL 证书验证; •高性能:etcd 单实例能够反对 2K/s 读操作,官网也有提供基准测试脚本; •统一牢靠:基于 Raft 共识算法,实现分布式系统外部数据存储、服务调用的一致性和高可用性; •Revision 机制:每个 Key 带有一个 Revision 号,每进行一次事务便加一,因而它是全局惟一的,如初始值为 0,进行一次 Put 操作,Key 的 Revision 变为 1,同样的操作,再进行一次,Revision 变为 2;换成 Key1 进行 Put 操作,Revision 将变为 3。这种机制有一个作用,即通过 Revision 的大小就可晓得写操作的程序,这对于实现偏心锁,队列非常无益; ...

December 20, 2022 · 1 min · jiezi

关于etcd:etcd集群安装和单机安装

etcd集群装置和单机装置etcd介绍etcd 是基于 Raft 的分布式 key-value 存储系统,由 CoreOS 开发,罕用于服务发现、共享配置以及并发管制(如 leader 选举、分布式锁等)。kubernetes 应用 etcd 存储所有运行数据。etcd基于Go语言实现。 etcd作为服务发现零碎,有以下特点: 简略:装置配置简略,而且提供了HTTP API进行交互,应用也很简略平安:反对SSL证书验证疾速:依据官网提供的benchmark数据,单实例反对每秒2k+读操作牢靠:采纳raft算法,实现分布式系统数据的可用性和一致性官网地址: http://www.etcd.cn/ 源代码地址: https://github.com/coreos/etcd 1.下载安装curl -L https://github.com/coreos/etcd/releases/download/v3.0.6/etcd-v3.0.6-linux-amd64.tar.gz -o etcd-v3.0.6-linux-amd64.tar.gztar xzvf etcd-v3.0.6-linux-amd64.tar.gzmv etcd-v3.0.6-linux-amd64 etcdcd etcd./etcd --version2.单机启动etcd --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls http://10.240.30.30:2379 &3.集群启动别离在三台机器启动etcd cd /data/apps/etcd/$ nohup /data/apps/etcd/etcd --name etcd0 --initial-advertise-peer-urls http://10.240.30.9:2380 \ --listen-peer-urls http://10.240.30.9:2380 \ --listen-client-urls http://10.240.30.9:2379,http://127.0.0.1:2379 \ --advertise-client-urls http://10.240.30.9:2379 \ --initial-cluster-token etcd-cluster-1 \ --initial-cluster etcd0=http://10.240.30.9:2380,etcd1=http://10.240.30.10:2380,etcd2=http://10.240.30.11:2380 \ --initial-cluster-state new & cd /data/apps/etcd/$ nohup /data/apps/etcd/etcd --name etcd1 --initial-advertise-peer-urls http://10.240.30.10:2380 \ --listen-peer-urls http://10.240.30.10:2380 \ --listen-client-urls http://10.240.30.10:2379,http://127.0.0.1:2379 \ --advertise-client-urls http://10.240.30.10:2379 \ --initial-cluster-token etcd-cluster-1 \ --initial-cluster etcd0=http://10.240.30.9:2380,etcd1=http://10.240.30.10:2380,etcd2=http://10.240.30.11:2380 \ --initial-cluster-state new &cd /data/apps/etcd/$ nohup /data/apps/etcd/etcd --name etcd2 --initial-advertise-peer-urls http://10.240.30.11:2380 \ --listen-peer-urls http://10.240.30.11:2380 \ --listen-client-urls http://10.240.30.11:2379,http://127.0.0.1:2379 \ --advertise-client-urls http://10.240.30.11:2379 \ --initial-cluster-token etcd-cluster-1 \ --initial-cluster etcd0=http://10.240.30.9:2380,etcd1=http://10.240.30.10:2380,etcd2=http://10.240.30.11:2380 \ --initial-cluster-state new &参考链接:https://skyao.gitbooks.io/lea... ...

December 2, 2022 · 1 min · jiezi

关于etcd:etcd实现分布式锁

转载自:etcd实现分布式锁 当并发的访问共享资源的时候,如果没有加锁的话,无奈保障共享资源安全性和正确性。这个时候就须要用到锁 1、须要具备的个性须要保障互斥拜访(分布式环境须要保障不同节点、不同线程的互斥拜访)须要有超时机制,避免锁意外未开释,其余节点无奈获取到锁;也要保障工作可能失常执行实现,不能超时了工作还没完结,导致工作执行个别被开释锁须要有阻塞和非阻塞两种申请锁的接口2、本地锁当业务执行在同一个线程内,也就是我初始化一个本地锁,其余申请也认这把锁。个别是服务部署在单机环境下。 咱们能够看下上面的例子,开1000个goroutine并发的给Counter做自增操作,后果会是什么样的呢? package mainimport ( "fmt" "sync")var sg sync.WaitGrouptype Counter struct { count int}// 自增操作func (m *Counter) Incr() { m.count++}// 获取总数func (m *Counter) Count() int { return m.count}func main() { c := &Counter{} for i := 0; i < 1000; i++ { sg.Add(1) // 模仿并发申请 go func() { c.Incr() sg.Done() }() } sg.Wait() fmt.Println(c.Count())}后果是count的数量并不是料想中的1000,而是上面这样,每次打印出的后果都不一样,然而靠近1000 user@userdeMacBook-Pro  ~/go/src/go-demo/mutex  go run main.go953 user@userdeMacBook-Pro  ~/go/src/go-demo/mutex  go run main.go982 user@userdeMacBook-Pro  ~/go/src/go-demo/mutex  go run main.go984呈现这个问题的起因就是没有给自增操作加锁 ...

September 4, 2022 · 4 min · jiezi

关于etcd:实现etcd服务注册与发现

转载自:实现etcd服务注册与发现 0.1、目录构造.├── api│   └── main.go├── common│   └── common.go├── docker-compose.yml├── etcd│   └── Dockerfile├── go.mod├── go.sum├── rpc│   ├── courseware│   │   ├── courseware.pb.go│   │   └── courseware_grpc.pb.go│   ├── courseware.proto│   └── main.go└── server ├── service_discovery.go └── service_registration.go1、docker-compose部署一个3节点的集群我的项目根目录下创立etcd目录,并在目录下新增Dockerfile文件FROM bitnami/etcd:latestLABEL maintainer="liuyuede123 <liufutianoppo@163.com>"我的项目根目录下新增docker-compose.ymlversion: '3.5'# 网络配置networks: backend: driver: bridge# 服务容器配置services: etcd1: # 自定义容器名称 build: context: etcd # 指定构建应用的 Dockerfile 文件 environment: - TZ=Asia/Shanghai - ALLOW_NONE_AUTHENTICATION=yes - ETCD_NAME=etcd1 - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd1:2380 - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380 - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 - ETCD_ADVERTISE_CLIENT_URLS=http://etcd1:2379 - ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster - ETCD_INITIAL_CLUSTER=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380 - ETCD_INITIAL_CLUSTER_STATE=new ports: # 设置端口映射 - "12379:2379" - "12380:2380" networks: - backend restart: always etcd2: # 自定义容器名称 build: context: etcd # 指定构建应用的 Dockerfile 文件 environment: - TZ=Asia/Shanghai - ALLOW_NONE_AUTHENTICATION=yes - ETCD_NAME=etcd2 - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd2:2380 - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380 - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 - ETCD_ADVERTISE_CLIENT_URLS=http://etcd2:2379 - ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster - ETCD_INITIAL_CLUSTER=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380 - ETCD_INITIAL_CLUSTER_STATE=new ports: # 设置端口映射 - "22379:2379" - "22380:2380" networks: - backend restart: always etcd3: # 自定义容器名称 build: context: etcd # 指定构建应用的 Dockerfile 文件 environment: - TZ=Asia/Shanghai - ALLOW_NONE_AUTHENTICATION=yes - ETCD_NAME=etcd3 - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd3:2380 - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380 - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 - ETCD_ADVERTISE_CLIENT_URLS=http://etcd3:2379 - ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster - ETCD_INITIAL_CLUSTER=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380 - ETCD_INITIAL_CLUSTER_STATE=new ports: # 设置端口映射 - "32379:2379" - "32380:2380" networks: - backend restart: always相干参数概念: ...

August 25, 2022 · 6 min · jiezi

关于etcd:etcd分布式锁的实现

etcd分布式锁并不是etcd server对外提供一个性能api,而是基于etcd的各种个性(lease、watch、mvcc等)集成的一个工具。在同一个过程外面,为了防止对共享变量产生数据竞争,通常能够通过加锁解锁的形式来防止。然而如果是多个过程,操作同一份资源,就不能用一般的锁了,这时候的“锁”须要一个能共享的介质来存储,应用它的过程能够通过一般的加锁解锁形式来防止同时操作。 思考的问题上面咱们从一个最根本的流程剖析下一个分布式锁要思考哪些事件。 加锁 在对共享资源操作时候,首先须要加锁,在加锁时候,抢到锁的过程能够间接返回,进而操作共享资源,而没有抢到锁的过程须要期待锁的开释,对于同一个锁,同一时刻只能有一个过程来持有,这体现了锁的互斥性。 锁期间 因为是多过程状况,须要思考过程宕机的状况,如果抢到锁的过程忽然宕机,须要可能有开释锁的机制,防止前面的过程始终阻塞导致死锁。提供锁的组件也应该具备高可用性,在某个节点宕机后可能持续提供服务。 解锁 对资源的操作完结之后,须要及时开释锁,然而不能开释其余过程的锁,前面没有抢到锁的过程能够取得锁。如果抢锁的过程过多,可能会导致惊群效应,提供锁的组件应在肯定水平上防止该景象。 实现思路etcd的几种非凡的机制都能够作为分布式锁的根底。etcd的键值对能够作为锁的本体,锁的创立与删除对应键值对的创立与删除。etcd的分布式一致性以及高可用能够保障锁的高可用性。 prefix 因为etcd反对前缀查找,能够将锁设置成“锁名称”+“惟一id”的格局,保障锁的对称性,即每个客户端只操作本人持有的锁。 lease 租约机制能够为锁做一个保活操作,在创立锁的时候绑定租约,并定期进行续约,如果取得锁期间客户端意外宕机,则持有的锁会被主动删除,防止了死锁的产生。 Revision etcd外部保护了一个全局的Revision值,并会随着事务的递增而递增。能够用Revision值的大小来决定获取锁的先后顺序,在上锁的时候曾经决定了获取锁先后顺序,后续有客户端开释锁也不会产生惊群效应。 watch watch机制能够用于监听锁的删除事件,不用应用忙轮询的形式查看是否开释了锁,更加高效。同时,在watch时候能够通过Revision来进行监听,只须要监听间隔本人最近而且比本人小的一个Revision就能够做到锁的实时获取。 源码剖析在etcdv3版本的客户端库中曾经有了分布式锁的实现,让咱们看一下实现逻辑。 示例func main() { //初始化etcd客户端 cli, _ := clientv3.New(clientv3.Config{ Endpoints: []string{"127.0.0.1:23790"}, DialTimeout: time.Second, }) //创立一个session,并依据业务状况设置锁的ttl s, _ := concurrency.NewSession(cli, concurrency.WithTTL(3)) defer s.Close() //初始化一个锁的实例,并进行加锁解锁操作。 mu := concurrency.NewMutex(s, "mutex-linugo") if err := mu.Lock(context.TODO()); err != nil { log.Fatal("m lock err: ", err) } //do something if err := mu.Unlock(context.TODO()); err != nil { log.Fatal("m unlock err: ", err) }}在调用NewSession办法时候实际上是初始化了一个用户指定行为的租约(行为能够是指定ttl,或者复用其余的lease等),并异步进行keepalive。 ...

February 10, 2022 · 3 min · jiezi

关于etcd:etcd的MVCC是怎么实现的

MVCC是什么在理解之前,首先须要明确乐观锁与乐观锁的概念。乐观锁与乐观锁是两种编程思维,并不局限与编程语言。 乐观锁在对临界资源做一些读写时候,为了避免其他人同步批改数据,间接把数据锁住,操作实现后才会开释锁,通过这种形式实现并发平安。常见的有Go的Mutex,java的synchronized等。 乐观锁在对临界资源做操作时候,不锁住数据实现独占,而是判断数据有没有被别人批改过,如果批改了则返回批改失败。校验是否批改常见的形式有多版本并发管制(MVCC)等。 MVCC简介MVCC即在对数据做批改操作时候,并不对原数据做批改,而是在数据根底上追加一个批改后的数据,并通过一个惟一的版本号做辨别,版本号个别通过自增的形式;在读取数据时候,读到的理论是以后版本号对应的一份快照数据。比方一个键值对数据K->{V.0},此时value的版本号为0。操作1首先对数据做批改,读取到的0版本号的数据,对其做批改提交事务后便成为K-> {V.0,V.1},操作2之后读到的数据是版本号1的数据,对其做批改后提交事务胜利变为K->{V.0, V.1, V.2}。每次批改只是往后面进行版本号以及数据值追加,通过这种形式使得每个事务操作到的是本人版本号内的数据,实现事务之间的隔离。也能够通过指定版本号拜访对应的数据。 etcd的实现etcd就是基于MVCC机制实现的一个键值对数据库。接下来通过一个示例演示一下。 etcd版本号首先通过一个简略的put,get例子认识一下etcd的版本号。 #首先put一个key为linugo,value为go的数据[XXXX etcdctl]$ ./etcdctl --endpoints=127.0.0.1:23790 put linugo goOK#获取数据,能够看到k与v都是用了base64加密,能够看到3个version[XXXX etcdctl]$ ./etcdctl --endpoints=127.0.0.1:23790 get linugo -w=json|python -m json.tool{ "count": 1, "header": { "cluster_id": 14841639068965178418, "member_id": 10276657743932975437, "raft_term": 2, "revision": 2 }, "kvs": [ { "create_revision": 2, #创立key时候对应的版本号 "key": "bGludWdv", "mod_revision": 2, #批改时候的版本号 "value": "Z28=", "version": 1 #批改次数(蕴含创立次数) } ]}#再次put两次[XXXX etcdctl]$ ./etcdctl --endpoints=127.0.0.1:23790 put linugo golOK[XXXX etcdctl]$ ./etcdctl --endpoints=127.0.0.1:23790 put linugo golaOK[XXXX etcdctl]$ ./etcdctl --endpoints=127.0.0.1:23790 get linugo -w=json|python -m json.tool{ "count": 1, "header": { "cluster_id": 14841639068965178418, "member_id": 10276657743932975437, "raft_term": 2, "revision": 4 }, "kvs": [ { "create_revision": 2,#创立的版本号仍然是2 "key": "bGludWdv", "mod_revision": 4,#批改时候的版本号变为了4 "value": "Z29sYQ==", "version": 3 #批改次数为3 } ]}能够看到创立时候对应了一个版本号,每次批改后会生成新的版本号,是不是相似于下面所说版本号叠加呢。接下来put一个与下面不同的键值对。 ...

February 8, 2022 · 6 min · jiezi

关于etcd:etcd的租约是怎么实现的

租约是什么咱们都晓得Redis能够通过expire命令对key设置过期工夫,来实现缓存的ttl,etcd同样有一种个性能够对key设置过期工夫,也就是租约(Lease)。不过相较来说,两者的实用场景并不相同,etcd的Lease宽泛的用在服务注册与保活上,redis则次要用于淘汰缓存。上面介绍一下etcd的Lease机制,会从应用形式,以及实现原理来逐渐探索。 应用形式首先通过一个案例简略介绍它的应用形式。 package mainimport ( "context" "log" "os" "os/signal" "syscall" "time" clientv3 "go.etcd.io/etcd/client/v3")func main() { key := "linugo-lease" cli, err := clientv3.New(clientv3.Config{ Endpoints: []string{"127.0.0.1:23790"}, DialTimeout: time.Second, }) if err != nil { log.Fatal("new client err: ", err) } //首先创立一个Lease并通过Grant办法申请一个租约,设置ttl为20秒,没有续约的话,该租约会在20s后隐没 ls := clientv3.NewLease(cli) grantResp, err := ls.Grant(context.TODO(), 20) if err != nil { log.Fatal("grant err: ", err) } log.Printf("grant id: %x\n", grantResp.ID) //接下来插入一个键值对绑定该租约,该键值对会随着租约的到期而相应被删除 putResp, err := cli.Put(context.TODO(), key, "value", clientv3.WithLease(grantResp.ID)) if err != nil { log.Fatal("put err: ", err) } log.Printf("create version: %v\n", putResp.Header.Revision) //通过KeepAliveOnce办法对该租约进行续期,每隔5s会将该租约续期到初始的20s go func() { for { time.Sleep(time.Second * 5) resp, err := ls.KeepAliveOnce(context.TODO(), grantResp.ID) if err != nil { log.Println("keep alive once err: ", err) break } log.Println("keep alive: ", resp.TTL) } }() sigC := make(chan os.Signal, 1) signal.Notify(sigC, os.Interrupt, syscall.SIGTERM) s := <-sigC log.Println("exit with: ", s.String())}咱们能够通过上述形式实现某个服务模块的保活,能够将节点的地址注册到etcd中,并绑定适当时长的租约,定时进行续约操作,若节点宕机,超过了租约时长,etcd中该节点的信息就会被移除掉,实现服务的主动摘除,通常配合etcd的watch个性来做到实时的感知。v3版的客户端接口除了上述的Grant,KeepAliveOnce办法,还包含了一些其余重要的办法如Revoke删除某个租约,TimeToLive查看某个租约残余时长等。etcd服务端面向租约对客户端服务的有5个接口,别离对client端的办法给予了实现。本次次要对服务端的实现办法进行剖析。 ...

February 8, 2022 · 4 min · jiezi

关于etcd:etcd的watch是怎么实现的

工作当中应用etcd作为配置核心,次要应用了etcdclient提供的watch接口对存储的配置进行实时监听更新,很好奇etcd外部是如何做到不丢数据并联通上下游的,于是翻看了局部v3版本实现代码,在惊叹大佬们的代码程度同时又在鄙视本人写的lowB代码。 简略应用简略应用etcdctl命令行做一个演示,次要展现一下性能。 # 首先启动一个etcd$ ./etcd# 存入数据,存三次$ etcdctl put testwatch 1$ etcdctl put testwatch 2$ etcdctl put testwatch 3# watch key,--rev=1示意从版本号为1开始watch$ etcdctl --endpoints=127.0.0.1:23790 watch testwatch --rev=1 -w=json{ "Header":{ "cluster_id":14841639068965178418, "member_id":10276657743932975437, "revision":27, "raft_term":25 }, "Events":[ { "kv":{ "key":"dGVzdHdhdGNo", "create_revision":25, "mod_revision":25, "version":1, "value":"MQ==" } }, { "kv":{ "key":"dGVzdHdhdGNo", "create_revision":25, "mod_revision":27, "version":3, "value":"Mw==" } } ], "CompactRevision":0, "Canceled":false, "Created":false}#此时下面返回了从rev为1开始的变动,这时候再次对该key做批改(put testwatch 4),还会源源不断#输入更改后的内容等信息{ "Header":{ "cluster_id":14841639068965178418, "member_id":10276657743932975437, "revision":28, "raft_term":25 }, "Events":[ { "kv":{ "key":"dGVzdHdhdGNo", "create_revision":25, "mod_revision":28, "version":4, "value":"NA==" } } ], "CompactRevision":0, "Canceled":false, "Created":false}当指定版本号时候会返回所有版本号前面的历史的批改记录,如果不指定则只会在发生变化时候返回变动后的键值。理解了最简略的用法后,咱们从上到下挖一挖watch机制的原理。 ...

August 27, 2021 · 6 min · jiezi

关于etcd:K8s-系列三-如何配置-etcd-https-证书

在 K8s 中,kube-apiserver 应用 etcd 对 REST object 资源进行长久化存储,本文介绍如何配置生成自签 https 证书,搭建 etcd 集群给 apiserver 应用,并附相干坑点记录。 1. 装置 cfssl 工具cd /data/workwget https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssl_1.6.0_linux_amd64 -O cfsslwget https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssljson_1.6.0_linux_amd64 -O cfssljsonwget https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssl-certinfo_1.6.0_linux_amd64 -O cfssl-certinfochmod +x cfssl*mv cfssl* /usr/local/bin/chmod +x cfssl*mv cfssl_linux-amd64 /usr/local/bin/cfsslmv cfssljson_linux-amd64 /usr/local/bin/cfssljsonmv cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo2. 创立 ca 证书cat > ca-csr.json <<EOF{ "CN": "etcd-ca", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "Beijing", "L": "Beijing", "O": "etcd-ca", "OU": "etcd-ca" } ], "ca": { "expiry": "87600h" }}EOFcfssl gencert -initca ca-csr.json | cfssljson -bare ca=> 会生成:ca-key.pem, ca.csr, ca.pem3. 配置 ca 证书策略cat > ca-config.json <<EOF{ "signing": { "default": { "expiry": "87600h" }, "profiles": { "etcd-ca": { "usages": [ "signing", "key encipherment", "server auth", "client auth" ], "expiry": "87600h" } } }}EOF4. 配置 etcd 申请 csrcat > etcd-csr.json <<EOF{ "CN": "etcd", "hosts": [ "127.0.0.1", "etcd0-0.etcd", "etcd1-0.etcd", "etcd2-0.etcd" ], "key": { "algo": "rsa", "size": 2048 }, "names": [{ "C": "CN", "ST": "Beijing", "L": "Beijing", "O": "etcd", "OU": "etcd" }]}EOF5. 生成 etcd 证书cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd-ca etcd-csr.json | cfssljson -bare etcd=> 会生成:etcd-key.pem, etcd.csr, etcd.pem6. 创立 etcd clusteryaml 文件:https://github.com/k8s-club/etcd-operator ...

August 26, 2021 · 3 min · jiezi

关于etcd:etcd基本使用

1.装置wget下载地址 https://mirrors.huaweicloud.c... etcd.config name: "etcd"data-dir: "/var/lib/etcd/data"listen-client-urls: "http://0.0.0.0:2379"advertise-client-urls: "http://0.0.0.0:2379"启动 ./etcd --config-file=/opt/etcd/etcd.config 2.根本命令设置key etcdctl put slq1 1获取key etcdctl get slq1 //获取key为slq1的valueetcdctl get slq1 --print-value-only //只打印对应的值etcdctl get slq1 --hex //以十六进制显示etcdctl get slq1 slq5 //获取肯定范畴的key 不包含slq5etcdctl get --prefix slq //获取以slq为前缀的keyetcdctl get --limit=2 --prefix slq //限度数量为2etcdctl get --from-key s //查找大于s的所有keyetcdctl get --prefix --rev=4 slq1 //获取slq1 key version为4时候对应的值删除key etcdctl del slq1 //删除slq1etcdctl del slq1 slq5 //删除slq1到slq5的keyetcdctl del --prefix slq //删除前缀为slq的keyetcdctl del --from-key s //删除大于s的所有key监听key变动 etcdctl watch slq1 //监测slq1 etcdctl watch slq1 slq5 //监测slq1到slq5的key etcdctl watch --prefix slq //监测前缀为slq的key etcdctl watch --from-key s //监测大于s的所有key对key进行加锁 ...

July 31, 2021 · 2 min · jiezi

关于etcd:使用etcd选主

概述etcd提供了线性一致性。在线性一致性的根底上。etcd提供了 Campaign 进入期待队列,当后面所有其它候选人的value都delete后返回。Proclaim 不失落leadership的状况下,从新申明一个新的值。Resign 放弃leadershipLeader 取得以后的的leader valueObserve 开始watch leader value 的变更这篇blog探讨了etcd选举机制的实现细节,以及应该如何利用etcd选举来防止脑裂。如果仅仅是须要晓得本人是否主节点,那么只须要Campaign指令,当Campaign返回时,本人便成为主节点。在一个分布式系统中,是没有同时这个概念的,假如Campaign指令的返回tcp包因丢包多次重试,晚了1分钟才达到Campaigner,那么Campaign返回的同时,这个后果就曾经生效。所以,要害是:心跳距离肯定要短于value的ttl,且心跳失败的工夫不能长于ttl,心跳失败数次时就应从新加入选举。这个时候,其它节点因value的ttl没过不能成为leader,而leader会因心跳失败放弃成为leader,从而躲避Campaign指令滞后问题,或其它起因导致的,leader campaigner的value过期后,该campaigner还认为本人是leader的问题,即避免出现脑裂。 Campaign代码见 https://github.com/etcd-io/et... 8ee1dd9e23bce4d9770816edf5816b13767ac51d 流程简述put value to prefix/lease_id (排队)waitDeletes (期待prefix下所有早于本人的value,即本人排到第一) Campaign 代码含正文type Election struct { session *Session keyPrefix string leaderKey string leaderRev int64 leaderSession *Session hdr *pb.ResponseHeader}election.go: 59 // Campaign puts a value as eligible for the election on the prefix// key.// Multiple sessions can participate in the election for the// same prefix, but only one can be the leader at a time.//// If the context is 'context.TODO()/context.Background()', the Campaign// will continue to be blocked for other keys to be deleted, unless server// returns a non-recoverable error (e.g. ErrCompacted).// Otherwise, until the context is not cancelled or timed-out, Campaign will// continue to be blocked until it becomes the leader.func (e *Election) Campaign(ctx context.Context, val string) error { s := e.session client := e.session.Client() k := fmt.Sprintf("%s%x", e.keyPrefix, s.Lease()) // put 一个 key value,一般而言,不会有抵触。 // 如果同一个session 反复put,导致key的 revision 不为0,txn才会失败。 txn := client.Txn(ctx).If(v3.Compare(v3.CreateRevision(k), "=", 0)) txn = txn.Then(v3.OpPut(k, val, v3.WithLease(s.Lease()))) txn = txn.Else(v3.OpGet(k)) resp, err := txn.Commit() if err != nil { return err } e.leaderKey, e.leaderRev, e.leaderSession = k, resp.Header.Revision, s // 如果 put 时发现 key 的revision 不为 0 if !resp.Succeeded { kv := resp.Responses[0].GetResponseRange().Kvs[0] // 更新 leaderRev e.leaderRev = kv.CreateRevision if string(kv.Value) != val { // value 不相等,更新value if err = e.Proclaim(ctx, val); err != nil { // 失败则通过删除本人的key (辞职) // 从新开始选举, 返回谬误 // 如果从新开始选举谬误?有心跳超时。 e.Resign(ctx) return err } } } _, err = waitDeletes(ctx, client, e.keyPrefix, e.leaderRev-1) if err != nil { // clean up in case of context cancel select { case <-ctx.Done(): // 产生谬误,删除本人的key,防止被误认为leader. e.Resign(client.Ctx()) default: e.leaderSession = nil } return err } // 成为leader e.hdr = resp.Header return nil}一个典型的选主过程 ...

May 28, 2021 · 2 min · jiezi

关于etcd:Etcd-实战练习二

文章继续更新,微信搜一搜「 吴亲强的深夜食堂 」上一篇etcd 实战根底篇(一)咱们次要介绍了 etcd 应用场景以及最基础性的一些操作(put、get、watch)。 这一篇咱们接着实战etcd其余业务场景。 基于 etcd 的分布式锁基于 etcd 实现一个分布式锁特地简略。etcd 提供了开箱即用的包 concurrency,几行代码就实现一个分布式锁。 package srcimport ( "context" "flag" "fmt" "github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/clientv3/concurrency" "log" "strings" "time")var addr = flag.String("addr", "http://127.0.0.1:2379", "etcd address")// 初始化etcd客户端func initEtcdClient() *clientv3.Client { var client *clientv3.Client var err error // 解析etcd的地址,编程[]string endpoints := strings.Split(*addr, ",") // 创立一个 etcd 的客户端 client, err = clientv3.New(clientv3.Config{Endpoints: endpoints, DialTimeout: 5 * time.Second}) if err != nil { fmt.Printf("初始化客户端失败:%v\\n", err) log.Fatal(err) } return client}func Lock(id int, lockName string) { client := initEtcdClient() defer client.Close() // 创立一个 session,如果程序宕机奔溃,etcd能够晓得 s, err := concurrency.NewSession(client) if err != nil { log.Fatal(err) } defer s.Close() // 创立一个etcd locker locker := concurrency.NewLocker(s, lockName) log.Printf("id:%v 尝试获取锁%v", id, lockName) locker.Lock() log.Printf("id:%v获得锁%v", id, lockName) // 模仿业务耗时 time.Sleep(time.Millisecond * 300) locker.Unlock() log.Printf("id:%v开释锁%v", id, lockName)} 咱们再写个脚本运行,看看后果。 ...

May 14, 2021 · 4 min · jiezi

关于etcd:讲真的etcd-服务入门一篇文章足够了

Etcd 是一个应用一致性哈希算法(Raft)在分布式环境下的 key/value 存储服务。利用 Etcd 的个性,应用程序能够在集群中共享信息、配置或作服务发现,Etcd 会在集群的各个节点中复制这些数据并保障这些数据始终正确。 System Requirements >= 8v CPU + 16GB RAM + 50GB SSD 装置应用动态就是在配置服务之前曾经晓得了节点的地址和集群的大小 源码编译装置############################# Build the latest version############################# 1.下载我的项目并编译$ git clone https://github.com/etcd-io/etcd.git && cd etcd$ ./buildTo build a vendored etcd from the master branch via go get:# 2.设置GOPATH环境变量$ export GOPATH='/Users/example/go'$ go get -v go.etcd.io/etcd$ go get -v go.etcd.io/etcd/etcdctl# 3.启动服务$ ./bin/etcd$ $GOPATH/bin/etcd# 4.简略应用$ ./bin/etcdctl put foo barOK 部署单机单服务(动态)################################### Running etcd in standalone mode################################### 1.设置启动的Node地址$ export NODE1='172.16.176.52'# 2.创立一个逻辑存储$ docker volume create --name etcd-data# 3.启动etcd服务# 正式的ectd端口是2379用于客户端连贯,而2380用于搭档通信# --data-dir: 到数据目录的门路# --initial-advertise-peer-urls: 集群中节点间通信的URL地址# --listen-peer-urls: 集群中节点间通信的URL地址# --advertise-client-urls: 客户端监听的URL地址# --listen-client-urls: 客户端监听的URL地址# --initial-cluster: 启动初始化集群配置$ docker run -p 2379:2379 -p 2380:2380 --name etcd \ --volume=etcd-data:/etcd-data \ quay.io/coreos/etcd:latest \ /usr/local/bin/etcd \ --data-dir=/etcd-data --name node1 \ --initial-advertise-peer-urls http://${NODE1}:2380 \ --listen-peer-urls http://0.0.0.0:2380 \ --advertise-client-urls http://${NODE1}:2379 \ --listen-client-urls http://0.0.0.0:2379 \ --initial-cluster node1=http://${NODE1}:2380# 4.列出当初集群中的服务状态$ etcdctl --endpoints=http://${NODE1}:2379 member list ...

May 8, 2021 · 5 min · jiezi

关于etcd:分布式集群中间件搭建2-etcd集群搭建

前言 本文次要介绍etcd的基本原理及基于CentOS模板机克隆搭建etcd集群。 简介 etcd这个名字源于两个想法,即unix “/etc” 文件夹和分布式系统”d”istibuted。 “/etc” 文件夹为单个零碎存储配置数据的中央,而 etcd 存储大规模分布式系统的配置信息。因而,”d”istibuted 的 “/etc” ,故而称之为 “etcd”。 etcd 是一个用Go编写的高可用 Key/Value 存储系统,分布式系统中最要害的数据的分布式、牢靠的键值存储(配置文件根本格局为key=value ),etcd 的灵感来自于 ZooKeeper 和 Doozer,它具备杰出的跨平台反对,小型二进制文件和背地的优良社区。 Kubernetes 将配置数据存储到etcd中,用于服务发现和集群治理; etcd 的一致性对于正确安顿和运行服务至关重要。Kubernetes API 服务器将群集状态长久化在 etcd 中。它应用etcd的 watch API监督集群,并公布要害的配置更改。 官方网站:https://etcd.io/ 特色装置应用简略:应用规范HTTP工具(如curl)读取和写入值。反对分布式配置、服务发现、分布式协调性能:键值存储,将数据存储在按档次组织的目录中,反对监督特定的键或目录中的更改,并对值的更改作出反应。它提供了数据TTL生效、数据扭转监督、多值、目录监听、分布式锁原子操作等性能,能够不便的跟踪并治理集群节点的状态。平安:可选 SSL 客户端证书认证。疾速:单实例反对每秒 2k+ 读操作,单实例可达每秒1k 次写操作。 etcd定位是来代替配置文件的,所以其吞吐量不会很高 ,要是把它当redis用那就大错特错了,一个三成员etcd集群在轻负载下能够在每秒实现1000个申请,重负载下能够每秒实现超过30000个申请。牢靠:通信应用 Raft 协定作为一致性算法实现分布式。 etcd目前默认应用2379端口提供http服务,2380 端口和 peers(集群内其余节点)通信。尽管 etcd 反对单点部署,但在生产环境中举荐应用集群部署形式,etcd 官网文档举荐的 etcd 集群大小是3、5、7、9奇数个节点。etcd 会保障所有的节点都会保留数据,并保证数据的一致性和正确性。在etcd的集群中会选举出一位leader,其余etcd服务节点就会成为follower,在此过程其余follower会同步leader的数据,所有的follower都须要从leader同步完数据之后,leader能力持续写入新的数据,所以如果etcd的节点数量过多,则会导致同步的工夫变长、导致leader的写入效率升高。工作原理架构 HTTP Server:承受客户端收回的 API 申请以及其它 etcd 节点的同步与心跳信息申请。Store:用于解决 etcd 反对的各类性能的事务,包含数据索引、节点状态变更、监控与反馈、事件处理与执行等等,是 etcd 对用户提供的大多数 API 性能的具体实现。Raft:强一致性算法的具体实现,是 etcd 的外围算法。WAL(Write Ahead Log,预写式日志):是 etcd 的数据存储形式,etcd 会在内存中贮存所有数据的状态以及节点的索引,此外etcd 还会通过 WAL 进行长久化存储。WAL 中所有的数据提交前都会当时记录日志。 ...

March 7, 2021 · 2 min · jiezi

关于etcd:etcd单点迁移到高可用集群

因为一个业务etcd存在单点,所以独自搭建一个集群,替换掉原来的单点,在数据同步的时候还折腾了一下,好忘性比方烂笔头!!! 一、部署一个全新的etcd集群OLDetcd=172.0.254.66 NEWetcd1=172.0.254.5etcd2=172.0.254.6etcd3=172.0.254.7 在脚本处填写3台ETCD集群的IP,并在每台服务器执行 #!/bin/bash# 下载二进制etcd并装置version=v3.1.11downloadUrl=https://github.com/etcd-io/etcd/releases/downloadetcd1=172.0.254.5etcd2=172.0.254.6etcd3=172.0.254.7localIp=$(ip a show eth0|grep -o -P '(\d*\.){3}\d*'|head -1)if [ "$localIp" == "$etcd1" ];then etcdNum="etcd-1"elif [ "$localIp" == "$etcd2" ];then etcdNum="etcd-2"elif [ "$localIp" == "$etcd3" ];then etcdNum="etcd-3"else echo "local server ip is not etcd server:${localIp}"; exitfimkdir -p /softcurl -L ${downloadUrl}/${version}/etcd-${version}-linux-amd64.tar.gz -o /soft/etcd-${version}-linux-amd64.tar.gzcd /soft && tar -xf /soft/etcd-${version}-linux-amd64.tar.gzmv /soft/etcd-${version}-linux-amd64 /soft/etcd/soft/etcd/etcd --version/soft/etcd/etcdctl version# etcd配置文件mkdir -p /soft/etcd/confcat >/soft/etcd/conf/etcd.yml <<EOFname: $etcdNumdata-dir: /data/etcdlisten-client-urls: http://${localIp}:2379,http://127.0.0.1:2379advertise-client-urls: http://${localIp}:2379,http://127.0.0.1:2379listen-peer-urls: http://${localIp}:2380initial-advertise-peer-urls: http://${localIp}:2380initial-cluster: etcd-1=http://${etcd1}:2380,etcd-2=http://${etcd2}:2380,etcd-3=http://${etcd3}:2380initial-cluster-token: etcd-cluster-tokeninitial-cluster-state: newEOFnohup /soft/etcd/etcd --config-file=/soft/etcd/conf/etcd.yml >>/soft/etcd/stdout.out 2>&1 &ps -ef|grep etcd二、过程治理通过一个shell脚本治理过程vim /etc/init.d/etcd ...

November 30, 2020 · 3 min · jiezi

关于etcd:etcd入门-go操作etcd

一、etcd1、简介etcd是应用Go语言开发的一个开源的、高可用的分布式key-value存储系统,能够用于配置共享和服务的注册和发现。相似我的项目有`zookeeper`和`consul`。2、特点`齐全复制`:集群中的每个节点都能够应用残缺的存档`高可用性`:Etcd可用于防止硬件的单点故障或网络问题`一致性`:每次读取都会返回跨多主机的最新写入`简略`:包含一个定义良好、面向用户的API(gRPC)`平安`:实现了带有可选的客户端证书身份验证的自动化TLS`疾速`:每秒10000次写入的基准速度`牢靠`:应用Raft算法实现了强统一、高可用的服务存储目录3、利用场景服务发现配置核心分布式锁 - 1.放弃独占 2.管制时序注: 奇数节点准则 4、etcd集群... 5、go 操作 etcdgo get go.etcd.io/etcd/clientv3 官网文档 PUT GETpackage mainimport ( "context" "fmt" "time" "go.etcd.io/etcd/clientv3")func main() { cli, err := clientv3.New(clientv3.Config{ Endpoints: []string{"127.0.0.1:2379"}, DialTimeout: 5 * time.Second, }) if err != nil { // handle error! fmt.Printf("connect to etcd failed, err:%v\n", err) return } fmt.Println("connect to etcd success") defer cli.Close() // put ctx, cancel := context.WithTimeout(context.Background(), time.Second) _, err = cli.Put(ctx, "kk", "123") cancel() if err != nil { fmt.Printf("put to etcd failed, err:%v\n", err) return } // get ctx, cancel = context.WithTimeout(context.Background(), time.Second) resp, err := cli.Get(ctx, "kk") cancel() if err != nil { fmt.Printf("get from etcd failed, err:%v\n", err) return } for _, ev := range resp.Kvs { fmt.Printf("%s:%s\n", ev.Key, ev.Value) }}WATCHpackage mainimport ( "context" "fmt" "time" "go.etcd.io/etcd/clientv3")func main() { cli, err := clientv3.New(clientv3.Config{ Endpoints: []string{"127.0.0.1:2379"}, DialTimeout: 5 * time.Second, }) if err != nil { fmt.Printf("connect to etcd failed, err:%v\n", err) return } fmt.Println("connect to etcd success") defer cli.Close() // watch key:kk change rch := cli.Watch(context.Background(), "kk") // <-chan WatchResponse for wresp := range rch { for _, ev := range wresp.Events { fmt.Printf("Type: %s Key:%s Value:%s\n", ev.Type, ev.Kv.Key, ev.Kv.Value) } }}命令行操作更改键值 ...

November 30, 2020 · 3 min · jiezi

关于etcd:CNCF-宣布-etcd-项目毕业

2020 年 10 月 24 日,CNCF 正式发表,etcd 成为第 14 个毕业我的项目。之前毕业的 13 个我的项目别离为 Kubernetes、Prometheus、Envoy、CoreDNS、containerd、TUF、Jaeger、Fluentd、Vitess、Helm、Harbor、TiKV、Rook。 etcd 我的项目地址:etcd.io长期致力于云原生软件生态构建的云原生计算基金会(CNCF)近日发表,etcd 成为第 14个毕业的我的项目。从孵化(incubation)级别晋升为毕业(graduation)级别的过程中,etcd 展示了其使用率的一直进步、凋谢的治理流程、残缺性能成熟度以及对社区持续性和包容性的动摇承诺。 etcd 是一个 Go 语言编写的分布式、高可用的一致性键值存储系统,用于提供牢靠的分布式键值(key-value)存储、配置共享和服务发现等性能。无论是 Web 利用继续还是 Kubernetes,etcd 能够帮忙各种简单的应用程序进行数据写入与读取。etcd 我的项目 2013 年诞生于 CoreOS,于 2018 年 12 月作为孵化我的项目退出 CNCF。 etcd 曾经被许多公司用于理论生产,包含阿里巴巴、亚马逊、百度、思科、EMC、谷歌、华为、IBM、Red Hat、Uber、Verizon等,同时也用于 Kubernetes、CoreDNS、M3、Rook 以及 TiKV 等我的项目。 2020 年 7 月,由 CNCF 资助的第三方平安审计团队针对 Traild Bits 的 etcd v3.4 进行了审计。结果表明,etcd 是一款成熟且失去宽泛采纳的产品,其外围组件中未发现任何重大问题。不过 etcd 网关内存在一项重大平安问题,但曾经修复,并将更新向后移植到 etcd 反对的各版本中。另外,etcd 于 2020 年 1 月还通过了 Jepsen 测试。该测试用于剖析开源分布式系统,以查看其是否满足一致性保障。结果表明,etcd 我的项目的性能曾经齐全成熟。 ...

November 27, 2020 · 1 min · jiezi

关于etcd:不使用-K8s-API如何直接修改-etcd-数据

作者:Flant staff翻译:Bach(才云)校对:星空下的文仔(才云)、bot(才云)大家是否已经思考过更改 Kubernetes 集群的 etcd 数据的“低级”办法?就是说在不应用任何通用的 Kubernetes 工具(例如 CLI 程序甚至 API)就更改 etcd 存储的数据。 K8sMeetup 所有从这开始 越来越多的客户(大多是开发人员)要求提供对 Kubernetes 集群的拜访权限,以便与外部服务进行交互。他们心愿可能间接连贯到数据库或服务,将本地应用程序连贯到集群中的其余应用程序等等。 例如,从本地计算机连贯到 memcached.staging.svc.cluster.local service。咱们能够通过客户端连贯的集群外部 VPN 来实现。咱们公开与 Pod 和 service 相干的子网,并将集群的 DNS 推送到客户端。后果,当客户端尝试连贯到 memcached.staging.svc.cluster.local service 时,申请转到了集群的 DNS,它从集群的服务网络或 Pod 的地址返回该 service 的地址。 咱们应用 kubeadm 配置 K8s 集群。在这种状况下,默认 service subnet(子网)是 192.168.0.0/16,而 Pod 子网是 10.244.0.0/16。此办法大部分时候成果很好,然而也有几点值得注意: 192.168.*.* 子网往往是在客户办公室中应用,甚至是开发商的家庭办公室。这就呈现了问题:家用路由器会应用雷同的地址空间,VPN 会将这些子网从集群推送到客户端。有几个集群(production、stage、多个 dev 集群)的状况下,它们将默认全副具备与  Pod 和服务的雷同子网,这使得同时应用多个集群中的 services 十分艰难。咱们在同一我的项目中应用了不同的子网来实现同一我的项目中的不同 service 和 Pod。在这种状况下,任何集群都有其本人的网络。在保护大量 K8s 集群时,咱们不心愿它们从头开始重新部署,因为会有许多正在运行的 service、有状态的应用程序等。这时候就呈现了一个问题:咱们如何更改现有集群中的子网? K8sMeetup 解决方案 最常见的办法是从新创立所有 ClusterIP 类型的 service。不过也有问题: ...

November 27, 2020 · 2 min · jiezi

关于etcd:EtcdKubernetes集群的大脑

Etcd是Kubernetes的要害组件,因为它存储了集群的整个状态:其配置,规格以及运行中的工作负载的状态。在本文中,咱们将会揭开其神秘的面纱,理解etcd如何存储所有这些信息。 Etcd 简介Etcd被定义为分布式,牢靠的键值存储,用于分布式系统中最要害的数据。在Kubernetes世界中,etcd用作服务发现的后端,并存储集群的状态及其配置。 Etcd被部署为一个集群,几个节点的通信由Raft算法解决。在生产环境中,集群蕴含奇数个节点,并且至多须要三个。在 http://thesecretlivesofdata.com/ 中,您能够找到一个很好的动画,阐明该算法的运行形式,它阐明了集群生命周期的几个阶段,其中包含: 选主日志复制Kubernetes 中的 Etcd在Kubernetes集群的上下文中,etcd实例能够作为Pod部署在master节点上(这是咱们将在本文中应用的示例)。 为了减少安全性和弹性,还能够将其部署为内部集群。 以下来自Heptio博客的序列图显示了在简略的Pod创立过程中波及的组件。它很好地阐明了API服务器和etcd的交互作用。 Kubernetes 测试集群在本篇文章中,咱们应用的Kubernetes集群,由kubeadm创立的三个节点组成,其中一个master节点运行了Etcd。所选的网络附加组件是weavenet。这种配置不适宜理论的HA集群,但足以浏览etcd中存储的数据。 $ kubectl get nodesNAME STATUS ROLES AGE VERSIONnode-01 Ready master 56m v1.15.2node-02 Ready <none> 2m17 v1.15.2node-03 Ready <none> 2m17 v1.15.2The Etcd Pod首先,让咱们列出集群中运行的所有Pod: $ kubectl get pods --all-namespacesNAMESPACE NAME READY STATUS RESTART AGEkube-system coredns-5c98db65d4–5kjjv 1/1 Running 0 57mkube-system coredns-5c98db65d4–88hkq 1/1 Running 0 57mkube-system etcd-node-01 1/1 Running 0 56mkube-system kube-apiserver-node-01 1/1 Running 0 56mkube-system kube-controller-manager-node-01 1/1 Running 0 56mkube-system kube-proxy-7642v 1/1 Running 0 3mkube-system kube-proxy-jsp4r 1/1 Running 0 3mkube-system kube-proxy-xj8qm 1/1 Running 0 57mkube-system kube-scheduler-node-01 1/1 Running 0 56mkube-system weave-net-2hvbx 2/2 Running 0 87skube-system weave-net-5mrjl 2/2 Running 0 87skube-system weave-net-c76fx 2/2 Running 0 87s因为集群刚刚被初始化,因而只有kube-system名称空间中的Pod正在运行。这些Pod负责集群的治理工作。咱们感兴趣的Pod是etcd-node-01,它运行etcd的实例来负责存储集群的状态。 ...

September 12, 2020 · 2 min · jiezi

raft协议在-etcd中的应用

一、简介etcd 是基于 raft 协定实现的分布式一致性jian值存储,本篇文章不介绍etcd的应用,本文解说在etcd源码中提供的example,通过这个example来学习etcd是如何应用 raft协定。 二、实现这个example在etcd源码目录下的contrib目录中 tree -L 1.├── Makefile├── NOTICE├── OWNERS├── Procfile├── Procfile.v2├── README.md├── ROADMAP.md├── auth├── bill-of-materials.json├── bill-of-materials.override.json├── build├── build.bat├── build.ps1├── client├── clientv3├── code-of-conduct.md├── contrib # 明天的配角├── docs├── embed├── etcd.conf.yml.sample├── etcdctl├── etcdmain├── etcdserver├── functional├── functional.yaml├── go.mod├── go.sum├── hack├── integration├── lease├── logos├── main.go├── main_test.go├── mvcc├── pkg├── proxy├── raft├── scripts├── test├── tests├── tools├── vendor├── version└── waltree -L 1 contrib/raftexample/contrib/raftexample/├── Procfile├── README.md├── doc.go├── httpapi.go├── kvstore.go├── kvstore_test.go├── listener.go├── main.go├── raft.go└── raftexample_test.go先看一下入口文件 main.go ...

July 11, 2020 · 6 min · jiezi

用-etcdraft-组建能够选举的最简集群-demo

当今互联网行业中,对于分布式一致性算法,个人觉得实用性最高并且应用最广泛的就是 Raft 算法了。Raft 非常适合用于所有的节点均为可信节点时的必要数据同步场景中。Raft 的基本原理理解起来并不难,网上很多文字简介,都不如一个很生动的动画来得直观。 etcd/raft在 Kubenetes 中广泛使用的分布式 KV 存储系统 etcd 使用的就是 Raft 算法。算法的实现就直接作为 etcd 的子 package(用 Go 编写),路径为:github.com/etcd-io/etcd/raft。 官方提供了一个 demo。这个 demo 其实已经非常完整了,它包含了网络通信、快照压缩、数据同步等完整的功能。而对于 etcd/raft 的初见者而言,还是稍微有点门槛了。本文的目的是尽量抽丝剥茧,首先从 raft 最基本的功能——选举来入手,构建一个小的集群 demo,一步一步说明 etcd/raft 的用法。 Demo 功能这个小 demo 只实现一个功能:已知数量的集群节点,能够进行 leader 的选举。更多的功能(比如数据的存储)在以后的文章陆续解析。 为此,我们需要研究 etcd/raft 的相关函数的用法。 Raft 节点数据结构包 raft 使用接口 Node 来描述一个 Raft 节点。该接口的函数中,本文(或者说本阶段)涉及的有四个: type Node interface { Tick() Step(ctx context.Context, msg raftpb.Message) error Ready() <-chan Ready Status() Status}启动节点Raft 节点数量建议是一个素数。这里我采用 3 个。在节点数量已知的情况下,我们首先要告知 Raft node 节点的列表。每个节点应该有唯一的一个 uint64 类型的 ID: ...

July 6, 2020 · 3 min · jiezi

从0到1手把手教你入门-etcd

作者:kaliarch 链接:https://juejin.im/post/5e02fb...背景:近期 k8s 应用中 etcd 的功能存在一些困惑,对其进行来单独的学习,能更深入理解 k8s 中的的一些特性。一、概述1.1 etcd 简介etcd 是 CoreOS 团队于 2013 年 6月发起的开源项目,它的目标是构建一个高可用的分布式键值(key-value)数据库。etcd 内部采用raft协议作为一致性算法,etcd 基于 Go 语言实现。 1.2 发展历史 1.3 etcd 的特点简单:安装配置简单,而且提供了HTTP API进行交互,使用也很简单安全:支持SSL证书验证快速:根据官方提供的benchmark数据,单实例支持每秒2k+读操作可靠:采用raft算法,实现分布式系统数据的可用性和一致性1.4 概念术语Raft:etcd所采用的保证分布式系统强一致性的算法。Node:一个Raft状态机实例。Member:一个etcd实例。它管理着一个Node,并且可以为客户端请求提供服务。Cluster:由多个Member构成可以协同工作的etcd集群。Peer:对同一个etcd集群中另外一个Member的称呼。Client:向etcd集群发送HTTP请求的客户端。WAL:预写式日志,etcd用于持久化存储的日志格式。snapshot:etcd防止WAL文件过多而设置的快照,存储etcd数据状态。Proxy:etcd的一种模式,为etcd集群提供反向代理服务。Leader:Raft算法中通过竞选而产生的处理所有数据提交的节点。Follower:竞选失败的节点作为Raft中的从属节点,为算法提供强一致性保证。Candidate:当Follower超过一定时间接收不到Leader的心跳时转变为Candidate开始竞选。Term:某个节点成为Leader到下一次竞选时间,称为一个Term。Index:数据项编号。Raft中通过Term和Index来定位数据。1.5 数据读写顺序为了保证数据的强一致性,etcd 集群中所有的数据流向都是一个方向,从 Leader (主节点)流向 Follower,也就是所有 Follower 的数据必须与 Leader 保持一致,如果不一致会被覆盖。 用户对于 etcd 集群所有节点进行读写 读取:由于集群所有节点数据是强一致性的,读取可以从集群中随便哪个节点进行读取数据写入:etcd 集群有 leader,如果写入往 leader 写入,可以直接写入,然后然后Leader节点会把写入分发给所有 Follower,如果往 follower 写入,然后Leader节点会把写入分发给所有 Follower1.6 leader 选举假设三个节点的集群,三个节点上均运行 Timer(每个 Timer 持续时间是随机的),Raft算法使用随机 Timer 来初始化 Leader 选举流程,第一个节点率先完成了 Timer,随后它就会向其他两个节点发送成为 Leader 的请求,其他节点接收到请求后会以投票回应然后第一个节点被选举为 Leader。 成为 Leader 后,该节点会以固定时间间隔向其他节点发送通知,确保自己仍是Leader。有些情况下当 Follower 们收不到 Leader 的通知后,比如说 Leader 节点宕机或者失去了连接,其他节点会重复之前选举过程选举出新的 Leader。 ...

June 29, 2020 · 5 min · jiezi