注:本文基于Calico v3.20.1版本编写

1 关于Calico

flannel是overlay网络, 主要工作在L2(VXLAN),calico主要是L3,通过BGP路由协议在机器之间传送报文。

2 安装Calico(IPIP模式)

因为之前有安装flannel,因此需要先删除,

kubectl delete -f kube-flannel.yml

同时需要删除flannel.1和cni0这两个网络设备,

ip link delete cni0
ip link delete flannel.1

之后就可以根据官网安装了,

curl https://docs.projectcalico.org/manifests/calico.yaml -O
kubectl apply -f calico.yaml

是的,就是这么简单,然后就可以在机器上看到新生成的网络设备,

cali00dc074ce54: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1480
...
tunl0: flags=193<UP,RUNNING,NOARP>  mtu 1480

因为默认情况下,calico使用的是ipip隧道模式,这一点我们可以从calico的日志里看出,

2021-10-02 05:04:26.657 [INFO][9] startup/startup.go 651: CALICO_IPV4POOL_NAT_OUTGOING is true (defaulted) through environment variable
2021-10-02 05:04:26.657 [INFO][9] startup/startup.go 992: Ensure default IPv4 pool is created. IPIP mode: Always, VXLAN mode: Never
2021-10-02 05:04:26.718 [INFO][9] startup/startup.go 1002: Created default IPv4 pool (10.244.0.0/16) with NAT outgoing true. IPIP mode: Always, VXLAN mode: Never

所以多了一个tunl0设备,

[root@master home]# ip -d link show tunl0
9: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1link/ipip 0.0.0.0 brd 0.0.0.0 promiscuity 0 ipip ...

与此同时,host上也多了两条通往node的路由记录,

[root@master calico]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.0.1     0.0.0.0         UG    0      0        0 ens33
10.244.104.0    192.168.0.112   255.255.255.192 UG    0      0        0 tunl0
10.244.166.128  192.168.0.111   255.255.255.192 UG    0      0        0 tunl0
...

3 Calico ipip模式工作原理

所谓ipip,也就是IP in IP,即在IP报文的基础上,又封装了一个IP头,和overlay网络相似。

我们以两个node上的两个容器为例,说一下报文的流动过程。

报文从Pod A发出,根据路由发往容器中的网关169.254.1.1,

[root@centos-bc2sm /]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         169.254.1.1     0.0.0.0         UG    0      0        0 eth0
169.254.1.1     0.0.0.0         255.255.255.255 UH    0      0        0 eth0

但是你会发现,host上并没有这设备,这就是calico独特之处。那报文到底是如何发送出去的呢?

我们先看下网关通向的二层地址,即mac地址,

[root@centos-bc2sm /]# arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
169.254.1.1              ether   ee:ee:ee:ee:ee:ee   C                     eth0

可以看到,容器中网关的arp地址是ee:ee:ee:ee:ee:ee,所以现在的问题就变成,哪个网卡的mac地址是这个。

我们在host上查看所有网卡,会发现,cali的所有网卡的mac地址都是ee:ee:ee:ee:ee:ee

[root@node2 ~]# ifconfig | grep -E "flags|ether"
cali0a4fde325ea: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1480ether ee:ee:ee:ee:ee:ee  txqueuelen 0  (Ethernet)
cali43af9e40d9b: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1480ether ee:ee:ee:ee:ee:ee  txqueuelen 0  (Ethernet)
cali61a9554ce92: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1480
...

另外,我们知道容器中的网卡用的是veth的pair虚拟网卡,一端连接到容器,另一端连着宿主机。所以我们需要查看下容器里网卡编号,

[root@centos-bc2sm /]# ethtool -S eth0
NIC statistics:peer_ifindex: 14

然后host中编号为14的即为另一端,

[root@node2 ~]# ip link show
...
14: cali0a4fde325ea@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP mode DEFAULT link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 4

因此,容器中的报文就通过cali0a4fde325ea到达宿主机。

然后根据宿主机的路由,报文发往tunl0

10.244.166.128  192.168.0.111   255.255.255.192 UG    0      0        0 tunl0

