总结:这是一个专门定制的三层网络解决方案,主要用于解决容器跨主机通信问题。 接收到的数据包被转发到进程。 查询路由表,解封装数据包,并将数据包发送至 。 在这种情况下,网络层源和目的地是容器和虚拟的。 容器网络解决方案也是默认使用的,并且在其官网上有明确说明。
简介
我们知道Docker并没有正式提供多主机容器通信解决方案。 主要的独立网络模式包括host、container、bridge、none。 none模式,顾名思义,就是docker本身不管理网络模式,交给其他人来管理和分发,比如cni。 Flannel 是为 Kubernetes 定制的三层网络解决方案。 这主要用于解决容器跨主机通信问题。
首先,flannel 使用 Kubernetes API 或 etcd 来存储集群范围的网络配置。 最重要的部分是配置集群的网络地址空间。 例如,将集群中所有容器的IP地址设置为来自10.1.0.0/16网段。
然后,Flannel 在每台主机上作为代理运行 flanneld。 主机从集群的网络地址空间中获取一个小网段子网,主机内的所有容器都从该子网中分配IP地址。 然后,Flanneld 存储该主机获得的子网以及用于主机到主机通信的公共 IP,同样通过 kubernetes API 或 etcd。
最后,flannel使用udp、vxlan、host-gw等各种后端来转发主机之间容器之间的网络流量,完成容器之间的跨主机通信。
Flannel网络实现原理
Flannel为每个主机提供独立的子网,集群范围的网络信息存储在etcd中。 对于跨主机转发,必须从etcd获取目标容器的IP地址。
上图比较直观:
步骤:
IP数据报被封装并通过容器的eth0发送。
Container1的eth0通过veth对与Docker0通信,并向Docker0发送数据包。 然后 Docker0 传输该包。
Docker0通过查询外部容器的本地路由表确定Container3的IP地址,并将数据包发送到虚拟网卡Flannel0。
Flannel0收到的数据包被转发到Flanneld进程。 Flaneld进程通过查询etcd维护的路由表来封装数据包,并通过主机的eth0发送数据包。
数据包标识网络内的目标主机。
目的主机上的Flanneld进程监听8285端口并解封装数据包。
解封装的数据包被转发到虚拟NICFlannel0。
Flannel0查询路由表,解封装数据包,并将数据包发送到Docker0。
Docker0确定目标容器,并将包发送到目标容器。
常用的vxlan模式,涉及到上述步骤中的打包和拆包,导致Flannel网络的传输效率较低。
下面重点介绍host-gw模式。
Hostgw 是最简单的后端。 原理很简单。 直接添加路由,以目的主机作为网关,直接路由原始数据包。
例如,监听来自 etcd 的 EventAdded 事件。 子网为10.1.15.0/24,分配给主机的公共IP 192.168.0.100。 hostgw 必须做的工作是在该主机上添加一个目标地址 10.1.15.0/ 的条目。 24、网关地址为192.168.0.100,输出设备为上面选择的用于集群间交互的网卡。 对于EventRemoved事件,只需删除相应的路由即可。
host-gw 的性能最好,因为没有打包和拆包。
但是,host-gw 需要主机网络的直接第 2 层互连。 因此,每个节点有n-1条路由,n个节点总共有n(n-1)/2条路由,保证flannel扁平网络功能。
为什么host-gw要求主机网络直连二层
一、通过抓包分析下面是抓包结果:
您可以看到主机-gw正在使用tcp。 传输层。 在这种情况下,网络层源IP和目标IP都是容器的IP和虚拟IP。 只是交换机不关注源IP和目的IP,这决定了第二层互连。 如果您在两个 LAN 中有两台主机,并且第 2 层被阻止但第 3 层已连接,则您将需要一个路由器,但路由器将无法看到容器的 IP 地址。 当然,您也可以配置路由规则,但显然没有这样做。
Openshift也默认使用Flannel host-gw容器网络方案,其官网也清晰地描绘了host-gw数据流图。
示例配置和启动参数
示例配置:
{ "Network": "10.0 .0.0/8”,“SubnetLen”:20,“SubnetMin”:“10.10.0.0”,“SubnetMax”:“10.99.0.0”,“后端”:{“类型”:“udp”,“端口”:7890 }}
启动参数:
--public-ip="":来自inter[k4中的其他节点[可访问IP]主机通信。 默认为 t用于通信的接口IP。 --etcd-endpoints=http://127.0.0.1:4001:逗号 - 分隔的 etcd 端点列表。 --etcd -prefix=/coreos.com/network:etcd 前缀。--etcd-keyfile="":用于保护 etcd 通信的 SSL 密钥文件。 --etcd-certfile ="":用于保护 etcd 通信的 SSL 证书文件。 --etcd-cafile="":用于保护 etcd 通信的 SSL 证书颁发机构文件。 --kube-subnet[ k4]mgr:代表 etcd 查询 Kubernetes API 以进行子网分配。 --iface="": -用于主机到主机通信的接口(IP 或名称)。 默认是您机器上的默认路由接口。 您可以多次指定此项以依次检查每个选项。 返回找到的第一个匹配项。 --]iface-regex="": -与用于主机到主机通信的第一个接口(IP 或名称)匹配的正则表达式。 如果不指定,则默认为机器上默认路由的接口。 您可以多次指定此项以依次检查每个正则表达式。 返回找到的第一个匹配项。 此选项替换 iface 选项,并且仅当 iface 选项中指定的选项不匹配时才使用。 --iptables-resync=5:iptables 规则的重新同步周期(以秒为单位)。 默认值为 5 秒,但如果您遇到 iptables 锁争用增加的情况,这可能会有所帮助。 --subnet-file=/ run/flannel/subnet.env: 文件名,其中 env 变量(子网)--subnet-lease-renew-margin=60:子网续租保证金(以分钟为单位)。 --ip-masq=false:为发往 flannel 网络外部的流量配置 IP 伪装。 Flannel 假定 NAT POSTROUTING 链的默认策略是 ACCEPT。 - v=0:V日志的日志级别。 设置为 1 以显示与数据路径相关的消息。 --healthz-ip="0.0.0.0":要监听的healthz服务器的IP地址(默认为“0.0.0.0”)--healthz-port=0:healthz server 监听的端口(0为禁用)--version:打印版本并退出
总结
接下来代码实现部分重点。
评论前必须登录!
注册