k8s calico vxlan式详解

news/2024/5/7 4:24:02

之前的文章讲了k8s ipip模式的使用以及流量路径,本篇文章主要是来讲解一下vxlan 模式下pod 流量是如何通信的。

一、ipip模式转vxlan

  • 修改calico backend参数

将calico_backend参数由bird设置为vxlan,因为vxlan部署不使用bgp

修改calico controllers的configmap配置
[root@node1 ~]# kubectl edit  cm/calico-config -n kube-systemcalico_backend: vxlan    ###修改为vxlan重启calico controllers  
[root@node1 ~]# kubectl rollout restart  deploy/calico-kube-controllers  -n kube-system 
  • 修改calico daemonset
编辑calico daemonset 
[root@node1 ~]# kubectl edit ds/calico-node  -n kube-system- name: CALICO_IPV4POOL_IPIPvalue: Never      ####修改为Never,禁用ipip- name: CALICO_IPV4POOL_VXLANvalue: Always     ####修改为vxlan2:禁用bird探针检测,因为vxlan不需要bgp,所以需要禁用livenessProbe:exec:command:- /bin/calico-node- -felix-live#- -bird-live      ###禁用此处探针检查periodSeconds: 10initialDelaySeconds: 10failureThreshold: 6timeoutSeconds: 10readinessProbe:exec:command:- /bin/calico-node- -felix-ready#- -bird-live     ######禁用此处探针检查periodSeconds: 10timeoutSeconds: 103:重启ds
[root@node1 ~]# kubectl rollout restart  ds/calico-node -n kube-system
  • 修改ippool
1:查看当前使用的ippool
[root@node1 ~]# kubectl get ippool
NAME                  AGE
default-ipv4-ippool   374d
new-ipv4-ippool       168d2:修改ippool的模式
[root@node1 ~]# kubectl edit ippool/new-ipv4-ippoolapiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:annotations:projectcalico.org/metadata: '{"uid":"f8ba255e-198a-4d7b-86b7-d47dc7066960","creationTimestamp":"2023-11-01T06:45:12Z"}'creationTimestamp: "2023-11-01T06:45:12Z"generation: 5name: new-ipv4-ippoolresourceVersion: "62183182"uid: f8ba255e-198a-4d7b-86b7-d47dc7066960
spec:allowedUses:- Workload- TunnelblockSize: 24cidr: 172.16.0.0/16ipipMode: Never    ####禁用ipipnatOutgoing: truenodeSelector: all()vxlanMode: Always  ###修改为vxlan
当vxlanMode参数设置为 Always 的时候,三层和二层的通信都通过vxlan的方式进行通信,当值为CrossSubnet的时候只有三层才进行vxlan的方式进行通信。
  • 确认没有bgp运行
[root@node1 ~]# calicoctl --allow-version-mismatch node status
Calico process is running.The BGP backend process (BIRD) is not running.[root@node1 ~]# 

二、vxlan模式讲解

通过上面的操作已经将ipip模式转换成了vxlan模式,环境中多了一个vxlan.calico的设备,这就是平时所说的vtep口,vxlan的封装以及解封装都在这个设备上进行。

