一次网络不通“争吵“引发的思考

news2024/12/23 18:08:42

作者: 郑明泉、余凯

为啥争吵,吵什么?

“你到底在说什么啊,我K8s的ecs节点要访问clb的地址不通和本地网卡有什么关系…” 气愤语气都从电话那头传了过来,这时电话两端都沉默了。过了好一会传来地铁小姐姐甜美的播报声打断了刚刚的沉寂「乘坐地铁必须全程佩戴口罩,下一站西湖文化广场…」。

pod需要访问clb的443的监听, 但是如果是集群内(集群内后面都指的K8s的节点或者POD)访问就会出现如下报错Connection refused:

在这里插入图片描述

所以就捋了一下客户链路如下:

在这里插入图片描述

具体现象是什么

无论是节点node还是pod里访问192.168.1.200:443都是不通的,但是访问192.168.1.200:80却是正常的。同时集群外的ECS192.168.3.100访问192.168.1.200:443和192.168.1.200:80都是正常的。

进一步分析看看

CLB1的IP192.168.1.200被绑定到了K8s的node节点的kube-ipvs0网卡上,这个是一张dummy 网卡,参考dummy interface。由于 SVC1 是LoadBalancer类型的,同时复用了这个CLB1,关联endpoint是POD1192.168.1.101:80,那么就可以解释为何访问192.168.1.200:80是正常,是由于kube-proxy根据SVC1的配置创建ipvs规则同时挂载了可被访问的后端服务。而集群里访问192.168.1.200:443都是不通的,因为IP被绑定到dummy网卡后,就不会再出节点去访问到CLB1,同时没有443对应ipvs规则,所以直接是拒绝的。

这个时候如果节点里没有ipvs规则(ipvs优先于监听)但是又能访问通的话, 可以检查一下是否本地有监听0.0.0.0:443的服务,那么这个时候所有网卡IP+443都能通,但是访问的是本地服务,而不是真正的CLB后端的服务。

在这里插入图片描述

是否有办法解决呢

最建议的方式

最好的方式拆分, 集群内和集群外的服务分开两个CLB使用。

阿里云svc注解的方式

SVC1使用这个注解service.beta.kubernetes.io/alibaba-cloud-loadbalancer-hostname,进行占位,这样就不会绑定CLB的IP到kube-ipvs0的网卡上,集群内访问CLB的IP就会出集群访问CLB,但是需要注意如果监听协议为TCP或UDP,集群内访问CLB IP时将会存在回环访问问题。详细信息,请参见客户端无法访问负载均衡CLB [ 1]

需要CCM版本在 v2.3.0及以上版本才支持这个注解, 具体参考:通过Annotation配置传统型负载均衡CLB [ 2]

在这里插入图片描述

demo:

apiVersion: v1
kind: Service
metadata:
  annotations:
    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-hostname: "${your_service_hostname}"
  name: nginx-svc
  namespace: default
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  type: LoadBalancer

集群内访问 ExternalTrafficPolicy 策略有影响吗?

我们都知道K8s的nodeport和loadbalancer模式是可以调整外部流量策略的,那么图中的「外部策略为Local/Cluster,所有集群节点创建IPVS规则是有区别的」该如何解释呢, 以及集群内访问nodePort/CLBIP的时候会发生什么。

在这里插入图片描述

以下都是针对svc的internalTrafficPolicy都是Cluster或者缺省的情况,这个ServiceInternalTrafficPolicy特性在1.22的K8s中默认开启,具体参考service-traffic-policy [ 3]

具体到阿里云容器在不同网络CNI情况下的数据链路,可以参考下面的文章:

  • 全景剖析阿里云容器网络数据链路(一)—— Flannel
  • 全景剖析阿里云容器网络数据链路(二)—— Terway ENI
  • 全景剖析阿里云容器网络数据链路(三)—— Terway ENIIP
  • 全景剖析阿里云容器网络数据链路(四)—— Terway IPVLAN+EBPF
  • 全景剖析阿里云容器网络数据链路(五)—— Terway ENI-Trunking
  • 全景剖析阿里云容器网络数据链路(六)—— ASM Istio

此处我们只讨论ipvs TrafficPolicy Local在Kubernetes 从1.22升级到1.24的行为变化。

Kubernetes 1.24 IPVS的变化

