[原] KVM虛擬機網絡閃斷分析

背景

公司雲平臺的機器時常會發生網絡閃斷,一般在10s-100s之間。html

異常狀況

VM出現問題時,表現出來的狀況是外部監控系統沒法訪問,猜想多是因爲系統假死,OVS鏈路問題等等。可是在出現網絡問題的時候,HV統一的表現爲iowait較高。node

排除過程

這是一個艱難的過程,因爲沒法重現現場,致使只能經過一些理論手段來推測緣由。git

肯定是不是網絡緣由

  1. 閃斷是否由OVS形成?
    在對OVS作了一段時間的壓力測試後,發現並未出現網絡閃斷的現象,這裏的壓測單純只針對OVS,壓測一段時間後並未發現有異常,初步排除因OVS引發的網絡問題,可是不能徹底排除。ubuntu

  2. 是不是virtio引發的?
    爲此,我還分析了一下QEMU與VM virtio與tap之間的數據交互過程.網絡


如下是我分析virtio與tap可能致使閃斷的緣由的原文

背景

最近研究了下kvm的io虛擬化,結合線上環境下,我初步認定網絡丟包不是OVS致使的,應該是 vhost-net 與 tap interfaces 傳輸階段致使的丟包架構

證明理由

2016-03-30 18:12:39 宿主機 ip-10-21-176-234.ds.yyclouds.com 上10.25.129.117 出現過網絡閃斷
在宿主機上查看丟包狀況:(其餘vm也有相應的丟包,不過tapac3c8c7d-43網卡特別突出)app

Iface           MTU Met  RX-OK     RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
qbrac3c8c7d-43  1500 0    161057        0      0 0             8      0      0      0 BMRU
qvbac3c8c7d-43  1500 0  8708405804      0    432 0      11426577032   0      0      0 BMPRU
qvoac3c8c7d-43  1500 0  11426577032     0      0 0      8708405804    0    216      0 BMPRU
tapac3c8c7d-43  1500 0  11426582924     0      0 0      8707387025    0 1012779     0 BMRU

發現tapac3c8c7d-43 出現過較多丟包(TX-DRP=1012779)
tap MAC信息異步

tapac3c8c7d-43 Link encap:Ethernet  HWaddr fe:16:3e:09:53:5e  
          inet6 addr: fe80::fc16:3eff:fe09:535e/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:11429067595 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8709318110 errors:0 dropped:1012779 overruns:0 carrier:0
          collisions:0 txqueuelen:500 
          RX bytes:2695286604414 (2.6 TB)  TX bytes:1171426033029 (1.1 TB)

VM eth0 MAC信息ide

eth0      Link encap:Ethernet  HWaddr FA:16:3E:09:53:5E  
          inet addr:10.25.129.117  Bcast:10.25.131.255  Mask:255.255.252.0
          inet6 addr: fe80::f816:3eff:fe09:535e/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8709294638 errors:0 dropped:0 overruns:0 frame:0
          TX packets:11429037291 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1171422605901 (1.0 TiB)  TX bytes:2695279473603 (2.4 TiB)

宿主機上的tap 就是 虛擬機eth0 網卡. 其對應的mac地址同樣,且eth0網卡沒有統計到丟包,而tap統計到丟包, 這是由於virtio-vhostnet是異步的,vm並不知道數據丟失。這裏是最重要的判斷依據函數

neutron 計算節點虛擬網卡結構圖

neutron-net-structure.png-161.2kB

結合vhost-net數據流程,能夠看到tap TX對應到的是tap發送數據到vhost-net的過程。(下圖的tun與vhost-net之間)

vhost-net.png-108.2kB

可能致使丟包的緣由

vhost-interactive.png-31.5kB
TX-DROP 丟包,懷疑是系統負載增長時,vhost-net處理不過來, 致使tap tx 隊列滿以致發送drop.

可能的解決方案

增長tap tx隊列,目前隊列爲 500, 增長爲1000

參考

tap丟包現象
Neutron計算節點網絡架構
KVM Troubleshooting
Vhost overview


通過實際分析,然而實際狀況並非這樣的

當時在考慮是否將虛擬機的多隊列打開,這樣就不會出現某一個vCPU在處理virtio event事件的時候(相似於軟中斷處理)沒法響應的狀況.

  1. 爲何不是tap queue隊列致使?
    發現網絡閃斷的機器丟包數達到1012779,發生在大概20s的時間內,也就是說,即便隊列增長到5000,也會出現丟包,根本緣由不在隊列大小。

  2. 之下而上的排查,是不是vm內部致使?
    在打開了VM的內核日誌後,發現閃斷時候都會出現以下堆棧信息:
