前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >K8S学习笔记之Flannel解读

K8S学习笔记之Flannel解读

作者头像
Jetpropelledsnake21
发布2019-03-15 10:45:13
7960
发布2019-03-15 10:45:13
举报
文章被收录于专栏:JetpropelledSnakeJetpropelledSnake

0x00 概述

我们知道docker官方并没有提供多主机的容器通信方案,单机网络的模式主要有host,container,brige,none。none这种模式,顾名思义就是docker本身不去管理网络模式,交由其他管理和分配,比如cni。Flannel是一个专为kubernetes定制的三层网络解决方案,主要用于解决容器的跨主机通信问题。

首先,flannel利用Kubernetes API或者etcd用于存储整个集群的网络配置,其中最主要的内容为设置集群的网络地址空间。例如,设定整个集群内所有容器的IP都取自网段“10.1.0.0/16”。 接着,flannel在每个主机中运行flanneld作为agent,它会为所在主机从集群的网络地址空间中,获取一个小的网段subnet,本主机内所有容器的IP地址都将从中分配。 然后,flanneld再将本主机获取的subnet以及用于主机间通信的Public IP,同样通过kubernetes API或者etcd存储起来。 最后,flannel利用各种backend ,例如udp,vxlan,host-gw等等,跨主机转发容器间的网络流量,完成容器间的跨主机通信。

0x01 Flannel实现原理

Flannel为每个主机提供独立的子网,整个集群的网络信息存储在etcd上。对于跨主机的转发,目标容器的IP地址,需要从etcd获取。 先上图,比较直观:

步骤

  • IP数据报被封装并通过容器的eth0发送。
  • Container1的eth0通过veth对与Docker0交互并将数据包发送到Docker0。然后Docker0转发包。
  • Docker0确定Container3的IP地址,通过查询本地路由表到外部容器,并将数据包发送到虚拟NIC Flannel0。
  • Flannel0收到的数据包被转发到Flanneld进程。 Flanneld进程封装了数据包通过查询etcd维护的路由表并发送数据包通过主机的eth0。
  • 数据包确定网络中的目标主机主机。
  • 目的主机的Flanneld进程监听8285端口,负责解封包。
  • 解封装的数据包将转发到虚拟NICFlannel0。
  • Flannel0查询路由表,解封包,并将数据包发送到Docker0。
  • Docker0确定目标容器并发送包到目标容器。

在常用的vxlan模式中,涉及到上面步骤提到的封包和拆包,这也是Flannel网络传输效率相对低的原因。

下面重点说一下host-gw模式。 hostgw是最简单的backend,它的原理非常简单,直接添加路由,将目的主机当做网关,直接路由原始封包。 例如,我们从etcd中监听到一个EventAdded事件subnet为10.1.15.0/24被分配给主机Public IP 192.168.0.100,hostgw要做的工作就是在本主机上添加一条目的地址为10.1.15.0/24,网关地址为192.168.0.100,输出设备为上文中选择的集群间交互的网卡即可。对于EventRemoved事件,只需删除对应的路由。

因为没有了封包和拆包,host-gw的性能是最好的。

不过host-gw 要求主机网络二层直接互联。所以每个节点上有n-1个路由,而n个节点一共有n(n-1)/2个路由以保证flannel的flat网络能力。

为什么host-gw 要求主机网络二层直接互联? 首先通过抓包分析,抓包结果如下图:

可以看出host-gw在传输层走的是tcp。然后在网络层的源IP和目的IP均是容器的IP,虚拟IP。这就决定了二层互联,因为只有交换机是不关注源IP和目的IP。假如两台主机在两个lan中,二层不通,三层通,那么就需要路由器,而路由器是无法识别容器的这些ip。当然也可以配置路由规则,但是显然没有这么做的。

Openshift默认也是使用Flannel host-gw容器网络方案,其官网也清晰的画出了host-gw的data flow diagram。

0x02 示例配置和启动参数

示例配置

 {
    "Network": "10.0.0.0/8",
    "SubnetLen": 20,
    "SubnetMin": "10.10.0.0",
    "SubnetMax": "10.99.0.0",
    "Backend": {
        "Type": "udp",
        "Port": 7890
    }
}

启动参数

--public-ip="": IP accessible by other nodes for inter-host communication. Defaults to the IP of the interface being used for communication.
--etcd-endpoints=http://127.0.0.1:4001: a comma-delimited list of etcd endpoints.
--etcd-prefix=/coreos.com/network: etcd prefix.
--etcd-keyfile="": SSL key file used to secure etcd communication.
--etcd-certfile="": SSL certification file used to secure etcd communication.
--etcd-cafile="": SSL Certificate Authority file used to secure etcd communication.
--kube-subnet-mgr: Contact the Kubernetes API for subnet assignment instead of etcd.
--iface="": interface to use (IP or name) for inter-host communication. Defaults to the interface for the default route on the machine. This can be specified multiple times to check each option in order. Returns the first match found.
--iface-regex="": regex expression to match the first interface to use (IP or name) for inter-host communication. If unspecified, will default to the interface for the default route on the machine. This can be specified multiple times to check each regex in order. Returns the first match found. This option is superseded by the iface option and will only be used if nothing matches any option specified in the iface options.
--iptables-resync=5: resync period for iptables rules, in seconds. Defaults to 5 seconds, if you see a large amount of contention for the iptables lock increasing this will probably help.
--subnet-file=/run/flannel/subnet.env: filename where env variables (subnet and MTU values) will be written to.
--subnet-lease-renew-margin=60: subnet lease renewal margin, in minutes.
--ip-masq=false: setup IP masquerade for traffic destined for outside the flannel network. Flannel assumes that the default policy is ACCEPT in the NAT POSTROUTING chain.
-v=0: log level for V logs. Set to 1 to see messages related to data path.
--healthz-ip="0.0.0.0": The IP address for healthz server to listen (default "0.0.0.0")
--healthz-port=0: The port for healthz server to listen(0 to disable)
--version: print version and exit

参考

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-03-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x00 概述
  • 0x01 Flannel实现原理
  • 0x02 示例配置和启动参数
  • 参考
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档