作者 | 骆冰利

来源 | Erda 公众号

某天晚上,客户碰到了这样的问题:K8s 集群一直扩容失败,所有节点都无法正常加入集群。在经过多番折腾无解后,客户将问题反馈到我们这里,希望得到技术支持。该问题的整个排查过程比较有意思,本文对其中的排查思路及所用的方法进行了归纳整理并分享给大家,希望能够对大家在排查此类问题时有些帮助和参考。

问题现象

运维同学在对客户的 K8s 集群进行节点扩容时,发现新增的节点一直添加失败。初步排查结果如下:

  • 在新增节点上,访问 K8s master service vip 网络不通。
  • 在新增节点上,直接访问 K8s master hostIP + 6443 网络正常。
  • 在新增节点上,访问其他节点的容器 IP 可以正常 ping 通。
  • 在新增节点上,访问 coredns service vip 网络正常。

该客户使用的 Kubernetes 版本是 1.13.10,宿主机的内核版本是 4.18(centos 8.2)。

问题排查过程

收到该一线同事的反馈,我们已经初步怀疑是 ipvs 的问题。根据以往网络问题排查的经验,我们先对现场做了些常规排查:

  • 确认内核模块 ip_tables 是否加载(正常)
  • 确认 iptable forward 是否默认 accpet (正常)
  • 确认宿主机网络是否正常(正常)
  • 确认容器网络是否正常(正常)
  • ...

排除了常规问题后,基本可以缩小范围,下面我们再继续基于 ipvs 相关层面进行排查。

1. 通过 ipvsadm 命令排查

10.96.0.1 是客户集群 K8s master service vip。



如上图所示,我们可以发现存在异常连接,处于 SYN_RECV 的状态,并且可以观察到,启动时 kubelet + kube-proxy 是有正常建连的,说明是在启动之后,K8s service 网络出现了异常。

2. tcpdump 抓包分析

两端进行抓包,并通过 telnet 10.96.0.1 443 命令进行确认。

结论:发现 SYN 包在本机没有发送出去。

3. 初步总结

通过上面的排查,我们可以再次缩小范围:问题基本就在 kube-proxy 身上。我们采用了 ipvs 模式,也依赖了 iptables 配置实现一些网络的转发、snat、drop 等。

根据上面的排查过程,我们又一次缩小了范围,开始分析怀疑对象 kube-proxy。

4. 查看 kube-proxy 日志



如上图所示:发现异常日志,iptables-restore 命令执行异常。通过 Google、社区查看,确认问题。



相关 issue 链接可参考:

5. 继续深入

通过代码查看(1.13.10 版本 pkg/proxy/ipvs/proxier.go:1427),可以发现该版本确实没有判断 KUBE-MARK-DROP 是否存在并创建的逻辑。当出现该链不存在时,会出现逻辑缺陷,导致 iptable 命令执行失败。

K8s master service vip 不通,实际容器相关的 ip 是通的,这种情况出现的原因,与下面的 iptable 规则有关:

iptable -t nat -A KUBE-SERVICES ! -s 9.0.0.0/8 -m comment --comment "Kubernetes service cluster ip + port for masquerade purpose" -m set --match-set KUBE-CLUSTER-IP dst,dst -j KUBE-MARK-MASQ

6. 根因探究

前面我们已经知道了 kube-proxy 1.13.10 版本存在缺陷,在没有创建 KUBE-MARK-DROP 链的情况下,执行 iptables-restore 命令配置规则。但是为什么 K8s 1.13.10 版本跑在 centos8.2 4.18 内核的操作系统上会报错,跑在 centos7.6 3.10 内核的操作系统上却正常呢?

我们查看下 kube-proxy 的源码,可以发现 kube-proxy 其实也就是执行 iptables 命令进行规则配置。那既然 kube-proxy 报错 iptables-restore 命令失败,我们就找一台 4.18 内核的机器,进入 kube-proxy 容器看下情况。



到容器内执行下 iptables-save 命令,可以发现 kube-proxy 容器内确实没有创建 KUBE-MARK-DROP 链(符合代码预期)。继续在宿主机上执行下 iptables-save 命令,却发现存在 KUBE-MARK-DROP 链。

