K8s为啥要启用bridge-nf-call-iptables内核参数?用案例给你讲明白!

使用 kubernetes 遇到最多的 70%问题都可以归于网络问题,最近发现如果内核参数: bridge-nf-call-iptables设置不当的话会影响 kubernetes 中 node 节点上的 pod 通过 clusterip 去访问同 node上的其它 pod 时会有超时现象,复盘记录一下排查的前因后因。

1

问题现象

集群环境为 K8s v1.15.9,cni 指定了 flannel-vxlan 跟 portmap, kube-proxy 使用 mode 为 ipvs

问题现象是,某个 Node 节点上的 pod 通过 service 访问其它服务时,有些能通,有些不通,不通的都提示 timeout

异常的请求:

代码语言:javascript代码运行次数:0运行复制

$ curl -v http://panorama-v2-frontend-service.spring-prod.svc.cluster.local:8080* Rebuilt URL to: http://panorama-v2-frontend-service.spring-prod.svc.cluster.local:8080/* Trying 10.233.53.172...* TCP_NODELAY set# 这里一直等待直到超时

这个节点上的很多 pod 都存在这个问题, 其它节点未发现异常.

正常请求:

代码语言:javascript代码运行次数:0运行复制

$ curl -v http://panorama-v2-frontend-service.spring-prod.svc.cluster.local:8080* Rebuilt URL to: http://panorama-v2-frontend-service.spring-prod.svc.cluster.local:8080/* Trying 10.233.53.172...* TCP_NODELAY set* Connected to panorama-v2-frontend-service.spring-prod.svc.cluster.local (10.233.53.172) port 8080 (#0)> GET / HTTP/1.1> Host: panorama-v2-frontend-service.spring-prod.svc.cluster.local:8080> User-Agent: curl/7.52.1> Accept: */*>< HTTP/1.1 200 OK

2

排查过程

先对异常 Node 进行排查,因为其它节点是正常的,通过对异常 Node 的网络、kube-proxy、 iptables、ipvs 规则、kubelet 等排查后未发现有可疑的地方,就暂时排除嫌疑了。

第二个可疑的是 DNS, coreDNS 负责对 service 解析成 ClusterIP, 在出问题的 Node 上经过多次测试均能正确解析,coreDNS 排除嫌疑。

可疑的地方都筛了一遍,无果, 那就只能再从现象来发现看看有没有相同点。

首先,访问路径为:Service – > ClusterIP – > PodIP

对 service 访问异常,coreDNS 已经被排除了,那先绕过 service,直接使用 ClusterIP 访问呢? 测试后现象依旧。另外关注公号“终码一生”,回复关键词“资料”,获取视频教程和最新的面试资料!

那再绕过 ClusterIP,直接使用 PodIP 呢? Bingo,之前会出问题的访问都是正常的了。

那么问题就出在 CluterIP – > PodIP 上, 那么又有以下可能:

ClusterIP 没有正确转发到 PodIP 上可能导致超时如果正确转发,响应没有返回也可能导致超时

第一种可能性很容易排查,之前已经确认了 ipvs 规则、iptables 规则都是没有问题的,且通过 ClusterIP 发起的请求可以到达 PodIP 上, 基本就排除了可能性一

另外,对比正常跟异常请求会发现,异常的请求原 Pod 跟目标 pod 都是在同一个 Node 上,而正常的请求则处于不同的 Node,会是这个影响吗?

上面的可能性二,只能祭出抓包神器了tcpdump, 通过抓包发现(抓包过程见文未)会发现请求中出现了Reset

那么问题转换一下: 为什么相同 Node 上 podA 通过 service/ClusterIP 访问 PodB 响应会不返回呢,而通过 PodIP 访问就没问题?

补充一句就是,相同 Node 上的 pod 相互访问是不需要经过 Flannel 的,因此 Flannel 可以排除嫌疑

so, 问题在哪?

回到 tcpdump 的抓包数据, 可以发现,响应的数据没有按照请求的路径返回,嗯,Interesting

3

罪魁祸首

