docker筆記31-網路外掛flannel
跨節點通訊,需要透過NAT,即需要做源地址轉換。
k8s網路通訊:
1) 容器間通訊:同一個pod內的多個容器間的通訊,透過lo即可實現;
2) pod之間的通訊,pod ip <---> pod ip,pod和pod之間要不經過任何轉換即可通訊;
3) pod和service通訊:pod ip <----> cluster ip(即service ip)<---->pod ip,他們透過iptables或ipvs實現通訊,另外大家要注意ipvs取代不了iptables,因為ipvs只能做負載均衡,而做不了nat轉換;
4) Service與叢集外部客戶端的通訊
[root@master pki]# kubectl get configmap -n kube-system NAME DATA AGE coredns 1 22d extension-apiserver-authentication 6 22d kube-flannel-cfg 2 22d kube-proxy 2 22d kubeadm-config 1 22d kubelet-config-1.11 1 22d kubernetes-dashboard-settings 1 9h
[root@master pki]# kubectl get configmap kube-proxy -o yaml -n kube-system mode: ""
看到mode是空的,我們把它改為ipvs就可以了。
k8s要靠CNI介面接入其他外掛來實現網路通訊。目前比較流行的外掛有flannet,callco,canel,kube-router。
這些外掛使用的解決方案都如下:
1)虛擬網橋,虛擬網路卡,多個容器共用一個虛擬網路卡進行通訊;
2)多路複用:MacVLAN,多個容器共用一個物理網路卡進行通訊;
3)硬體交換:SR-LOV,一個物理網路卡可以虛擬出多個介面,這個效能最好。
CNI外掛存放位置
[root@master ~]# cat /etc/cni/net.d/10-flannel.conflist { "name": "cbr0", "plugins": [ { "type": "flannel", "delegate": { "hairpinMode": true, "isDefaultGateway": true } }, { "type": "portmap", "capabilities": { "portMappings": true } } ] }
flanel只支援網路通訊,但是不支援網路策略。
callco網路通訊和網路策略都支援。
canel:flanel+callco合起來的功能。
我們可以部署flanel提供網路通訊,再部署一個callco只提供網路策略。而不用canel。
mtu:是指一種通訊協議的某一層上面所能透過的最大資料包大小。
[root@master ~]# ifconfig cni0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.244.0.1 netmask 255.255.255.0 broadcast 0.0.0.0 inet6 fe80::4097:d5ff:fe28:6b64 prefixlen 64 scopeid 0x20<link> ether 0a:58:0a:f4:00:01 txqueuelen 1000 (Ethernet) RX packets 1609844 bytes 116093191 (110.7 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1632952 bytes 577989701 (551.2 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:83:f8:b8:ff txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ens192: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.16.1.100 netmask 255.255.255.0 broadcast 172.16.1.255 inet6 fe80::9cf3:d9de:59f:c320 prefixlen 64 scopeid 0x20<link> inet6 fe80::5707:6115:267b:bff5 prefixlen 64 scopeid 0x20<link> inet6 fe80::e34:f952:2859:4c69 prefixlen 64 scopeid 0x20<link> ether 00:50:56:a2:4e:cb txqueuelen 1000 (Ethernet) RX packets 5250378 bytes 704067861 (671.4 MiB) RX errors 139 dropped 190 overruns 0 frame 0 TX packets 4988169 bytes 4151179300 (3.8 GiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.244.0.0 netmask 255.255.255.255 broadcast 0.0.0.0 inet6 fe80::a82c:bcff:fef8:895c prefixlen 64 scopeid 0x20<link> ether aa:2c:bc:f8:89:5c txqueuelen 0 (Ethernet) RX packets 51 bytes 3491 (3.4 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 53 bytes 5378 (5.2 KiB) TX errors 0 dropped 10 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1 (Local Loopback) RX packets 59118846 bytes 15473986573 (14.4 GiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 59118846 bytes 15473986573 (14.4 GiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 veth6ec94aab: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet6 fe80::487d:5bff:fef7:484d prefixlen 64 scopeid 0x20<link> ether 4a:7d:5b:f7:48:4d txqueuelen 0 (Ethernet) RX packets 88112 bytes 19831802 (18.9 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 105718 bytes 13343894 (12.7 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 vethf703483a: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet6 fe80::b06a:eaff:fec3:33a8 prefixlen 64 scopeid 0x20<link> ether b2:6a:ea:c3:33:a8 txqueuelen 0 (Ethernet) RX packets 760882 bytes 59400960 (56.6 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 763263 bytes 282299805 (269.2 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 vethff579703: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet6 fe80::d82f:37ff:fe9a:b6d0 prefixlen 64 scopeid 0x20<link> ether da:2f:37:9a:b6:d0 txqueuelen 0 (Ethernet) RX packets 760850 bytes 59398245 (56.6 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 764016 bytes 282349248 (269.2 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
透過ifconfig命令,我們可以看到flannel.1的地址是10.244.0.0,子網掩碼是255.255.255.255,mtu是1450,mtu要留出一部分做封裝疊加,額外開銷使用。
cni0只有在pod執行時才會出現。
兩個節點上的pod可以藉助flannel隧道進行通訊。預設使用的VxLAN協議,因為它有額外開銷,所以效能有點低。
flannel第二種協議叫host-gw(host gateway),即Node節點把自己的網路介面當做pod的閘道器使用,從而使不同節點上的node進行通訊,這個效能比VxLAN高,因為它沒有額外開銷。不過他有個缺點,
就是各node節點必須在同一個網段中
。
另外,如果兩 個pod所在節點在同一個網段中 ,可以讓VxLAN也支援host-gw的功能, 即直接透過物理網路卡的閘道器路由轉發,而不用隧道flannel疊加,從而提高了VxLAN的效能,這種flannel的功能叫directrouting。
[root@master ~]# kubectl get daemonset -n kube-system NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE kube-flannel-ds-amd64 3 3 3 3 3 beta.kubernetes.io/arch=amd64 22d
[root@master ~]# kubectl get pods -n kube-system -o wide NAME READY STATUS RESTARTS AGE IP NODE kube-flannel-ds-amd64-6zqzr 1/1 Running 8 22d 172.16.1.100 master kube-flannel-ds-amd64-7qtcl 1/1 Running 7 22d 172.16.1.101 node1 kube-flannel-ds-amd64-kpctn 1/1 Running 6 22d 172.16.1.102 node2
看到flannel是以pod的daemonset控制器形式執行的(其實flannel還可以以守護程式的方式執行)。
[root@master ~]# kubectl get configmap -n kube-system NAME DATA AGE kube-flannel-cfg 2 22d
[root@master ~]#kubectl get configmap -n kube-system kube-flannel-cfg -o json -n kube-system \\\"10.244.0.0/16\\\",\\n \\\"Backend\\\": {\\n \\\"Type\\\": \\\"vxlan\
flannel的配置引數:
1、network
:flannel使用的CIDR格式的網路地址,用於為pod配置網路功能。
1)10.244.0.0/16--->
master: 10.244.0.0./24
node01: 10.244.1.0/24
....
node255: 10.244.255.0/24
可以支援255個節點
2)10.0.0.0/8
10.0.0.0/24
...
10.255.255.0/24
可以支援6萬多個節點
2、SubnetLen
:把network切分為子網供各節點使用時,使用多長的掩碼進行切分,預設為24位;
3、SubnetMin
:指明子網中的地址段最小多少可以分給子網使用,比如可以限制10.244.10.0/24,這樣0~9就不讓用;
4、SubnetMax
:表示最多使用多少個,比如10.244.100.0/24
5、Backend:
Vxlan,host-gw,udp(最慢)
flannel
支援多種後端
Vxlan
1.valan
2.Dirextrouting
host-gw:Host Gateway #不推薦,只能在二層網路中,不支援跨網路,如果有成千上萬的Pod,容易產生廣播風暴
UDP:效能差
[root@master ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE myapp-deploy-69b47bc96d-79fqh 1/1 Running 4 7d 10.244.1.97 node1 myapp-deploy-69b47bc96d-tc54k 1/1 Running 4 7d 10.244.2.88 node2
[root@master ~]# kubectl exec -it myapp-deploy-69b47bc96d-79fqh -- /bin/sh / # ping 10.244.2.88 #ping對方Node上容器的ip PING 10.244.2.88 (10.244.2.88): 56 data bytes 64 bytes from 10.244.2.88: seq=0 ttl=62 time=0.459 ms 64 bytes from 10.244.2.88: seq=0 ttl=62 time=0.377 ms 64 bytes from 10.244.2.88: seq=1 ttl=62 time=0.252 ms 64 bytes from 10.244.2.88: seq=2 ttl=62 time=0.261 ms
在其他節點上抓包,發現根本就在ens192上抓不到包。
[root@master ~]# tcpdump -i ens192 -nn icmp
[root@master ~]# yum install bridge-utils -y
[root@master ~]# brctl show docker0 bridge namebridge idSTP enabledinterfaces docker08000.024283f8b8ffno
[root@master ~]# brctl show cni0 bridge namebridge idSTP enabledinterfaces cni08000.0a580af40001noveth6ec94aab vethf703483a vethff579703
可以看到veth這些介面都是橋接到cni0上的。
brctl show表示檢視已有網橋。
[root@node1 ~]# tcpdump -i cni0 -nn icmp tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on cni0, link-type EN10MB (Ethernet), capture size 262144 bytes 23:40:11.370754 IP 10.244.1.97 > 10.244.2.88: ICMP echo request, id 4864, seq 96, length 64 23:40:11.370988 IP 10.244.2.88 > 10.244.1.97: ICMP echo reply, id 4864, seq 96, length 64 23:40:12.370888 IP 10.244.1.97 > 10.244.2.88: ICMP echo request, id 4864, seq 97, length 64 23:40:12.371090 IP 10.244.2.88 > 10.244.1.97: ICMP echo reply, id 4864, seq 97, length 64 ^X23:40:13.371015 IP 10.244.1.97 > 10.244.2.88: ICMP echo request, id 4864, seq 98, length 64 23:40:13.371239 IP 10.244.2.88 > 10.244.1.97: ICMP echo reply, id 4864, seq 98, length 64 23:40:14.371128 IP 10.244.1.97 > 10.244.2.88: ICMP echo request, id 4864, seq 99, length 64
可以看到,在node節點,可以在cni0埠上抓到容器裡面的Ping時的包。
其實,上面ping時的資料流是先從cni0進來,然後從flannel.1出去,最後藉助物理網路卡ens32發出去。所以,我們在flannel.1上也能抓到包:
[root@node1 ~]# tcpdump -i flannel.1 -nn icmp tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on flannel.1, link-type EN10MB (Ethernet), capture size 262144 bytes 03:12:36.823315 IP 10.244.1.97 > 10.244.2.88: ICMP echo request, id 4864, seq 12840, length 64 03:12:36.823496 IP 10.244.2.88 > 10.244.1.97: ICMP echo reply, id 4864, seq 12840, length 64 03:12:37.823490 IP 10.244.1.97 > 10.244.2.88: ICMP echo request, id 4864, seq 12841, length 64 03:12:37.823634 IP 10.244.2.88 > 10.244.1.97: ICMP echo reply, id 4864, seq 12841, length 64
同樣,在ens192物理網路卡上也能抓到包:
[root@node1 ~]# tcpdump -i ens192 -nn host 172.16.1.102 #172.16.1.102是node2的物理ip tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on ens192, link-type EN10MB (Ethernet), capture size 262144 bytes 10:59:24.234174 IP 172.16.1.101.60617 > 172.16.1.102.8472: OTV, flags [I] (0x08), overlay 0, instance 1 IP 10.244.1.97 > 10.244.2.88: ICMP echo request, id 7168, seq 0, length 64 10:59:24.234434 IP 172.16.1.102.54894 > 172.16.1.101.8472: OTV, flags [I] (0x08), overlay 0, instance 1 IP 10.244.2.88 > 10.244.1.97: ICMP echo reply, id 7168, seq 0, length 64 10:59:25.234301 IP 172.16.1.101.60617 > 172.16.1.102.8472: OTV, flags [I] (0x08), overlay 0, instance 1 IP 10.244.1.97 > 10.244.2.88: ICMP echo request, id 7168, seq 1, length 64 10:59:25.234469 IP 172.16.1.102.54894 > 172.16.1.101.8472: OTV, flags [I] (0x08), overlay 0, instance 1 IP 10.244.2.88 > 10.244.1.97: ICMP echo reply, id 7168, seq 1, length 64 10:59:26.234415 IP 172.16.1.101.60617 > 172.16.1.102.8472: OTV, flags [I] (0x08), overlay 0, instance 1 IP 10.244.1.97 > 10.244.2.88: ICMP echo request, id 7168, seq 2, length 64 10:59:26.234592 IP 172.16.1.102.54894 > 172.16.1.101.8472: OTV, flags [I] (0x08), overlay 0, instance 1 IP 10.244.2.88 > 10.244.1.97: ICMP echo reply, id 7168, seq 2, length 64 10:59:27.234528 IP 172.16.1.101.60617 > 172.16.1.102.8472: OTV, flags [I] (0x08), overlay 0, instance 1 IP 10.244.1.97 > 10.244.2.88: ICMP echo request, id 7168, seq 3, length 64
下面我們把flannel的通訊模式改成directrouting的方式
[root@master flannel]# cd /root/manifests/flannel
[root@master flannel]# kubectl edit configmap kube-flannel-cfg -n kube-system
{ "Network": "10.244.0.0/16", "Backend": { "Type": "vxlan", "Directrouting": true #加一行這個 } }
[root@master flannel]# ip route show default via 172.16.1.254 dev ens192 proto static metric 100 10.244.0.0/24 dev cni0 proto kernel scope link src 10.244.0.1 #訪問10.244.0.0/24要透過10.244.0.1 10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink #10.244.1.0是配置在flannel上的地址,表示訪問10.244.1.0/24透過本機flannel.1上的10.244.1.0送出去,下同 10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink #10.244.2.0是配置在flannel上的地址 172.16.1.0/24 dev ens192 proto kernel scope link src 172.16.1.100 metric 100
[root@master flannel]# kubectl get configmap kube-flannel-cfg -o json -n kube-system
"net-conf.json": "{\n \"Network\": \"10.244.0.0/16\",\n \"Backend\": {\n \"Type\": \"vxlan\",\n \"Directrouting\": true\n }\n}\n"
看到有Directrouting,說明生效了。
重啟整個k8s,然後再看:
[root@master ~]# ip route show default via 172.16.1.254 dev ens192 proto static metric 100 10.244.0.0/24 dev cni0 proto kernel scope link src 10.244.0.1 #訪問本機直接在本機直接轉發,而不需要其他介面,這就是directrouting 10.244.1.0/24 via 172.16.1.101 dev ens192 #看到現在訪問10.244.1.0,透過本地物理網路卡ens192上的172.16.1.101送出去,即透過物理網路卡通訊了,而不再透過隧道flannel通訊。 10.244.2.0/24 via 172.16.1.102 dev ens192 172.16.1.0/24 dev ens192 proto kernel scope link src 172.16.1.100 metric 100 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
繼續登入到一個pod中進行ping測試:
[root@master ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE myapp-deploy-69b47bc96d-75g2b 1/1 Running 0 12m 10.244.1.124 node1 myapp-deploy-69b47bc96d-jwgwm 1/1 Running 0 3s 10.244.2.100 node2
[root@master ~]# kubectl exec -it myapp-deploy-69b47bc96d-75g2b -- /bin/sh / # ping 10.244.2.100 PING 10.244.2.100 (10.244.2.100): 56 data bytes 64 bytes from 10.244.2.100: seq=0 ttl=62 time=0.536 ms 64 bytes from 10.244.2.100: seq=1 ttl=62 time=0.206 ms 64 bytes from 10.244.2.100: seq=2 ttl=62 time=0.206 ms 64 bytes from 10.244.2.100: seq=3 ttl=62 time=0.203 ms 64 bytes from 10.244.2.100: seq=4 ttl=62 time=0.210 ms
[root@node1 ~]# tcpdump -i ens192 -nn icmp tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on ens192, link-type EN10MB (Ethernet), capture size 262144 bytes 12:31:10.899403 IP 10.244.1.124 > 10.244.2.100: ICMP echo request, id 8960, seq 24, length 64 12:31:10.899546 IP 10.244.2.100 > 10.244.1.124: ICMP echo reply, id 8960, seq 24, length 64 12:31:11.899505 IP 10.244.1.124 > 10.244.2.100: ICMP echo request, id 8960, seq 25, length 64 12:31:11.899639 IP 10.244.2.100 > 10.244.1.124: ICMP echo reply, id 8960, seq 25, length 64
透過抓包可以看到,現在在pod中進行互ping,是從物理網路卡ens192進出的,這就是directrouting,這種效能比預設vxlan高。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28916011/viewspace-2215295/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Docker網路解決方案 - Flannel部署記錄Docker
- Flannel和Calico網路外掛工作流程對比
- kubernetes實踐之四:Flannel網路外掛安裝
- flannel網路概述
- 360外掛化方案RePlugin學習筆記-外接外掛Plugin筆記
- 四、建立覆蓋網路--Flannel
- docker筆記49-容器虛擬化網路Docker筆記
- bootstrap學習筆記 外掛概述boot筆記
- Kubernetes網路分析之Flannel
- 用Fundebug外掛記錄網路請求異常
- Gradle外掛學習筆記(一)Gradle筆記
- Gradle外掛學習筆記(四)Gradle筆記
- Gradle外掛學習筆記(三)Gradle筆記
- Gradle外掛學習筆記(二)Gradle筆記
- webpack4入門筆記——外掛Web筆記
- jQuery入門筆記之(七)外掛jQuery筆記
- k8s網路外掛K8S
- Kubernetes CNI網路外掛
- docker k8s 1.3.8 + flannelDockerK8S
- 外掛化開發筆記(一)代理模式筆記模式
- Egg 學習筆記 - 外掛的使用筆記
- 極光筆記 | 大語言模型外掛筆記模型
- Android 外掛化原理入門筆記Android筆記
- bootstrap 學習筆記 輪播(Carousel)外掛boot筆記
- K8S Calico網路外掛K8S
- 容器中跨主機的網路方案-flannel
- flannel網路在kubernetes中的運用
- 筆記:Docker筆記Docker
- Docker筆記Docker筆記
- docker 筆記Docker筆記
- 初學Docker容器網路不得不看的學習筆記Docker筆記
- docker筆記32-k8s基於canal的網路策略Docker筆記K8S
- IDEA的Docker外掛實戰(Docker Image篇)IdeaDocker
- 【山外筆記-四級計算機網路】第1章 網路技術基礎筆記計算機網路
- 網路層筆記(1)筆記
- 【筆記】Android 網路筆記Android
- 使用maven外掛構建docker映象MavenDocker
- webpack筆記——在html-webpack-plugin外掛中提供給其它外掛是使用的hooksWeb筆記HTMLPluginHook