暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

etcd社区issue分析:(1)

零君聊软件 2021-10-19
910

本文简要分析etcd社区的几个真实的issue,希望对etcd感兴趣的同学有所收获,这也是社区互助的精神。本文这个系列的第一篇文章,后面不定期可能会有后续的总结分享。

13340

这个issue的原始链接如下:

https://github.com/etcd-io/etcd/issues/13340


这个问题主要是反馈etcd的'/health'这个endpoint的处理逻辑不合理,是VMware的一个engineer反馈的问题。当etcd作为static POD部署到K8S中时,可以添加livenessProbe以及startupProbe,例如下面就是一个livenessProbe定义:

        livenessProbe:
    failureThreshold: 8
    httpGet:
    host: 127.0.0.1
    path: /health
    port: 2381
    scheme: HTTP
    initialDelaySeconds: 10
    periodSeconds: 10
    timeoutSeconds: 15


    这个问题的关键就在于,当etcd cluster有多个member时,etcd在处理/health请求时,是进行了lineariable read,所以这个endpoint实际上检查的cluster的健康状态。关于Linearizablity,请参与零君前一篇文章:


    这样就有一个问题,就是本地member其实是健康的,但是有可能其他member还没有启动完成,导致quorum还不达标,或者发生了leader change;这就导致/health返回false,最后kubelet就restart了当前member,造成恶性循环。


    为了解决这个问题,零君给etcd提交了一个PR(还在review过程中),为"/health"增加了一个新的参数serializable=true。这样etcd就执行serialiable read,从而只检查本地member的健康状态。具体请参考PR:

    https://github.com/etcd-io/etcd/pull/13399


    13406

    这个issue的原始链接如下:

    https://github.com/etcd-io/etcd/issues/13406


    这个问题主要是反馈etcd无法正常启动,刚一启动就会panic。好在reporter提供了db文件。经过分析,是db文件损坏了。


    etcd的db文件是由boltDB来管理的,所有数据是按照B+tree的方式组织的。一般来说,一个page的大小就是4K。

    关于BoltDB的具体分析,请先关注公众号,然后用关键字“bolt"搜索零君的历史文章。


    reporter提供的文件大小总共2527232字节,那么这个DB文件中总共应该有617 (2527232/4096) 个page。但是meta page中记录的却是1706个page,显然超出的范围。另外,B+tree的internal page中也有些无效的记录。


    零君临时写了一个简单的小程序(如下),修复了这些错误之后,etcd就正常启动了。有可能有一定的数据丢失,不过总比etcd无法启动要好很多了。

    https://github.com/ahrtr/etcd-issues/blob/master/13406/main.go


    13415

    这个issue的原始链接如下:

    https://github.com/etcd-io/etcd/issues/13415


    这个问题主要是反馈etcd 3.5在enable authentication之后,/health就返回false。


    这个问题的确是在3.5中新引入的。但严格来说,这并不是一个问题。在3.4中,当enable auth之后,/health其实并不经过auth。而在3.5中,则需要经过auth。当request context中没有auth info,etcd会certificate中获取auth info。所以解决办法也简单,就是请求/health时,采用HTTPS而不是HTTP。


    这个问题的具体分析见:

    https://github.com/ahrtr/etcd-issues/tree/master/13415


    13418

    这个issue的原始链接如下:

    https://github.com/etcd-io/etcd/issues/13418


    这个问题主要是一个哥们尝试用编程的方式来启动一个etcd cluster,发现总有问题。程序的执行逻辑大致如下:

    start a node A with one peer object define node A     

    wait until A become leader     

    send ProposeConfChange to add node B     

    start node B with 2 peers objects defines node A & B     

    results -> reject/hint inf loop


    如果看过零君之前写的一篇文章《管理etcd cluster成员的几点注意事项》,这个问题自然就引刃而解了。关键就在于启动第二个node的时候,要加入一个现有的cluster,而不是创建一个新cluster。从CLI的角度来说,就是要是设置参数:

    --initial-cluster-state existing"


    从编程的角度来说,启动第二个节点,要调用raft.RestartNode,而不是raft.StartNode。reporter按照我的建议修改之后,就正常 工作了。详细分析以及具体的代码,请参考:

    https://github.com/ahrtr/etcd-issues/tree/master/13418


    13418

    所有这些issue都总结在了如下的repo中,以后会陆续加入新的issue分析。

      https://github.com/ahrtr/etcd-issues

      --END--

      文章转载自零君聊软件,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

      评论