Openstack虛擬機防止誤刪除操作的幾種實現(xiàn)方法
1.虛擬機保護的重要性
虛擬機是Openstack中最重要的角色之一,我們接觸比較多的Nova服務(wù)就是通過虛擬機方式提供計算虛擬化服務(wù)。除此之外,還有很多高層服務(wù)也是完全依賴于Nova服務(wù)提供的虛擬機,比如Sahara大數(shù)據(jù)服務(wù)、Magnum容器編排服務(wù)、Manila文件共享服務(wù)以及Trove數(shù)據(jù)庫服務(wù)等,這些服務(wù)底層都是基于虛擬機實現(xiàn)的。虛擬機的保護至關(guān)重要,不僅承載著用戶活動的業(yè)務(wù),還保存著用戶的重要數(shù)據(jù)。虛擬機意外丟失不僅可能導致用戶業(yè)務(wù)中止,還可能導致重要數(shù)據(jù)的丟失,甚至造成重大生產(chǎn)事故,虛擬機的保護不容忽視!
Openstack Nova服務(wù)相對來說比較成熟了,虛擬機通常不會出現(xiàn)突然消失的情況,排除天災,剩下的就是人禍了,最危險的莫過于誤刪除操作,危險等級不亞于以下幾種:
- rm -rf /
- ceph osd pool delete rbd rbd --yes-i-really-really-mean-it
- drop database nova;
不幸的是,Openstack一直沒有一套完善的虛擬機保護機制,默認的權(quán)限策略也存在一定的問題:
- admin是全局的,只要屬于admin組,就能夠操作所有租戶的資源,刪除所有虛擬機只需一個命令。
- 虛擬機的Lock感覺形同虛設(shè),admin完全無視任何鎖。
當然盡管不完善,Openstack針對虛擬機的保護措施還是做了一些工作的,本文接下來將逐一介紹。
2.Lock機制
Openstack很早就開始支持對虛擬機加鎖操作:
- usage: nova lock <server>
- Lock a server. A normal (non-admin) user will not be able to execute actions
- on a locked server.
被locked的虛擬機不允許非管理員執(zhí)行任何操作,包括delete、reboot、resize、rebuild、migrate等等。但是到目前為止也沒有實現(xiàn)通過API獲取虛擬機的鎖狀態(tài),換句話說,只有當你執(zhí)行以上操作時,才會莫名其妙地告訴你執(zhí)行失敗了,因為虛擬機被加鎖了:
- $ nova delete 5a7b14b0-a47c-47be-98bb-92e139d16b00
- Instance 5a7b14b0-a47c-47be-98bb-92e139d16b00 is locked (HTTP 409) (Request-ID: req-6366a53b-d696-47cc-8111-1a760b8d0253)
- ERROR (CommandError): Unable to delete the specified server(s).
2014年2月就已經(jīng)有人提關(guān)于查看虛擬機lock狀態(tài)API實現(xiàn)BP:get-lock-status-of-instance,目前已被標記為Slow progress。
需要注意的是,正如前面所言,管理員賬號是無視鎖的,檢查鎖的代碼非常簡單:
- def check_instance_lock(function):
- @functools.wraps(function)
- def inner(self, context, instance, *args, **kwargs):
- if instance.locked and not context.is_admin:
- raise exception.InstanceIsLocked(instance_uuid=instance.uuid)
- return function(self, context, instance, *args, **kwargs)
- return inner
我們?yōu)榱藦娀i的作用,直接把if后面的and not context.is_admin去掉了,這樣即使是管理員在確認需要刪除虛擬機時也必須先unlock,一定程度上提高了虛擬機的安全性。
注意: 鎖定的虛擬機即使執(zhí)行nova force-delete也會失敗。
3.soft-delete
微信聊天時如果不小心說錯話了,兩分鐘內(nèi)可以立馬撤回消息,并不明覺厲地向?qū)Ψ饺右粋€對方撤回了一條消息。不小心誤刪虛擬機時,你是否也會在心里想如果可以撤回剛剛的操作該多好!
值得慶幸的是,Openstack原生支持軟刪除操作。開啟了軟刪除功能后,刪除的虛擬機不會立刻清除,而是會保留一段時間(比如一天),在虛擬機保留期內(nèi)你可以隨時restore恢復。
開啟辦法是修改Nova配置文件/etc/nova/nova.conf,在DEFAULT配置組下設(shè)置reclaim_instance_interval值,該值表示刪除虛擬機后保留的時間,單位為秒。
我們簡單驗證下:
我們首先創(chuàng)建了一個虛擬機,uuid為c6fd7a92-bf51-4000-b9e1-18850090ab47:
- $ nova list | grep c6fd7a92-bf51-4000-b9e1-18850090ab47
- | c6fd7a92-bf51-4000-b9e1-18850090ab47 | int32bit-test-3 | ACTIVE | - | Running | rally-shared-net=10.168.0.18 |
然后執(zhí)行刪除操作:
- nova delete c6fd7a92-bf51-4000-b9e1-18850090ab47
查看虛擬機狀態(tài),注意--deleted選項,否則看不到已經(jīng)刪除的虛擬機:
- $ nova list --deleted | grep c6fd7a92-bf51-4000-b9e1-18850090ab47
- | c6fd7a92-bf51-4000-b9e1-18850090ab47 | int32bit-test-3| SOFT_DELETED | - |Shutdown| rally-shared-net=10.168.0.18|
可見虛擬機此時為SOFT_DELETED狀態(tài),此時我們可以使用nova restore操作恢復:
- nova restore c6fd7a92-bf51-4000-b9e1-18850090ab47
再次使用nova list可發(fā)現(xiàn)虛擬機已經(jīng)回來了。
軟刪除的代碼實現(xiàn)也相對簡單,直接上核心代碼(nova/compute/manager.py:
- def soft_delete_instance(self, context, instance, reservations):
- # ...
- try:
- self._notify_about_instance_usage(context, instance,
- "soft_delete.start")
- try:
- self.driver.soft_delete(instance)
- except NotImplementedError:
- self.driver.power_off(instance)
- instance.power_state = self._get_power_state(context, instance)
- instance.vm_state = vm_states.SOFT_DELETED
- instance.task_state = None
- instance.save(expected_task_state=[task_states.SOFT_DELETING])
- except Exception:
- with excutils.save_and_reraise_exception():
- quotas.rollback()
- quotas.commit()
從代碼發(fā)現(xiàn)會調(diào)用driver的soft_delete方法,但實際上libvirt driver并未實現(xiàn)該方法,因此會fallback到except語句,即執(zhí)行簡單關(guān)機操作,然后更新虛擬機狀態(tài)到數(shù)據(jù)庫即完成軟刪除操作。
因此,虛擬機的軟刪除操作原理就是關(guān)機虛擬機并標記為軟刪除。
需要注意的是: nova force-delete會立即強制刪除虛擬機,不會保留虛擬機,請小心操作。
4.禁止刪除
這個應該算是Nova的隱藏功能了,不閱讀源碼真的不知道,虛擬機有一個disable_terminate標記,具有該標記的虛擬機無法通過任何API刪除虛擬機,無論你是admin還是force-delete都會刪除失敗,對于非常重要的虛擬機,萬萬不能刪除的虛擬機,可以設(shè)置該標記。
不過目前并沒有API設(shè)置該標記,社區(qū)提了好幾個與之相關(guān)的BP:
目前只能靠操作數(shù)據(jù)庫查看和設(shè)置該標記了。
- update instances set disable_terminate=1 where uuid='a80d78c0-9f5f-4f01-8ace-72a5133a4763';
此時執(zhí)行刪除虛擬機操作不會有任何反應。
實現(xiàn)方式非常簡單,在nova/compute.api.py,只要設(shè)置了該標記,直接return:
- def _delete(self, context, instance, delete_type, cb, **instance_attrs):
- if instance.disable_terminate:
- LOG.info(_LI('instance termination disabled'),
- instance=instance)
- return
- # ...
5. 快照備份
以上都是通過刪除保護方式來保證虛擬機的安全性,為了更全面地保護虛擬機,快照備份也是保護虛擬機的有效途徑,可參考的方式如下:
- 使用nova image-create創(chuàng)建虛擬機快照。
- 使用nova backup定期快照備份。
- 如果使用Ceph做后端存儲,可以考慮使用rbd mirror。
- 掛載的volume可以使用cinder backup服務(wù)增量備份。
6.總結(jié)
雖然Openstack提供的虛擬機保護措施還不夠完善,但做的工作還是不少的,用戶可以根據(jù)自己的需求選擇適合自己的方案。
【本文是51CTO專欄作者“付廣平”的原創(chuàng)文章,如需轉(zhuǎn)載請通過51CTO獲得聯(lián)系】