这里有两个疑问:

  • 为什么 4.18 内核宿主机的 iptables 有 KUBE-MARK-DROP 链?
  • 为什么 4.18 内核宿主机的 iptables 规则和 kube-proxy 容器内的规则不一致?

第一个疑惑,凭感觉怀疑除了 kube-proxy,还会有别的程序在操作 iptables,继续撸下 K8s 代码。

结论:发现确实除了 kube-proxy,还有 kubelet 也会修改 iptables 规则。具体代码可以查看:pkg/kubelet/kubelet_network_linux.go



第二个疑惑,继续凭感觉······Google 一发捞一下为何 kube-proxy 容器挂载了宿主机 /run/xtables.lock 文件的情况下,宿主机和容器 iptables 查看的规则不一致。

​结论:CentOS 8 在网络方面摒弃 iptables,采用 nftables 框架作为默认的网络包过滤工具。

至此,所有的谜团都解开了。

团队完成过大量的客户项目交付,这里有些问题可以再解答下:​

  • 问题一:为什么这么多客户环境第一次碰到该情况?

因为需要 K8s 1.13.10 + centos 8.2 的操作系统,这个组合罕见,且问题必现。升级 K8s 1.16.0+ 就不出现该问题。

  • 问题二:为什么使用 K8s 1.13.10 + 5.5 内核却没有该问题?

因为与 centos 8 操作系统有关,我们手动升级 5.5 版本后,默认还是使用的 iptables 框架。

可以通过 iptables -v 命令,来确认是否使用 nftables。

题外话:nftables 是何方神圣?比 iptables 好么?这是另一个值得进一步学习的点,这里就不再深入了。

总结与感悟

针对以上的排查问题,我们总结下解决方法:

  • 调整内核版本到 3.10(centos 7.6+),或者手动升级内核版本到 5.0 +;
  • 升级 Kubernetes 版本,当前确认 1.16.10+ 版本没有该问题。

以上是我们在进行 Kubernetes 网络故障排查中的一点经验,希望能够对大家高效排查,定位原因有所帮助。

如果对于 Erda 项目你有其它想要了解的内容,欢迎添加小助手微信(Erda202106)加入交流群!

欢迎参与开源

Erda 作为开源的一站式云原生 PaaS 平台,具备 DevOps、微服务观测治理、多云管理以及快数据治理等平台级能力。点击下方链接即可参与开源,和众多开发者一起探讨、交流,共建开源社区。欢迎大家关注、贡献代码和 Star!

