實時 KVM

jopen 8年前發布 | 11K 次閱讀 KVM

實時虛擬化聽起來有點矛盾,但是它確實是有用的(在某些條件下),并且為 Linux 內核的靈活性又提供了一個強有力的證明。KVM2015 論壇的前兩個演講就詳細的討論了實時虛擬化。第一個演講者是 Rik van Riel,他講解了實時虛擬化的內核部分的工作(油Tube視頻幻燈片)。而第二個演講者 Jan Kiszka 則解釋了如何配置主機以及如何管理實時虛擬機(油Tube視頻幻燈片)。我們這篇文章就采取了他們兩人的意見,首先是 Van Riel 的想法。

PREEMPT_RT 內核

實時的重點是準確性,精確性,而不是速度。實時工作是那些沒有及時處理工作就會致命的工作,例如電信設備里的壞音,股票交易中的機會錯失,航空機械中的火箭爆炸。這些應用的特點是在一秒鐘可能會有上千個這樣的關鍵點,他們允許的最慢響應時間可能小到幾毫秒,并且 99.999% 的這些關鍵點工作都要被即時處理,如果沒有被及時處理的話... (想想上面的火箭爆炸吧),總之要全部及時的處理好。速度是重要的,但是要一直保證這種低延遲會帶來另一個問題,那就是產出下降。

幾乎每一個潛在的系統因素都來自于內核。比如,某個驅動程序可能會關閉中斷而阻斷高優先級的程序的調度。非實時內核中的自旋鎖也是另外一個潛在的原因,因為 linux 在持有自旋鎖的同時不能進行 schedule() 調度。這些問題可以通過運行 PREEMPT_RT(實時內核補丁集)構建的內核控制。除了臨界區代碼,一個 PREEMPT_RT 內核致力于使 linux 的每一部分都是可搶占的。

大多數的修改要求已經被并入 linus 的內核結構中:搶占式內核支持,優先級繼承,高分辨率定時器,線程中斷處置支持,自旋鎖元注解和 NO_HZ_FULL 模式。雖然 PREEMPT_RT 補丁很大,但和過去相比已經優化了很多。目前應該解決的主要三件事是:把 non-raw 自旋鎖轉為優先級繼承互斥鎖,把中斷處理真正放在線程中運行以便實時任務可以搶占他們,和支持搶占的 RCU(Read-Copy Update,讀取-復制更新)實現。

遺留的主要問題在固件當中。x86的系統管理中斷(SMIs)關心諸如風扇轉速等事情。SMIs 不能夠被操作系統阻塞,極端情況下會消耗數毫秒的時間。在此期間,操作系統完全被阻塞,除了購買良好的硬件之外,別無它法。內核模塊 hwlatdetect 可以用來檢測該問題,其阻塞一個 CPU 上的中斷,尋找異常的延時峰值,并用特殊模塊寄存器(MSRs)將該峰值關聯到 SMIs 之上。

實時虛擬化,真的嗎?

當前,實時虛擬化聽起來可能難以置信,但確實可以。當然,仍有諸多問題存在:例如,虛擬機(VM)中任務的優先級和客戶機中鎖的持有者在主機中均不可見。這限制了調度器的靈活性,并阻止了優先級集成。因此,所有虛擬 CPU(VCPU)被置于非常高的優先級。僅僅內核軟中斷有更高的優先級,因此其向虛擬 CPU 傳遞中斷指令。為了避免讓主機處于饑餓狀態,系統必須在運行系統任務的 CPU 和運行實時客戶機的 CPU 間分區(使用 ioslcpus 和 nohz_fulkernel 命令行參數進行標記)。客戶機必須以相同的方式在 VCPU 和運行普通任務的 CPU 間進行分區。后者可能會偶發性的退出到主機的用戶態,這可能會比較長(非常像裸機狀態的SMI),并且阻止客戶機的調度。

因此,虛擬化的實時客戶機比在裸機上的同樣工作負載要使用更多的資源,而且這些資源必須專用于特定客戶機。但是,這是可以接受的代價,以支持虛擬化提供的改善的隔離性,可管理性和硬件兼容性。此外,最近的每一代處理器在一個 CPU 插槽里有越來越多的內核可用;摩爾定律看上去在彌補這個問題,至少目前是這樣。

