前言
性能調優的“望聞問切”
容器化性能調優的難點
- VM級別的調優方式在容器中實現難度較大
在VM級別我們看到的即是所有,網絡棧是完整暴漏在我們面前的,CPU、內存、磁盤等也是完全沒有限制的。性能調優老司機的工具箱安個遍,診斷流程走一趟基本問題就查個八九不離十了,但是在容器中,很多時候,都是默認不自帶診斷、調優工具的,很多時候連ping或者telnet等等基礎命令都沒有,這導致大部分情況下我們需要以黑盒的方式看待一個容器,所有的症狀只能從VM層的鏈路來看。但是我們知道容器通過namespace的隔離,具備完整網絡棧,CPU、內存等通過隔離,只能使用limit的資源,如果將容器當做黑盒會導致很多時候問題症狀難以快速發現。排查問題的方式變難了。 - 容器化后應用的鏈路邊長導致排查問題成本變大
容器的場景帶來很多酷炫的功能和技術,比如故障自動恢復,彈性伸縮,跨主機調度等等,但是這一切的代價是需要依賴容器化的架構,比如Kubernetes網絡中需要FullNat的方式完成兩層網絡的轉發等等,這會給排查問題帶來更復雜的問題,當你不清楚編排引擎的架構實現原理的時候,很難將問題指向這些平時不會遇到的場景。例如上面這個例子中,FullNat的好處是降低了網絡整體方案的復雜性,但是也引入了一些NAT場景下的常見問題,比如短連接場景中的SNAT五元組重合導致包重傳的問題等等。排查問題的方位變大了。 - 不完整隔離帶來的調優復雜性
容器技術本質是一種虛擬化技術,提到虛擬化技術就離不開隔離性,雖然我們平時並不需要去考慮隔離的安全性問題,但是當遇到性能調優的時候,我們發現內核的共享使我們不得不面對的是一個更復雜的場景。舉個,由於內核的共享, 系統的proc是以只讀的方式進行掛載的,這就意味着系統內核參數的調整會帶來的宿主機級別的變更。在性能調優領域經常有人提到C10K或者C100K等等類似的問題,這些問題難免涉及到內核參數的調整,但是越特定的場景調優的參數越不同,有時會有彼之蜜糖,我之毒葯的效果。因此同一個節點上的不同容器會出現非常離奇的現象。 - 不同語言對cgroup的支持
這個問題其實大多數場景下我們是不去考慮的,但是在此我們把他列在第四位的原因是期望能夠引起大家的重視。一次在和Oracel Java基礎庫的負責同學聊天中了解到Java針對與Cgroup的場景做了大量的優化,而且時至今日,在Java的標准庫中對於Cgroup的支持還是不完全的,好在這點在大多數的場景中是沒有任何影響,也就不過多的討論。排查問題的腦洞更大了。 - 網絡方案不同帶來的特定場景的先天缺欠
提到容器架構我們逃不掉的話題是網絡、存儲和調度,網絡往往是一個容器架構好壞的最根本的評判標准,不同的網絡方案也會有不同的實現方式與問題。比如在阿里雲的Kubernetes中我們使用了Flannel的CNI插件實現的網絡方案,標准Flannel支持的Vxlan的網絡方案,Docker的Overlay的macVlan,ipvlan的方案等等。這些不同的網絡方案無一例外都是分布式的網絡方案而存儲的數據都會存放在一個中心存儲中,因此越大型的集群對網絡中心存儲的壓力也就越大,出錯的可能性就越大。此外跨宿主機的二層網絡很多都會通過一些封包解包的方式來進行數據傳輸,這種方式難免會增加額外的系能損耗,這是一種先天的缺欠,並不是調優能夠解決的問題。有的時候排查出問題也只能繞過而不是調優。
最后
這篇文章中我們主要討論了基礎的性能調優的方式以及容器化場景中性能調優的難點,在下篇文章中我們會來套路下不同的性能瓶頸現象對應的診斷和調優方法。
