k8s生产集群主机批量重启后,大量Pod启动失败故障排查复盘
在k8s生产环境运维过程中,主机批量重启是较为常见的操作,但往往容易因细节疏漏引发连锁故障。本文记录一次生产集群主机批量重启后,大量Pod容器启动报错的完整排查过程、解决方案及后续优化建议。
一、故障现象
某k8s生产集群,租户执行主机批量重启操作,所有主机重启完成后,集群内出现大量Pod启动失败的情况。查看Pod报错日志,核心报错信息统一为:无法链接到169.169.0.1:443。
初步观察集群状态:集群节点均已正常上线,无节点NotReady情况;查看kubernetes的Endpoint(ep)资源,三个master节点对应的kube-apiserver地址均正常存在,但当时并无仔细核查ip正确性。
二、故障排查过程
针对上述故障现象,我们按照"先应急、再排查、后根治"的思路,逐步推进问题定位,过程如下:
1. 首次应急尝试:重启单个kube-apiserver
结合过往运维经验,kube-apiserver作为集群的核心入口,其异常可能导致Pod与集群控制面通信失败。因此,首先尝试重启kube-apiserver服务,但当时仅重启了其中一个kube-apiserver实例,另外两个实例未进行重启。
重启完成后,观察Pod状态,发现报错现象未得到缓解,大量Pod仍报"无法链接到169.169.0.1:443"。
2. 参考过往经验:配置防火墙+重启kube-proxy
回忆此前在其他项目中遇到的类似通信故障,当时通过添加相关防火墙策略、重启kube-proxy服务,成功恢复了Pod通信。因此,我们沿用该思路进行操作:
-
添加防火墙策略,放行集群内部通信所需端口(重点放行169.169.0.1相关通信,以及kube-apiserver、kube-proxy工作所需端口);
-
重启所有节点的kube-proxy服务,确保网络代理规则正常加载。
操作完成后,部分Pod恢复正常运行,但仍有部分核心服务Pod持续报错,依旧提示"链接169.169.0.1:443拒绝",故障未彻底解决。
3. 关键排查:发现kube-apiserver端点异常
再次重点检查kubernetes的ep资源(核心命令:kubectl get ep kubernetes -n default),此时发现了关键异常:三个kube-apiserver对应的IP地址中,有两个是集群管理IP ,只有一个是业务IP。
结合故障报错的169.169.0.1:443,推测问题根源在于:kube-apiserver端点异常,部分端点使用了管理IP,而Pod通过业务网络访问管理IP时被拦截,导致通信失败;此前重启单个kube-apiserver只同步更新其中一个kube-apiserver端点信息,当部分pod访问kubernetes的svc轮询到其中一个正常的ip上时,才能恢复。因此故障未彻底解决。
三、解决方案
明确问题根源后,我们立即执行以下操作,彻底解决故障:
-
重启剩余两个未重启的kube-apiserver实例,确保三个kube-apiserver服务均完成重启,触发端点信息更新;
-
重启完成后,再次查看kubernetes的ep资源,确认三个kube-apiserver对应的IP地址均已更新为业务IP;
-
观察Pod状态,所有此前报错的Pod均自动重启并正常运行,集群恢复正常,169.169.0.1:443链接报错彻底消失。
四、故障根因分析
复盘本次故障,核心根因主要有两点,均与主机批量重启的操作规范缺失相关:
- 主机批量重启前,未提前停止master节点核心服务、etcd服务及集群内有状态服务,导致重启过程中,kube-apiserver服务异常退出,kube-apiserver配置中未固定绑定业务IP,导致服务重启后,随机绑定了管理IP,进而导致Pod通过业务网络无法访问管理IP,出现通信拒绝报错。
五、后续优化建议
为避免此类故障再次发生,结合本次排查经验,制定以下优化措施,规范主机重启及集群配置操作:
1. 规范主机批量重启流程
在执行主机批量重启(尤其是master节点重启)前,必须先执行以下操作,降低故障风险:
-
停止master节点核心服务:依次停止kube-apiserver、kube-controller-manager、kube-scheduler服务;
-
停止etcd服务:确保etcd集群数据一致性,避免重启导致数据损坏或集群分裂;
-
停止集群内有状态服务(如数据库、消息队列等):避免重启过程中,有状态服务数据丢失或异常;
-
重启完成后,优先检查master节点核心服务、etcd服务状态,确认正常后,再检查集群ep、Pod状态,逐步恢复业务。
2. 优化kube-apiserver配置
在kube-apiserver的启动配置中,添加固定业务IP地址的配置(通过--advertise-address 参数指定业务IP),向集群成员通知 apiserver 消息的 IP 地址。 这个地址必须能够被集群中其他成员访问。 如果 IP 地址为空,将会使用 --bind-address, 如果未指定 --bind-address,将会使用主机的默认接口地址。
六、总结
本次故障看似是Pod通信异常,实则是主机重启操作不规范、kube-apiserver配置参数缺失导致的连锁问题。k8s生产集群的稳定性,离不开规范的操作流程和严谨的配置优化。