新聞中心
前言

網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、成都微信小程序、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了天元免費(fèi)建站歡迎大家使用!
Weave作為Docker(一個開源的應(yīng)用容器引擎)跨主機(jī)集群網(wǎng)絡(luò)解決方案的一種,可以用于連接部署在多臺主機(jī)上的Docker容器,使用網(wǎng)絡(luò)的應(yīng)用程序不必去配置端口映射、鏈接等信息。另外,Weave的通信支持加密,用戶可以從一個不受信任的網(wǎng)絡(luò)連接到主機(jī)。
Weave在控制層和Calico類似,在數(shù)據(jù)層通過UDP封裝實(shí)現(xiàn)L2 overlay。Weave在1.2 版本之前都是通過usersapce實(shí)現(xiàn),在Weave-1.2版本之后,Weave結(jié)合了內(nèi)核Open vSwitch模塊,實(shí)現(xiàn)了Open vSwitch datapath(ODP)功能,結(jié)合kernel的vxlan特性,在網(wǎng)絡(luò)性能上有較大提升。
由于ODP功能與內(nèi)核相關(guān)模塊結(jié)合較為緊密,因此在實(shí)際使用中可能會遇到一些與內(nèi)核相關(guān)的“坑”。本文描述的這兩個問題都跟內(nèi)核有關(guān)系。
坑一:使用Weave FastDb造成虛擬機(jī)網(wǎng)絡(luò)中斷
1. 問題描述
在Weave的1.2版本之后,考慮到原先sleeve模式網(wǎng)絡(luò)性能較差,故增加FastDb模式,該模式也成為Weave啟動時的默認(rèn)模式。在FastDb模式中使用了kernel中的Open vSwitch模塊,做報(bào)文封裝時使用vxlan協(xié)議。在使用qemu-kvm創(chuàng)建的云主機(jī)上,如果安裝centos7.0,內(nèi)核版本為kernel-3.10.123,那么在啟動Weave并使用FastDb模式時,會造成virtio_net虛擬網(wǎng)卡無法發(fā)送數(shù)據(jù),進(jìn)而導(dǎo)致整個虛擬機(jī)的網(wǎng)絡(luò)中斷。
問題分析導(dǎo)致網(wǎng)絡(luò)斷開的原因是由于觸發(fā)了內(nèi)核的一個bug,該內(nèi)核bug的commit鏈接
觸發(fā)該bug主要是因?yàn)閃eave在初始化時會發(fā)送一個60000字節(jié)的UDP數(shù)據(jù)包進(jìn)行PMTU探測,并且 Weave發(fā)送使用的套接字為raw socket,導(dǎo)致virtio_net使用的內(nèi)存被污染,具體表現(xiàn)就是無法通知到宿主機(jī)上vhost獲取數(shù)據(jù),在接口上看到發(fā)送報(bào)文的計(jì)數(shù)始終不會增加。
該問題不是只有Weave才能觸發(fā),用普通應(yīng)用程序建立socket時使用raw socket,并且發(fā)送的數(shù)據(jù)大于接口的MTU值,接口的UFO功能是打開的,這些情況下都極有可能觸發(fā)該問題,造成網(wǎng)絡(luò)中斷。
(圖:FastDb模式的數(shù)據(jù)流原理)
2. 解決方法
1)升級內(nèi)核,保證內(nèi)核版本大于等于3.13;
2)關(guān)閉虛擬機(jī)網(wǎng)卡的ufo特性;
3)centos7.1的kernel-3.10.229內(nèi)核已經(jīng)修復(fù)了該問題。
(圖:guest通知vhost讀取數(shù)據(jù)流程)
坑二:Weave無法使用FastDb模式
1. 問題描述
在內(nèi)核版本CentOS Linux (3.10.0-327.10.1.el7.x86_64) 7 (Core)上 ,Weave版本大于1.2,如果云主機(jī)的MTU值為1450或者小于1474,Weave啟動時無法正常選擇Fast Data Path模式。在Weave啟動后一直選擇sleeve模式,本應(yīng)該默認(rèn)模式為FastDb,該問題也和內(nèi)核的版本相關(guān)。
2. 問題分析
Weave的Fast Data Path路徑使用到ODP技術(shù),也就是內(nèi)核中的OVS模塊,在Container中直接發(fā)送數(shù)據(jù)包到ovs模塊。在啟動Weave時,會自動選擇使用sleeve模式還是FastDb模式,這里通過發(fā)送心跳包來決定。出現(xiàn)該問題時,在云主機(jī)通過Docker logs Weave日志可以看到出錯信息:FastDb timed out waiting for vxlan heartbeat。
heartbeat數(shù)據(jù)包是一個UDP包,目的端口號為6784,在某些云主機(jī)上接口的MTU值為1454,但在發(fā)送UDP的heartbeat數(shù)據(jù)包時,發(fā)送的是1474字節(jié),這樣就會對報(bào)文在IP層進(jìn)行分片,而在主機(jī)上發(fā)現(xiàn)心跳報(bào)文發(fā)送不出去,當(dāng)MTU的值修改為1500后,就可以發(fā)送出去。
在MTU為1454的情況下,會出現(xiàn)下面的ICMP錯誤報(bào)文。
(圖3: 出現(xiàn)的錯誤ICMP報(bào)文)
上面出現(xiàn)錯誤的ICMP報(bào)文是內(nèi)核中的ip_fragment函數(shù)調(diào)用ICMP_send函數(shù)發(fā)送的,
- if (unlikely(((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) ||
- (IPCB(skb)->frag_max_size &&
- IPCB(skb)->frag_max_size > mtu))) {
- IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS);
- ICMP_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
- htonl(mtu));
- kfree_skb(skb);
- return -EMSGSIZE;
- }
通過上述代碼可以看出,如果出現(xiàn)錯誤ICMP報(bào)文,下面的判斷條件iph->frag_off & htons(IP_DF)) && !skb->ignore_df 需要成立。通過對抓取的報(bào)文分析可知iph->frag_off & htons(IP_DF))的值為真,那么skb->ignore_df值需要為0,而此處的關(guān)鍵在于skb->ignore_df的值是何時賦值為0的。
通過分析Weave發(fā)送心跳包的流程可知,在vxlan_tnl_send函數(shù)中,對skb->ignore_df賦值為1,***調(diào)用tunnel的發(fā)送函數(shù)iptunnel_xmit時,調(diào)用了skb_scrub_packet函數(shù),在該函數(shù)中又重新對skb->ignore_df賦值為0(kernel版本為:3.10.0-327.el7),造成后續(xù)發(fā)送報(bào)文時,ICMP目的不可達(dá),并且錯誤碼為ICMP_FRAG_NEEDED的報(bào)文。
- void skb_scrub_packet(struct sk_buff *skb, bool xnet)
- {
- skb->tstamp.tv64 = 0;
- skb->pkt_type = PACKET_HOST;
- skb->skb_iif = 0;
- skb->ignore_df = 0;
- skb_dst_drop(skb);
- secpath_reset(skb);
- nf_reset(skb);
- nf_reset_trace(skb);
- if (!xnet)
- return;
- skb_orphan(skb);
- skb->mark = 0;
- }
上面代碼是centos7的3.10.0-327.el7,而在一些舊內(nèi)核版本3.10.0-123.el7上,iptunnel_xmit調(diào)用的是secpath_reset(skb)函數(shù),該函數(shù)并沒有對skb->local_df(低版本內(nèi)核使用local_df)進(jìn)行重新初始化,也就是skb->local_df值仍舊為1,因此在該版本上不會出現(xiàn)上述問題。
- static inline void
- secpath_reset(struct sk_buff *skb)
- {
- #ifdef CONFIG_XFRM
- secpath_put(skb->sp);
- skb->sp = NULL;
- #endif
- }
(圖:內(nèi)核版本不同造成設(shè)置不同)
雖然新的內(nèi)核版本中存在該問題,不過內(nèi)核本身沒有問題,還是Weave用戶態(tài)管理datapath程序與內(nèi)核適配上出現(xiàn)問題(它并不是使用ovs-switchd),在OVS中對tunnel類型可以設(shè)置為df_default=false進(jìn)行分片。
解決方法
保證接口的MTU值為默認(rèn)為1500。
總結(jié)
Weave的ODP功能使用了內(nèi)核特性,在使用Weave的FastDb功能時遇到上述兩個問題都與內(nèi)核密切相關(guān)。通過對內(nèi)核層分析,可以定位到問題的根本原因,所以后續(xù)遇到類似問題時,可以多從內(nèi)核角度進(jìn)行考慮。
標(biāo)題名稱:如何跨過使用Docker網(wǎng)絡(luò)解決方案Weave遇到的“坑”?
網(wǎng)頁路徑:http://m.fisionsoft.com.cn/article/djpecie.html


咨詢
建站咨詢
