公有云 Loadbalancer 与 Cilium 网络组件联通故障一例

我是 LEE,老李,一个在 IT 行业摸爬滚打 16 年的技术老兵。

事件背景

我们的几个核心 k8s 集群规则持续增长,网络稳定性和效能之间的平衡性成为目前主要需要攻克的问题。目前单个集群的节点 270+ 、Pod 40000+ ,这样的规模 Pod 之间的请求流量规模十分巨大,而且网络流量压力对传统的 k8s 网络组件压力很大。为了要解决这个问题,我把目标转向了基于 ebpf 的 cilium 组件,决定使用 cilium 来替换 kubelet 中的 kubenet 组件。

我选择了一个有点量的测试 k8s 集群,安装了 cilium 1.11.8 后,做了集群内部的网络测试,Pod 到节点以及 Pod 之间都是可以 ping 通,而且端口访问是正常。随后我们对外发布测试服务的时候,发现外部无法连接到测试 k8s 集群内的应用。这个事情让我百思不得其解,明明网络测试都是 OK 的,为什么对外发布的测试服务却无法正常访问。

现象获取

这个时候拉来了底层云平台供应商的小伙伴一起排查,也是毫无进展。此时我只能逐一层次网络测试排查,通过一个下午的排查,最后发现外部直接访问 Pod 提供的服务是 OK,但是通过 Service 中 Loadbalancer 模式发布的服务确实访问不通的。

我们登录到云供应商上的 Loadbalancer 服务上,查看对应服务实例的状态和日志。通过观察,发现 Loadbalancer upstream 的 RealServer 状态不停的翻滚,一会状态“健康”,一会状态“异常”。我想这个“现象”应该是导致外部流量没有办法通过 Loadbalancer 到后端服务的原因。

公有云的 Loadbalancer 与后端健康检测异常

另外一个问题:我们直接访问 Node 和 Pod 的端口提供的服务都是正常的,但是 Loadbalancer 健康检测这个服务端口却是失败的?

一看究竟就必须要请出 tcpdump 大法,抓包复原 Loadbalancer 健康检测会话流。

健康检测会话流分析

正常情况

公有云的 Loadbalancer 正确健康检测步骤

按照原供应商小伙伴提供的信息,同时结合抓包结果,我们得知正常的一个健康检测是:

  1. Loadbalancer --> RealServer: sync
  2. RealServer --> Loadbalancer: sync,ack
  3. Loadbalancer --> RealServer: rst,ack

公有云的 Loadbalancer 会与 RealServer 尝试建立 tcp 连接,1,2 步交换 syncsync,ack,Loadbalancer 再收到了 sync,ack,就会向 RealServer 发送 rst,ack 关闭 tcp 连接,成功完成一次健康检测

异常情况

公有云的 Loadbalancer 异常健康检测步骤

我们看过了正常的健康检测的样子,那么我们这边公有云的 Loadbalancer 健康异常检测如上图所示。
经过分析,总结出现异常的情况如下:

  1. Loadbalancer --> RealServer 发送了 sync
  2. Loadbalancer --> RealServer RealServer 没有回应 sync,ack,然后公有云 Loadbalancer 尝试重传 sync
  3. RealServer(另外 IP) --> Loadbalancer 另外一个 IP 的 RealServer 回应 sync,ack

感觉到了一丝丝不对的情况,我想心细的小伙伴应该看到了问题所在。问题出现在 RealServer --> Loadbalancer 这里,为什么回应 Loadbalancer 的 RealServer IP 地址不对,导致 Loadbalancer 认为正确的 RealServer 没有回应自己的检测,随之将此 RealServer 的状态标记成“异常”。

原理分析

在沉思片刻后,我觉得最复杂的问题导致的原因可能最简单,一定是 cilium 组件哪里设置有问题,因为公有云 Loadbalancer 到后端 Pod 的这样业务模型在其他的没有部署 cilium 的集群内都是正常。

既然知道数据流的情况,也知道出问题的组件,问题就好解决了。

cilium 网络架构

Cilium 网络架构

cilium 的安装命令

helm upgrade -i cilium cilium/cilium --version 1.11.8 --namespace kube-system \
    --set tunnel=disabled \
    --set ipam.mode=kubernetes \
    --set nativeRoutingCIDR=10.192.32.0/19  \
    --set loadBalancer.mode=hybrid \    # 此参数是问题所在
    --set kubeProxyReplacement=probe \
    --set prometheus.enabled=true \
    --set operator.prometheus.enabled=true \
    --set hubble.enabled=true \
    --set hubble.metrics.enabled="{dns,drop,tcp,flow,port-distribution,icmp,http}"

庖丁解牛

结合 cilium 网络架构看来看去,最值得怀疑的地方就是 loadBalancer.mode=hybrid 这个参数,按照 cilium 官方的参考文档解释如下:

Cilium also supports a hybrid DSR and SNAT mode, that is, DSR is performed for TCP and SNAT for UDP connections. This has the advantage that it removes the need for manual MTU changes in the network while still benefiting from the latency improvements through the removed extra hop for replies, in particular, when TCP is the main transport for workloads.

The mode setting loadBalancer.mode allows to control the behavior through the options dsr, snat and hybrid. By default the snat mode is used in the agent.

By default, Cilium’s eBPF NodePort implementation operates in SNAT mode. That is, when node-external traffic arrives and the node determines that the backend for the LoadBalancer, NodePort or services with externalIPs is at a remote node, then the node is redirecting the request to the remote backend on its behalf by performing SNAT. This does not require any additional MTU changes at the cost that replies from the backend need to make the extra hop back that node in order to perform the reverse SNAT translation there before returning the packet directly to the external client.

This setting can be changed through the loadBalancer.mode Helm option to dsr in order to let Cilium’s eBPF NodePort implementation operate in DSR mode. In this mode, the backends reply directly to the external client without taking the extra hop, meaning, backends reply by using the service IP/port as a source. DSR currently requires Cilium to be deployed in Native-Routing, i.e. it will not work in either tunneling mode.

Note that usage of DSR mode might not work in some public cloud provider environments due to the Cilium-specific IP options that could be dropped by an underlying fabric. Therefore, in case of connectivity issues to services where backends are located on a remote node from the node that is processing the given NodePort request, it is advised to first check whether the NodePort request actually arrived on the node containing the backend. If this was not the case, then switching back to the default SNAT mode would be advised as a workaround.

一大堆英文的看完了,大概的意思是同时使用 NativeRoutingloadBalancer.mode=hybrid,cilium 内部的 Loadbalancer 工作在了 DSR 的模式下。 那么公有云的 Loadbalancer 对后端 RealServer 检测异常的问题就能很好解释了。整个异常的过程跟 DSR 工作模式完全一样。

处理方法

通过一通复杂的分析与验证后,我们在 cilium 的安装命令中去掉了 loadBalancer.mode=hybrid 参数,重新部署 cilium,然后重启相关的 Pod。

最终效果

公有云的 Loadbalancer 与 Node 节点之间健康检测恢复正常,对外发布的服务也能够正常的访问。

公有云的 Loadbalancer 与后端健康检测正常
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,233评论 6 495
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,357评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,831评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,313评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,417评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,470评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,482评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,265评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,708评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,997评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,176评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,503评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,150评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,391评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,034评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,063评论 2 352

推荐阅读更多精彩内容