问题来自于一个朋友,不是笔者亲身经历
k8s集群进行滚动更新发布时未生效,通过kube-apiserver查看发现这个Deployment已经是最新版,但是这个最新版的Pod并未创建出来 针对该现象,开始猜测可能是kube-controller-manager的bug导致,但是观察controller-manager日志并未发现明显异常,第一次调高controller-manager的日志等级并进行重启操作之后,似乎由controller-manager并没有watch到这个更新事件,我们仍然没有发现问题所在。此时 观察kube-appserver,诡异的事情发生了 之前的Deployment正常滚动更新了
由于kube-apiserver的日志中同样无法提取出能够帮助解决问题的有用信息,起初我们只能猜测可能是kube-apiserver的缓存更新异常导致的。正要从这个切入点解决问题的时候,有一个诡异的问题 创建的pod无法通过kubectl 查询到 那么问题来了 kube api的list操作是没有缓存的,数据是kube-apiserver直接从etcd拉取返回给客户端的 ,初步判断可能是etcd这里有问题 etcd是cap架构,一个强一致性的kv存储,在写操作成功的情况下两次请求不应该读取到不一样的数据,我们通过etcdctl直接查询了etcd的集群状态和集群数据,得到的结果是集群状态正常 Raftindex一致,观察etcd的日志也没有发现报错信息,唯一可疑的地方是3个节点的dbsize差别比较大,接着我们又将client访问的endpoint指定为不同节点地址来查询每个key的数量,结果发现3个节点返回的key数量不一致,并且直接通过etcdctl查询刚创建的pod,发现访问某些endpoint可以查到该pod,而访问其他endpoint则查不到 至此,基本可以确定etcd集群的节点存在数据不一致现象
初步验证 通常集群正常运行没有外部变更,一般不会出现这么严重的问题,查询etcd集群近几天的发布记录时发现故障前一天对该集群的一次发布中,由于之前dbsize配置不合理 导致db被写满集群无法写入新的数据,为此运维人员更新了集群dbsize和compaction相关配置并且重启了etcd 重启后继续对ectd手动执行了compact和defrag操作来压缩db空间 通过上述场景 我们基本可以初步判断一下几个可疑的触发条件 1.dbsize满 2.dbsize和compaction配置更新 3.compaction操作和defrag操作 4.重启etcd