前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >记一次EKS troubleshoting问题

记一次EKS troubleshoting问题

作者头像
richard.xia_志培
发布2022-11-30 15:10:50
7890
发布2022-11-30 15:10:50
举报
文章被收录于专栏:PT运维技术PT运维技术

背景介绍:

周五下班时刻,开发人员跟我反馈有业务偶尔超时,但业务很长时间并未重现异常, 让开发者以网络抖动打发掉这些询问者(实在抽不开时间)。熟悉业务的人即将抽出调岗,新的同学刚入职时间不久,还不能非常熟练处理业务问题,这个时刻只能自己先顶上了。

首先根据开发者提供的应用名,顺藤摸瓜,很快找到对应的pod, 登录到Pod查看日志,确实存在应用访问SVC超时的现象, pod因为访问超时异常导致内存过大OOM 很多次(程序得好好检查超时异常是否处理恰当!!!)。 经过curl命令行的测试,超时现象稳定复现。协议栈默认参数的作用下,应用程序不加超时机制的情况下,一般需要63+s的时间才会报connect timeout!。但下游的apisix, openresty的默认proxy_connect_timeout的时间为60s, 势必造成下下游openresty 报504 gateway timeout 错误, 下游apisix 499错误 (apisix的处理时间大于openresty proxy_connect_timeout:60s, 导致openresty主动终止request.)。查看日志,下游的各种报错都在预期的范围之内。 剩下的问题是:

4个pod ,只有1个pod 访问svc 超时, 其他的3个pod无此现象。

过程分析:

为了快速解决这个问题,直接将node设置为不可用调度,同时删除业务的pod(业务pod调度到其他的Node上)。在新创建的pod中,使用curl命令模拟请求测试,经测试正常,告知业务方问题得到缓解。周六中午又有开发者反馈业务超时仍然存在。WTF!看来问题并不是表面那么容易解决!经过开发者沟通,不止一个应用有这个现象,昨天晚上处理的仅仅是其中的一个应用。 经过统计分析,看到以下现象:

1. 其中eks 集群中的一个node现象严重,因为EKS集群中应用均有4-5个pod, 通过iptabes random模块做负载均衡,<=20%概率访问到异常pod, 访问量不大的情况下,就会偶发超时,因此可以解释这个现象。

2. 业务阻塞超时都发生跨EKS nodeport访问上。

由于eks版本原因,需要对容器进行迁移,因此在迁移期间,出现了跨EKS的nodeport的访问技术方案。第三方应用的访问拓扑:

SPOT -》 终端节点 --》 openresty --> NLB --> apisix -> pod -> service ->TGW -> nodeport ->pod

nodeport在老EKS集群中。

出现慢的时候,都是访问某个应用的nodeport比较慢,进而业务响应缓慢。

基于运维故障的'冰山理论',需要将引发故障原因的范围缩小。

是不是只有这台eks node存在未知问题?

基于以上的疑惑,分别在eks node,pod上抓包。

正常的eks node的抓包: 可以正常访问跨EKS集群nodeport的tcpdump:

异常的eks node的抓包: 不能正常访问跨EKS集群nodeport的tcpdump:

由于eks的SVC工作基于iptables, 因此需要了解tcpdump的和netfilter/iptables的关系:

进方向:网卡 eth0-> 网络中断 -> tcpdump -> netfilter/iptables

出方向: netfilter/iptables -> tcpdump -> 网络中断 ->网卡 eth0 【 iptables out 规则抓不到】

对比以上抓包的数据,看得出来:

1. 异常的eks node 是可以正常做SNAT的,只是nodeport 端无回包。【基于tcpdump和netfilter的关系,到底是包没有发送出去?还是对端收到了包,但是返回不了?】

因此需要确认发出包到底有没有出eks node的网卡。

nodeport端的老EKS无法ssh管理,无法抓包,因而打开eks node所在子网的vpc flow日志,通过命令模拟请求,观察了一段时间,下载vpc flow log。

分析完日志,eks node发到10.11.0.0/16根本就没有出eks node!!

因此问题范围锁定到 eks node上。

查看异常eks node的策略路由和iptables的规则, 然后和正常的eks node的策略路由和规则做对比,条目一致,内容一致。因此大概率排除掉iptables的规则配置问题, 但这个问题一定跟SNAT有关系。