不管是 iptables 还是 ipvs 模式,Kubernetes 中访问 service 都会进行 DNAT,将原本访问 ClusterIP:Port 的数据包 DNAT 成 service 的某个 Endpoint (PodIP:Port),然后内核将连接信息插入 conntrack 表以记录连接,目的端回包的时候内核从 conntrack 表匹配连接并SNAT,这样原路返回形成一个完整的连接链路.

K8s为啥要启用bridge-nf-call-iptables内核参数?用案例给你讲明白!

从 tcpdump 看到请求被 reset 了, 没错, bridge-nf-call-iptables(如果是 ipv6 的话则是net.bridge.bridge-nf-call-ip6tables)参数

但是不对,这个参数 linux 默认开启的呢?难道是有人修改了么?

使用命令查看该参数是否开启:

代码语言:javascript代码运行次数:0运行复制

$ cat /proc/sys/net/bridge/bridge-nf-call-iptables# 0

返回 0,说明确实没有开启(后来被证实是被同事修改了),那这个参数是如何影响的返回路径的呢?

那就不得不说linux bridge了!

虽然 CNI 使用的是 flannel, 但 flannel 封装的也是 linux bridge,linux bridge 是虚拟的二层转发设备,而 iptables conntrack 是在三层上,所以如果直接访问同一网桥内的地址(ip 同一网段),就会直接走二层转发,不经过 conntrack:

结合上面的图来看,同 Node 通过 service 访问 pod 的访问路径如下:

PodA 访问 service, 经过 coreDNS 解析成 Cluster IP,不是网桥内的地址(ClusterIP 一般跟 PodIP 不在一个网段),走 Conntrack,进行 DNAT,将 ClusterIP 转换成 PodIP:PortDNAT 后发现是要转发到了同节点上的 PodB,PodB 回包时发现目的 IP(此时是 PodA 的 IP) 在同一网桥上(PodA 与 PodB 的 IP 段一致),就直接走二层转发了,不会去调 conntrack,这样就导致回包时没有原路返回

没有返回包就导致请求方一直等直到超时退出.

这样也解释了为何访问在其它节点的应用的 ClusterIP 没有问题,因为目标 PodIP 与源 PodIP 不在同一个网段上,肯定要走 conntrack.

4

问题解决

总述,开启参数后问题解决

代码语言:javascript代码运行次数:0运行复制

$ echo "net.bridge.bridge-nf-call-iptables=1" >> /etc/sysctl.conf$ echo "net.bridge.bridge-nf-call-ip6tables=1" >> /etc/sysctl.conf$ sysctl -p /etc/sysctl.conf

5

linux conntrack

关于 conntrack 其实也是个值得好好研究一番的知识点, 各个发行版都有工具可以看到 conntrack 里的记录,格式如下:

代码语言:javascript代码运行次数:0运行复制

$ conntrack -Ltcp 6 119 SYN_SENT src=10.224.1.34 dst=10.233.53.172 sport=56916 dport=8080 [UNREPLIED] src=10.224.1.56 dst=10.224.1.34 sport=8080 dport=56916 mark=0 use=1

那个著名的DNS 5s timeout[1]的问题就跟 conntrack 机制有关,由于篇幅有限,就不在这里展开.

6

tcpdump

在容器中的抓包命令

代码语言:javascript代码运行次数:0运行复制

$ tcpdump -vvv host 10.224.1.34 or 10.233.53.172 or 10.224.1.56

其中的三个 ip 分别对应 podA IP, podB 的 ClusterIP, podB 的 PodIP

这里由于篇幅的关系,只保存有关键信息,同时使用注释是作者加入的,方便理解.

对于异常请求的 tcpdump,如下:

代码语言:javascript代码运行次数:0运行复制

