標籤:

那些年走過的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 |