Apr 22 20:17:01 snapshot kernel: BUG: soft lockup - CPU#9 stuck for 67s! [mongod:58233]
Apr 22 20:17:01 snapshot kernel: [<ffffffff81052268>] ? flush_tlb_others_ipi+0x128/0x130
Apr 22 20:17:01 snapshot kernel: [<ffffffff810522e6>] ? native_flush_tlb_others+0x76/0x90
Apr 22 20:17:01 snapshot kernel: [<ffffffff8105240e>] ? flush_tlb_page+0x5e/0xb0
Apr 22 20:17:01 snapshot kernel: [<ffffffff8114e467>] ? do_wp_page+0x2f7/0x920
Apr 22 20:17:01 snapshot kernel: [<ffffffff8114eef9>] ? __do_fault+0x469/0x530
Apr 22 20:17:01 snapshot kernel: [<ffffffff8114f28d>] ? handle_pte_fault+0x2cd/0xb00
Apr 22 20:17:01 snapshot kernel: [<ffffffff81169e19>] ? alloc_page_interleave+0x89/0x90
Apr 22 20:17:01 snapshot kernel: [<ffffffff810516b7>] ? pte_alloc_one+0x37/0x50
Apr 22 20:17:01 snapshot kernel: [<ffffffff8114fcea>] ? handle_mm_fault+0x22a/0x300
Apr 22 20:17:01 snapshot kernel: [<ffffffff8104d0d8>] ? __do_page_fault+0x138/0x480
Apr 22 20:17:01 snapshot kernel: [<ffffffff8144a21b>] ? sys_recvfrom+0x16b/0x180
Apr 22 20:17:01 snapshot kernel: [<ffffffff81041e98>] ? pvclock_clocksource_read+0x58/0xd0
Apr 22 20:17:01 snapshot kernel: [<ffffffff81040f2c>] ? kvm_clock_read+0x1c/0x20
Apr 22 20:17:01 snapshot kernel: [<ffffffff81040f39>] ? kvm_clock_get_cycles+0x9/0x10
Apr 22 20:17:01 snapshot kernel: [<ffffffff810a9af7>] ? getnstimeofday+0x57/0xe0
Apr 22 20:17:01 snapshot kernel: [<ffffffff8152ffde>] ? do_page_fault+0x3e/0xa0
Apr 22 20:17:01 snapshot kernel: [<ffffffff8152d395>] ? page_fault+0x25/0x30

看到,大部分狀況下,是因爲mongod進程引發,偶爾會有其餘進程。
讓咱們來回憶(瞭解)下Mongodb的存儲原理
Mongodb 使用到了系統的 mmap 系統調用來完成進程內部的內存與磁盤的關聯,在一個比較大的操做的時候,好比掃表,會出現物理內存不夠用的狀況,這個時候會mmap出來的內存會頻繁的產生內存與磁盤之間的交換,具體表現爲產生不少的缺頁中斷。
好了,到這裏,慢慢的有點眉目了,大概狀況是因爲vCPU soft lockup致使。

  1. 爲何cpu lockup 會致使網絡閃斷?
    先說說cpu soft lockup, 在內核調度的過程當中,會對每個調度的cpu的當前進程的上下文作一個時間戳,有一個watchdog會用來reporting這個時間戳,當進程被調度出去後,watch dog發現cpu的時間戳時間大於配置時間,好比10s,就會記錄這個soft lockup。
    那就是說,這個機率事件發生在,當前的lockup的cpu,正好是處理virtio event的cpu,此時網絡發生中斷,外部系統沒法訪問。

  2. 是什麼緣由致使了 cpu soft lockup ?
    首先簡要的瞭解下缺頁中斷,以及tlb
    堆棧請從下往上看,謝謝.
    [ ] ? page_fault+0x25/0x30 訪問到了一個不在tlb表記錄的內存?怎麼辦,產生一個缺頁中斷
    [ ] ? do_page_fault+0x3e/0xa0 中斷處理過程
    [ ] ? kvm_clock_read+0x1c/0x20 // 如下步驟爲獲取時間戳
    [ ] ? kvm_clock_get_cycles+0x9/0x10
    [ ] ? getnstimeofday+0x57/0xe0
    算了,讓咱們直接跳到最後吧
    [ ] ? flush_tlb_others_ipi+0x128/0x130
    [ ] ? native_flush_tlb_others+0x76/0x90
    [ ] ? flush_tlb_page+0x5e/0xb0
    [ ] ? do_wp_page+0x2f7/0x920
    [ ] ? __do_fault+0x469/0x530
    [ ] ? handle_pte_fault+0x2cd/0xb00
    在完成了缺頁中斷處理後,系統要作的工做是刷新TLB表, 這裏不只要刷新本身當前CPU的TLB,還要刷新其餘CPU的TLB
    [ ] ? flush_tlb_others_ipi+0x128/0x130 系統調用,會向其餘CPU發送(ipi) Inter-processor interrupt

在經過CPU 核間中斷(ipi)通知其餘CPU的時候,會不斷的阻塞等待其餘CPU完成flush操做,主要體如今cpu_relax()函數阻塞。
在虛擬化環境中,有可能在發送ipi的時候,其餘的vCPU(體如今HV就是一個線程)被調度,此時的vCPU不處於online模式,不會對此ipi作中斷響應,因而發起ipi的vCPU就會阻塞。
此BUG後來在3.2.7後被reporting,後面的版本修復。

加上了對是否vCPU online的判斷。 因此對於此soft lockup事件,咱們建議使用3.2.7版本之後的內核。

總結

KVM環境下,VM請使用3.2.7之後版本的內核,呵呵噠

相關文章
相關標籤/搜索