以下均以kube-proxy的IPVS模式为例:

  • 当externalTrafficPolicy为Cluster模式或缺省的时候,ipvs规则里的nodePort/CLBIP后端会挂载所有的Endpoint的IP,这时候集群内访问会丢失源IP,因为节点会做一层SNAT。
  • 当externalTrafficPolicy是Local的时候
    • 当节点上有对应service的Endpoint的时候,ipvs规则里的nodePort/CLBIP后端只挂载自己节点的Endpoint的IP,集群内访问会保留源IP。
    • 当节点上没有对应service的Endpoint的时候
    • 在1.24之前的版本是会挂空的后端的,集群内访问会拒绝。
    • 在1.24之后的K8s集群里,当节点上没有对应service的Endpoint的时候,ipvs规则里的nodePort/CLB IP后端会挂载所有的Endpoint的IP,这时候集群内访问会丢失源IP,因为节点会做一层SNAT。社区调整了Local策略后端服务的规则挂载策略,具体参考社区PR [ 4]

https://github.com/kubernetes/kubernetes/pull/97081/commits/61085a75899a820b5eebfa71801e17423c1ca4da

集群外访问SLB

集群外访问SLB的话,CCM只会挂载Local类型的节点,情况跟1.24 kubernetes前一样,这里不做过多阐述,请见上面连接。

集群外访问NodePort

1.24 Kubernetes之前版本

  • 访问有Endpoint的节点的NodePort,可以通,可以保留源IP

Nginx分布在cn-hongkong.10.0.4.174和cn-hongkong.10.0.2.84节点。

在这里插入图片描述

从外部10.0.3.72节点访问有后端pod所在节点的cn-hongkong.10.0.2.84的30479端口,可以访问。

在这里插入图片描述

cn-hongkong.10.0.0.140节点上是有相关的IPVS的规则的,但是只有该节点上后端Pod IP。

在这里插入图片描述

通过conntrack表可以到,这是由于在cn-hongkong.10.0.0.140节点上,相关的链路被dnat,最后是由pod cn-hongkong.10.0.2.84节点上的 的nginx-7d6877d777-tzbf7 10.0.2.87返回源,所有的相关转化都在该节点上,所以TCP四层建连可以成功。

在这里插入图片描述

  • 访问没有Endpoint的节点的NodePort,不能通,因为节点上没有相关的ipvs转发规则

从外部10.0.3.72节点访问无后端pod所在节点的cn-hongkong.10.0.0.140的30479端口,不可以访问。

在这里插入图片描述

查看该cn-hongkong.10.0.0.140节点,并没有相关的ipvs转发规则,所以无法进行dnat,访问会失败。

在这里插入图片描述

1.24 Kubernetes版本之后(含)

访问有Endpoint节点的NodePort,可以通,可以保留源IP

访问没有Endpoint节点的NodePort:

  • terway ENIIP or host网络:不通

Nginx分布在cn-hongkong.10.0.2.77和cn-hongkong.10.0.0.171 节点。

在这里插入图片描述

从外部10.0.3.72节点访问无后端pod所在节点的cn-hongkong.10.0.5.168的30745端口,可以看到,访问失败。

在这里插入图片描述

cn-hongkong.10.0.5.168节点上是有相关的IPVS的规则的,并且会把所有的后端Pod IP加到IPVS规则中。

在这里插入图片描述

通过conntrack表可以到,这是由于在cn-hongkong.10.0.5.168节点上,相关的链路被dnat,最后是由pod cn-hongkong.10.0.2.77节点上的nginx-79fc6bc6d-8vctc 10.0.2.78返回源,源在接受这个链路后,会发现和自己的五元组不匹配,直接丢弃,三次握手必然失败,所以建连失败。

在这里插入图片描述

  • flannel网络:可以通,但是保留不了源IP

Nginx分布在cn-hongkong.10.0.2.86。

在这里插入图片描述

从外部访问cn-hongkong.10.0.4.176的31218端口,可以访问成功。

在这里插入图片描述

cn-hongkong.10.0.4.176记录了src是10.0.3.72,并做了dnat为172.16.160.135,期望它返回给10.0.4.176的58825端口。

在这里插入图片描述

后端ep所在节点cn-hongkong.10.0.2.86,conntrack表记录了src是10.0.4.176,sport是58825。所以可以看到应用pod是记录的源IP是10.0.4.176,丢失了源IP。

