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

作者: 郑明泉、余凯

为啥争吵,吵什么?

“你到底在说什么啊,我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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

消息队列

消息队列是和管道并列的概念,也是进程间通信IPC中的一种。 本文参考:消息队列(定义、结构、如何创建、消息队列的发送与接收、发送与接收实例)_咋么又饿了的博客-CSDN博客 基本概念 消息队列是一种先进先出的队列型数据结构&…

Stable Diffusion核心算法DDPM解析

DDPM:Denoising Diffusion Probabilistic Model,去噪扩散概率模型 本文参考:一个视频看懂扩散模型DDPM原理推导|AI绘画底层模型_哔哩哔哩_bilibili 1、大概原理 从右往左为正向加噪过程,从左往右为逆向降噪过程。 在正向过程中不…

专访 BlockPI:共建账户抽象未来的新一代 RPC 基础设施

在传统 RPC 服务板块上,开发者一直饱受故障风险、运行环境混乱等难题的折磨。实现 RPC 服务的去中心化,且保持成本优势和可扩展性,始终是区块链基础设施建设的重要命题之一。从 2018 年观察中心化 RPC 供应商服务现状开始,BlockPI…

Kubernetes 企业级高可用部署

1、Kubernetes高可用项目介绍 单master节点的可靠性不高,并不适合实际的生产环境。Kubernetes 高可用集群是保证 Master 节点中 API Server 服务的高可用。API Server 提供了 Kubernetes 各类资源对象增删改查的唯一访问入口,是整个 Kubernetes 系统的数…

使用断言抛异常操作

使用断言抛异常操作 常用方法 public static void isNull(Nullable Object object, String message) {if (object ! null) {throw new IllegalArgumentException(message);}}public static void notNull(Nullable Object object, String message) {if (object null) {throw n…

问道管理:股票打板风险大吗?怎么降低打板风险?

在股票市场上,一些出资者喜爱低吸,一些喜爱打板,那么,股票打板危险大吗?怎么下降打板危险?下面问道管理为大家准备了相关内容,以供参阅。 股票打板通常是指在个股涨停时买入,这种买入…

您可以购买 Banana Pi BPI-CM2 而不是 Raspberry Pi CM4。它提供什么?

最近,Banana Pi(SINOVOIP)推出了Banana Pi BPI-CM2系统级模块(SoM)。BPI-CM2 是类似于Raspberry Pi CM4 的计算模块,提供一系列令人印象深刻的功能。Banana BPI-CM2 SoM 采用Rockchip RK3568四核 Cortex-A5…

数据结构—排序

8.排序 8.1排序的概念 什么是排序? 排序:将一组杂乱无章的数据按一定规律顺序排列起来。即,将无序序列排成一个有序序列(由小到大或由大到小)的运算。 如果参加排序的数据结点包含多个数据域,那么排序往…

WebSocket服务端数据推送及心跳机制(Spring Boot + VUE)

一、WebSocket简介 HTML5规范在传统的web交互基础上为我们带来了众多的新特性,随着web技术被广泛用于web APP的开发,这些新特性得以推广和使用,而websocket作为一种新的web通信技术具有巨大意义。WebSocket是HTML5新增的协议,它的…

当你出差在外时,怎样轻松访问远程访问企业局域网象过河ERP系统?

文章目录 概述1.查看象过河服务端端口2.内网穿透3. 异地公网连接4. 固定公网地址4.1 保留一个固定TCP地址4.2 配置固定TCP地址 5. 使用固定地址连接 概述 ERP系统对于企业来说重要性不言而喻,不管是财务、生产、销售还是采购,都需要用到ERP系统来协助。…

快速解决Ubuntu 中 wine 程序 中文显示为方块/显示错误/无法显示中文(2023)

解决办法就是在创建prefix的命令行里加上LANG“zh_CN.UTF8” LC_ALL“zh_CN.UTF8”,并安装cjkfonts,即可。 1、生成prefix、安装cjk字体 以下是基本流程: 现在假定wine和winetricks已经装好, // 先创建一个prefix,按…

ArcGIS 利用cartogram插件制作变形地图

成果图 注:本图数据并不完全对,只做为测试用例 操作 首先需要下载一个插件cartogram 下载地址在这里 https://www.arcgis.com/home/item.html?idd348614c97264ae19b0311019a5f2276 下载完毕之后解压将Cartograms\HelpFiles下的所有文件复制到ArcGIS…

K8s实战4-使用Helm在Azure上部署Ingress-Nginx和Tokengateway

手动发布Ingress-Nginx 1 登录到aks(dfinder-gw-aks) az login az account set --subscription ${sub ID} az aks get-credentials --resource-group ${groupname} --name ${aks name} 2 下载 ingress-nginx-4.2.5.tgz curl -LO https://github.com/kubernetes/ingress-ngi…

【002】学习笔记之typescript的【任意类型】

任意类型 顶级类型:any类型和 unknown 类型 any类型 声明变量的时候没有指定任意类型默认为any任意类型都可以赋值给any,不需要检查类型。也是他的弊端如果使用any 就失去了TS类型检测的作用 unknown 类型 TypeScript 3.0中引入的 unknown 类型也被认为…

Tomcat 一次请求的生命周期

在使用 Tomcat 的时候,我们只需要在 Servlet 实现类中写我们的业务逻辑代码即可,不需要管 Socket 连接、协议处理要怎么实现,因为这部分作为不经常变动的部分,被封装到了 Tomcat 中,程序员只需要引入 Tomcat 中即可&am…

【C# 基础精讲】文件读取和写入

文件读取和写入是计算机程序中常见的操作,用于从文件中读取数据或将数据写入文件。在C#中,使用System.IO命名空间中的类来进行文件读写操作。本文将详细介绍如何在C#中进行文件读取和写入,包括读取文本文件、写入文本文件、读取二进制文件和写…

R语言APSIM模型进阶应用与参数优化、批量模拟实践技术

随着数字农业和智慧农业的发展,基于过程的农业生产系统模型在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农田固碳和温室气体排放等领域扮演着越来越重要的作用。APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物生…

Vue用JSEncrypt对长文本json加密以及发现解密失败

哈喽 大家好啊,最近发现进行加密后 超长文本后端解密失败,经过看其他博主修改 JSEncrypt原生代码如下: // 分段加密,支持中文JSEncrypt.prototype.encryptUnicodeLong function (string) {var k this.getKey();//根据key所能编…

初识Sentinel

目录 1.解决雪崩的方式有4种: 1.1.2超时处理: 1.1.3仓壁模式 1.1.4.断路器 1.1.5.限流 1.1.6.总结 1.2.服务保护技术对比 1.3.Sentinel介绍和安装 1.3.1.初识Sentinel 1.3.2.安装Sentinel 1.4.微服务整合Sentinel 2.流量控制 2.1.簇点链路 …

vscode用ssh远程连接linux

1、vscode是利用ssh远程连接linux的,所以首先确保vscode已经安装了这两个插件 2、点击左下角的连接 3、选择Connect to Host…… 5、按格式输入 ssh 主机名ip 比如我的:ssh mnt192.168.198.128 6、选择第一个打开配置文件,确保输入正确 7、…