为了避免风险, 重新创建一个rtm-test namespace, 然后创建pod, 然后创建一个SVC和Endpoint(跨eks nodeport访问), 创建busybox pod, 登录busybox中 访问svc , 这次居然可以正常访问!!!! 更换一个namespace就可以正常访问跨eks的nodeport ???

这种情况下,外部隔靴挠痒式的排查,显然不起作用!!

于是只能祭出perf/ftrace/systemtap 进行跟踪kernel和协议栈:

通过systemtap跟踪后:

确实存在丢包,但是不清楚在iptables 哪些环节丢失,最后只能跟踪netfilter/iptables的日志。于是开启netfilter/iptables的trace日志:

代码语言:javascript
复制
iptables -t raw -j TRACE -p tcp --dport 8080 -I PREROUTING 1
iptables -t raw -j TRACE -p tcp --dport 8080 -I OUTPUT 1
iptables -t raw -j TRACE -p tcp --dport 31980 -I PREROUTING 1
iptables -t raw -j TRACE -p tcp --dport 31980 -I OUTPUT 1

对比正常eks node和不正常eks node 访问跨eks的nodeport的trace日志:

正常访问trace的日志:

异常访问的trace的日志:

发现正常访问和异常访问差异点在于走的网卡不一样! 不同的网卡,可能存在SNAT的问题,可能存在非对称路由(Asymmetry Routing)问题。

于是检查策略路由:

果然通过策略路由完成双网卡的流量进出!!

10.175.36.32 是访问异常pod的IP,走的路由表居然是route table 2,route table 2是默认路由走的是eth1。而iptables 的NAT规则中是:

-A AWS-SNAT-CHAIN-1 ! -o vlan+ -m comment --comment "AWS, SNAT" -m addrtype ! --dst-type LOCAL -j SNAT --to-source 10.175.36.155 --random-fully

eth1的SNAT 肯定不成功:原因如下:

查了相关资料和aws eks的配置:

修改这个可以解决问题(调整为true),但需要重启kube-proxy, 且所有的跨node请求都需要SNAT。问题的本质是多网卡NAT+非对称路由问题。

咨询AWS相关的人,AWS告知这个是AWS CNI插件工作逻辑!!

AWS EKS在创建pod的时候,会分配IP,这些分配的IP可能会在eth0, 也可能在eth1, eni插件会自动添加策略路由,因此会存在着不对称路由和SNAT的问题。

eth1和eth0的网卡上分布着不同pod的IP。

查看了下eth0/eth1的网卡上的IP

代码语言:javascript
复制
[root]# curl http://169.254.169.254/latest/meta-data/network/interfaces/macs/06:94:28:24:a1:b6/local-ipv4s
10.175.36.155
10.175.42.110
10.175.35.46
10.175.33.173
10.175.47.43
10.175.43.234
....
[root]# curl http://169.254.169.254/latest/meta-data/network/interfaces/macs/06:99:f5:db:8a:04/local-ipv4s
10.175.42.179
10.175.58.46
10.175.52.237
10.175.50.173
10.175.36.103
10.175.56.38
.....
到此原因已经清楚!!

解决办法:

1. 不论经过哪张网卡,都开启SNAT,configmap kube-proxy-config 中masqueradeAll: true

。(弊端每次跨eks node都需要做一次NAT,效率会是问题,另外也会引起nat conntract满的问题) --次优先级方案

2. 关闭AWS eks CNI SNAT功能或者特殊网段禁止SNAT 。

AWS_VPC_K8S_CNI_EXTERNALSNAT=true 或者AWS_VPC_K8S_CNI_EXCLUDE_SNAT_CIDRS

代码语言:javascript
复制
kubectl set env  daemonset aws-node AWS_VPC_K8S_CNI_EXTERNALSNAT=true -n kube-system

--- 高优先级方案

展望:

1. 该技术方案是用于迁移EKS的,属于中短期的技术方案,经沟通了解到该问题居然存在很长时间(居然拖了3周+,是如何被上线生产环境的,笔者需要面壁思过!),

2. AWS EKS的CNI的插件机制完全不了解, 寻求最佳解决方案的时间拉长了, 后面需要全面了解EKS厂商相关的特性, Q4迁移EKS需要重点这个特性。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-07-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PT运维技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档