一、前言
1、Docker的網絡模型
Bridge Joined Open None(具體參見:https://www.cnblogs.com/cmxu/p/11624699.html)
跨節點之間通信時都需要NAT,需要經過兩次地址轉換。效率低,並且很難構建需要的網絡。
2、Kubernetes網絡通信
(1) 容器間通信:同一個Pod內的多個容器間的通信,通過lo;
(2) Pod通信:Pod IP < -- > Pod IP;
(3) Pod與Service通信:Pod IP< -- > Cluster IP;
(4)Service與集群外部客戶端的通信;
3、CNI(Container Network Interface)
容器虛擬化網絡方案:
基於隧道:flannel vxlan模式,calico的IPIP模式
基於路由:flannel的host-gw模式,calico的bgp模式
Flannel的host-gw模式只能用於二層直接可達的網絡,由於廣播的問題,這種網絡規模都比較小(但目前規模小的解決方案有:“大二層”網絡)
K8S自身不提供網絡解決方案,但支持任何第三方的網絡解決方案(CNI)。常見的CNI:flannel,calico,canel,kube-router等等
解決方案:
虛擬網橋
多路復用:MacVLAN
硬件交換:SR-IOV(Single-root I/O virtualization,單根I/O虛擬化)
K8S自動去此目錄下找配置,只要把配置文件放在此目錄下,k8s自動加載使用此網絡插件。
[root@master ~]# ll /etc/cni/net.d/
4、白話flannel和calico
參見:https://www.lbbniu.com/6548.html
二、Flannel
Flannel不支持網絡策略(Pod之間的網絡訪問控制),只支持地址分配。
Calico既支持地址分配也支持網絡策略。
Flannel是被kubelet調用,但凡運行kubelet運行的節點都應該部署網絡插件,所以作為Pod運行時應該部署為DaemonSet,也可以直接部署為操作系統的守護進程。
[root@master ~]# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
1、flannel支持的后端
VxLAN:
(1)原生vxlan
(2)Directrouting(源節點和目標節點在同一個網絡,則使用host-gw方式直接通信,不用隧道疊加,不在同一個網絡,則降級為vxlan模式)
host-gw:Host Gateway 各節點都要工作在同一個二層網絡中;維護路由表。可能會出現廣播風暴。
UDP:使用普通的UDP報文轉發,性能最差,最好不要用。
Flannel默認使用VxLAN的模式:
flannel.1網卡用於隧道創建。性能會降低,因為隧道會封裝幾層首部。
2、Flannel的配置參數
[root@master ~]# kubectl get configmap kube-flannel-cfg -o yaml -n kube-system Network: flannel使用的CIDR格式的網絡地址,用於為Pod配置網絡功能; 10.244.0.0/16 --> Master:10.244.0.0/24 Node1:10.244.1.0/24 Node2:10.244.2.0/24 集群最多能有256個網絡,也就意味着至多只能有256個節點。 SubnetLen:把Network切分為子網供各節點使用時,使用多長的掩碼進行切分,默認為24位;則每個子網最多有256個Pod。 SubnetMin:指定用於分配給節點子網使用的起始子網;10.244.10.0/24 SubnetMin:指定用於分配給節點子網使用的最大子網;10.244.100.0/24 Backend:vxlan,host-gw,udp
3、默認VxLAN的數據包流向分析
跨節點的Pod間通信。在node1上的Pod Ping node2上的Pod,在物理網卡上抓ICMP的包是抓不到的,因為到達ens33時,ICMP的包已經被封裝為UDP的包了。
報文從cni0進來,從flannel.1出去,在flannel.1就被封裝成VxLAN的包了。
在到達cni0網絡接口時報文還沒有封裝,並且報文的源地址和目的地址還是Pod IP.
[root@node1 ~]# tcpdump -i flannel.1 -nn -p icmp
[root@node1 ~]# tcpdump -i cni0 -nn -p icmp
[root@node1 ~]# tcpdump -i flannel.1 -nn -p icmp
[root@node1 ~]# tcpdump -i ens33 -nn host 192.168.42.130
在物理網卡能看到封裝后的報文。
4、修改Flannel的后端為directrouting的VxLAN
未修改前,路由表如下,出口都是flannel.1網卡。
[root@master flannel]# ip route show
[root@master flannel]# kubectl edit configmap kube-flannel-cfg -n kube-system #直接編輯,在 net-conf.json處添加字段Directrouting,不建議直接使用edit,不生效。記得加逗號。
Flannel會自動重讀配置。本節點走cni,其他節點走物理接口。
通過edit修改configmap修改后端后,不會生效,路由表不會更新,目前只能刪除flannel,修改kube-flannel.yml,重新apply才會生效。
事實上,我們應該在前期集群部署時就規划好網絡相關,中途修改會引發很多問題。
5、Directrouting VxLAN的數據包流向分析
在node1上的Pod Ping node2上的Pod,(Pod間的橋接網絡)直接在物理網卡上抓包,結果如下:
三、Tips:
更改Service通信模式為ipvs:
Modeprobe加載ipvs需要的內核模塊
[kubelet@master dashboard]$ kubectl get configmap kube-proxy -n kube-system -o yaml
修改mode為ipvs之后,重載一下kube-proxy應用即可。