[root@node1 ~]# ip -d link show vxlan.calico
12: vxlan.calico: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN mode DEFAULT group default link/ether 66:f9:37:c3:7e:94 brd ff:ff:ff:ff:ff:ff promiscuity 0 vxlan id 4096 local 192.168.5.79 dev eth0 srcport 0 0 dstport 4789 nolearning ageing 300 noudpcsum noudp6zerocsumtx noudp6zerocsumrx addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 可以看到vxlan.calico设备使用的驱动为vxlan
[root@node1 ~]# ethtool  -i vxlan.calico 
driver: vxlan     ###驱动为vxlan
version: 0.1
firmware-version: 
expansion-rom-version: 
bus-info: 
supports-statistics: no
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: no
[root@node1 ~]# #####参数解析如下:
vxlan: 指定要创建或配置的 VXLAN 隧道。
id 4096: 指定 VXLAN 的标识符(VNI,Virtual Network Identifier),这是一个用于区分不同 VXLAN 网络的唯一标识符。
local 192.168.5.59: 指定本地端点vtep的 IP 地址,即 VXLAN 隧道所在主机的 IP 地址。
dev eth0: 指定 VXLAN 隧道所使用的底层网络设备,即用于发送和接收 VXLAN 封装数据包的物理网络接口。
srcport 0 0: 指定 VXLAN 封装数据包的源端口范围,这里的0 0表示源端口范围是从0到0,即随机选择源端口。
dstport 4789: 指定 VXLAN 封装数据包的目标端口,即用于发送和接收 VXLAN 数据包的目标端口号。
nolearning: 禁用学习模式,即不允许 VXLAN 设备自动学习 MAC 地址。
ageing 300: 设置 MAC 地址表的老化时间为 300 秒,即在 300 秒内没有收到关于某个 MAC 地址的数据包时,将该 MAC 地址从表中删除。
noudpcsum: 禁用 UDP 校验和,即不对 VXLAN 封装的 UDP 数据包进行校验和计算。
noudp6zerocsumtx: 禁用 UDPv6 发送时的零检验和,即不对发送的 UDPv6 数据包的校验和字段进行填充。
noudp6zerocsumrx: 禁用 UDPv6 接收时的零检验和,即不对接收的 UDPv6 数据包的校验和字段进行验证。
addrgenmode eui64: 设置地址生成模式为 EUI-64,即使用 EUI-64 地址生成算法生成接口标识符。
numtxqueues 1: 设置发送队列的数量为 1。
numrxqueues 1: 设置接收队列的数量为 1。
gso_max_size 65536: 设置每个数据包的最大 GSO(Generic Segmentation Offload,通用分段卸载)大小为 65536 字节。
gso_max_segs 65535: 设置每个数据包的最大 GSO 段数为 65535

如下为vxlan模式下pod 跨节点通信数据流向图
在这里插入图片描述

三、实验模拟

  • 启动pod,位于不同节点
[root@node1 ~]# kubectl get po -o wide 
NAME                    READY   STATUS    RESTARTS   AGE     IP              NODE    NOMINATED NODE   READINESS GATES
test-5977dc5756-4nx25   1/1     Running   0          142m    172.16.154.16   node1   <none>           <none>
test-5977dc5756-8xrr9   1/1     Running   0          3h55m   172.16.28.33    node3   <none>           <none>
test-5977dc5756-zhg56   1/1     Running   0          97m     172.16.28.34    node3   <none>           <none>本次测试用nod1e 的172.16.154.16 和node3 的172.16.28.34地址
  • 进入网络ns