报文到达tunl0时,会再次封装一层ip报文头,把目标node的ip作为目的ip,然后通过ens33将报文发出。

对端node收到报文后,解开外层ip报文头,发现是ipip报文,会转交给tunl0, tunl0把内层ip报文头解开,查找路由,就发送给cali7dadcb96356,

10.244.166.140  0.0.0.0         255.255.255.255 UH    0      0        0 cali7dadcb96356

而这个cali7dadcb96356正是目标容器的veth pair网络设备的另一端。

[root@node1 ~]# ip link show cali7dadcb96356
14: cali7dadcb96356@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP mode DEFAULT link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 0[root@centos-t854j /]# ethtool -S eth0
NIC statistics:peer_ifindex: 14

最终报文到达目标pod。

对于封装后的报文,我们可以通过tcpcump看下报文信息,
而对于同个node的情况,就不需要经过tunl0设备了,因为报文到达host上时,直接根据路由规则就可以转发到对应的cali设备。

4 几个疑问

4.1 容器内网关为169.254.1.1,为什么报文会到宿主机cali网络设备

我们通过arp命令查询mac缓存是逆推而来,而实际上,在发送报文时,会先通过arp广播报文,查询网关的mac地址,由于cali网络设备都开启了arp代理,因此在接收到arp请求时,就会响应该请求,把自己的mac地址回复给ARP广播请求发送者,这样报文就会发往该cali网络设备,同时也就有了这条arp缓存记录。

[root@node2 ~]# cat /proc/sys/net/ipv4/conf/cali0a4fde325ea/proxy_arp
1

所以,理论上容器内的网关设置为什么并不重要,最终由于arp代理,报文到会发送到宿主机的cali设备上。

4.2 为什么cali网络设备mac地址都为ee:ee:ee:ee:ee:ee

因为有一些系统无法在启动时给网络设备分配好mac地址,并且cali的mac地址并不会在实际的链路层报文中使用,因此calico将所有cali网络设备的mac地址都设置为全e,便于管理。

4.3 calico的cali网络设备和flannel的docker0网桥设备有和不同

flannel中所有容器都连接到docker0上,意味着所有容器都可以互通。而对于cali网络设备,每个容器连接到不同的host cali设备中,就能通过网络策略规则实现容器间的隔离,这就为多租户的场景提供了可能。

4.4 每个host是如何获取其他host的路由信息

这是通过BGP协议获取的,calico会在每个host上运行felix和bird进程,

[root@node2 ~]# ps aux | grep -iE "felix|bird"
root       4204  0.0  0.0   4236   400 ?        Ss   Oct08   0:00 runsv felix
root       4207  0.0  0.0   4236   400 ?        Ss   Oct08   0:00 runsv bird
root       4208  0.0  0.0   4236   400 ?        Ss   Oct08   0:00 runsv bird6
root       4213  4.7  2.4 1510880 45552 ?       Sl   Oct08 105:50 calico-node -felix
root       4412  0.0  0.0   1712   516 ?        S    Oct08   1:45 bird6 -R -s /var/run/calico/bird6.ctl -d -c /etc/calico/confd/config/bird6.cfg
root       4414  0.0  0.0   1828   780 ?        S    Oct08   1:51 bird -R -s /var/run/calico/bird.ctl -d -c /etc/calico/confd/config/bird.cfg

其中,felix进程负责监听etcd事件,获取路由、ARP 管理、ACL 管理和同步、状态上报等;而bird进程则负责把felix注入的路由信息通过BGP协议发送给其他机器,这样整个集群中都能获取到相关node的路由信息。


参考资料:

  1. https://docs.projectcalico.org/getting-started/kubernetes/self-managed-onprem/onpremises
  2. https://docs.projectcalico.org/reference/faq
  3. https://docs.projectcalico.org/reference/architecture/overview