一旦實時 KVM 設計如上實現出來,剩下的部分就是修復 bug。許多修復要么是針對 KVM 的,要么是針對 PREEMPT_RT 的,所以它們將有利于所有的實時用戶和所有虛擬化用戶。例如,RCU 被改為有客戶機運行時的擴展靜默狀態。擴展了 NOHZ_FULL 的支持,當運行 SCHED_FIFO(實時)任務時來完全禁用定時器時鐘。在這種情況下,由于更高級別的任務已經搶先,此任務不會被重新調度,所以并不需要計時器時鐘。加入了一些設置點來禁用能引入延遲(比如從宿主機到客戶機的時間同步)的不必要 KVM 功能;這會占用幾微秒時間,解決方法就是簡單地在客戶機運行 ntpd。

虛擬化的開支可以通過使用 PREEMPT_RT 的"簡單等待隊列"而不是全功能的 Linux 等待隊列加以限制。這只會占用有限時間的鎖,所以操作的長度同樣是有限的(中斷處理程序經常需要喚醒,所以它們的消耗會直接影響延遲)。將簡單等待隊列合并到主流內核的事正在被討論

另一個技巧就是稍微提前一點調度 KVM 的定時器,這樣就可以抵消注入虛擬中斷時的消耗。虛擬層將中斷傳遞給客戶機需要幾個微秒,KVM 核心模塊中有一個參數允許基于客戶機測得的延遲進行微調。

最后,新的處理器技術也有一些幫助。下面的案例是 Intel 的"CacheAllocation Technology" (CAT),這在一些 Haswell CPU 上可以使用。從 DRAM 和 TLB 中加載數據未命中結合起來的消耗可以導致一個單點未緩存環境,這將導致聯合延遲高達 50 微秒。CAT 允許對指定的應用保留部分緩存,以防止一個工作負載將另一個工作負載驅逐出緩存,而且它使用一個基于控制組的接口完美進行控制。但是,這個補丁還沒有納入 Linux 中。

使用反復測試得出的結果出乎意料的好。純物理延遲小于 2 微秒,盡管 KVM 測量的結果為 6 毫秒,但任然是一個很好的結果。為了達到這些數字,系統需要仔細地設置以避免所有高延遲的系統操作:沒有 CPU 變頻,沒有 CPU 熱插拔,不進行內核模塊加載或卸載,同時也沒有 swapping。除非實時輔助程序外,應用也進行了調整,以避免使用慢速的設備(如:硬盤或音響設備)。所以,部署實時 KVM 需要對系統和工作負載有深入的了解(例如,確保時間戳計數器的穩定,使系統不會回退到其它的時鐘源)。隨著人們更多地使用實時 KVM,一些新的瓶頸將會被發現,但是內核方面的工作大體上進行良好。

"我可以在我的云上使用它嗎?"

在這一點上,Van Riel 將舞臺留給了 Kiszka,Kiszka 將會對主機配置進行更多地討論,包括怎樣自動化,怎樣使用 libvirt 和 OpenStack 管理系統。

Kiszka 是一個長期的 KVM 貢獻者,他供職于西門子。在許多年前他開始使用 KVM,并解決了硬件兼容性問題這是一個遺留的軟件問題 [PDF]。他已經研究實時KVM [油Tube] 許多年,人們現在會問:“我可以把它部署在我的云上么?”

答案是“可以”,但是也有一些限制。當然這不是公有云。為生產做實時控制不是很順利,那是因為你需要從一些數據中心做 I/O 很遠。“云”這里指的是私有云,里面的虛擬機和進程是通過快速以太網連接的。云環境下還有許多特性,因為他們不提供確定的延遲。舉例來說,實時路徑不能使用磁盤或動態遷移,但是這通常不是個問題。

Van Riel 解釋說,基本的配置已經不滿足需要,首先要看的就是網絡。許多 QEUM 仍然是通過“大 QEMU 鎖(big QEMU lock)”來保證的,設備透傳已經有延遲問題。不過在一些方面正取得進展,比如,它已經可以能讓準虛擬化設備(virtio-net)和 non-QEMU 后端在一起使用。

