暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

flannel网络详解

运维笔记本 2020-11-23
5988

一、Kubernetes网络通信需要解决的问题

  1. 同一机器下的不同pod间是怎么通信的?

  2. 同一个pod中不同的容器是怎么通信的?

  3. 不同的机器下不同的pod是怎么通信的?

  4. 容器间通信:同一个Pod内的多个容器间的通信,localhost

  5. Pod通信:Pod IP <-直达-> Pod IP

  6. Pod与Service通信:Pod IP <--> Cluster IP

  7. Service与集群外部客户端的通信;(ingress、nodeport、loadbalancer)

二、flannel的配置文件的目录

Ⅰ、指定pod的网段 kubeadm init --pod-network-cidr=10.244.0.0/16

Ⅱ、subnet.env文件目录 /run/flannel/subnet.env

[root@zbomc2 ~]# cat /run/flannel/subnet.env FLANNEL_NETWORK=10.244.0.0/16FLANNEL_SUBNET=10.244.0.1/24FLANNEL_MTU=1450FLANNEL_IPMASQ=true
复制

三、flannel的原理

  1. Flannel为每个host分配一个subnet,容器从这个subnet中分配IP,这些IP可以在host间路由,容器间无需使用nat和端口映射即可实现跨主机通信

  2. 每个subnet都是从一个更大的IP池中划分的,flannel会在每个主机上运行一个叫flanneld的agent,其职责就是从池子中分配subnet

  3. 建立一个覆盖网络(overlay network),通过这个覆盖网络,将数据包原封不动的传递到目标容器Flannel使用etcd存放网络配置、已分配的subnet、host的IP等信息

  4. Flannel数据包在主机间转发是由backend实现的,目前已经支持UDP、VxLAN、host-gw、AWS VPC和GCE路由等多种backend

什么是Overlay Network和Underlay Network

Overlay网络

四、flannel架构图

Ⅰ、pod1与pod2不在同一台主机

下面是从pod1 ping pod2的数据包流向

  1. pod1(10.0.14.15)向pod2(10.0.5.150)发送ping,查找pod1路由表,把数据包发送到cni0(10.0.14.1)
  2. cni0查找host1路由,把数据包转发到flannel.1
  3. flannel.1虚拟网卡再把数据包转发到它的驱动程序flannel
  4. flannel程序使用VXLAN协议封装这个数据包,向api-server查询目的IP所在的主机IP,称为host2(不清楚什么时候查询)
  5. flannel向查找到的host2 IP的UDP端口8472传输数据包
  6. host2的flannel收到数据包后,解包,然后转发给flannel.1虚拟网卡
  7. flannel.1虚拟网卡查找host2路由表,把数据包转发给cni0网桥,cni0网桥再把数据包转发给pod2

Ⅱ、pod1与pod2在同一台主机

pod1和pod2在同一台主机的话,由cni0网桥直接转发请求到pod2,不需要经过flannel。

Ⅲ、pod到service的网络

创建一个service时,相应会创建一个指向这个service的域名,域名规则{服务名}.{namespace}.svc.{集群名称}
。之前service ip的转发由iptables和kube-proxy负责,目前基于性能考虑,全部为iptables维护和转发。iptables则由kubelet维护。service仅支持udp和tcp协议,所以像ping的icmp协议是用不了的,所以无法ping通service ip

现在我们尝试看看在pod1向kube-dns的service ip 10.16.0.10:53发送udp请求是如何转发的。我们先找出与此IP相关的iptables规则:

【PREROUTING链】-m comment --comment "kubernetes service portals" -j KUBE-SERVICES 【KUBE-SERVICES链】-d 10.16.0.10/32 -p udp -m comment --comment "kube-system/kube-dns:dns cluster IP" -m udp --dport 53 -j KUBE-SVC-TCOU7JCQXEZGVUNU 【KUBE-SVC-TCOU7JCQXEZGVUNU链】-m comment --comment "kube-system/kube-dns:dns" -j KUBE-SEP-L5MHPWJPDKD7XIFG 【KUBE-SEP-L5MHPWJPDKD7XIFG链】-p udp -m comment --comment "kube-system/kube-dns:dns" -m udp -j DNAT --to-destination 10.0.0.46:53
复制
  1. pod1向service ip 10.16.0.10:53发送udp请求,查找路由表,把数据包转发给网桥cni0(10.0.14.1)
  2. 在数据包进入cnio网桥时,数据包经过PREROUTING链,然后跳至KUBE-SERVICES链
  3. KUBE-SERVICES链中一条匹配此数据包的规则,跳至KUBE-SVC-TCOU7JCQXEZGVUNU链
  4. KUBE-SVC-TCOU7JCQXEZGVUNU不做任何操作,跳至KUBE-SEP-L5MHPWJPDKD7XIFG链
  5. KUBE-SEP-L5MHPWJPDKD7XIFG里对此数据包作了DNAT到10.0.0.46:53,其中10.0.0.46即为kube-dns的pod ip
  6. 查找与10.0.0.46匹配的路由,转发数据包到flannel.1
  7. 之后的数据包流向就与上面的pod1到pod2的网络一样了

四、pod到外网

  1. pod向qq.com发送请求
  2. 查找路由表,转发数据包到宿主的网卡
  3. 宿主网卡完成qq.com路由选择后,iptables执行MASQUERADE,把源IP更改为宿主网卡的IP
  4. 向qq.com服务器发送请求

文章转载自运维笔记本,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论