K8S Calico网络插件之IPIP模式相关推荐

  1. K8S Calico网络插件

  2. 企业运维实战--k8s学习笔记 k8s网络通信、Flannel vxlan模式简介、calico网络插件替换、网络策略范例总结

    1.k8s网络通信 k8s通过CNI接口接入其他插件来实现网络通讯.目前比较流行的插件有flannel,calico等. CNI插件存放位置:# cat /etc/cni/net.d/10-flann ...

  3. k8s网络基础学习-Calico网络插件

    第十课 k8s网络基础学习-Calico网络插件 tags: k8s网络 calico proxy arp bgp full mesh bgp RR 文章目录 第十课 k8s网络基础学习-Calico ...

  4. Kubernetes(k8s)集群部署七、k8s网络通信+service扩展ingress(TLS,认证,地址重写)calico网络插件(允许指定pod访问服务,禁止其他namespace访问服务)

    k8s网络通信 k8s网络通信 1.容器间通信 2.pod之间的通信 2.1同一节点的pod 2.2不同节点的pod之间的通信 flannel网络原理 flannel支持多种后端: 3.pod和ser ...

  5. 安装calico网络插件后K8s集群节点间通信找不到主机路由(no route to host)

    安装calico网络插件后K8s集群节点间通信找不到主机路由(no route to host) 背景:k8s安装calico网络插件后master节点ping不通其它node节点,但可以ping通外 ...

  6. 第二篇:kubernetes部署calico网络插件

    说明: 总的目标是在k8s集群部署gitlab.jenkins,并且在本地提交代码到gitlab后jenkin流水线可以自动编译打包成为docker镜像然后部署到k8s中并实现客户端外部域名访问,在文 ...

  7. 解析 | K8S之网络插件exec

    K8S支持3种类型的网络插件. 今天继续介绍下另一种插件exec K8S网络插件支持exec.CNI.kubenet 3种类型.插件满足K8S网络插件接口即可. type NetworkPlugin ...

  8. k8s的网络插件kube-flannel.yml

    k8s的网络插件kube-flannel.yml 文件下载地址如下: 链接:https://pan.baidu.com/s/1DznYEH4tzfAfgBB3axX-6A 提取码:ZgLt 复制这段内 ...

  9. kubernetes系列之二十:Kubernetes Calico网络插件

    一.前言 Calico作为Kubernetes的CNI插件可以支持underlay和overlay模式的网络互联:在BGP信息的交互方式上也同时支持中心服务方式和grid mesh方式:但是Calic ...

最新文章

  1. JavaScript正则表达式test的用法
  2. 将DataTable中的数据一次性提交到数据库中
  3. 马斯克确诊新冠后续:已从低烧、感冒症状中完全恢复
  4. 查看sqlserver 2008中性能低下的语句
  5. 虚拟机ubuntu系统硬盘扩容
  6. mysql 存储过程:提供查询语句并返回查询执行影响的行数
  7. 【狂神说Redis】2Redis入门 2-3测试性能
  8. 软考系统分析师考试大纲
  9. 43张图详解计算机网络,看这一篇就够了
  10. DM642的PCI驱动编程笔记:缺页中断问题阐述以及与改变中断级相关的内核函数
  11. SPARC Learn Note
  12. 使用信锐无线控制器对接营运商portal服务器的原理分析与排错
  13. 【C语言】街区最短路径问题解题思路
  14. 对抗样本生成算法复现代码解析:FGSM和DeepFool
  15. 日本要把123万吨核污水排入太平洋,核威胁距离我们有多远?
  16. 【自动驾驶】基于面部Fatigue检测的技术报告
  17. 6.easyui+ztree案例:zTree树
  18. 深入探索Linux虚拟化KVM-Qemu分析之CPU虚拟化
  19. Vuforia+Unity AR项目开发测试
  20. win10多合一原版系统_win10简体中文64位16299.15多合一版本

热门文章

  1. 教你批量分析顺丰快递物流,并验证信息是否正确
  2. 腾讯校招笔试题之纸牌游戏
  3. 计算机辅助绘图中级,计算机辅助设计CAD绘图员(中级)技能鉴定③评分标准
  4. 最高16% ,微信首批付费阅读公众号分析
  5. 继承2019.06.13
  6. 小米10开始抓取日志怎么关闭_小米10手机降价,原因原来在这里
  7. 主成分分析——PCA降维Python实现及碎石图
  8. 防抖节流理解与应用场景
  9. 新零售--店铺选址问题
  10. 数据结构与算法——24. 树的应用:表达式解析树