ljzsdut
GitHubToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

3 Calico IP Ip模式深入分析

转载声明:

https://blog.csdn.net/u010771890/article/details/103224004

IPIP模式简介

Calico中的IP Pool可以使用两种模式:BGP或者IPIP。本文使用的是IPIP模式,是一种将各Node的路由之间做一个tunnel,再把网络连接起来的模式:

image.png

从字面上说,就是将一个IP数据包套在另一个IP包里,使用到了Linux提供的隧道技术。可以理解为一个基于IP层的网桥,将两个本不通的网络通过点对点连接起来。

IPIP是一种将各Node的路由之间做一个tunnel,再把两个网络连接起来的模式,启用IPIP模式时,Calico将在各Node上创建一个名为"tunl0"的虚拟网络接口。

K8s-Calico-IPIP网络实战分析

下面我们就进行基于Calico-IPIP模式下的K8s容器互联网络分析。

实验准备

准备了1个master 2个slaver的K8s集群,设置为Calico-IPIP网络。每个slaver内(node1,node2)分别部署了一个Pod容器,结构示意图如下:

image.png

网络结构解析

pod网络

首先通过指令kubectl exec -it pod1 /bin/bash进入pod1容器中,再使用指令 ip addr 查看pod1内的网络设备。

ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
4: eth0@if26: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc noqueue state UP group default 
    link/ether ce:83:2b:89:af:9e brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.100.15.150/32 scope global eth0
       valid_lft forever preferred_lft forever

可以看到,pod只有普通的loopback和eth0。

node网络

先查看node网络设备。

ip addr
...省略部分
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:16:3e:02:03:5c brd ff:ff:ff:ff:ff:ff
    inet 172.31.112.2/20 brd 172.31.127.255 scope global dynamic eth0
       valid_lft 311927346sec preferred_lft 311927346sec
4: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1440 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
    inet 10.100.15.128/32 brd 10.100.15.128 scope global tunl0
       valid_lft forever preferred_lft forever
26: cali3ef8aad4b4e@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc noqueue state UP group default 
    link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 1

node中除了eth0外,多了tunl0和cali3ef8aad4b4e(下面简称为cali.4e),结合之前的Calico简介,大家肯定可以猜到,tunl0就是Calico在IPIP模式下的隧道名称 ,而cali.4e是啥子类,注意到,该设备的编号为26。让我们回到pod1中,查看pod1内的ip link:

$ip link show eth0
4: eth0@if26: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc noqueue state UP mode DEFAULT group default 
    link/ether ce:83:2b:89:af:9e brd ff:ff:ff:ff:ff:ff link-netnsid 0

eth0@if26,这里eth0连接的设备号也是26!其实这个设备就是veth pair,K8s在创建Pod的时候,会创建一个veth pair设备。设备的一端是pod2的网卡,另一端就是我们在node中看见的cali.4e了。是不是清楚了很多☺node2与之类似。

下面我们将node节点的route规则也贴上,后面会用到。

# node1
route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.31.127.253  0.0.0.0         UG    0      0        0 eth0
10.100.6.128    172.31.112.1    255.255.255.192 UG    0      0        0 tunl0
10.100.9.192    172.31.127.252  255.255.255.192 UG    0      0        0 tunl0
10.100.15.128   0.0.0.0         255.255.255.192 U     0      0        0 *
10.100.15.129   0.0.0.0         255.255.255.255 UH    0      0        0 cali386c6dca3ac
10.100.15.150   0.0.0.0         255.255.255.255 UH    0      0        0 cali3ef8aad4b4e
169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
172.31.112.0    0.0.0.0         255.255.240.0   U     0      0        0 eth0
# node2
route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.31.127.253  0.0.0.0         UG    0      0        0 eth0
10.100.6.128    172.31.112.1    255.255.255.192 UG    0      0        0 tunl0
10.100.9.192    0.0.0.0         255.255.255.192 U     0      0        0 *
10.100.9.193    0.0.0.0         255.255.255.255 UH    0      0        0 cali4360a48538f
10.100.9.206    0.0.0.0         255.255.255.255 UH    0      0        0 cali2d771657bc2
10.100.9.207    0.0.0.0         255.255.255.255 UH    0      0        0 cali7116f2b12fa
10.100.15.128   172.31.112.2    255.255.255.192 UG    0      0        0 tunl0
169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
172.31.112.0    0.0.0.0         255.255.240.0   U     0      0        0 eth0

