问题:今天同事安装了一套k8s环境, 结果发现calico网络互相访问不通,同台机器上的pod之间的calico ip都ping不通

分析解决:

calico支持三种网络模式,可通过修过calico.yaml进行配置:

  • overlay之ipip
  • overlay之vxlan
  • underlay之BGP

overlay — ipip

traffic flow

 

overlay — vxlan

traffic flow

underlay — BGP

traffic flow

本环境用的是CrossSubnet且都在同网段,用的是BGP

下面是node信息:

 

查看yks2上的路由:

 

可以看到, 172.23.27.0/24 via 10.16.245.47 dev ens3 proto bird 这条路由,172.23.27.0/24这个地址是直接到yks2主机上的

在yks2上ping coredns:

上主机yks2上抓包:

首先抓宿主机网卡:

可以接收到包

看下yks2的路由:

 

172.23.27.2 dev calif945d263abc scope link 是calif945d263abc网上接收的

抓calif945d263abc:

 

没有收到请求

可以看到,是宿主机网卡到calixxx网络出现了问题

查看yks2的iptables规则:

 

有条:FORWARD DROP [0:0]规则

可以从对应版本的docker源码中找到线索

通过源码可以看出来,当内核参数 net.ipv4.ip_forward 的值不为1时,docker daemon会默认把iptables的filter表的FORWARD链默认设置为DROP。

解决方法

1. 外围的解决方法

我们自己可以在外围这么修改systemd的service脚本

 

 

其实主要是加最后那句 ExecStartPost=/usr/sbin/iptables -P FORWARD ACCEPT

2. 推荐的解决方法

先设置如下两个关键的内核参数并让其生效:


 

之后再安装docker,然后启动即可。这里的关键是,安装或者首次启动docker前,linux操作系统需要设置内核参数 net.ipv4.ip_forward = 1 才可以。

 

附:calico组网的原理如下:

Calico 是一个纯三层的数据中心网络方案,而且无缝集成像 OpenStack 这种 Iaas 云架构,能够提供可控的 VM、容器、裸机之间的 IP 通信。为什么说它是纯三层呢?因为所有的数据包都是通过路由的形式找到对应的主机和容器的,然后通过 BGP 协议来将所有路由同步到所有的机器或数据中心,从而完成整个网络的互联。

简单来说,Calico 在主机上创建了一堆的 veth pair,其中一端在主机上,另一端在容器的网络命名空间里,然后在容器和主机中分别设置几条路由,来完成网络的互联。

任意选择 k8s 集群中的一个节点作为实验节点,进入容器 A,查看容器 A 的 IP 地址:

这里容器获取的是 /32 位主机地址,表示将容器 A 作为一个单点的局域网。

容器A的路由:

从路由表可以知道 169.254.1.1 是容器的默认网关,当一个数据包的目的地址不是本机时,就会查询路由表,从路由表中查到网关后,它首先会通过 ARP 获得网关的 MAC 地址,然后在发出的网络数据包中将目标 MAC 改为网关的 MAC,而网关的 IP 地址不会出现在任何网络包头中。也就是说,没有人在乎这个 IP 地址究竟是什么,只要能找到对应的 MAC 地址,能响应 ARP 就行了。可以通过 ip neigh 命令查看一下本地的 ARP 缓存:

这个 MAC 地址应该是 Calico 硬塞进去的,而且还能响应 ARP。但它究竟是怎么实现的呢?

我们先来回想一下正常情况,内核会对外发送 ARP 请求,询问整个二层网络中谁拥有 169.254.1.1 这个 IP 地址,拥有这个 IP 地址的设备会将自己的 MAC
地址返回给对方。但现在的情况比较尴尬,容器和主机都没有这个 IP 地址,甚至连主机上的端口 calicba2f87f6bb,MAC 地址也是一个无用的 ee:ee:ee:ee:ee:ee。按道理容器和主机网络根本就无法通信才对呀!所以 Calico 是怎么做到的呢?实际上Calico 利用了网卡的代理 ARP 功能。代理 ARP 是 ARP 协议的一个变种,当 ARP 请求目标跨网段时,网关设备收到此 ARP 请求,会用自己的 MAC 地址返回给请求者,这便是代理 ARP(Proxy ARP)

1。Calico 通过一个巧妙的方法将 workload 的所有流量引导到一个特殊的网关 169.254.1.1,从而引流到主机的 calixxx 网络设备上,最终将二三层流量全部转换成三层流量来转发。
2。在主机上通过开启代理 ARP 功能来实现 ARP 应答,使得 ARP 广播被抑制在主机上,抑制了广播风暴,也不会有 ARP 表膨胀的问题。

 

参考:https://icloudnative.io/posts/poke-calicos-lies/

https://singhwang.github.io/2019/10/02/docker_trouble_shooting_001/

https://blog.csdn.net/fengcai_ke/article/details/125716634

Categories: NETWORK

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *