匿名
未登录
登录
Linux78|wiki
搜索
查看“Flannel网络原理”的源代码
来自Linux78|wiki
名字空间
页面
讨论
更多
更多
页面选项
查看
查看源代码
历史
←
Flannel网络原理
因为以下原因,您没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:
wiki:用户|用户
您可以查看与复制此页面的源代码。
=== overlay网络简介 === 覆盖网络就是应用层网络,它是面向应用层的,不考虑或很少考虑网络层,物理层的问题。 详细说来,覆盖网络是指建立在另一个网络上的网络。该网络中的结点可以看作通过虚拟或逻辑链路而连接起来的。虽然在底层有很多条物理链路,但是这些虚拟或逻辑链路都与路径一一对应。例如:许多P2P网络就是覆盖网络,因为它运行在互连网的上层。覆盖网络允许对没有IP地址标识的目的主机路由信息,例如:Freenet 和DHT(分布式哈希表)可以路由信息到一个存储特定文件的结点,而这个结点的IP地址事先并不知道。 覆盖网络被认为是一条用来改善互连网路由的途径,让二层网络在三层网络中传递,既解决了二层的缺点,又解决了三层的不灵活! === Flannel的工作原理 === Flannel实质上是一种“覆盖网络(overlay network)”,也就是将TCP数据包装在另一种网络包里面进行路由转发和通信,目前已经支持UDP、VxLAN、AWS VPC和GCE路由等数据转发方式。 默认的节点间数据通信方式是UDP转发。 ===Fannel架构=== lannel默认使用8285端口作为UDP封装报文的端口,VxLan使用8472端口。 [[文件:Fannel-6.png|500px|居中|缩略图|Fannel架构]] 那么一条网络报文是怎么从一个容器发送到另外一个容器的呢? 容器直接使用目标容器的ip访问,默认通过容器内部的eth0发送出去。 报文通过veth pair被发送到vethXXX。 vethXXX是直接连接到虚拟交换机docker0的,报文通过虚拟bridge docker0发送出去。 查找路由表,外部容器ip的报文都会转发到flannel0虚拟网卡,这是一个P2P的虚拟网卡,然后报文就被转发到监听在另一端的flanneld。 flanneld通过etcd维护了各个节点之间的路由表,把原来的报文UDP封装一层,通过配置的iface发送出去。 报文通过主机之间的网络找到目标主机。 报文继续往上,到传输层,交给监听在8285端口的flanneld程序处理。 数据被解包,然后发送给flannel0虚拟网卡。 查找路由表,发现对应容器的报文要交给docker0。 docker0找到连到自己的容器,把报文发送过去。 === 工作原理 === 数据从源容器中发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡,这是个P2P的虚拟网卡,flanneld服务监听在网卡的另外一端。 Flannel通过Etcd服务维护了一张节点间的路由表,详细记录了各节点子网网段 。 源主机的flanneld服务将原本的数据内容UDP封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达以后被解包,然后直接进入目的节点的flannel0虚拟网卡,然后被转发到目的主机的docker0虚拟网卡,最后就像本机容器通信一下的有docker0路由到达目标容器。 ==== 配置文件 ==== /etc/sysconfig/flanneld [root@k8s-master ~]# vi /etc/sysconfig/flanneld Flanneld configuration options etcd url location. Point this to the server where etcd runs FLANNELETCDENDPOINTS="http://etcd:2379" etcd config key. This is the configuration key that flannel queries For address range assignment FLANNELETCDPREFIX="/atomic.io/network" Any additional options that you want to pass FLANNEL_OPTIONS="" Flannel使用Etcd进行配置,来保证多个Flannel实例之间的配置一致性,所以需要在etcd上进行如下配置:(‘/atomic.io/network/config’这个key与上文/etc/sysconfig/flannel中的配置项FLANNELETCDPREFIX是相对应的,错误的话启动就会出错) [root@k8s-master ~]# etcdctl mk /atomic.io/network/config '{ "Network": "10.0.0.0/16" }' { "Network": "10.0.0.0/16" } ==== UDP报文封装 ==== 原始数据是在起始节点的Flannel服务上进行UDP封装的,投递到目的节点后就被另一端的Flannel服务还原成了原始的数据包,两边的Docker服务都感觉不到这个过程的存在。 ==== docker IP 分配 ==== Flannel通过Etcd分配了每个节点可用的IP地址段后,偷偷的修改了Docker的启动参数。 [root@k8s-node-1 ~]# ps aux | grep bip root 3142 0.1 2.7 560620 27364 ? Ssl 19:50 0:11 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current -- default-runtime=docker-runc --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/libexec/docker/docker-proxy-current --seccomp- profile=/etc/docker/seccomp.json --insecure-registry registry:5000 --storage-driver overlay2 --bip=10.0.53.1/24 --ip-masq=true --mtu=1472 这个是在运行了Flannel服务的节点上查看到的Docker服务进程运行参数。 注意其中的“--bip=10.0.53.1/24”这个参数,它限制了所在节点容器获得的IP范围。 这个IP范围是由Flannel自动分配的,由Flannel通过保存在Etcd服务中的记录确保它们不会重复。 容器IP并不固定,IP分配还是Docker在做,Flannel只是分配了子网段。 ==== 数据转发 ==== 以下是 k8s集群两个node节点的路由表: [root@k8s-node-1 ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.1.1 0.0.0.0 UG 100 0 0 ens33 10.0.0.0 0.0.0.0 255.255.0.0 U 0 0 0 flannel0 10.0.53.0 0.0.0.0 255.255.255.0 U 0 0 0 docker0 192.168.1.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33 [root@k8s-node-2 ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.1.1 0.0.0.0 UG 100 0 0 ens33 10.0.0.0 0.0.0.0 255.255.0.0 U 0 0 0 flannel0 10.0.80.0 0.0.0.0 255.255.255.0 U 0 0 0 docker0 192.168.1.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33 例如:现在有一个数据包要从IP为10.0.53.2的容器发到IP为10.0.80.2的容器。根据数据发送节点的路由表,它只与10.0.0.0/16匹配这条记录匹配,因此数据从docker0出来以后就被投递到了flannel0。同理在目标节点,由于投递的地址是一个容器,因此目的地址一定会落在docker0对于的10.0.80.0/24这个记录上,然后投递到了docker0网卡
返回至
Flannel网络原理
。
导航
导航
首页
最近更改
随机页面
栏目
Nginx
Kubernetes
Spring Cloud
Wiki工具
Wiki工具
特殊页面
页面工具
页面工具
用户页面工具
更多
链入页面
相关更改
页面信息
页面日志