一、Kubernetes网络通信需要解决的问题
同一机器下的不同pod间是怎么通信的?
同一个pod中不同的容器是怎么通信的?
不同的机器下不同的pod是怎么通信的?
容器间通信:同一个Pod内的多个容器间的通信,localhost
Pod通信:Pod IP <-直达-> Pod IP
Pod与Service通信:Pod IP <--> Cluster IP
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的原理
Flannel为每个host分配一个subnet,容器从这个subnet中分配IP,这些IP可以在host间路由,容器间无需使用nat和端口映射即可实现跨主机通信
每个subnet都是从一个更大的IP池中划分的,flannel会在每个主机上运行一个叫flanneld的agent,其职责就是从池子中分配subnet
建立一个覆盖网络(overlay network),通过这个覆盖网络,将数据包原封不动的传递到目标容器Flannel使用etcd存放网络配置、已分配的subnet、host的IP等信息
Flannel数据包在主机间转发是由backend实现的,目前已经支持UDP、VxLAN、host-gw、AWS VPC和GCE路由等多种backend
什么是Overlay Network和Underlay Network
Overlay网络
四、flannel架构图

Ⅰ、pod1与pod2不在同一台主机
下面是从pod1 ping pod2的数据包流向
pod1(10.0.14.15)向pod2(10.0.5.150)发送ping,查找pod1路由表,把数据包发送到cni0(10.0.14.1) cni0查找host1路由,把数据包转发到flannel.1 flannel.1虚拟网卡再把数据包转发到它的驱动程序flannel flannel程序使用VXLAN协议封装这个数据包,向api-server查询目的IP所在的主机IP,称为host2(不清楚什么时候查询) flannel向查找到的host2 IP的UDP端口8472传输数据包 host2的flannel收到数据包后,解包,然后转发给flannel.1虚拟网卡 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
复制
pod1向service ip 10.16.0.10:53发送udp请求,查找路由表,把数据包转发给网桥cni0(10.0.14.1) 在数据包进入cnio网桥时,数据包经过PREROUTING链,然后跳至KUBE-SERVICES链 KUBE-SERVICES链中一条匹配此数据包的规则,跳至KUBE-SVC-TCOU7JCQXEZGVUNU链 KUBE-SVC-TCOU7JCQXEZGVUNU不做任何操作,跳至KUBE-SEP-L5MHPWJPDKD7XIFG链 KUBE-SEP-L5MHPWJPDKD7XIFG里对此数据包作了DNAT到10.0.0.46:53,其中10.0.0.46即为kube-dns的pod ip 查找与10.0.0.46匹配的路由,转发数据包到flannel.1 之后的数据包流向就与上面的pod1到pod2的网络一样了
四、pod到外网
pod向qq.com发送请求 查找路由表,转发数据包到宿主的网卡 宿主网卡完成qq.com路由选择后,iptables执行MASQUERADE,把源IP更改为宿主网卡的IP 向qq.com服务器发送请求