在这里插入图片描述

集群内访问SLB或者NodePort

1.24 Kubernetes之前版本

  • 有Endpoint的节点上访问,可以通,可以保留源IP

Nginx分布在ap-southeast-1.192.168.100.209和ap-southeast-1.192.168.100.208节点,ap-southeast-1.192.168.100.210节点没有Nginx pod。

在这里插入图片描述

从集群任意节点(本例就在209节点)访问有后端pod所在节点的ap-southeast-1.192.168.100.209的NodePort 31565端口,可以访问。

在这里插入图片描述

从有后端pod所在节点ap-southeast-1.192.168.100.209访问SLB 8.222.252.252 的80端口,可以访问。

在这里插入图片描述

ap-southeast-1.192.168.100.209节点上是有NodePort 和SLB 的IPVS的规则的,但是只有该节点上后端Pod IP。

在这里插入图片描述

通过conntrack表可以到,这是由于在ap-southeast-1.192.168.100.209 节点上,相关的链路被dnat,最后是由pod 在ap-southeast-1.192.168.100.209 节点上的 的nginx-7d6877d777-2wh4s 192.168.100.222返回源,所有的相关转化都在该节点上,所以TCP四层建连可以成功。

在这里插入图片描述

  • 没有Endpoint的节点上访问,不能通,因为节点上没有相关的ipvs转发规则

从集群任意节点(本例就在210节点)访问没有后端pod所在节点的ap-southeast-1.192.168.100.210 的NodePort 31565端口或者SLB,不可以访问。

也进一步证实,集群内访问关联svc的SLB不出节点,即使SLB有其他监听端口,访问SLB其他端口也会拒绝。

在这里插入图片描述

查看该ap-southeast-1.192.168.100.210 节点,并没有相关的ipvs转发规则,所以无法进行dnat,访问会失败。

在这里插入图片描述

1.24 Kubernetes版本之后(含)

  • 有Endpoint节点上访问,可以通,可以保留源IP

与上文的1.24 Kubernetes之前版本集群内访问一致,可以参考上文描述。

  • 没有Endpoint节点上访问:

Nginx分布在cn-hongkong.10.0.2.77和cn-hongkong.10.0.0.171节点,所以在没有Nginx的cn-hongkong.10.0.4.141节点上测试。

在这里插入图片描述

分别有以下几种情况:

  • terway或后端为hostNetwork
    • 节点访问的通 NodePort(源 IP 是 ECS IP,不需要做 SNAT),无法保留源IP

可以看到没有Endpoint的节点的NodePort 110.0.4.141:30745 的IPVS 的规则添加的Nginx的所有后端POD nginx-79fc6bc6d-8vctc 10.0.2.78 和 nginx-79fc6bc6d-j587w 10.0.0.172。

在这里插入图片描述

集群内节点自身访问没有后端pod所在节点的cn-hongkong.10.0.4.141 的NodePort 30745/TCP端口,可以访问。

在这里插入图片描述

通过conntrack表可以到,在cn-hongkong.10.0.4.141节点上,相关的链路被dnat,最后是由后盾Nginx pod nginx-79fc6bc6d-8vctc 10.0.2.78返回源。

在这里插入图片描述

而在nginx-79fc6bc6d-8vctc 10.0.2.78 所在的节点cn-hongkong.10.0.2.77上的conntrack表记录的是10.04.141访问10.0.2.78,并期望10.0.2.78直接返回10.0.4.141的的39530端口。

在这里插入图片描述

集群内有endpoint 节点访问没有后端pod所在节点的ap-southeast-1.192.168.100.131 的NodePort 32292端口,不可以访问,与上文1.24 Kubernetes版本之后(含) 集群外访问一致,可以参考上文描述。

    • 节点访问不通 SLB IP(源 IP 是 SLB IP,没有人做 SNAT)

可以看到没有Endpoint的节点的SLB IP 的IPVS 的规则添加的Nginx的所有后端POD nginx-79fc6bc6d-8vctc 10.0.2.78 和 nginx-79fc6bc6d-j587w 10.0.0.172。

在这里插入图片描述

没有Endpoint的节点上访问 SLB 47.243.247.219,访问确是超时。

在这里插入图片描述

