背景 http://www.itdecent.cn/p/56ea47e91b74
上回通過(guò)操作數(shù)據(jù)庫(kù)刪除了一個(gè)“自認(rèn)為”多余的 cell,怎么刪的呢?簡(jiǎn)單回顧下,先刪了 nova_api 數(shù)據(jù)庫(kù)里 instance_mappings 里的 instance,再刪了 cell_mappings 里面的 cell。
當(dāng)時(shí)還洋洋得意以為解決了一個(gè)大問(wèn)題,睡前越想越覺(jué)得不對(duì)勁,我居然動(dòng)了instance_mappings 表,萬(wàn)一里面存了什么重要信息怎么辦?
果然自食其果了,在horizon界面上查看不了虛擬機(jī)詳情了,也無(wú)法操作虛擬機(jī)了。。。
且看下面
1. 消失的虛擬機(jī)
無(wú)法點(diǎn)開(kāi)虛擬機(jī)查看詳情

錯(cuò)誤:無(wú)法獲取實(shí)例 "2f565c93-6eec-4a74-b8e8-f55638b56da3" 的詳情。
在控制節(jié)點(diǎn)上查看
tail /var/log/httpd/error_log

NotFound: Instance 2f565c93-6eec-4a74-b8e8-f55638b56da3 could not be found. (HTTP 404) (Request-ID: req-999c856a-e2b6-4360-9fba-3bf8db6e283f)
看到這樣的提示,一般是出現(xiàn)僵尸實(shí)例了,但它確實(shí)運(yùn)行著,還連得上去呢:

數(shù)據(jù)庫(kù)里也有:

不行了,趕快學(xué)一下 cell 的知識(shí)。在目前的Pike版本,cell版本為v2版本,簡(jiǎn)單的說(shuō),cell_v2是一種扁平化的架構(gòu),用來(lái)在集群節(jié)點(diǎn)擴(kuò)張時(shí),降低數(shù)據(jù)庫(kù)和消息隊(duì)列訪問(wèn)瓶頸的。
參考 http://www.itdecent.cn/p/653e43a02ddc
cell的相關(guān)數(shù)據(jù)表在nova_api中,看到這張圖就明白了:

虛擬機(jī)在 instance_mappings 表里,計(jì)算節(jié)點(diǎn)在 host_mappings 表里,cell 在 cell_mappings表里。
當(dāng)想要獲取一個(gè)機(jī)器的詳細(xì)信息時(shí) :
1.nova-api 先從 instance_mappings 表拿到 instance 的 cell_id
2.再?gòu)?cell_mappings 表拿到所在 cell 的 DB connection
3.直接連接 cell 的 DB 拿到機(jī)器的詳細(xì)信息
還記得之前為了刪除多余的 cell,在nova_api 的 instance_mappings 里刪了n多條記錄嗎?
這個(gè)虛擬機(jī)之前在 instance mapping 表里,但被刪了,再也找不回來(lái)了……
所以說(shuō),沒(méi)事還是別動(dòng)數(shù)據(jù)庫(kù),動(dòng)之前一定要備份?。?!
發(fā)生了這種操作真的該敲警鐘了,要是在公司可以直接卷鋪蓋了》》》》
2. 神奇的NoValidHost(reason="")
也就是做以上改動(dòng)的前后,環(huán)境里突然創(chuàng)建不起虛擬機(jī)了,連 1GRam/1VCPU/10GBDisk 都創(chuàng)不起來(lái),而且控制節(jié)點(diǎn)中除了 /var/log/nova/nova-conducter.log 中以下log,/var/log/nova/nova-scheduler.log 中幾乎沒(méi)有有用的信息,看不出nova filter的過(guò)濾log。
(奇怪的是,210mbRam/1VCPU/10GBDisk 是創(chuàng)的起來(lái)了,但當(dāng)時(shí)并沒(méi)有懷疑到內(nèi)存真的不夠了)
/var/log/nova/nova-conducter.log 中日志如下:
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager [req-49530488-2149-4f15-85ea-5659267ffada 8668aa3368c0427c98b1d1824a36f720 f30a92c42d264a79ba5744b084346a2d - default default] Failed to schedule instances: NoValidHost_Remote: \u627e\u4e0d\u5230\u6709\u6548\u4e3b\u673a\uff0c\u539f\u56e0\u662f \u3002
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/oslo_messaging/rpc/server.py", line 232, in inner
return func(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/nova/scheduler/manager.py", line 138, in select_destinations
raise exception.NoValidHost(reason="")
NoValidHost: \u627e\u4e0d\u5230\u6709\u6548\u4e3b\u673a\uff0c\u539f\u56e0\u662f \u3002
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager Traceback (most recent call last):
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager File "/usr/lib/python2.7/site-packages/nova/conductor/manager.py", line 1072, in schedule_and_build_instances
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager instance_uuids)
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager File "/usr/lib/python2.7/site-packages/nova/conductor/manager.py", line 636, in _schedule_instances
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager request_spec, instance_uuids)
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager File "/usr/lib/python2.7/site-packages/nova/scheduler/utils.py", line 586, in wrapped
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager return func(*args, **kwargs)
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager File "/usr/lib/python2.7/site-packages/nova/scheduler/client/__init__.py", line 52, in select_destinations
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager instance_uuids)
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager File "/usr/lib/python2.7/site-packages/nova/scheduler/client/__init__.py", line 37, in __run_method
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager return getattr(self.instance, __name)(*args, **kwargs)
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager File "/usr/lib/python2.7/site-packages/nova/scheduler/client/query.py", line 33, in select_destinations
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager instance_uuids)
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager File "/usr/lib/python2.7/site-packages/nova/scheduler/rpcapi.py", line 137, in select_destinations
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager return cctxt.call(ctxt, 'select_destinations', **msg_args)
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager File "/usr/lib/python2.7/site-packages/oslo_messaging/rpc/client.py", line 169, in call
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager retry=self.retry)
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager File "/usr/lib/python2.7/site-packages/oslo_messaging/transport.py", line 123, in _send
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager timeout=timeout, retry=retry)
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager File "/usr/lib/python2.7/site-packages/oslo_messaging/_drivers/amqpdriver.py", line 566, in send
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager retry=retry)
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager File "/usr/lib/python2.7/site-packages/oslo_messaging/_drivers/amqpdriver.py", line 557, in _send
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager raise result
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager NoValidHost_Remote: \u627e\u4e0d\u5230\u6709\u6548\u4e3b\u673a\uff0c\u539f\u56e0\u662f \u3002
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager Traceback (most recent call last):
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager File "/usr/lib/python2.7/site-packages/oslo_messaging/rpc/server.py", line 232, in inner
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager return func(*args, **kwargs)
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager File "/usr/lib/python2.7/site-packages/nova/scheduler/manager.py", line 138, in select_destinations
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager raise exception.NoValidHost(reason="")
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager NoValidHost: \u627e\u4e0d\u5230\u6709\u6548\u4e3b\u673a\uff0c\u539f\u56e0\u662f \u3002
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager
2018-12-27 15:05:44.860 31027 ERROR nova.conductor.manager
2018-12-27 15:05:45.321 31027 WARNING oslo_config.cfg [req-49530488-2149-4f15-85ea-5659267ffada 8668aa3368c0427c98b1d1824a36f720 f30a92c42d264a79ba5744b084346a2d - default default] Option "enable" from group "cells" is deprecated for removal (Cells v1 is being replaced with Cells v2.). Its value may be silently ignored in the future.
2018-12-27 15:05:45.402 31027 WARNING nova.scheduler.utils [req-49530488-2149-4f15-85ea-5659267ffada 8668aa3368c0427c98b1d1824a36f720 f30a92c42d264a79ba5744b084346a2d - default default] Failed to compute_task_build_instances: 找不到有效主機(jī),原因是 。
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/oslo_messaging/rpc/server.py", line 232, in inner
return func(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/nova/scheduler/manager.py", line 138, in select_destinations
raise exception.NoValidHost(reason="")
NoValidHost: \u627e\u4e0d\u5230\u6709\u6548\u4e3b\u673a\uff0c\u539f\u56e0\u662f \u3002
: NoValidHost_Remote: \u627e\u4e0d\u5230\u6709\u6548\u4e3b\u673a\uff0c\u539f\u56e0\u662f \u3002
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/oslo_messaging/rpc/server.py", line 232, in inner
return func(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/nova/scheduler/manager.py", line 138, in select_destinations
raise exception.NoValidHost(reason="")
NoValidHost: \u627e\u4e0d\u5230\u6709\u6548\u4e3b\u673a\uff0c\u539f\u56e0\u662f \u3002
2018-12-27 15:05:45.403 31027 WARNING nova.scheduler.utils [req-49530488-2149-4f15-85ea-5659267ffada 8668aa3368c0427c98b1d1824a36f720 f30a92c42d264a79ba5744b084346a2d - default default] [instance: c2963f0d-370c-43aa-8cee-0131760d6ef2] Setting instance to ERROR state.: NoValidHost_Remote: \u627e\u4e0d\u5230\u6709\u6548\u4e3b\u673a\uff0c\u539f\u56e0\u662f \u3002
我查了下,幾個(gè)計(jì)算節(jié)點(diǎn)的內(nèi)存、vcpu數(shù)、磁盤絕對(duì)夠用,為啥它就報(bào) NoValidHost 的錯(cuò)?而且 reason="" ?
我跟著日志中報(bào)錯(cuò)的代碼一個(gè)文件一個(gè)文件的看,直到在 /usr/lib/python2.7/dist-packages/nova/scheduler/manager.py 的第138行之上看到了這條:

"Got no allocation candidates from the Placement "
"API. This may be a temporary occurrence as compute "
"nodes start up and begin reporting inventory to "
"the Placement service."
谷歌了一下,看了某些回復(fù),答案的天平逐漸傾向了我最不敢相信的一處:是資源不夠。
我看著這張圖擦著眼睛,真的是資源不夠嗎?

等等,allocation candidates ,Placement API,這些都是什么東西?我要?jiǎng)?chuàng)個(gè)虛擬機(jī)跟它們都有什么關(guān)系?
是時(shí)候?qū)W習(xí)一下了,原來(lái),OpenStack現(xiàn)在使用 placement 來(lái)記錄跟蹤資源提供者的庫(kù)存和使用情況,并使用CPU、內(nèi)存和磁盤來(lái)標(biāo)記資源類型。
參考 https://blog.csdn.net/jmilk/article/details/81264240
于是,我來(lái)到了數(shù)據(jù)庫(kù)。
在 nova_api 數(shù)據(jù)庫(kù)的 inventories 表中,我們可以看到每個(gè) 資源提供者(resource_provider) 提供三種資源,分別用resource_class_id的0、1、2標(biāo)記cpu、內(nèi)存和磁盤。total一列是資源總量,reserved是保留大小,allocation_ratio是資源超配比。