# podA 请求 PodBpanorama-frontend-deploy-c8f6fd4b6-52tvf.45954 > panorama-v2-frontend-service.spring-prod.svc.cluster.local.8080: Flags [S], cksum 0x4cc5 (incorrect -> 0xba1b), seq 1108986852, win 28200, options [mss 1410,sackOK,TS val 1345430037 ecr 0,nop,wscale 7], length 0# 10-224-1-56是PodB的podIP, 这里省略了解析过程,可以看到返回数据给PodA10-224-1-56.panorama-v2-frontend-service.spring-prod.svc.cluster.local.8080 > panorama-frontend-deploy-c8f6fd4b6-52tvf.45954: Flags [S.], cksum 0x1848 (incorrect -> 0x99ac), seq 3860576650, ack 1108986853, win 27960, options [mss 1410,sackOK,TS val 2444502128 ecr 1345430037,nop,wscale 7], length 0# 重点: podA直接reset了请求.panorama-frontend-deploy-c8f6fd4b6-52tvf.45954 > 10-224-1-56.panorama-v2-frontend-service.spring-prod.svc.cluster.local.8080: Flags [R], cksum 0xb6b5 (correct), seq 1108986853, win 0, length 0

最后会发现 PodA 给 PodB 发送了个R Flags, 也就是reset, 就是因为当 PodB 返回握手确认给到 PodA,PodA 根本不认识这个请求,所以直接给 reset 掉了, 三手握手都没有建立,this is why!

而对于net.bridge.bridge-nf-call-iptables=1的正常请求的 tcpdump 如下:

代码语言:javascript代码运行次数:0运行复制

# 能看到正常的三次握手, 这里省略# 开启传输数据panorama-frontend-deploy-c8f6fd4b6-52tvf.36434 > panorama-v2-frontend-service.spring-prod.svc.cluster.local.8080: Flags [P.], cksum 0x4d3c (incorrect -> 0x6f84), seq 1:128, ack 1, win 221, options [nop,nop,TS val 1346139372 ecr 2445211463], length 127: HTTP, length: 127    GET / HTTP/1.1    Host: panorama-v2-frontend-service.spring-prod.svc.cluster.local:8080    User-Agent: curl/7.52.1    Accept: */*panorama-v2-frontend-service.spring-prod.svc.cluster.local.8080 > panorama-frontend-deploy-c8f6fd4b6-52tvf.36434: Flags [.], cksum 0x4cbd (incorrect -> 0xe8a6), seq 1, ack 128, win 219, options [nop,nop,TS val 2445211463 ecr 1346139372], length 0panorama-v2-frontend-service.spring-prod.svc.cluster.local.8080 > panorama-frontend-deploy-c8f6fd4b6-52tvf.36434: Flags [P.], cksum 0x4dac (incorrect -> 0x0421), seq 1:240, ack 128, win 219, options [nop,nop,TS val 2445211463 ecr 1346139372], length 239: HTTP, length: 239    HTTP/1.1 200 OK    Server: nginx/1.17.1    Date: Wed, 18 Aug 2021 15:10:17 GMT    Content-Type: text/html    Content-Length: 1540    Last-Modified: Fri, 09 Jul 2021 06:36:53 GMT    Connection: keep-alive    ETag: "60e7ee85-604"    Accept-Ranges: bytes

相信这个请求路径还是很清晰的,就不再啰嗦.

7

结语

禁用net.bridge.bridge-nf-call-ip6tables这个参数当然也有好外,那就是考虑同网段的 IP 访问没必要走 conntrack,一定程度有助于性能。

kubernetes 的官方文档[2]中明确提及 Node 节点上需要开启这个参数,不然碰到各种诡异的现象也只是时间问题,所以还是不要随意调整。

以防后患的话可以对该参数是否开启进行监控,防止被人误修改。

以上就是K8s为啥要启用bridge-nf-call-iptables内核参数?用案例给你讲明白!的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/29765.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月3日 14:18:32
下一篇 2025年11月3日 14:19:10

