那些年走過的OpenStack的坑(上)
OpenStack是由眾多內部組件和第三方軟體組成的龐大而複雜的分散式系統。各組件和第三方軟體都有自己不同的特點,如果不了解這些特點,很容易陷入坑中。
正是如此,作為OpenStack行業相關的工作者,不僅要學習OpenStack各組件、第三方軟體的功能,還要學習積累一些調試和排錯的方法,這樣在遇到問題時,才能臨危不亂,找准突破口,逐步找到問題所在。
本文列舉了雲途騰測試團隊在實際測試OpenStack過程中所遇到的7個奇葩的問題以及針對這些問題的排查過程和解決辦法。在本期中,重點對雲主機方面的三個問題進行討論,希望能對大家有所幫助。
問題現象:
在對公司內部的一個openstack版本進行測試時,發現創建出的雲主機異常,在雲主機里執行ps命令會卡住不動,執行top命令,發現有很多殭屍進程,而且這些雲主機無法刪除。
排查過程:
首先懷疑是鏡像有問題,造成所有基於該鏡像的雲主機都異常。
於是使用同樣的鏡像,在穩定的版本中反覆創建雲主機並進入雲主機查看,經過多次測試沒有出現問題。
由此排除鏡像的問題。
接下來查看兩個環境中雲主機的libvirt xml配置文件(位於目錄/v ar/lib/nova/instances/),在CPU的配置方面有如下差異:
有問題的雲主機:<topologysockets=1ncores=4threads=1>
正常的雲主機: <topology sockets=4ncores=1threads=1>
也就是說,雖然都是給雲主機配置4個CPU,但是前一種相當於是1顆4核心的CPU,後一種相當於是4顆單核心的CPU。
懷疑是這裡的問題造成的,因此對比雲主機類型(flavor),發現出問題的雲主機和正常的雲主機相比,flavor中的metadata有些差異:
"hw:cpu_cores":"4","quota:cpu_quota":"1000","quota:cpu_period":"1000"
正常的雲主機中沒有"hw:cpu_cores":"4",而且"quota:cpu_quota"和"quota:cpu_period"的值都是"2000"。
使用排除法,先排查"hw:cpu_cores":"4"
使用命令nova flavor-keyflavorID unset hw:spu_cores去除hw:cpu_cores:4這個參數
再次創建雲主機查看其libvirt xml文件,發現CPU配置變為和正常的機器一致,即:
<topologysockets=4 cores=1threads=1>
這時候在雲主機中使用ps命令不會再卡住,但是還是會有雲主機不能關閉(destory)的問題。
所以排除hw:cpu_cores:4的問題。
繼續排查,在出問題的環境中,將flavor中的quota:cpu_quota和quota:cpu_period都設置為2000。
再次創建雲主機,在雲主機中ps命令不會卡住,雲主機也能正常刪除了。
為了驗證問題,在這種配置的情況下,又繼續測試了幾小時,沒有發現問題。
基本確定是這兩個參數在搞鬼。
這裡有必要解釋一下cpu_period和cpu_quota這2個參數:
linux系統使用cgroup來管理cpu資源。cgroup用cpu.cfs_period_us 和 cpu.cfs_quota_us 來限制進程在單位時間裡可以使用的 cpu 時間。這裡的 cfs 是完全公平調度器的縮寫。cpu.cfs_period_us 就是時間周期,默認為 100000,即百毫秒。cpu.cfs_quota_us 就是在這期間內可使用的cpu時間,默認 -1,即無限制。類似地,在openstack中,nova也是通過使用cgroup對cpu資源進行管理的。
在linux系統中,對於多核CPU的情況,在數值上cpu.cfs_quota_us可以是cpu.cfs_period_us的n倍;對於nova來說,flavor中設置的這2個值會作用在雲主機申請的每個核上,即不用考慮多核的情況。
至於為什麼cpu_quota設置成1000,應該是為了更細化地分配cpu資源,讓cpu的利用率更高。
鑒於以上的定義,後面又測試了cpu_quota為1000,cpu_period為2000的場景,問題重現。
因此判斷,cpu_quota的值在1000時,會造成雲主機cpu死鎖。
後來,針對quota:cpu_quota和quota:cpu_period設置為2000的情況又進行了很長時間的壓力測試。
發現quota:cpu_quota值在2000時,還是會小几率出現此問題;而將這個參數調整為默認值:100000則沒有復現問題。
解決辦法:
在雲主機使用的flavor中,修改quota:cpu_quota和quota:cpu_period的值為默認值100000
問題現象:
在dashboard刪除雲主機,雲主機狀態一直處於刪除中。
排錯過程:
OpenStack中nova-compute服務負責管理雲主機,該服務如果工作不正常,會影響對雲主機的操作。
在控制節點使用nova service-list查看,發現novacompute服務down;在計算節點查看nova-compute服務狀態,顯示為active。
猜測nova compute服務已經不正常了,不能正常上報狀態,所以nova service-list顯示為down。
還有一個現象是,此時日誌文件/var/log/nova/nova-compute.log不再變化,進一步確定nova compute 服務卡死。
對於出現卡死的問題,可以採用gdb調試的方法來排查問題。
gdb是一個在UNIX環境下的命令行調試工具,具體使用方法多種多樣,這裡簡單使用bt(breaktrace)方法,列印調用棧。
先找出nova compute服務的進程號(2973),使用gdb python -p 2973進行調試。
進入gdb後輸入bt,列印當前函數調用棧的所有信息,結果發現在調用ceph時,程序卡住。
註:ceph是性能卓越的分散式存儲方案,cephnosd是ceph中實際存儲數據的地方,雲主機的硬碟就位於cephnosd中。
用ceph -s查看ceph osd狀態,發現有3個osd down掉,查看一個osd的log,提示:FileStore: sync_entry timed outnafter600 seconds。
在部署ceph osd時設置了ssdnjournal,即用一個ssd盤作為journal,它服務於5個SATA盤,也就是5個osd。有數據寫入osd時,數據會先緩存到ssd盤中,再從ssd寫入後端的5個SATA盤。
經過調查發現,在寫入數據比較大的時候,如果ssd到某個磁碟的寫入操作時間大於600秒(預設值),就會超時,造成對應的osd進程報錯並異常退出,不能發送心跳報文,導致osd down掉。
在使用ceph的時候,設置了副本數為2,也就是說一個文件會分成若干小的數據,而每一份數據會存放在兩個osd上,以提供冗餘。經過排查,發現雲主機硬碟的部分數據的雙副本所在的兩個osd都down掉了。造成ceph無法找到並刪除目標雲主機的數據,進而造成nova compute卡死。
解決方法:
在/etc/ceph/ceph.conf配置文件中,調整filestore_commit_timeout= 600,將600修改為較大的數值,比如30000,單位是秒,以增大每次從journal寫入後端磁碟的超時時間,防止osd down掉。
修改完成後重啟ceph以應用新的配置。
另外一個值得關注的問題是,問題環境中ssd和sata的比例是1:5。在用ssd盤做journal時,ceph社區推薦的是1:4,而根據後來的實際使用情況和測試結果來看,1:3效果比較好。如果有高性能設備做journal cache時,則該比例可以高達1:12到1:18。所以在部署ceph的時候也要考慮這一點,以提高存儲性能。
通常用戶可以通過ipmi/iLO等方式對物理伺服器的控制台進行訪問,而不需要連接伺服器的業務網路。類似地,openstack也提供了這種方式,它利用了VNC,可以讓用戶在瀏覽器中訪問雲主機的控制台,不管用戶業務網路是否正常。
通常用戶可以通過ipmi/iLO等方式對物理伺服器的控制台進行訪問,而不需要連接伺服器的業務網路。類似地,openstack也提供了這種方式,它利用了VNC,可以讓用戶在瀏覽器中訪問雲主機的控制台,不管用戶業務網路是否正常。
問題現象:
打開雲主機的VNC控制台,頁面一直處於刷新頁面,無法進入VNC。
排查過程:
VNC的正常工作依賴於nova-consoleauth和nova-novncproxy這兩個服務。
排查後發現上述兩個服務都是active狀態。
查看進程,novncproxy相關的子進程已經成為殭屍進程。
而此時雖然novncproxy服務還顯示正常運行,但其實它已經不能正常響應請求了,日誌文件也不再刷新。
由於還是卡死的問題,依然用gdb調試,列印出調用棧。
nnnn發現在執行/usr/lib/python2.7/site-packages/websockify/websocket.py中的start_server方法時卡住,具體是在調用vmsg方法的時候卡住。
查看start_server方法,發現它實際的功能就像一個普通的socketserver一樣,先建立一個server,然後循環監聽是否有客戶端連接,這是父進程。
一旦有客戶端連接,就創建一個新的進程來處理該連接,這是子進程。
一般情況下進程終止的時候,和它相關的系統資源並不是主動釋放的,而是先進入一種通常稱為「殭屍」(zombie)的狀態。它所佔有的資源一直被系統保留,直到它的父進程顯式地為其「收屍」。
當前的問題是,novncproxy主進程卡死在vmsg方法,而不能響應子進程。所以在子進程結束任務時,父進程沒有辦法來替子進程來收屍。這個時候,子進程就真的成了「殭屍」了,也就是圖中的 defunct的進程。
為什麼會在執行vmsg方法時卡住呢, 查看novncproxy的老日誌,發現有下面一條錯誤信息。
通過搜索該錯誤信息,在網上查到一個類似的錯誤,noVNC hangs after some time (variable) · Issue #556 · novnc/noVNC · GitHub在這個bug中說到了在使用VNC過程中遇到的問題,大致說的是每過幾個星期,就會出現vnc不能連接的情況。只能重啟novncproxy來解決。
在這個bug中看到websocket開發人員給出了另一個比較老的bug:OpenStack Compute (nova)
這個bug的標題是Using loggingnmodulefrom signal handler can wedge process,在bug中也說到It does look like using logging in a signal handler is a bad idea。由此我們得知,最好不要在signal handler中使用logging,因為會造成進程卡住。
在websocket.py中,在很多地方調用vmsg方法的場景,正是在signal handler中使用logging,比如:
這就解釋來了vmsg為什麼會卡住。所以應該避免在這些場景下使用vmsg。
解決方法:
bug中給出的解決方法,正是刪除對vmsg不合理的調用,比如:
具體修改處可以參考下面的鏈接:
Remove additional signal calls in websockify that causes novnc to hang. by noah8713 · Pull Request #219 · novnc/websockify · GitHub
我們將在下一期內容中從服務的層面為大家繼續分析那些年走過OpenStack的「keng」
推薦閱讀:
※今天說說OpenStack Pike的功能
※openstack入門的書該看什麼,求推薦?
※oVirt安裝配置——第一章(oVirt引擎篇)
※構建中移杭研OpenStack雲平台,迎接萬物互聯新時代
※如何在 OpenStack 中隱藏 Glance 鏡像
TAG:OpenStack |