在 allocations 表中:
消費(fèi)者(虛擬機(jī))15372401-e970-4594-bc19-e65bac9613b8 使用了資源提供者1的1VCPU、1024MB內(nèi)存、10G磁盤
消費(fèi)者 01b6377f-5b0c-4273-a24a-921f793b3004 使用了資源提供者3的1VCPU、1024MB內(nèi)存、10G磁盤,還使用了資源提供者1的1VCPU、1024MB內(nèi)存、10G磁盤!
鬼鬼,還會(huì)分身術(shù),一個(gè)人占兩份資源?

趕緊數(shù)據(jù)庫(kù)中查一下:

沒(méi)這號(hào)人物???怎么回事?
我猜可能是這位仁兄在兩臺(tái)計(jì)算節(jié)點(diǎn)間遷移出錯(cuò),成為僵尸實(shí)例,我在nova數(shù)據(jù)庫(kù)的instances表中雖然把它刪除了,但它還留在nova_api表里,占用著資源。
看了下,allocations表中共245條記錄,怎么不是3的倍數(shù)?

于是我找到了它,也是夠孤單的:

除去這條記錄,表中大約有80臺(tái)虛擬機(jī),還有很多虛擬機(jī)和上面一樣,一個(gè)人占用著兩份資源。這些虛擬機(jī)的絕大部分在horizon里看不到,只是在背后默默地吃著資源,導(dǎo)致我現(xiàn)在連一臺(tái)1VCPU、1024MB內(nèi)存、10G磁盤的虛擬機(jī)都創(chuàng)不起來(lái)了……
數(shù)據(jù)庫(kù)之旅到此結(jié)束,我們還可以用另一種方法查看一下每個(gè)資源提供者具體的資源使用情況:
1.獲得placement服務(wù)的訪問(wèn)入口
openstack catalog list
root@controller:~# openstack catalog list
+------------+----------------+------------------------------------------------------------------------+
| Name | Type | Endpoints |
+------------+----------------+------------------------------------------------------------------------+
| | | |
| placement | placement | RegionOne |
| | | public: http://controllerv:8778 |
| | | RegionOne |
| | | admin: http://controllerv:8778 |
| | | RegionOne |
| | | internal: http://controllerv:8778 |
| | | |
2.將訪問(wèn)入口寫入變量
PLACEMENT_ENDPOINT=http://controllerv:8778
3.獲得token
root@controller:~# openstack token issue -f value -c id
gAAAAABcJZlJ1dBRNYO2994is9JdT7XYnL-IqcbZrkg_Sf9oZChTWwNjZG1HWV4KYTjVoxs82RP77lMHtud4NTgPEREK7LiDdSp2ABuw4pKlmi8ce8Z77uQueeeXNOAlzX6iXYIBJHDBuXTcjRTnKebNQdB57tw_OwRMufVIrPN4LMMpvCFFN10
4.將token寫入變量
TOKEN=gAAAAABcJZlJ1dBRNYO2994is9JdT7XYnL-IqcbZrkg_Sf9oZChTWwNjZG1HWV4KYTjVoxs82RP77lMHtud4NTgPEREK7LiDdSp2ABuw4pKlmi8ce8Z77uQueeeXNOAlzX6iXYIBJHDBuXTcjRTnKebNQdB57tw_OwRMufVIrPN4LMMpvCFFN10
5.查看資源提供者
curl ${PLACEMENT_ENDPOINT}/resource_providers -H "x-auth-token: $TOKEN" | python -m json.tool