通过conntrack表可以到,在没有ep的节点访问SLB的IP,可以看到期望的是后端pod返回给SLB IP。而SLB IP 在节点上已经被kube-ipvs虚拟占位了,所以没有做snat,造成无法访问。

在这里插入图片描述

  • flannel并且后端为普通pod,可以访问通,但是保留不了源IP

Nginx分布在cn-hongkong.10.0.2.86。

在这里插入图片描述

在cn-hongkong.10.0.4.176访问SLB 47.242.86.39 是可以访问成功的。

在这里插入图片描述

cn-hongkong.10.0.4.176节点的conntrack表可以看到是src和dst都是47.242.86.39,但是期望的是 nginx pod172.16.160.135 返回给 10.0.4.176 的54988端口,47.242.86.39 snat成10.0.4.176。

在这里插入图片描述

后端ep所在节点cn-hongkong.10.0.2.86,conntrack表记录了src是10.0.4.176,sport是54988。所以可以看到应用pod是记录的源IP是10.0.4.176,丢失了源IP。

在这里插入图片描述

相关链接:

[1] 客户端无法访问负载均衡CLB

https://help.aliyun.com/document_detail/55206.htm

[2] 通过Annotation配置传统型负载均衡CLB

https://www.yuque.com/r/goto?url=https%3A%2F%2Fhelp.aliyun.com%2Fzh%2Fack%2Fack-managed-and-ack-dedicated%2Fuser-guide%2Fadd-annotations-to-the-yaml-file-of-a-service-to-configure-clb-instances

[3] service-traffic-policy

https://kubernetes.io/zh-cn/docs/concepts/services-networking/service-traffic-policy/

[4] 社区PR

https://github.com/kubernetes/kubernetes/pull/97081/commits/61085a75899a820b5eebfa71801e17423c1ca4da

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/892284.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Druid解析SQL,获取SQL中所有使用的表

一、sqlParse组成 Druid SQL Parser分三个模块: - Parser - AST - Visitor 1.1 Parser parser是将输入文本转换为ast(抽象语法树),parser有包括两个部分,Parser和Lexer,其中Lexer实现词法分析&#x…

vue项目根据word模版导出word文件

一、安装依赖 //1、docxtemplaternpm install docxtemplater pizzip -S//2、jszip-utilsnpm install jszip-utils -S//3、pizzipnpm install pizzip -S//4、FileSaver npm install file-saver --save二、创建word模版 也就是编辑一个word文档,文档中需要动态取值的…

【开源分享】在线客服系统搭建-基于php和swoole客服系统CRMchat(附源码完整搭建教程)...

CRMChat是一款开源的在线客服系统,后台管理使用thinkphp框架,消息通讯使用swoole扩展,现在我来部署搭建一下。 这是一款不可商用的开源客服系统,如果有商用需求可以访问我的网站:gofly.v1kf.com 域名解析 以阿里云为例…

C++笔记之unique_ptr转移堆内空间的所有权

C笔记之unique_ptr转移堆内空间的所有权 code review! 文章目录 C笔记之unique_ptr转移堆内空间的所有权一.C笔记之unique_ptr转移堆内空间的所有权方法1.使用std::move函数方法2.使用std::unique_ptr的reset方法方法3.返回unique_ptr方法4.std::unique_ptr的swap方法 二.uniq…

http学习笔记3

第 11 章 Web 的攻击技术 11.1 针对 Web 的攻击技术 简单的 HTTP 协议本身并不存在安全性问题,因此协议本身几乎不会成为攻击的对象。应用 HTTP 协议的服务器和客户端,以及运行在服务器上的 Web 应用等资源才是攻击目标。目前,来自互联网的攻…

LaWGPT零基础部署win10+anaconda

准备代码,创建环境 # 下载代码 git clone gitgithub.com:pengxiao-song/LaWGPT.git cd LaWGPT # 创建环境 conda create -n lawgpt python3.10 -y conda activate lawgpt pip install -r requirements.txt # 启动可视化脚本(自动下载预训练模型约15GB&…

(三)行为模式:1、责任链模式(Chain of Responsibility Pattern)(C++示例)

目录 1、责任链模式(Chain of Responsibility Pattern)含义 2、责任链模式的UML图学习 3、责任链模式的应用场景 4、责任链模式的优缺点 5、C实现责任链模式的实例 1、责任链模式(Chain of Responsibility Pattern)含义 责任…

ElasticSearch相关概念