[root@node1 ~]# crictl ps | grep test
dba4c621b262e       12766a6745eea       2 hours ago         Running             nginx                     0                   3e0ae3c3fad42       test-5977dc5756-4nx25
[root@node1 ~]# crictl inspect dba4c621b262e | grep -i pid "pid": 44939,"pid": 1"type": "pid"
[root@node1 ~]# nsenter -t 44939 -n bash 
[root@node1 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000link/ipip 0.0.0.0 brd 0.0.0.0
4: eth0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default link/ether 76:32:89:65:0d:ee brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 172.16.154.16/32 scope global eth0valid_lft forever preferred_lft foreverinet6 fe80::7432:89ff:fe65:dee/64 scope link valid_lft forever preferred_lft forever查看pod的默认路由
[root@node1 ~]# ip r
default via 169.254.1.1 dev eth0 
169.254.1.1 dev eth0 scope link 
[root@node1 ~]# 
############################
############################
可以看到pod的默认路由下一条地址是169.254.1.1,一个不存在于主机上的地址。这里主要是calico 使用了网卡的proxy arp 功能。在Kubernetes Calico网络中,当一个数据包的目的地址不是本网络时,会先发起ARP广播,网关即169.254.1.1收到会将自己的mac地址返回给发送端,后续的请求由这个veth对 进行完成,使用代理arp做了arp欺骗。这样做抑制了arp广播攻击,并且通过代理arp也可以进行跨网络的访问。
###############
根据pod内部eth0@if7 可以得到位于物理机上的veth pair 名称为cali3c99e896108
17: cali3c99e896108@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 1inet6 fe80::ecee:eeff:feee:eeee/64 scope link valid_lft forever preferred_lft forever
  • 在node1上的pod网卡eth0抓包
[root@node1 ~]# ping 172.16.28.34
PING 172.16.28.34 (172.16.28.34) 56(84) bytes of data.
64 bytes from 172.16.28.34: icmp_seq=1 ttl=62 time=1.53 ms
64 bytes from 172.16.28.34: icmp_seq=2 ttl=62 time=0.715 ms
64 bytes from 172.16.28.34: icmp_seq=3 ttl=62 time=1.10 ms
64 bytes from 172.16.28.34: icmp_seq=4 ttl=62 time=1.09 ms
64 bytes from 172.16.28.34: icmp_seq=5 ttl=62 time=0.724 ms
64 bytes from 172.16.28.34: icmp_seq=6 ttl=62 time=0.849 ms
64 bytes from 172.16.28.34: icmp_seq=7 ttl=62 time=0.568 ms
64 bytes from 172.16.28.34: icmp_seq=8 ttl=62 time=0.893 ms
64 bytes from 172.16.28.34: icmp_seq=9 ttl=62 time=1.03 ms
^C
--- 172.16.28.34 ping statistics ---
9 packets transmitted, 9 received, 0% packet loss, time 8007ms
rtt min/avg/max/mdev = 0.568/0.945/1.532/0.269 ms
[root@node1 ~]# 网卡抓包
[root@node1 ~]# tcpdump -enp -i eth0 -w node1-pod-eth0.pcap
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
^C22 packets captured
22 packets received by filter
0 packets dropped by kernel

通过wireshark 分析包的内部结构

1:首先根据前面讲到的由于目的ip和podip不在一个网络内以及不知道目的ip的mac地址,pod首先发起广播,默认网关169.254.1.1将自己的mac返回给发起者,即对端veth pair的mac(ee:ee:ee:ee:ee:ee),后面的网络请求由这个veth pai设备进行网络应答。
在这里插入图片描述
2:icmp 报文

以下可知,icmp报文中src ip为172.16.154.16,dest ip为172.16.28.34 。src mac为76:32:89:65:0d:ee,dest mac 为ee:ee:ee:ee:ee:ee
在这里插入图片描述

  • 在node1 pod对端网卡cali抓包
[root@node1 ~]# tcpdump -enp -i cali3c99e896108 -w node-pod-cali3c99e896108.pcap
tcpdump: listening on cali3c99e896108, link-type EN10MB (Ethernet), capture size 262144 bytes
^C38 packets captured
40 packets received by filter
0 packets dropped by kernel
[root@node1 ~]# 

由于此veth pair网卡和pod内部网卡eth0报文机几乎一致,此处不做分析
在这里插入图片描述

  • 在node1 vxlan.calico抓包
[root@node1 ~]# tcpdump -enp -i vxlan.calico -w node-pod-vxlan-calico.pcap
tcpdump: listening on vxlan.calico, link-type EN10MB (Ethernet), capture size 262144 bytes
^C63 packets captured
76 packets received by filter
0 packets dropped by kernel
[root@node1 ~]# 

在这里插入图片描述
在这里插入图片描述

  • 在node1 物理机设备eth0抓包
[root@node1 ~]# tcpdump -enp -i vxlan.calico -w node1-pod-peth0.pcap
tcpdump: listening on vxlan.calico, link-type EN10MB (Ethernet), capture size 262144 bytes
^C56 packets captured
66 packets received by filter
0 packets dropped by kernel

从物理网卡上可以看到封装好的vxlan报文,在最外层封装了物理node的ip和mac
在这里插入图片描述

  • 在node3上的物理eth0网卡抓包
[root@node3 ~]# tcpdump -enp -i eth0 -w node3-pod-peth0.pcap
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
^C378 packets captured
387 packets received by filter
0 packets dropped by kernel

通过在node3上的eth0网卡抓包分析和node1上的eth0是一致的,未进行任何改变
在这里插入图片描述

  • 在node3上的vxlan.calico设备抓包
[root@node3 ~]# tcpdump -enp -i vxlan.calico -w node3-pod-vxlan-calico.pcap
tcpdump: listening on vxlan.calico, link-type EN10MB (Ethernet), capture size 262144 bytes
^C81 packets captured
81 packets received by filter
0 packets dropped by kernel

以下可知经过内核中的vxlan模块解封之后,去掉了vxlan的包头,露出原始的报文,src mac和dst mac为各自节点的vtep 设备的mac地址。
在这里插入图片描述

  • 在node3上的veth pair calixxxxx设备抓包
[root@node3 ~]# tcpdump -enp -i calic6d8dba2cdd -w node3-pod-calic6d8dba2cdd.pcap
tcpdump: listening on calic6d8dba2cdd, link-type EN10MB (Ethernet), capture size 262144 bytes
^C64 packets captured
64 packets received by filter
0 packets dropped by kernel

从vtep 设备出来之后,src 和dst mac分别换成了ee:ee:ee:ee:ee:ee和真实pod的mac地址,并最后通过veth pair设备的proxy arp 功能将网络请求发送给目标地址。
在这里插入图片描述

以上就是calico vxlan模式下,数据包的在不同主机的转发路径以及封装过程。首先需要给所有的 pod 配置一条特殊的路由,并利用 veth 的代理 ARP 功能让 pod出来的所有流量转发都变成三层路由转发,然后再利用主机的路由进行转发。这种方式不仅实现了同主机的二三层转发,也能实现跨主机转发。


http://www.mrgr.cn/p/46722417

相关文章

Python升级打怪(5)

链式调用:用一个函数的返回值作为另外一个函数参数 嵌套调用:一个函数在另一个函数定义里面&#xff0c;而调用该定义函数既可以使用在其里面的函数 在Pycharm中调试器的左下角能够看到函数之间的"调用栈" 调用栈里面描述了当前这个代码的函数之间&#xff0c;调用…

Chartist.js折线图(四)

线插值/平滑代码如下<!DOCTYPE html> <html><head><link rel="stylesheet" href="./chartist.min.css"><script src="./chartist.min.js"></script></head><body><div class="ct-chart…

Yolov5 export.py实现onnx模型的导出

查了很多资料&#xff0c;很多用python代码写的&#xff0c;只需要这个库那个库的&#xff0c;最后都没成功。 不如直接使用Yolov5里面的 export.py实现模型的转换。 一&#xff1a;安装依赖 因为yolov5里面的requirments.txt是将这些转换模型的都注释掉了 所以需要解除注释…

双屏后wocam手绘板手感奇怪

把比例一定给关掉,就舒服很多1.打开驱动面板 2.选中映射 3.取消比例一定

前端框架EXT.NET Dotnet 3.5开发的实验室信息管理系统(LIMS)成品源码 B/S架构

前端框架EXT.NET Dotnet 3.5开发的实验室信息管理系统&#xff08;LIMS&#xff09;成品源码 B/S架构 LIMS实验室管理系统 发展历史 实验室信息管理系统(LIMS)&#xff0c;就是指通过计算机网络技术对实验的各种信息进行管理的计算机软、硬件系统。也就是将计算机网络技术与现…

【Qt 专栏】文件对话框 文件的弹窗选择-QFileDialog

前言: 通过按钮实现文件弹窗选择以及关联的操作 效果图就和平时用电脑弹出的选文件对话框一样原型图 技能: 头文件: #include<QFileDialog>//头文件QString filename = QFileDialog::getOpenFileName(this, "弹窗标题", "E://","Images(*.pn…

探索MATLAB在计算机视觉与深度学习领域的实战应用

随着人工智能技术的快速发展&#xff0c;计算机视觉与深度学习已成为科技领域中最热门、最具挑战性的研究方向之一。 它们的应用范围从简单的图像处理扩展到了自动驾驶、医疗影像分析、智能监控行业等多个领域。 在这样的背景下&#xff0c;《MATLAB计算机视觉与深度学习实战…

JDK升级专题

一、JVM17与JVM8的变化 模块化系统(Project Jigsaw) 新的垃圾收集器 JDK 17 引入了 ZGC 和 Shenandoah,这两个垃圾回收器在低延迟和高吞吐量方面表现优秀,同时提高了内存管理效率。二、SpringBoot与SpringCloud版本对应关系及Spring Boot与JDK对应关系。 参考资料1、【译…

【八股】Spring Boot

SpringBoot是如何实现自动装配的&#xff1f; 首先&#xff0c;SpringBoot的核心注解SpringBootApplication里面包含了三个注解&#xff0c;SpringBootConfigurationEnableAutoConfigurationComponentScan&#xff0c;其中EnableAutoConfiguration是实现自动装配的注解&#x…

Qt Creator Pro文件添加库和源文件

在项目的pro文件所在的文件夹中添加源文件lib_header &#xff0c;entityobject 如下图所示&#xff1a; 在 pro 文件里面添加源文件的路径如下所示&#xff1a; 这个英文符号点&#xff0c;表示当前目录&#xff0c;因为这个文件是和pro文件在同一个目录下&#xff0c;所以用…

python--使用pika库操作rabbitmq实现需求

Author: wencoo Blog&#xff1a;https://wencoo.blog.csdn.net/ Date: 22/04/2024 Email: jianwen056aliyun.com Wechat&#xff1a;wencoo824 QQ&#xff1a;1419440391 Details:文章目录 目录正文 或 背景pika链接mqpika指定消费数量pika自动消费实现pika获取队列任务数量pi…

【电控笔记5.4】pwm延迟

PWM延迟 1标准采样法 Td=MCU计算延迟+输出延迟 Tcon=电流控制周期 Ts=PWM载波周期 Td=1.5Ts(6.3节 ) 电流环跟PWM采样周期同步 2修改采样法

python爬虫学习------scrapy第二部分(第三十天)

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…

压缩即智能:为什么 ChatGPT 拥有智能?(转)

源地址: 背景 随着 ChatGPT、GPT4、PaLM2、文心一言各种大模型的爆火,我们在惊讶大模型能力的同时,也在不断的问自己一个问题,为什么 Decode-only 的 ChatGPT 拥有智能? GPT 其实就是基于 Transformer 的 Decode-only,本质是就是 Next Token Prediction,为啥如此简单的结…

docker常用基本命令

把jar包和 dockerfile文件放到同一目录下#构建Docker镜像 注意后面的 . 不能省略 docker build -t your-image-name .#运行并创建一个容器 docker run -d -p 8080:8080 --name container_name your-image-name# 停止容器 767fce4cb990 容器ID (容器名也可以) docker stop 767f…

Android Studio开发工具学习之Git远程仓库拉取与推送

Git远程仓库操作 1.1 推送项目到远端服务器1.1.1 进入Gitee或Github、创建一个新的仓库1.1.2 将Android Studio中项目推送至Gitee 1.2 从远端服务器拉取项目1.2.1 AS工程页拉取新项目1.2.2 AS启动页拉取项目 1.1 推送项目到远端服务器 1.1.1 进入Gitee或Github、创建一个新的仓…

vue3推荐算法

Vue 3 推荐算法主要指的是在 Vue 3 框架中实现的或者适用于 Vue 3 的算法库或组件库。Vue 3 由于其优秀的设计和性能&#xff0c;被广泛应用于构建各种类型的应用程序&#xff0c;包括需要复杂算法支持的项目。以下是一些在 Vue 3 中可能会用到的推荐算法资源&#xff1a; Vue-…

【Network Automation系列】-- 第一章

引言: 本系列是根据《Mastering Python NetworkingThird Edition》翻译整理出来的,原著作者:Eric Chou,大家可以关注一下。 随着网络工程领域的快速变化,我们无疑也经历了类似的变化。 随着软件开发越来越多地集成到网络的各个方面、传统的命令行接口和垂直集成中,网络堆栈…

selenium--绕过网站监控操作

driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {"source": """Object.defineProperty(navigator, webdriver, {get: () => undefined})""", }) #r绕过网站对webdriver的监测