6.查看資源提供者庫(kù)存
如查看 b266b258-d78d-414c-a71d-1bf5137abbe2 即上圖compute1的資源庫(kù)存:
curl ${PLACEMENT_ENDPOINT}/resource_providers/b266b258-d78d-414c-a71d-1bf5137abbe2/inventories -H "x-auth-token: $TOKEN" | python -m json.tool

7.查看資源提供者資源使用情況
如查看 b266b258-d78d-414c-a71d-1bf5137abbe2 即compute1的資源使用情況:
curl ${PLACEMENT_ENDPOINT}/resource_providers/b266b258-d78d-414c-a71d-1bf5137abbe2/usages -H "x-auth-token: $TOKEN" | python -m json.tool

什么??jī)?nèi)存都使用了11426MB了?總共才7841MB?。∥姨统鲇?jì)算器,乘一下超配比:
7841 * 1.5 = 11761.5
11761.5 - 11426 - 512(保留大?。?= -176.5 ???
怪不得創(chuàng)不出虛擬機(jī)了,內(nèi)存不夠??!
又按照這個(gè)方法,查了別的資源提供者(即計(jì)算節(jié)點(diǎn)),發(fā)現(xiàn)幾乎都是內(nèi)存不夠,有太多horizon上看不到的虛擬機(jī)在背后尸位素餐了!
該做一次全面清洗了!
怎么辦?先查,查出哪些虛擬機(jī)是沒(méi)用的,得到它們的ID,然后,刪!
比如那個(gè)一人占用兩份資源的仁兄 01b6377f-5b0c-4273-a24a-921f793b3004,先拿它開(kāi)刀!
怎么刪?
curl ${PLACEMENT_ENDPOINT}/allocations/01b6377f-5b0c-4273-a24a-921f793b3004 -H "x-auth-token: $TOKEN" -X DELETE
再看一下compute1的使用情況:

對(duì)比一下,心情舒爽多了!
繼續(xù)刪吧,唉。。。
3. 分析NoValidHost(reason="")
在placement的官方文檔上寫著這么一段
https://docs.openstack.org/nova/rocky/user/placement.html

大意是nova的scheduler調(diào)度從placement服務(wù)獲取資源分配候選人
scheduler從placement api獲取資源分配候選人后用它從cell里取到計(jì)算節(jié)點(diǎn),計(jì)算節(jié)點(diǎn)通過(guò)篩選后,scheduler遍歷通過(guò)篩選的計(jì)算節(jié)點(diǎn)列表,并嘗試在placement api中聲明要占用這些資源。
聲明資源包括找到符合虛擬機(jī)所需資源的資源分配候選人(即計(jì)算節(jié)點(diǎn)),并要求placement api分配這些所需資源,當(dāng)在聲明資源過(guò)程中資源分配候選人用盡,就報(bào)出NoValidHost錯(cuò)誤。
哦哦哦。。。
再看一張圖理解一下:

好了,基本明白了。
在清理了一些廢棄的虛擬機(jī)后,根據(jù)官網(wǎng)文檔,可查詢是否能提供資源:

查詢一下,失敗了,試了很多次,不知道怎么用。。。
curl ${PLACEMENT_ENDPOINT}/resource_providers?resources=VCPU:2,MEMORY_MB:1024,DISK_GB:50 -H "x-auth-token: $TOKEN"

算了,反正虛擬機(jī)已經(jīng)可以創(chuàng)起來(lái)了。這個(gè)API怎么使用,日后再說(shuō)。
另外,數(shù)據(jù)庫(kù)里那么多尸位素餐的虛擬機(jī)是怎么產(chǎn)生的,為什么沒(méi)被刪掉,還要好好追查一下,再研究下吧》》》》》》》》