1、概述 先说Elasticsearch的文件存储,Elasticsearch是面向文档型数据库,一条数据在这里就是一个文档,用JSON作为文档序列化的格式,比如下面这条用户数据: {"name" : "John","sex"…

论文写作中容易忽略的空格

持续更新吧,给自己提个醒,老是忘 1、数字和单位之间有一个四分之一空格,严格来说属于特殊符号,不知之间按空格键 应用场景: latex:语句$ 3\,m$ 可以实现, origin:网上的教程说可…

【HarmonyOS】【DevEco Studio】ohpm安装失败该如何解决?

【关键词】 HarmonyOS、DevEco Studio、ohpm安装失败 【问题背景及解决方案】 最近遇到很多DevEco Studio安装ohpm失败的问题,下面给大家介绍几种出现的问题以及解决方案: 1、ohpm not set up,报错截图如下: ​ 解决方案&…

AWS WAF实战、优势对比和缺陷解决

文章目录 挑战和目标AWS WAF的优势AWS WAF的不足我是怎么做的?什么是比较好的AWS WAF设计? 笔者为了解决公司Web站点防御性问题,较为深入的研究AWS WAF的相关规则。面对上千万的冲突,笔者不得设计出一种能漂亮处理冲突数据WAF规则。 AWS WAF开发人员在…

angular 的 alert 的应用分析笔记

声明: 今天自己在写angular项目时 遇到alert问题 做个记录而已 不代表广大angular用户,如果多你有帮助那个就是凑巧!!!! 效果: 第一步: 第二步: 第三步: 是不是找不到,ModaUtils这个方法(因为我项目里有这个 文件 里边存了 alert和confirm等公共方法) 都说了是个人笔记,看看…

启动 WSL 2时报错“参考的对象类型不支持尝试的操作”

引言 启动 WSL 2时报错“参考的对象类型不支持尝试的操作”。 或者是:占位程序接收到错误数据 Error code: Wsl/Service/0x8007273d 一番搜索 发现说和代理有关。 解决方案: 最有用的解决方案看这个issue。 这里我给出我的总结方案: 首…

84-基于stm32单片机蔬菜大棚温湿度光照强度监测控制系统Proteus仿真+源码

资料编号:084 一:功能介绍: 1、采用stm32单片机OLED显示屏光照强度检测DHT11温湿度电机按键LED灯,制作一个温湿度采集、光照强度检测,OLED显示相关数据, 2、通过按键设置温度上限、湿度下限、光照强度下限值…

webrtc学习(五)-peerconnect_client

一.类关系图 conduct实现webrtc native api相关实现的调用,创建answer,创建offer,是最核心的,对于两个模块的调度;mainwindow主要用于界面的展示与调度。橙色模块主要是信令模块,所有的用户的登录登出交换信…

71 # 协商缓存的配置:通过内容

对比(协商)缓存 比较一下再去决定是用缓存还是重新获取数据,这样会减少网络请求,提高性能。 对比缓存的工作原理 客户端第一次请求服务器的时候,服务器会把数据进行缓存,同时会生成一个缓存标识符&#…

Android系统-进程-AIDL

引言: Android系统的进程间通信,主要是Binder,AIDL就是一种Android接口定义语言,主要就是为了能更简单方便地实现跨进程通信。 概念与理解: AIDL:Android Interface Definition Language 序列化&#x…

NVIDIA Jetson 项目:机器人足球比赛

推荐:使用 NSDT场景编辑器 助你快速搭建可二次编辑器的3D应用场景 事实上,整个比赛都致力于这个想法。RoboCup小型联盟(SSL)视觉停电技术挑战赛鼓励团队“探索本地传感和处理,而不是非车载计算机和全球摄像机感知环境的…

非结构化数据库-MinIO基本集成

是什么 MinIO 是一个高性能的分布式对象存储服务,适合存储非结构化数据,如图片,音频,视频,日志等。对象文件最大可以达到5TB。 安装启动 mkdir -p /usr/local/minio cd /usr/local/minio# 下载安装包 wget https:/…

Spring之AOP的特性

一. AOP简介 AOP是Aspect-Oriented Programming的缩写,即面向切面编程。利用oop思想,可以很好的处理业务流程,但是不能把系统中某些特定的重复性行为封装到模块中。例如,在很多业务中都需要记录操作日志,结果我们不得…