Flannel CNI初探 电脑版发表于:2022/11/29 11:41  ># Flannel CNI初探 [TOC] ## Flannel 简介 tn2>Flannel是由CoreOs提出的跨主通信容器网络解决方案,通过分配和管理全局唯一容器IP以及实现跨组网络转发的方式,构建基于Overlay Network的容器通信网络。作为最早出现的网络编排方案,Flannel是最简单的集群编排方案之一,为容器跨节点通信提供了多种网络连接方式,后续很多插件的方案也是基于Flannel的方案进行扩展。 ## Flannel 安装 tn2>Flannel的安装非常的简单。 ```bash kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml ``` tn2>但是需要注意的是:如果您使用自定义podCID(而不是`10.244.0.0/16`),请在下载该文件后修改为自己Pod的网段然后再执行。 tn>我们知道Kubernetes在创建的Pod的时候,会通过CNI为Pod添加网络(如下图所示)。Flannel也不例外,在配置清单中使用了`flannel`插件以及`portmap`插件,关于`net-conf.json`主要是配置Pod的网络地址和Flannel的处理包采取什么样的网络类型(Flannel模式是使用的Vxlan)。   tn2>关于相关的插件是通过DaemonSet部署挂载卷的方式放到`/opt/cni/bin`目录下的。  tn2>还有就是关于特权模式的使用,Flannel默认是关闭的,并且有`Net_admin`和`net_raw`的权限进行网络管理。  tn2>关于运行Flannel的时候,可以通过修改里面的相关命令来进行实现。举例:如果有多网卡的环境情况下,我们可以通过`--iface`来指定使用的网卡名称。 更多设置`net-conf.json`以及命令参数请参考:https://github.com/flannel-io/flannel/blob/master/Documentation/configuration.md  ## Flannel后端支持 tn2>关于Flannel有如下几个后端网络模式的支持:Vxlan、IPIP、host-gw、UDP。 其中Vxlan模式是官方比较推荐的,当主机的内核比较落后可使用UDP模式来进行替代。 Vxlan和IPIP模式在进行封包的时候是通过IPIP的模式进行封包的。 >### Vxlan 模式 tn2>Vxlan虽然是Flannel的默认模式,它也有其他的参数可以在`net-conf.json`配置中的`Backend`下进行设置。 | 参数名 | 描述 | | ------------ | ------------ | | `Type` | `vxlan` | | `VNI` | Vxlan的VNI数值默认为1,在Windows上默认是4096.(虚拟网络的标识) | | `Port` | 用于发送封装数据包的UDP端口。在Linux上,默认为内核默认值,当前为8472,但在Windows上,默认值必须为4789。 | | `GBP` | 启用基于VXLAN组的策略。默认为false。Windows不支持GBP | | `DirectRouting` | 当主机位于同一子网上时,启用直接路由(如主机gw)。VXLAN将仅用于将数据包封装到不同子网上的主机。默认为false。Windows不支持DirectRouting。 | | `MacPrefix` | 仅在Windows上使用,设置为MAC前缀。默认为0E-2A。 | tn>win不用管了。 >### host-gw 模式 tn2>使用`host-gw`通过远程计算机IP创建到子网的IP路由。 需要运行Flannel的主机之间的直接第2层连接。 host-gw提供了良好的性能,几乎没有依赖性,并且易于设置。 | 参数名 | 描述 | | ------------ | ------------ | | `Type` | `host-gw` | >### UDP 模式 tn2>当内核版本比较低,不支持Vxlan和host-gw模式的时候,可以使用UDP模式。 首先Pod通过用户进程发送ping请求,到网络协议栈然后检测到从veth0中出去到主机网络名称空间中,然后进入内核网络协议栈; 通过规程我们判断出它需要到Flanneld进程中处理一下,所以内核协议栈开放了tun0发送到用户态的Flanneld中进行封处理,然后再丢给内核网络协议栈中从eth0转出去。接收时反之。 它的路线如下图所示:  | 参数名 | 描述 | | ------------ | ------------ | | `Type` | `udp` | | `Port` | 用于发送封装数据包的UDP端口。默认值为`8285`。 | >### IPIP 模式 tn2>IPIP类型的隧道是最简单的一种。它的开销最低,但只能封装IPv4单播流量,因此您将无法设置OSPF、RIP或任何其他基于多播的协议。 | 参数名 | 描述 | | ------------ | ------------ | | `Type` | `ipip` | | `DirectRouting` | 当主机位于同一子网上时,启用直接路由(如主机gw)。IPIP将仅用于将数据包封装到不同子网上的主机。默认为false。| tn2>注意,可能存在两个ipip隧道设备tunl0和`flannel.ipip`。 tunl0是由modprobe ipip模块上的ipip内核模块根据网络名称空间自动创建的。它是具有属性`local=any`和`remote=any`的命名空间默认IPIP设备。当接收到IPIP协议包时,如果内核找不到本地或远程属性与src/dst ip地址更精确匹配的选项,内核会将其转发到tunl0作为备用设备。`flannel.ipip`由flannel创建,以实现一对多ipip网络。 >### WireGuard模式 tn2>在内核中使用WireGuard来封装和加密数据包。 | 参数名 | 描述 | | ------------ | ------------ | | `Type` | `wireguard` | | `PSK` | 可选择的要使用的预共享密钥。使用`wg genpsk`生成密钥。 | | `ListenPort` | 可选择的要侦听的udp端口。默认值为`51820`。 | | `ListenPortV6` | 要侦听ipv6的udp端口。默认值为`51821`。 | | `Mode` | `separate`-为ipv4和ipv6使用单独的有线保护隧道(默认)<br/>`auto`-两个地址系列的单一有线保护隧道;自动确定首选对等地址<br/>`ipv4`-两个地址系列的单一有线保护隧道;对对等地址使用ipv4<br/>`ipv6`-两个地址系列的单一有线保护隧道;对对等地址使用ipv6 | | `PersistentKeepaliveInterval` | 默认值为0(禁用)。 | tn2>如果在将私钥写入`/run/france/wgkey`之前未生成私钥。您可以使用环境`WIREGUARD_KEY_FILE`更改此路径。 接口的静态名称是`flannel-wg`和`flannel-wg-v6`。像`wg show`这样的WireGuard工具可以用来调试接口和对等端。 内核小于5.6的用户需要安装额外的Wireguard包,请访问:https://www.wireguard.com/install/ 。 >### 防火墙 tn2>当使用udp后端时,Flannel使用udp端口8285发送封装的数据包。 当使用vxlan后端时,内核使用UDP端口8472发送封装的数据包。 确保您的防火墙规则允许所有参与覆盖网络的主机使用此流量。 确保您的防火墙规则允许来自pod网络cidr的流量访问您的kubernetes主节点。