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

news2024/11/17 21:26:21

为啥争吵,吵什么?

"你到底在说什么啊,我 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 使用这个注解 http://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]

此处我们只讨论 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。

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

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

相关文章

【校招VIP】java语言考点之List和扩容

考点介绍: List是最基础的考点,但是很多同学拿不到满分。本专题从两种实现子类的比较,到比较复杂的数组扩容进行分析。 『java语言考点之List和扩容』相关题目及解析内容可点击文章末尾链接查看!一、考点题目 1、以下关于集合类…

仪表板展示 | DataEase看中国:2023年中国电影市场分析

背景介绍 随着《消失的她》、《变形金刚:超能勇士崛起》、《蜘蛛侠:纵横宇宙》、《我爱你》等国内外影片的上映,2023年上半年的电影市场也接近尾声。据国家电影专资办初步统计,上半年全国城市院线票房达262亿元,已经超…

气象监测站:用科技感知气象变化

气象监测站是利用科学技术感知当地小气候变化情况的气象观测仪器,可用于农业、林业、养殖业、畜牧业、环境保护、工业等多个领域,提高对环境数据的利用率,促进产业效能不断提升。 气象监测站主要由气象传感器、数据传输系统、电源系统、支架…

Python web实战之Django 的跨站点请求伪造(CSRF)保护详解

关键词:Python、Web、Django、跨站请求伪造、CSRF 大家好,今天我将分享web关于安全的话题:Django 的跨站点请求伪造(CSRF)保护,介绍 CSRF 的概念、原理和保护方法. 1. CSRF 是什么? CSRF&#…

字符设备驱动实例(LED、按键、input输入子系统)

目录 本章目标 一、LED驱动 二、基于中断的简单按键驱动 三、基于输入子系统的按键驱动 本章目标 本章综合前面的知识,实现了嵌入式系统的常见外设驱动,包括 LED、按键、ADC、PWM和RTC。本章从工程的角度、实用的角度探讨了某些驱动的实现。比如LED …

ZooKeeper的应用场景(命名服务、分布式协调通知)

3 命名服务 命名服务(NameService)也是分布式系统中比较常见的一类场景,在《Java网络高级编程》一书中提到,命名服务是分布式系统最基本的公共服务之一。在分布式系统中,被命名的实体通常可以是集群中的机器、提供的服务地址或远程对象等一这…

ListNode相关

目录 2. 链表相关题目 2.1 合并两个有序链表(简单):递归 2.2 删除排序链表中的重复元素(简单):一次遍历 2.3 两链表相加(中等):递归 2.4 删除链表倒数第N个节点&…

数据结构:栈和队列(超详细)

目录 ​编辑 栈: 栈的概念及结构: 栈的实现: 队列: 队列的概念及结构: 队列的实现: 扩展知识: 以上就是个人学习线性表的个人见解和学习的解析,欢迎各位大佬在评论区探讨&#…

取证的学习

Volatility命令语法 1.判断镜像信息,获取操作系统类型 Volatility -f xxx.vmem imageinfo 在查到操作系统后如果不确定可以使用以下命令查看 volatility - f xxx.vmem --profile [操作系统] volshell 2.知道操作系统类型后,用–profile指定 volat…

redis查看执行的命令

1.SLOWLOG LEN 获取 Slowlog 的长度,以确定 Slowlog 中有多少条记录 2.SLOWLOG GET 获取 Slowlog 中的具体记录。你可以使用 SLOWLOG GET 命令来获取第 n 条记录的详细信息,其中 n 是记录的索引(从 0 开始) 3.如果你想获取多条最…

68 # 中间层如何请求其他服务

前端 ajax 有跨域问题,可以先访问中间层,在通过 node 去请求别的服务端口,可以解决跨域问题 编写中间层调用 // 中间层的方式const http require("http");// http.get 默认发送 get 请求 // http.request 支持其他请求格式 postl…

1.物联网IWIP网络,TCP/IP协议簇

一。TCP/IP协议簇 1.应用层:FTP,HTTP,Telent,DNS,RIP 2.传输层:TCP,UDP 3.网络层:IPV4,IPV6,OSPF,EIGRP 4.数据链路层:Ethernet&#…

3.微服务概述

1.大型网络架构变迁 SOA与微服务最大的差别就是服务拆分的细度,目前大多数微服务实际上是SOA架构,真正的微服务应该是一个接口对应一个服务器,开发速度快、成本高; 微服务SOA能拆分的就拆分是整体的,服务能放一起的都…

Docker Compose的入门与使用

Docker Compose的概念在上一篇Docker的介绍中有讲解,现在说一下怎么使用 安装Docker Compose 从官网上下载,速度会比较慢 执行 sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname …

【《深入浅出计算机网络》学习笔记】第2章 物理层

内容来自b站湖科大教书匠《深入浅出计算机网络》视频和《深入浅出计算机网络》书籍 目录 2.1 物理层概述 2.1.1 物理层要实现的功能 2.1.2 物理层接口特性 2.1.2.1 机械特性 2.1.2.2 电气特性 2.1.2.3 功能特性 2.1.2.4 过程特性 2.2 物理层下面的传输媒体 2.2.1 导向…

mac录屏工具,录屏没有声音的解决办法

mac录屏工具,录屏没有声音的解决办法 在使用macbook录制屏幕时,发现自带的录屏工具QuickTime Player没有声音,于是尝试了多款录屏工具,对其做一些经验总结(省流:APP Store直接可以免费下载使用Omi录屏专家…

互联网发展历程:保护与隔离,防火墙的安全壁垒

互联网的快速发展,不仅带来了便利和连接,也引发了越来越多的安全威胁。在数字时代,保护数据和网络安全变得尤为重要。然而,在早期的网络中,安全问题常常让人担忧。 安全问题的困扰:网络威胁日益增加 随着互…

对话 4EVERLAND:Web3 是云计算的新基建吗?

在传统云计算的发展过程中,数据存储与计算的中心化问题,对用户来说一直存在着潜在的安全与隐私风险——例如单点故障可能会导致网络瘫痪和数据泄露等危险。同时,随着越来越多 Web3 项目应用的落地,对于数据云计算的性能要求也越来…

GaussDB 实验篇+openGauss的4种1级分区案例

✔ 范围分区/range分区 -- 创建表 drop table if exists zzt.par_range; create table if not exists zzt.par_range (empno integer,ename char(10),job char(9),mgr integer(4),hiredate date,sal numeric(7,2),comm numeric(7,2),deptno integer,constraint pk_par_emp pri…

docker compose部署zookeeper

单机部署 新建docker-compose.yaml version: 3 services:zookeeper:image: zookeeper:3.5.7container_name: base-zookeeperhostname: zookeeperprivileged: truerestart: alwaysports:- 2181:2181environment:TZ: "Asia/Shanghai"volumes:- ./volumes/zookeeper/d…