相关推荐

  • CSS mask属性无法获取图片:为什么我的图片不见了?

    CSS mask属性无法获取图片 在使用CSS mask属性时,可能会遇到无法获取指定照片的情况。这个问题通常表现为: 网络面板中没有请求图片:尽管CSS代码中指定了图片地址,但网络面板中却找不到图片的请求记录。 问题原因: 此问题的可能原因是浏览器的兼容性问题。某些较旧版本的浏览器可能不支持CSS…

    2025年12月24日
    900
  • 为什么设置 `overflow: hidden` 会导致 `inline-block` 元素错位?

    overflow 导致 inline-block 元素错位解析 当多个 inline-block 元素并列排列时,可能会出现错位显示的问题。这通常是由于其中一个元素设置了 overflow 属性引起的。 问题现象 在不设置 overflow 属性时,元素按预期显示在同一水平线上: 不设置 overf…

    2025年12月24日 好文分享
    400
  • 网页使用本地字体:为什么 CSS 代码中明明指定了“荆南麦圆体”,页面却仍然显示“微软雅黑”?

    网页中使用本地字体 本文将解答如何将本地安装字体应用到网页中,避免使用 src 属性直接引入字体文件。 问题: 想要在网页上使用已安装的“荆南麦圆体”字体,但 css 代码中将其置于第一位的“font-family”属性,页面仍显示“微软雅黑”字体。 立即学习“前端免费学习笔记(深入)”; 答案: …

    2025年12月24日
    000
  • 为什么我的特定 DIV 在 Edge 浏览器中无法显示?

    特定 DIV 无法显示:用户代理样式表的困扰 当你在 Edge 浏览器中打开项目中的某个 div 时,却发现它无法正常显示,仔细检查样式后,发现是由用户代理样式表中的 display none 引起的。但你疑问的是,为什么会出现这样的样式表,而且只针对特定的 div? 背后的原因 用户代理样式表是由…

    2025年12月24日
    200
  • inline-block元素错位了,是为什么?

    inline-block元素错位背后的原因 inline-block元素是一种特殊类型的块级元素,它可以与其他元素行内排列。但是,在某些情况下,inline-block元素可能会出现错位显示的问题。 错位的原因 当inline-block元素设置了overflow:hidden属性时,它会影响元素的…

    2025年12月24日
    000
  • 为什么 CSS mask 属性未请求指定图片?

    解决 css mask 属性未请求图片的问题 在使用 css mask 属性时,指定了图片地址,但网络面板显示未请求获取该图片,这可能是由于浏览器兼容性问题造成的。 问题 如下代码所示: 立即学习“前端免费学习笔记(深入)”; icon [data-icon=”cloud”] { –icon-cl…

    2025年12月24日
    200
  • 为什么使用 inline-block 元素时会错位?

    inline-block 元素错位成因剖析 在使用 inline-block 元素时,可能会遇到它们错位显示的问题。如代码 demo 所示,当设置了 overflow 属性时,a 标签就会错位下沉,而未设置时却不会。 问题根源: overflow:hidden 属性影响了 inline-block …

    2025年12月24日
    000
  • 为什么我的 CSS 元素放大效果无法正常生效?

    css 设置元素放大效果的疑问解答 原提问者在尝试给元素添加 10em 字体大小和过渡效果后,未能在进入页面时看到放大效果。探究发现,原提问者将 CSS 代码直接写在页面中,导致放大效果无法触发。 解决办法如下: 将 CSS 样式写在一个单独的文件中,并使用 标签引入该样式文件。这个操作与原提问者观…

    2025年12月24日
    000
  • 为什么我的 em 和 transition 设置后元素没有放大?

    元素设置 em 和 transition 后不放大 一个 youtube 视频中展示了设置 em 和 transition 的元素在页面加载后会放大,但同样的代码在提问者电脑上没有达到预期效果。 可能原因: 问题在于 css 代码的位置。在视频中,css 被放置在单独的文件中并通过 link 标签引…

    2025年12月24日
    100
  • 为什么在父元素为inline或inline-block时,子元素设置width: 100%会出现不同的显示效果?

    width:100%在父元素为inline或inline-block下的显示问题 问题提出 当父元素为inline或inline-block时,内部元素设置width:100%会出现不同的显示效果。以代码为例: 测试内容 这是inline-block span 效果1:父元素为inline-bloc…

    2025年12月24日
    400
  • HTML 和 CSS 中的“联系我们”页面

    开发者您好!在本教程中,我将向您展示如何使用 html 和 css 创建现代的联系我们页面。联系我们表单是指网页表单的一部分,用户可以在其中向指定人员或网站管理员发送消息。 主要特点 响应式设计:布局灵活,适合移动和平板设备。现代 UI 元素:其中添加了图标、阴影和按钮悬停效果。 此联系表格完全响应…

    2025年12月24日
    100
  • HTML、CSS 和 JavaScript 中的简单侧边栏菜单

    构建一个简单的侧边栏菜单是一个很好的主意,它可以为您的网站添加有价值的功能和令人惊叹的外观。 侧边栏菜单对于客户找到不同项目的方式很有用,而不会让他们觉得自己有太多选择,从而创造了简单性和秩序。 今天,我将分享一个简单的 HTML、CSS 和 JavaScript 源代码来创建一个简单的侧边栏菜单。…

    2025年12月24日
    200
  • 带有 HTML、CSS 和 JavaScript 工具提示的响应式侧边导航栏

    响应式侧边导航栏不仅有助于改善网站的导航,还可以解决整齐放置链接的问题,从而增强用户体验。通过使用工具提示,可以让用户了解每个链接的功能,包括设计紧凑的情况。 在本教程中,我将解释使用 html、css、javascript 创建带有工具提示的响应式侧栏导航的完整代码。 对于那些一直想要一个干净、简…

    2025年12月24日
    000
  • uniapp 中图片加载显示灰块,如何排查问题?

    uniapp 图片加载灰块问题排查 在 uniapp 中使用 image 组件时,可能会遇到图片加载不出来的情况,显示为灰色的占位区块。导致此问题的主要原因是: base64 代码不正确 使用 base64 编码加载图片时,如果编码有误,浏览器将无法正确解析和渲染图片。这会导致出现灰色的占位块。 解…

    2025年12月24日
    000
  • 在 JavaScript 中移动 TodoList 中的“正在进行”任务如何解决?

    javascript 中使用 dom 更新 todolist 在您的问题中,您遇到了在使用 javascript 通过 dom 更新 todolist 时遇到困难的问题。具体来说,您无法将“正在进行”的任务移动到“已完成”部分。 问题原因 在您提供的 javascript 代码中,拼写错误导致“正在…

    2025年12月24日
    000
  • 在使用 JavaScript 实现的 TodoList 中,如何正确判断 Checkbox 点击事件,从而归类任务?

    使用 javascript 实现 todolist,点击 checkbox 后无法正确归类任务 问题描述:在使用 javascript 实现的 todolist 中,点击“正在进行”任务中的 checkbox,无法将任务自动归类到“已完成”任务列表。 原因分析:在提供的代码中,发现有一个单词拼写错误…

    2025年12月24日
    400
  • 如何在 VS Code 中解决折叠代码复制问题?

    解决 VS Code 折叠代码复制问题 在 VS Code 中使用折叠功能可以帮助组织长代码,但使用复制功能时,可能会遇到只复制可见部分的问题。以下是如何解决此问题: 当代码被折叠时,可以使用以下简单操作复制整个折叠代码: 按下 Ctrl + C (Windows/Linux) 或 Cmd + C …

    2025年12月24日
    000
  • 姜戈顺风

    本教程演示如何在新项目中从头开始配置 django 和 tailwindcss。 django 设置 创建一个名为 .venv 的新虚拟环境。 # windows$ python -m venv .venv$ .venvscriptsactivate.ps1(.venv) $# macos/linu…

    2025年12月24日
    000
  • css中文手册当前页面发生错误怎么办

    发生“当前页面发生错误”错误时,请依次尝试:检查网络连接;刷新页面;清除浏览器缓存;禁用浏览器扩展;检查浏览器版本;联系网站管理员;尝试其他浏览器;查看浏览器控制台。 CSS 中文手册当前页面发生错误怎么办 当您在使用 CSS 中文手册时遇到当前页面发生错误的情况,可以采用以下步骤进行排查和解决: …

    2025年12月24日
    000
  • css怎么设置超出显示省略号

    css设置超出显示省略号的方法:1、使用“overflow:hidden;”语句把超出的部分隐藏起来;2、使用“text-overflow:ellipsis;”语句在文本溢出包含元素时,显示省略符号来代表被隐藏的部分。 本教程操作环境:windows7系统、CSS3&&HTML5版、…

    2025年12月24日
    000

发表回复

登录后才能评论
关注微信