网络结构小结

根据上节的信息,绘出当前实验网络的主要设备图。后面将进行网络连接实战。

YoTQ0b-1619161688523

网络流量实战

node间访问

很容易的,我们先猜测一个从pod2发往pod1的ip数据流向。 image.png

下面让我们一起来验证我们的猜测吧!使用的工具就是tcpdump啦~

分别在两个node的Cali.c2、tunl0、eth0出进行抓包分析,结果如下图所示,其中Cali.c2与tunl0的ip完全一致,因此合并输出。 image.png

按照标志的①、②、③、④来依次分析:

①:上节已经说了,pod2中的eth0(即图中的vthe0)与Cali.c2是一对veth pair,因此,Cali.c2接收到的ip流向一定与vthe0相同,为 10.100.9.206->10.100.15.150。

查看之前的node2 route表,发现有一条 :

 Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.100.15.128   172.31.112.2    255.255.255.192  UG    0      0        0 tunl0

所有发往10.100.15.128/255.255.255.192(26位掩码)的ip报都需要通过tunl0,经过172.31.112.2作为gateway发送。因此,cali.c2的ip报会发往tunl0。

流量到达tunl0接口后,接口会做什么操作呢?

②:经过tunl0的ip报会被再封上一层ip,将IP包封装为宿主机IP包。

因此我们在eth0处的抓包结果为 IP 172.31.127.252 > 172.31.112.2: IP 10.100.9.206 > 10.100.15.150

在tunl0接口上对IP层封完包后,通过node2 的route规则,目的IP为172.31.112.2的报文会匹配如下规则,会发往eth0接口(172.31.127.252)链路层,达到eth0后进入链路层进行链路层封包,源MAC为eth0(172.31.127.252)的MAC地址,目标MAC为172.31.112.2的对应的MAC地址。链路层封包结束之后,流量从eth0网卡设备(物理层)发出。

# scope link 条目
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
172.31.112.0    0.0.0.0         255.255.240.0   U     0      0        0 eth0

可以使用如下命令进行IPIP报文的抓取:

原理:指定内层的iP地址。参考:https://blog.csdn.net/leeshuheng/article/details/7729514

示例:pod1(10.42.23.229) –> pod2(10.42.23.186)

tcpdump -nn -e -i eth0 “ip proto 4 and ( (ip[20+12:1]=10 and ip[20+13:1]=42 and ip[20+14:1]=23 and ip[20+15:1]=186) or (ip[20+16:1]=10 and ip[20+17:1]=42 and ip[20+18:1]=23 and ip[20+19:1]=229) )”

15:48:57.724473 IP 64.115.5.224 > 64.115.5.225: IP 10.42.23.229 > 10.42.23.186: ICMP echo request, id 59502, seq 0, length 64 (ipip-proto-4)

③、④:三和四其实就是①、②的逆过程,检查node1的route表即可知道流向。etho0将ipip拆封后,将流量发给tunl0,tunl0再转发给cali.4e。

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.100.15.150   0.0.0.0         255.255.255.255 UH    0      0        0 cali3ef8aad4b4e

node内访问

如果是同一个node内的两个pod进行访问,那么还会走tunl0进行ipip封装吗?

其实很容易回答这个问题,通过上节的route规则就可以知道,Calico会为每一个node分配一小段网络,同时会Wie每个pod创建一个“入”的ip route规则。如下图所示,当从pod2访问pod3时,Cali.c2是直接发出10.100.9.206-> 10.100.9.207流量的,在node2的ip route中,发往10.100.9.207的ip报直接会被转发到cali.fa,不会用到tunl0,只有在node间访问的时候才会使用tunl0进行ipip封装!

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.100.9.207    0.0.0.0         255.255.255.255 UH    0      0        0 cali7116f2b12fa

FZae31-1619161926171

总结

  • IPIP模式下,node间的Pod访问会使用IPIP技术对出node的ip报进行隧道封装
  • node内的Pod访问不会用到ipip隧道封装。
  • Pod的ip都是由calico-node设置的IP地址池进行分配的,docker0对kubernetes设置的Pod的IP地址将不再起作用。