记一次 k8s 集群单点故障引发的血案

本文详细记录了一次由于k8s集群apiserver单点故障导致的严重问题。当运行apiserver、controller-manager和scheduler的机器宕机后,重新部署的apiserver无法被kubelet访问,触发pod eviction,导致业务受到影响。复盘中强调了系统高可用的重要性,以及对k8s特性的深入理解与实践的必要性。
摘要由CSDN通过智能技术生成

写在前面

公司使用了 k8s 集群来管理一些比较基础的有状态集群,基于 k8s 进行了简单的二次开发,使之可以支持有状态的集群(并没有使用自带的petset,现在改名为statefulset了好像)。运行了了挺长时间,一直比较正常。但由于一些历史原因及侥幸心理,k8s 集群中的 apisever 一直都是单点,是的,只有一台机器。世上很多事情就是这样,你做了防范,事故却从不出现,显得防范毫无用处,当你没做防范的时候,事故总是如约而至,打你个措手不及。

血案经过

  • 那是一个安静的晚上,楼主在安静的撸码,突然发现一台机器 down 掉了,就是那台跑了 apiserver controller-manager scheduler 的机器(一挂全挂。不作就不会死啊真的是)
  • 但是楼主并没有太在意,在楼主的认知里,这些挂了,对正在运行的容器应该不会有影响。但为了保险起见,楼主又在别的机器上搭建了新的 k8s 控制组件,并用 ha 作了高可用。共用的都是同一套 etcd 集群。这个是不可避免的。做完后看了下业务容器,都是正常的。
  • 但是,过了五分钟,同事向我反映,他的业务的 pod 的状态全部变成 terminating 了。我赶紧看了一下,果然如此。当时直接吓尿,赶紧查看实际的业务容器,发现都是正常的。这是怎么回事?
  • 想了一下,突然想起重新搭建的 k8s apiserver 对现在集群的 kubelet 来说,是根本访问不到的,因为现在 kubelet 启动连接的 apiserver 地址还是之前的地址。另外,依稀记得 controller-manager 超过 5min 检测不到来自 node 的心跳,就会认为这个 node 已经挂掉,然后就会把该 node 上的 pod 全部删除。所以,目前的情况符合 pod eviction 条件,所有 node 上的 pod 已经被标记为删除,但由于 kubelet 现在与 apiserver 无法通信,所以容器并没有被实际干掉。
  • (事后来看,这时候正确的处理办法是停掉所有 node 上的 kubelet,保证业务容器的安全,然后再想其它解决办法,跳过 apiserver 直接修改 etcd 是最有效的办法;或者之前不启动新的 apiserver 及其它组件,当时有别的业务需要访问 apiserver,所以需要搭建一套, 但 controller-manager 是用不到的,如果没有启动 controller-manager 则 node-controller 就不会进行 pod eviction, 后面的悲剧就不会出现了)
  • 之前挂掉的 apiserver 机器我们无法直接控制,后面网络突然又恢复了,所有 kubelet 开始同步状态,杀掉正在运行的容器,血案爆发。

复盘

这次故障最大的教训就是不要留有侥幸心理,系统中不要留下单点,做好高可用。但如果处理得当,故障是可以止于机器故障的,不会引发后来的血案,究其原因,还是自己对 k8s 理解和实践的不够深入,对一些并不常用但其实很重要的特点没有深入研究。比如这次故障主要涉及到的 node controller 和 pod eviction,之前只是简单了解过,真正遇到问题,完全无法进行完善的处理。对故障涉及到的 k8s 特性进行了一些了解&#x

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值