KVM 提供了兩個這樣 virtio-net 的后端,vhost-net 和 vhost-user。Vhost-net 位于內核,在虛擬機上,它從 Linux 網絡棧的 virtio-net 設備上連出一個 TAP 設備。他們都不接受延遲。Vhost-user 與之相反,允許任何用戶空間進程提供網絡,并可以與專業的網絡庫一起使用。

以具有實時能力網絡庫包括數據平臺開發套件(DPDK)或者 SnabbSwitch 為例。這些棧是替代輪詢策略的選擇;這減少了大量的信號和事件,作為結果它也會導致延遲。Kiszka 設置使用 DPDK 作為 vhost-user 客戶端;當然,其運行在一個優先級。為客戶提供及時的 vcpu 中斷,它必須比 VCPU 線程放置在一個更高的優先級上。

Kiszka 的應用程序沒有高的包率,所以一個物理 CPU 足以運行所有網絡接口系統的切換;更苛刻的應用程序可能需要為每個接口提供一個物理 CPU。

在實驗室里,實時虛擬化成型后,轉移它們到數據中心需要一些額外的工作。成百上千的虛擬機和大量的異構網絡,它們中的一些是實時的,另外一些不是,這需要管理和靈活計費。實現這種需求需要一個云管理堆疊,諸如:OpenStack 就是一個被選擇出來和可擴展的,具有實時能力的平臺。它參考的架構包含(自底向上):PREEMPT_RT 內核,QEMU(在這里客戶機不是實時的,這需要設置 vhost-user 開關),基于 DPDK 的開關,libvirt,和 OpenStack。每一臺主機,或者說“計算節點”,被設定為獨立的物理 CPU,這解釋了上半部分的內容。IRQ 相關內容還需要顯式地設置(通過失衡的守護進程),默認來說,這不涉及內核的 isolcpus 設置。但是,根據工作負載,可能需要調整,在任何情況下,如果有許多類似的主機,安裝很容易被復制。有一個被叫做 partrt 的工具有助于建立隔離。

Libvirt 和 OpenStack

更高一層的 libvirt,不需要太多的規則,它僅僅會從高層上執行命令。在 libvirt 1.2.13 上,所有必需的可調參數是可用的:設置可調參數(規則,優先級,阻塞物理 CPU),用 mlock()查詢 QEMU 所有的客戶機內存(RAM),并啟動虛擬機連接到 vhost-user 進程。這些參數是由 OpenStack 計算節點的 Nova 組件處理的。

Nova 已經可以被配置為虛擬 CPU(VCPU)阻塞并指定物理 CPU。其他的設置,在 OpenStack 中被錯過,這在一個藍圖(a blueprint)中已被討論。它還沒有被完成(舉例來說,它提供了聯合無實時 CPU 到無實時 QEMU 的線程),藍圖將會使得剩余的 libvirt 功能生效。補丁正在被討論,目標是在 OpenStack 的“Mitaka”版本發布,大概是在 2016 年的上半年左右。 Kiszka 的團隊會集成補丁部署;團隊將會提出擴展的補丁和藍圖。

OpenStack 是通過 Neutron 組件控制網絡的。然而,實時網絡趨向于特殊:他們根本不使用TCP/IP,Neutron 想要使用自己的方式管理網絡。西門子(Siemens)說 Neutron 是“非托管型”網絡(沒有DHCP,甚至沒有IP)。

總而言之,工作在更高層上的棧主要是為有實時能力的計算節點的基本設置進行標準化,許多工作是為了優化參數處理,諸如 partrt。在問答環節,如前所述,也被擴展以支持實時優化參數文件。然而, Kiszka 還計劃著再看看更低的棧;最新的芯片有功能消除中斷延遲,當直接分配設備給虛擬機的時候,不涉及到管理程序而直接路由中斷,另外,Kiszka 過去的工作[PDF]讓 QEMU 可以模擬實時設備并可以使其在未來恢復。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!