一次“不负责任”的 K8s 网络故障排查经验分享的更多相关文章

  1. golang 服务诡异499、504网络故障排查

    事故经过 排查 总结 事故经过 11-01 12:00 中午午饭期间,手机突然收到业务网关非200异常报警,平时也会有一些少量499或者网络抖动问题触发报警,但是很快就会恢复(目前配置的报警阈值是5% ...

  2. Linux 网络故障排查

    1.第一步是要确认网卡本身是否工作正常?利用ping工具可以确认这点.输入ping 127.0.0.1 ,然后看是否正常ping 通? 这里的127.0.0.1 被称作主机的回环接口,是TCP/IP协 ...

  3. Linux网络故障排查

    1.先排查网络配置信息 IP地址->子网掩码->网关->DNS 2.查看到达的网关是否连通 ping IP地址. 3.查看DNS解析是否正常.

  4. Linux 学习之网络故障排查

    1.ping www.baidu.com 查看高速有没有修通,如果通,但还不能上网:可能是浏览器.中毒等问题2.ping 网关(10.0.0.254),目的是排除物理链路(网线,网卡,驱动,IP设置等 ...

  5. NO31 配置网卡--主机名--网络故障排查面试题--DNS

    修改网卡配置信息: 修改主机名规范的三个步骤: 配置默认网关: DNS解析过程,用命令看:  DNS相关命令: 口述DNS解析过程: 客户端(电脑)通过浏览器输入域名,先找hosts文件及本地dns缓 ...

  6. 通过Microsoft Azure服务设计网络架构的经验分享(转)

    原文:http://www.infoq.com/cn/articles/azure-networking-tips 本文从产品设计和架构角度分享了 Microsoft Azure 网络服务方面的使用经 ...

  7. 通过Microsoft Azure服务设计网络架构的经验分享

    作者 王枫  发布于 2014年4月8日 本文从产品设计和架构角度分享了Microsoft Azure网络服务方面的使用经验,希望你在阅读本文之后能够了解这些服务之间,从而更好地设计你的架构. Mic ...

  8. [ASP.NET]大文件无法上传排查经验分享

    最近我们标桥下载模块,在经过正常更新后,发现软件包无法上传. 临时解决方案 因为问题结点在于文件无法上传到服务器,所以我们临时手动将文件丢到服务器,通过测试服务器将数据造出来,然后再更新到正式数据库, ...

  9. 1个工具,助你提升K8S故障排查效率!

    Kubernetes的故障排查一直困扰众多运维团队或DevOps,除了Kubernetes本身的复杂性之外,还有Kubernetes的工作负载是动态的原因.本文将介绍1个工具可以帮助你可视化K8S的网 ...

随机推荐

  1. JVM:Hotspot虚拟机中的对象

    在HotSpot虚拟机中,对象在内存中存储的布局可以被分为3个区域:对象头(Header).实例数据(Instance data)和对齐填充(Padding).对象头包括两部分信息,第一部分存储自身的 ...

  2. MySQL实战优化之InnoDB整体架构

    一.InnoDB 更新数据得整体架构 每个组件的作用说明: 用一条更新数据来说明每个主键得作用: update student set name = 'zhangsan' where id = 10 ...

  3. 奔跑吧linux-第三章实验

    基于树莓派+openeuler平台 实验 3-2:汇编语言练习--查找最大数 1.实验目的 通过本实验了解和熟悉 ARM64 汇编语言. 2.实验要求 使用 ARM64 汇编语言来实现如下功能:在给定 ...

  4. 另类加法 牛客网 程序员面试经典 C++ Python

    另类加法  牛客网 程序员面试经典 C++ Python 题目描述 请编写一个函数,将两个数字相加.不得使用+或其他算数运算符. 给定两个int A和B.请返回A+B的值 测试样例: 1,2 返回:3 ...

  5. cf Two Sets (我用二分最大匹配做的)

    题意: n个数p1,p2....pn     两个数a,b 把它们分成A,B两个集合. 若x属于A,a-x一定属于A. 若x属于B,b-x一定属于B. 问是否可能将这n个数分成两个集合.若可以,输出每 ...

  6. Spring事务的介绍,以及基于注解@Transactional的声明式事务

    前言 事务是一个非常重要的知识点,前面的文章已经有介绍了关于SpringAOP代理的实现过程:事务管理也是AOP的一个重要的功能. 事务的基本介绍 数据库事务特性: 原子性 一致性 隔离性 持久性 事 ...

  7. Awesome metaverse projects (元宇宙精选资源汇总)

    Awesome Metaverse 关于 Metaverse 的精彩项目和信息资源列表. 由于关于 Metaverse 是什么存在许多相互竞争的想法,请随时以拉取请求.问题和评论的形式留下反馈. We ...

  8. 【Git 系列】一个超好用的命令你会用吗?

    stash在英文意思是隐藏.git stash 的作用也是隐藏没完成的代码,防止它干扰别人或者新分支的工作. 一.背景 1.1 我们经常会遇到这样的情况 正在 dev 分支开发新功能,做到一半时有人过 ...

  9. 深入理解Spring IOC容器

    本文将从纯xml模式.xml和注解结合.纯注解的方式讲解Spring IOC容器的配置和相关应用. 纯XML模式 实例化Bean的三种方式: 使用无参构造函数 默认情况下,会使用反射调用无参构造函数来 ...

  10. 大一C语言学习笔记(9)---指针篇--从”内存的使用“和“流程控制”的角度来理解“指针变量的使用‘

    #深入理解指针变量 举个错误栗子: //以下代码的目的是输出100和1000,但输出结果只有一个100 #include<stdio.h> #include<malloc.h> ...