虛擬機和Linux Container的性能比較
IBM研究部門發表了一篇關于容器和虛擬機環境性能比較的論文。這篇論文使用了Docker和KVM作為研究對象,闡述了Docker使用NAT或AUFS時的開銷,并且質疑了在虛擬機上運行容器的實踐方法。
論文作者在原生、容器和虛擬化環境中運行了CPU、內存、網絡和I/O的benchmark。其中,分別使用KVM和Docker作為虛擬化和容器技術的代表。Benchmark也包含了對不同環境下Redis和MySQL負載的采樣。通過小數據包和多客戶端,Redis側重于網絡棧的性能。而MySQL側重于內存,網絡和文件系統的性能。
結果顯示,在每一項測試中,Docker的性能等同于或超出KVM的性能。在CPU和內存性能方面,KVM和Docker都引入了明顯的,但可略不計的開銷。但是,對于I/O密集型的應用,兩者都需要進行調整以減少開銷帶來的影響。
當使用AUFS存儲文件時,Docker的性能會降低。而相比之下,使用卷(volume)能夠獲得更好的性能。卷是一種專門設計的目錄,存在于一個或多個容器內。通過這種目錄能夠繞過聯合文件系統(union file system)。這樣它就沒有了存儲后端可能帶來的開銷。默認的AUFS后端會引起顯著的I/O開銷,特別是當有多層目錄深度嵌套的時候。
Docker的默認網絡選項,--net=bridge
,由于NAT會重寫數據包,也引入了性能開銷。當數據包收發率變高時,這種開銷會變得很明顯。可以通過使用--net=host
改善網絡的性能。這個選項告訴Docker不要為容器創建一個獨立的網絡棧,并允許容器擁有宿主機網絡接口的完全訪問權限。但是,使用這個選項時要小心。因為它允許容器內的進程像其他根進程一樣,使用數值較小的端口;并允許容器內的進程訪問本地網絡服務,如D-bus。這使得容器內的進程可以做一些預料之外的事情,如重啟宿主機。
盡管自誕生以來,KVM性能有了相當大的提升,但它仍然不適用于對延時敏感或高I/O訪問率的工作負載。因為每次I/O操作,它都會增加一些開銷。這個開銷對于耗時較少的I/O操作是有意義的,但對于耗時較長的I/O操作是可以忽略的。
根據這些測試結果,論文對使用虛擬機實現IaaS的方法提出了質疑:
傳統觀點(在某種程度上,這種觀點存在于年輕的云生態圈中)認為使用虛擬機實現IaaS,使用容器實現PaaS。我們沒有找到技術方面的理由來證明必須這么做,尤其是證明容器基于IaaS能提供更好的性能或者更容易部署。由于容器提供了控制手段,并在不使用虛擬機的情況下能達到物理機的性能,所以它能夠消除IaaS和非虛擬化的服務器間的差異。
盡管在虛擬環境中運行容器是一種常見的實踐方法,但是論文建議直接在物理的Linux服務器上運行它們。否則,相比于直接運行在非虛擬化的Linux上的方法,由于虛擬機的性能開銷,這種實踐方法不會得到任何額外的好處。
參考英文原文:Comparing Virtual Machines and Linux Containers Performance