網絡方案性能驗證
1 測試說明
涉及網絡性能變量較多,比如網卡MTU值及報文大小、TCP windows size、多線程等,由於我們使用橫向對比,在相同測試場景下比較不同網絡方案的性能,所以暫時統一配置。
1.1 虛擬機配置
兩台4C、8G的centos7虛擬機,使用橋接方式連通在同一台物理機上,分別作為服務器和客戶端。
1.2 測試過程
本次測試使用 iperf 來打流,測試了 TCP 場景下 60s 的平均帶寬,客戶端和服務器端使用的命令分別如下:
ip netns exec ns0 iperf -c $server_ip -i 1 -t 60
ip netns exec ns0 iperf –s
注:由於 hostnetwork 場景下未用到網絡命令空間,所以 iperf 命令在主機網絡棧上執行。
1.3 數據展示
上圖展示了8種不同的網絡方案,相同的測試場景下得到了網絡容器之間通信帶寬數據,測試結果單位為 Gbit/sec。
2 結果分析:
2.1 hostnetwork 性能最優
從測試結果可以看出,hostnetwork 場景下跨節點容器帶寬性能最好,原因是由於通信過程中使用了主機網絡棧,其他場景下由於使用了網絡命名空間隔離,報文通信過程除了使用容器網絡棧還都會經過主機網卡或者經過主機網絡棧(除ovs和macvlan),所以性能上會有所損失
2.2 macvlan bridge 性能逼近 hostnetwork
macvlan 場景由於跨過主機網絡棧,直接從宿主機網卡將報文投遞出去,所以性能方面會較其他非 hostwork 場景下高。
由於不經過宿主機網絡棧且沒有控制流程,所以安全策略等不容易生效。
2.3 ovs 場景性能僅次於 macvlan
ovs 場景下使用 veth 直連容器網絡命名空間和 ovs 網橋,並由 ovs datapath 在內核態匹配處理報文送至物理網卡投遞報文,所以也沒有經過宿主機命名空間,但是由於其受在內核態首包匹配不成功需要上送到用戶態處理,且需要有 ovs 的控制,在增加了報文控制的,相較於 macvlan 簡單直白的流程性能有所降低。
Ovs + linux bridge,相比於單純使用 ovs + veth 場景性能下降 26%。Ovs + Linux bridge 提出的
2.4 增加了報文在容器網絡命名空間的處理,Calico 較hostnetwork 性能下降 30%
Calico 使用了 underlay 網絡來實現跨主機容器通信,相比於 hostnetwork 場景,只是增加了容器網絡棧的處理流程,性能下降了將近 30%,相比於同樣使用了有容器網絡命名空間的 macvlan 和 ovs 場景,性能分別下降了29% 和 20%。
flannel host-gw場景與 calico 場景區別在於flannel host-gw 使用 linux bridge, calico 使用 veth 來連接主機和空器網絡棧,性能差距將近1%。
2.5 flannel vxlan和 canal 場景網絡性能最差
flannel vxlan 和canal 由於使用 vxlan 隧道技術,跨主機通信時要有報文封裝解封裝、性能上損耗很明顯,較 hostnework 方案下了降86 %。 flannel 和 canal 的差別在於flannel 使用 linux bridge 來完成容器網絡命名空間與宿主機/同節點容器通信,而 canal 則使用 veth,但是仍然可以看得出來直接使用veth 的網絡性能比linux bridge 略高,有 1% 的性能提升。
3 總結:
上面介紹對比了,相同測試場景下不同容器網絡方案的跨節點容器通信性能對比, hostnetwork 場景; 在容器場景下macvlan 的網絡損耗非常低,但是由於其跨過主機網絡棧,無法通過主機網絡棧來實現網絡訪問控制,因而適用於對於網絡安全要求較低,但是追求網絡性能的場景;ovs 由於其高效、易用以及強大的 SDN 能力,在 Openstack 為主的 IaaS 和 Openshift,Controiv 等主導的 PaaS 平台占領了相當一部分的市場。 而且相比於 macvlan 對於報文的控制能力更強,所以可適用於業務場景較復雜的場景;flannel 和 canal 使用 vxlan 隧道來封裝跨主機容器訪問報文,性能損失嚴重,但是由於 vxlan 隔離了容器網絡與基礎物理網絡,所以很容易地通過此方案將 PaaS 平台與原有業務平台有整合。
4 實現命令
flannel host-gw場景將flannel vxlan 場景下主機路由規則將從物理網卡
hostnework 場景下
4.1 macvlan
4.1.1 hosta
ip netns add ns0
ip netns add ns1
ip link add link eth0 macvlan0 type macvlan mode bridge
ip link set macvlan0 netns ns0
ip netns exec ns0 ip link set macvlan0 up
ip netns exec ns0 ip link set lo up
ip netns exec ns0 ip addr add 192.168.2.3/24 dev macvlan0
ip link set eth0 promisc on
4.1.2 hostb
ip netns add ns0
ip netns add ns1
ip link add link eth0 macvlan0 type macvlan mode bridge
ip link set macvlan0 netns ns0
ip netns exec ns0 ip link set macvlan0 up
ip netns exec ns0 ip link set lo up
ip netns exec ns0 ip addr add 192.168.2.5/24 dev macvlan0
ip link set eth0 promisc on
4.2 flannel vxlan
4.2.1 hosta
ip link add dev flannel_vxlan_c type veth peer name flannel_vxlan_h
brctl addif docker0 flannel_vxlan_h
ip link set flannel_vxlan_h up
ip addr add 10.5.58.1/24 dev docker0
ip netns add flannel_vxlan
ip netns exec flannel_vxlan ip link set lo up
ip link set flannel_vxlan_c netns flannel_vxlan
ip netns exec flannel_vxlan ip link set flannel_vxlan_c up
ip netns exec flannel_vxlan ip addr add 10.5.58.3/24 dev flannel_vxlan_c
ip netns exec flannel_vxlan ip route add default via 10.5.58.1
ip nei add 10.5.47.0 dev flannel.1 lladdr 8e:09:f3:4f:94:34
bridge fdb add 8e:09:f3:4f:94:34 dst 192.168.20.43 dev flannel.1
ip route add 10.5.58.0/24 via 10.5.58.0 dev flannel.1 onlink
4.2.2 hostb
ip link add dev flannel_vxlan_c type veth peer name flannel_vxlan_h
brctl addif docker0 flannel_vxlan_h
ip link set flannel_vxlan_h up
ip addr add 10.5.47.1/24 dev docker0
ip netns add flannel_vxlan
ip netns exec flannel_vxlan ip link set lo up
ip link set flannel_vxlan_c netns flannel_vxlan
ip netns exec flannel_vxlan ip link set flannel_vxlan_c up
ip netns exec flannel_vxlan ip addr add 10.5.47.3/24 dev flannel_vxlan_c
ip netns exec flannel_vxlan ip route add default via 10.5.47.1
ip nei add 10.5.58.0 dev flannel.1 lladdr 2a:33:36:9b:2f:28
bridge fdb add 8e:09:f3:4f:94:34 dst 192.168.20.42 dev flannel.1
ip route add 10.5.47.0/24 via 10.5.47.0 dev flannel.1 onlink
4.3 canal
4.3.1 hosta
ip link add dev canal-c type veth peer name canal-h
ip link set canal-c netns canal
ip netns exec canal ip link set lo up
ip netns exec canal ip link set canal-c up
ip netns exec canal ip addr add 10.5.58.103/24 dev canal-c
ip netns exec calico ip route add default via 169.254.1.1
ip netns exec canal ip route add 169.254.1.1 dev canal-c
ip route add 10.5.58.103 dev canal-h
ip link set canal-h up
sysctl -w net.ipv4.conf.canal-h.proxy_arp=1
ip nei add 10.5.47.0 dev flannel.1 lladdr 8e:09:f3:4f:94:34
bridge fdb add 8e:09:f3:4f:94:34 dst 192.168.20.43 dev flannel.1
ip route add 10.5.47.0/24 via 10.5.47.0 dev flannel.1 onlink
4.3.2 hostb
ip link add dev canal-c type veth peer name canal-h
ip link set canal-c netns canal
ip netns exec canal ip link set lo up
ip netns exec canal ip link set canal-c up
ip netns exec canal ip addr add 10.5.47.103/24 dev canal-c
ip netns exec calico ip route add default via 169.254.1.1
ip netns exec canal ip route add 169.254.1.1 dev canal-c
ip route add 10.5.47.103 dev canal-h
ip link set canal-h up
sysctl -w net.ipv4.conf.canal-h.proxy_arp=1
ip nei add 10.5.58.0 dev flannel.1 lladdr 8e:09:f3:4f:94:34
bridge fdb add 8e:09:f3:4f:94:34 dst 192.168.20.43 dev flannel.1
ip route add 10.5.58.0/24 via 10.5.58.0 dev flannel.1 onlink
4.4 calico
4.4.1 hosta
ip netns add calico
ip link add dev calico-c type veth peer name calico-h
ip link set calico-c netns calico
ip netns exec calico ip link set lo up
ip netns exec calico ip link set calico-c up
ip netns exec calico ip addr add 172.28.0.3/24 dev calico-c
ip netns exec calico ip route add default via 169.254.1.1
ip netns exec calico ip route add 169.254.1.1 dev calico-c
ip route add 172.28.0.3 dev calico-h
ip link set calico-h up
sysctl -w net.ipv4.conf.calico-h.proxy_arp=1
ip route add 172.28.1.0/24 via 192.168.20.43
4.4.2 hostb
ip netns add calico
ip link add dev calico-c type veth peer name calico-h
ip link set calico-c netns calico
ip netns exec calico ip link set lo up
ip netns exec calico ip link set calico-c up
ip netns exec calico ip addr add 172.28.1.3/24 dev calico-c
ip netns exec calico ip route add default via 169.254.1.1
ip netns exec calico ip route add 169.254.1.1 dev calico-c
ip route add 172.28.1.3 dev calico-h
ip link set calico-h up
sysctl -w net.ipv4.conf.calico-h.proxy_arp=1
ip route add 172.28.0.0/24 via 192.168.20.42
4.5 OVS
4.5.1 hosta
ip netns add ovs
ovs-vsctl add-br br-int -- set Bridge br-int fail_mode=secure
ip link add dev veth-c type veth peer name veth-ovs
ip link set veth-c netns ovs
ip netns exec ovs ip link set lo up
ip netns exec ovs ip link set veth-c up
ip netns exec ovs ip addr add 172.28.200.3/24 dev veth-c
ip link set veth-ovs promisc on
ip link set veth-ovs up
ovs-vsctl --may-exist add-port br-int veth-ovs -- set Interface veth-ovs ofport_request=1
ovs-vsctl --may-exist add-port br-int eth0 -- set Interface eth0 ofport_request=2
ovs-ofctl add-flow br-int "table=0, priority=100, ip, nw_dst=172.28.200.3 actions=output:1"
ovs-ofctl add-flow br-int "table=0, priority=100, arp,arp_tpa=172.28.200.3 actions=output:1"
ovs-ofctl add-flow br-int "table=0, priority=99, actions=output:2"
4.5.2 hostb
ip netns add ovs
ovs-vsctl add-br br-int -- set Bridge br-int fail_mode=secure
ip link add dev veth-c type veth peer name veth-ovs
ip link set veth-c netns ovs
ip netns exec ovs ip link set lo up
ip netns exec ovs ip link set veth-c up
ip netns exec ovs ip addr add 172.28.200.4/24 dev veth-c
ip link set veth-ovs promisc on
ip link set veth-ovs up
ovs-vsctl --may-exist add-port br-int veth-ovs -- set Interface veth-ovs ofport_request=1
ovs-vsctl --may-exist add-port br-int eth0 -- set Interface eth0 ofport_request=2
ovs-ofctl add-flow br-int "table=0, priority=100, ip, nw_dst=172.28.200.4 actions=output:1"
ovs-ofctl add-flow br-int "table=0, priority=100, arp,arp_tpa=172.28.200.4 actions=output:1"
ovs-ofctl add-flow br-int "table=0, priority=99, actions=output:2"
4.6 ovs with linux bridge
4.6.1 hosta
ip netns add ovs
brctl addbr linux-br
ip link set linux-br up
ovs-vsctl add-br br-int -- set Bridge br-int fail_mode=secure
ip link add dev ovs-br type veth peer name br-ovs
ip link set br-ovs promisc on
ip link set ovs-br promisc on
ip link set br-ovs up
ip link set ovs-br up
ovs-vsctl --may-exist add-port br-int br-ovs -- set Interface br-ovs ofport_request=1
brctl addif linux-br ovs-br
brctl addif linux-br veth-br
ip link add dev veth-c type veth peer name veth-br
brctl addif linux-br veth-br
ip link set veth-br up
ip link set veth-c netns ovs
ip netns exec ovs ip link set ovs up
ip netns exec ovs ip link set veth-c up
ip netns exec ovs ip addr add 172.28.100.3/24 dev veth-c
ovs-vsctl --may-exist add-port br-int eth0 -- set Interface eth0 ofport_request=2
ovs-vsctl add-port br-int eth0
ovs-ofctl add-flow br-int "table=0, priority=100, ip, nw_dst=172.28.100.3 actions=output:1"
ovs-ofctl add-flow br-int "table=0, priority=100,arp,arp_tpa=172.28.100.3 actions=output:1"
ovs-ofctl add-flow br-int "table=0, priority=99, actions=output:2"
4.6.2 hostb
ip netns add ovs
brctl addbr linux-br
ip link set linux-br up
ovs-vsctl add-br br-int -- set Bridge br-int fail_mode=secure
ip link add dev ovs-br type veth peer name br-ovs
ip link set br-ovs promisc on
ip link set ovs-br promisc on
ip link set br-ovs up
ip link set ovs-br up
ovs-vsctl --may-exist add-port br-int br-ovs -- set Interface br-ovs ofport_request=1
brctl addif linux-br ovs-br
brctl addif linux-br veth-br
ip link add dev veth-c type veth peer name veth-br
brctl addif linux-br veth-br
ip link set veth-br up
ip link set veth-c netns ovs
ip netns exec ovs ip link set ovs up
ip netns exec ovs ip link set veth-c up
ip netns exec ovs ip addr add 172.28.100.4/24 dev veth-c
ovs-vsctl --may-exist add-port br-int eth0 -- set Interface eth0 ofport_request=2
ovs-vsctl add-port br-int eth0
ovs-ofctl add-flow br-int "table=0, priority=100, ip, nw_dst=172.28.100.4 actions=output:1"
ovs-ofctl add-flow br-int "table=0, priority=100,arp,arp_tpa=172.28.100.4 actions=output:1"
ovs-ofctl add-flow br-int "table=0, priority=99, actions=output:2"
5 參考
Running etcd under Docker
https://coreos.com/etcd/docs/latest/v2/docker_guide.html
Running flannel
https://github.com/coreos/flannel/blob/master/Documentation/running.md
Centos7 安裝openvswitch
https://www.jianshu.com/p/658332deac99