?
?
本文系圖技術(shù)在大型、復(fù)雜基礎(chǔ)設(shè)施之中 SRE / DevOps 的實(shí)踐參考,并以 OpenStack 系統(tǒng)之上的圖數(shù)據(jù)庫(kù)增強(qiáng)的運(yùn)維案例為例,揭示圖數(shù)據(jù)庫(kù)、圖算法在智能運(yùn)維上的應(yīng)用。本文所有示例代碼開(kāi)源。
最近,有些尚未使用過(guò)圖技術(shù)、DevOps / Infra 領(lǐng)域的工程師在 NebulaGraph 社區(qū)詢(xún)問(wèn)是否有「圖技術(shù)在運(yùn)維的應(yīng)用」相關(guān)案例參考。于是,我又可以“借題發(fā)揮”來(lái)實(shí)踐下如何利用圖的能力與優(yōu)勢(shì)去幫助運(yùn)維工程師們基于復(fù)雜基礎(chǔ)設(shè)施上構(gòu)建輔助運(yùn)維系統(tǒng)。如果你對(duì)本文有任何看法,歡迎評(píng)論區(qū)或者來(lái)論壇 https://discuss.nebula-graph.com.cn/ 交流,非常感謝。 通常,我們說(shuō)的復(fù)雜的基礎(chǔ)設(shè)施運(yùn)維環(huán)境指的是資源(manifest)繁多且分布在不同層面的系統(tǒng)。為了讓實(shí)踐更加真實(shí)、貼近實(shí)際的運(yùn)維情況,讓運(yùn)維問(wèn)題復(fù)雜又可控,這里我選擇了用一個(gè)基礎(chǔ)設(shè)施平臺(tái):OpenStack。在 OpenStack 系統(tǒng)上,我分別利用 Push 和 Pull 兩種模式將資源在圖模型中對(duì)應(yīng)點(diǎn)、邊信息加載到 NebulaGraph 的 Graph ETL 管道的路徑中。 在我們基于運(yùn)維資源構(gòu)建的圖譜,會(huì)做如下用例圖探索:
告警、狀態(tài)的推理與傳導(dǎo);
網(wǎng)絡(luò)直連與互聯(lián)關(guān)系;
鏡像、云盤(pán)、快照血緣管理;
高相關(guān)性虛機(jī)預(yù)警;
秘鑰泄漏的圖上風(fēng)控分析;
鏡像、云盤(pán)漏洞范圍分析;
宿主機(jī)逃離影響范圍分析;
脆弱依賴(lài)資源檢測(cè);
實(shí)驗(yàn)環(huán)境搭建
背景知識(shí)
01
OpenStack 是一個(gè)開(kāi)源的云計(jì)算平臺(tái),提供了類(lèi)似于 AWS 的云服務(wù)。它提供了一組可插拔的模塊,包括了計(jì)算,存儲(chǔ)和網(wǎng)絡(luò)等功能,可以幫助用戶(hù)構(gòu)建和管理云環(huán)境。OpenStack 采用分布式架構(gòu),支持多種操作系統(tǒng)和硬件平臺(tái),可以在企業(yè)級(jí)和服務(wù)提供企業(yè)級(jí)環(huán)境中使用。
最初,OpenStack 是由 NASA 和 Rackspace Inc. 發(fā)起的 Nova(虛擬化計(jì)算項(xiàng)目)和 Swift(兼容 S3 的對(duì)象存儲(chǔ))項(xiàng)目組成。隨著項(xiàng)目的發(fā)展,OpenStack 現(xiàn)在已經(jīng)有非常多不同的子項(xiàng)目:
本次實(shí)踐中涉及到 OpenStack 的主要項(xiàng)目有:
Nova 是 OpenStack 的計(jì)算服務(wù),用于管理虛擬機(jī);
Cinder 是 OpenStack 的塊存儲(chǔ)服務(wù),用于管理云存儲(chǔ);
Neutron 是 OpenStack 的網(wǎng)絡(luò)服務(wù),用于管理云網(wǎng)絡(luò);
Glance 是 OpenStack 的鏡像服務(wù),用于管理云鏡像;
Horizon 是 OpenStack 的可視化控制臺(tái)服務(wù)。
除此之外,我還引入了 Vitrage 項(xiàng)目輔助我們收集部分資源數(shù)據(jù):
Vitrage 是 OpenStack 的一個(gè)高級(jí)分析和可視化工具,用于分析和可視化 OpenStack 環(huán)境中的資源和事件。它可以匯集來(lái)自 OpenStack 各個(gè)服務(wù)的數(shù)據(jù),并以可視化的方式呈現(xiàn)。Vitrage 能發(fā)現(xiàn)和診斷問(wèn)題,提高 OpenStack 環(huán)境的可用性和可維護(hù)性。
得益于 OpenStack Decouple 的設(shè)計(jì)理念,Vitrage 可以很容易、無(wú)侵入式(只用修改要收集的服務(wù)的兩行配置)就可以在 OpenStack 的消息隊(duì)列中訂閱資源信息的 Push 消息。 不過(guò),介于 Vitrage 許久沒(méi)有大更新,且維護(hù)維艱,比如:在 zed 里 Vitrage Dashboard 作為 Horizon 插件已經(jīng)無(wú)法正常工作了。所以,本實(shí)踐只利用它的資源收集能力。
環(huán)境準(zhǔn)備搭建
02
NebulaGraph 集群
快速試玩 NebulaGraph 的話,安裝有這么幾個(gè)選項(xiàng):
30 天免費(fèi)試用的阿里云上的 NebulaGraph 企業(yè)版,含有配套的可視化周邊工具。復(fù)制鏈接開(kāi)啟試用: https://market.aliyun.com/isv-nebulagraph ?
有 Docker 環(huán)境,Nebula-Up 一鍵安裝: https://github.com/wey-gu/nebula-up ?
RPM、TAR 包、源碼編譯等安裝方式,可參考文檔: https://docs.nebula-graph.com.cn/ ?
OpenStack 集群
本文需要的 OpenStack 集群是一個(gè)多機(jī)的環(huán)境,因此我在 Linux Server 上用 Libvirt 和 Linux Bridge 搭建了多個(gè)虛擬機(jī)來(lái)模擬 OpenStack 的物理機(jī)。得益于 CPU 的嵌套虛擬化和 QEMU,我們完全可以在虛擬機(jī)搭建的實(shí)驗(yàn)環(huán)境中模擬可正常工作的 OpenStack Nova instance 虛機(jī)。 虛擬機(jī)搭建完成后,還需要模擬真實(shí)的多資源 Infra 環(huán)境。這邊略去具體的操作步驟,感興趣的小伙伴可以閱讀本文的參考文獻(xiàn),當(dāng)中有詳細(xì)的實(shí)踐過(guò)程。 完成 OpenStack 環(huán)境的搭建后,我們通過(guò) Horizon Dashboard 查看集群和資源: 虛擬機(jī)情況:
網(wǎng)盤(pán)情況,其中四個(gè)掛載在不同的虛擬機(jī)上
集群租戶(hù)的網(wǎng)絡(luò)拓?fù)洌?/p>
通過(guò) OpenStack Vitrage 的 API/CLI 可獲得部分主要資源的拓?fù)洌?/p>
source?openrc?admin?admin vitrage?topology?show?--all-tenants? 這個(gè)結(jié)果是一個(gè) JSON,數(shù)據(jù)已經(jīng)是邊(links)和點(diǎn)(nodes)的序列化圖結(jié)構(gòu)了。
{ ??"directed":?true, ??"graph":?{}, ??"links":?[ ????{ ??????"vitrage_is_deleted":?false, ??????"relationship_type":?"contains", ??????"source":?0, ??????"target":?11, ??????"key":?"contains" ????}, ????{ ??????"vitrage_is_deleted":?false, ??????"relationship_type":?"contains", ??????"source":?0, ??????"target":?13, ??????"key":?"contains" ????}, ... ????{ ??????"vitrage_is_deleted":?false, ??????"relationship_type":?"attached", ??????"source":?27, ??????"target":?28, ??????"key":?"attached" ????} ??], ??"multigraph":?true, ??"nodes":?[ ????{ ??????"id":?"node0", ??????"vitrage_type":?"nova.host", ??????"vitrage_category":?"RESOURCE", ??????"vitrage_is_deleted":?false, ??????"update_timestamp":?"2023-01-13T0848Z", ??????"vitrage_sample_timestamp":?"2023-01-13T0849Z", ??????"vitrage_is_placeholder":?false, ??????"vitrage_id":?"630b4c2c-5347-4073-91a3-255ec18dadfc", ??????"name":?"node0", ??????"vitrage_cached_id":?"d043d278a6a712909e30e50ca8ec2364", ??????"is_real_vitrage_id":?true, ??????"vitrage_aggregated_state":?"AVAILABLE", ??????"vitrage_operational_state":?"OK", ??????"vitrage_datasource_name":?"nova.host", ??????"state":?"available", ??????"graph_index":?0 ????}, ????{ ??????"id":?"nova", ??????"vitrage_type":?"nova.zone", ??????"vitrage_category":?"RESOURCE", ??????"vitrage_is_deleted":?false, ??????"vitrage_sample_timestamp":?"2023-01-12T0348Z", ??????"vitrage_is_placeholder":?false, ??????"vitrage_id":?"a1e9c808-dac8-4b59-8f80-f21a90e9869d", ??????"vitrage_cached_id":?"125f1d8c4451a6385cc2cfa2b0ba45be", ??????"is_real_vitrage_id":?true, ??????"vitrage_aggregated_state":?"AVAILABLE", ??????"vitrage_operational_state":?"OK", ??????"state":?"available", ??????"update_timestamp":?"2023-01-12T0348Z", ??????"name":?"nova", ??????"vitrage_datasource_name":?"nova.zone", ??????"graph_index":?1 ????}, ... ??"raw":?true }
圖譜建模
將資源映射成圖譜:
nova instance 是 Nova 服務(wù)中的虛擬機(jī)實(shí)例,每個(gè) nova instance 都有自己的配置信息(如 CPU、內(nèi)存、磁盤(pán)等),有時(shí)候我們就叫它 server 或者 VM、虛機(jī)。
nova host 是 Nova 服務(wù)中的物理主機(jī),是 nova instance 運(yùn)行的物理環(huán)境。nova host 上面會(huì)運(yùn)行 nova-compute 服務(wù),這個(gè)服務(wù)負(fù)責(zé)管理和調(diào)度 nova instance。nova host 上面還可能運(yùn)行其他服務(wù),如網(wǎng)絡(luò)服務(wù)等。
nova keypair 是 Nova 服務(wù)中的密鑰對(duì),用于訪問(wèn) nova instance。
cinder volume 是 Cinder 服務(wù)中的云存儲(chǔ)卷,可以 attach 到 nova instance 上做為硬盤(pán)。
cinder snapshot 是 Cinder 服務(wù)中的云存儲(chǔ)快照,可以在 cinder volume 上做快照。
glance image 是 Glance 服務(wù)中的鏡像,可以作為創(chuàng)建 nova instance 時(shí)候的啟動(dòng)硬盤(pán)。
neutron network 是 Neutron 服務(wù)中的網(wǎng)絡(luò),可以用于配置 nova instance 的網(wǎng)絡(luò)連接。
neutron port 是 Neutron 服務(wù)中的端口,用來(lái)連接 nova instance 和 neutron network 之間。在 nova instance 虛擬機(jī)上,如果不是 trunk port 的話,一個(gè) port 常常對(duì)應(yīng)一個(gè)網(wǎng)卡。
它們之間的關(guān)系如下:
基礎(chǔ)設(shè)施圖 ETL
接下來(lái)我們解決從基礎(chǔ)設(shè)施中抽取資源元數(shù)據(jù)的問(wèn)題:
push 模式
01
這里的 push 指的是以基礎(chǔ)設(shè)施為出發(fā)點(diǎn),通過(guò)事件驅(qū)動(dòng)主動(dòng)地發(fā)出資源變動(dòng)的信息。它的好處是實(shí)時(shí)掌握資源情況,壞處是過(guò)于依賴(lài)基礎(chǔ)設(shè)施,很多非常瘦的、軟件定義 / 可編程程度不高的組件、某些硬件設(shè)備是沒(méi)有 push 機(jī)制的。比如:有些年份的軟件系統(tǒng)不一定能存在 push 的接口,改造起來(lái)有侵入性。 前面提及過(guò),OpenStack 自身是存在 Push Hook 機(jī)制的,它的子項(xiàng)目 vitrage 就利用這個(gè)機(jī)制很優(yōu)雅地收集系統(tǒng)資源、告警等信息進(jìn)入圖中,類(lèi)似的機(jī)制在其他平臺(tái)中也是可以實(shí)現(xiàn)的。 本實(shí)驗(yàn)中我們就利用 vitrage 的機(jī)制去收集一部分圖譜中的資源信息,如下圖,可以看到 vitrage 會(huì)在 OpenStack message bus 中訂閱 nova / cinder / neutron 等服務(wù)中的資源時(shí)間,把事件傳入 Entity Queue,經(jīng)過(guò)處理,存儲(chǔ)到 Entity Graph 中。 在此之上,我們可以通過(guò) vitrage API 獲取圖譜的拓?fù)?,?lái)消費(fèi)它。
注意:實(shí)際上 Vitrage 服務(wù)還提供了推理告警、推理狀態(tài)、定義決策事件的能力,這里我們并沒(méi)有采用,后邊我們?cè)趫D上做的一些事情甚至還和它的能力有一些重疊。
這里我只是用它來(lái)展示 push 模式的工作機(jī)制,如果沒(méi)有 Virtrage 這個(gè)項(xiàng)目存在,我們也可以比較容易通過(guò) OpenStack 的 oslo.messaging 這個(gè)庫(kù)很容易寫(xiě)出在 Message Bus(可能是 Kafka, RabbitMQ 等不同底層實(shí)現(xiàn))上訂閱資源時(shí)間的應(yīng)用,然后把事件通過(guò) Flink / Kafka / Pulsar 等方式接駁 NebulaGraph。 因?yàn)?Vitrage 的存在,我就偷懶不用去實(shí)現(xiàn)這部分邏輯,只消寫(xiě)一小部分代碼調(diào)用 Vitrage API 取這個(gè)數(shù)據(jù)就可以了,諷刺的是,從這個(gè)角度來(lái)看,這其實(shí)是一種 pull 的模式了,不用拘泥它本質(zhì)上算是哪一種方式,至少在資源發(fā)起測(cè),我們把它當(dāng)做 push 模式的例子看待吧。 這部分從 Vitrage 抓取的代碼我放在 https://github.com/wey-gu/openstack-graph/blob/main/utils/vitrage_to_graph.py 了,調(diào)用方式很簡(jiǎn)單,在有 OpenStack 客戶(hù)端的環(huán)境中,執(zhí)行它就可以了,比如:
?
#?連到?node0?上 ssh?stack@node0_ip #?進(jìn)入?devstack?目錄 cd?devstack #?下載?vitrage?中圖數(shù)據(jù),解析為?NeublaGraph?DML/DQL?的工具 wget?https://raw.githubusercontent.com/wey-gu/openstack-graph/main/utils/vitrage_to_graph.py #?執(zhí)行它 python3?vitrage_to_graph.py? 執(zhí)行之后,會(huì)生成如下文件:
?
?
schema.ngql ? ? 圖數(shù)據(jù)的 Schema 定義
vertices/ ?點(diǎn)數(shù)據(jù)的文件夾
edges/ ?邊數(shù)據(jù)的文件夾
pull?模式
02
反過(guò)來(lái),pull 模式是從資源外部定期或者事件驅(qū)動(dòng)地拉取資源,存入圖譜的方式。剛好,本實(shí)驗(yàn)中 Vitrage 抓取的資源是有限,部分額外的資源單獨(dú)寫(xiě)了 Python 的代碼來(lái)主動(dòng)全量抓取。pull 模式的好處是對(duì)資源方?jīng)]有任何侵入性,只需要調(diào)用它的接口獲取信息就可以,壞處則是有的系統(tǒng)不太容易獲得增量變化,可能只能全量去取。 這部分我抓取的關(guān)系如下:
glance_used_by: image -[:used_by]-> instance (get from instance) ?
glance_created_from: image -[:created_from]-> volume (get from image) ?
nova_keypair_used_by: keypair -[:used_by]-> instance (get from instance) ?
cinder_snapshot_created_from: volume snapshot -[:created_from]-> volume (get from snapshot) ?
cinder_volume_created_from: volume -[:created_from]-> volume snapshot (get from volume) ?
cinder_volume_created_from: volume -[:created_from]-> image (get from volume) ?
代碼在 https://github.com/wey-gu/openstack-graph/blob/main/utils/pull_resources_to_graph.py。在真實(shí)場(chǎng)景下,我們可能會(huì)用 Apache Airflow、Dagster 甚至是 Cron Job 等方式定期執(zhí)行它。 手動(dòng)執(zhí)行的方式也很簡(jiǎn)單:
?
#?連到?node0?上 ssh?stack@node0_ip #?進(jìn)入?devstack?目錄 cd?devstack #?下載抓取?OpenStack?資源,生成?NeublaGraph?DML/DQL?的工具 wget?https://raw.githubusercontent.com/wey-gu/openstack-graph/main/utils/pull_resources_to_graph.py.py #?執(zhí)行它 python3?pull_resources_to_graph.py? 執(zhí)行之后,會(huì)生成點(diǎn)、邊的 nGQL 語(yǔ)句在兩個(gè)文件夾下:
?
?
vertices/ ?點(diǎn)數(shù)據(jù)的文件夾
edges/ ?邊數(shù)據(jù)的文件夾
加載數(shù)據(jù)到?NebulaGraph
03
加載數(shù)據(jù)到 NebulaGraph
我們只需要在 NebulaGraph Studio Console,Explorer Console 或者 NebulaGraph 命令行 Console 中執(zhí)行上邊生成的 .ngql 文件就好了:
?
#?DDL?from?vitrage cat?schema.ngql #?DDL?and?DML?for?both?push?and?pull?mode?data cat?edges/*.ngql cat?vertices/*.ngql? 之后,在 NebulaGraph 中我們會(huì)有一個(gè)叫做 openstack 的圖空間,用這個(gè)查詢(xún)可以查到所有數(shù)據(jù):
MATCH?(n)?WITH?n?LIMIT?1000 OPTIONAL?MATCH?p=(n)--() RETURN?p,?n? 在 NebulaGraph Explorer 中渲染,手動(dòng)設(shè)置一下數(shù)據(jù)的圖標(biāo),就可以看到 OpenStack 集群里的所有租戶(hù)的資源圖了:
接下來(lái),我們終于可以在圖上看看有意思的洞察了!
?
?
基于圖譜的基礎(chǔ)設(shè)施運(yùn)維示例
作為非 SRE、DevOps 人員,我嘗試藉由自己在 OpenStack 和圖技術(shù)的理解模擬出以下實(shí)例,希望對(duì)你有所幫助。
告警、狀態(tài)的推理與傳導(dǎo)
01
受啟發(fā)于 Vitrage 項(xiàng)目,我們可以借助資源圖譜實(shí)時(shí)圖查詢(xún)、圖計(jì)算甚至圖可視化能力,在圖上推理、傳導(dǎo)信息,把重要的事件藉由圖上組織好的知識(shí)分發(fā)給需要收到通知的人、組織、系統(tǒng)。 一個(gè)簡(jiǎn)單的例子,我們?cè)?nova host(虛擬機(jī)的宿主機(jī)、Hypervisor 機(jī)器,以下簡(jiǎn)稱(chēng)宿主機(jī))中獲得了一個(gè)告警、事件的時(shí)候,可能是網(wǎng)卡失敗、物理硬盤(pán)預(yù)警、CPU 占用過(guò)高之類(lèi)的告警。借助圖譜查詢(xún)獲得所有相關(guān)聯(lián)的虛機(jī)后,再把 WARN 級(jí)別的告警發(fā)出去或者設(shè)置它們?yōu)閬喗】?unhealthy 狀態(tài)。 獲得通知的對(duì)象,往往是一些用戶(hù)系統(tǒng),它們可以根據(jù)預(yù)先定義好的策略做些自動(dòng)化運(yùn)維,或者通知 Hook:
收到“宿主機(jī) CPU 過(guò)高”的告警情況,根據(jù)用戶(hù)自己設(shè)定的不同策略把虛機(jī)遷移走,或者采用更高級(jí)、復(fù)雜的撤離方式,像是開(kāi)始不接受新流量,創(chuàng)建新的替代 workload,再優(yōu)雅地關(guān)閉這個(gè) workload;
“控制面網(wǎng)絡(luò)故障”告警情況,這時(shí)候往往無(wú)法成功進(jìn)行主機(jī)的撤離、遷移,故可以考慮觸發(fā)備份主機(jī)、啟動(dòng)新 workload、關(guān)機(jī);
其他“亞健康狀態(tài)”,可以作為負(fù)載層面出問(wèn)題的根因分析 RCA 依據(jù)。
這里給出一個(gè)在圖譜上進(jìn)行告警、狀態(tài)傳遞的查詢(xún)例子。假設(shè) vid 為 node0?的宿主機(jī)出現(xiàn)了高 CPU 告警,下面這個(gè)查詢(xún)可以得到所有該宿主機(jī)上的虛機(jī),獲得時(shí)間、告警通知列表:
?
MATCH?(vm:nova_instance)<-[:`contains`]-(host_CPU_high:nova_host) ????WHERE?id(host_CPU_high)?==?"node0" RETURN?vm.nova_instance.name?AS?VM_to_raise_CPU_alarms? 這條語(yǔ)句的查詢(xún)圖模式是從 host_CPU_high 這個(gè) nova_host 向外經(jīng)由 contains 這個(gè)關(guān)系指向 vm 這個(gè) nova_instance 的。
(vm:nova_instance)<-[:`contains`]-(host_CPU_high:nova_host)? 它的結(jié)果是:
?
?
?
VM_to_raise_CPU_alarms |
---|
server-4 |
server-3 |
server-1 |
server-0 |
?
如果我們把查詢(xún)改動(dòng)一下,選擇輸出全路徑,則可以看到這個(gè)信息傳遞的方向:
?
MATCH?p=(vm:nova_instance)<-[:`contains`]-(host_CPU_high:nova_host) ????WHERE?id(host_CPU_high)?==?"node0" RETURN?p? 我們?cè)?Explorer 中渲染下,點(diǎn)擊 N 跳檢測(cè):
這個(gè)例子比較簡(jiǎn)單,甚至用不到圖能力。因?yàn)橐惶樵?xún)?cè)诒斫Y(jié)構(gòu)中也能很輕松地用一、兩個(gè) nova API call 搞定。實(shí)際上,圖上是可以做很多更 Graphy(具有圖屬性的)、復(fù)雜、獨(dú)特的工作的,我們慢慢來(lái)看:
?
?
網(wǎng)絡(luò)可達(dá)檢測(cè)
02
考慮下這樣的場(chǎng)景,在 OpenStack 中,不同的主機(jī)可以連接到相同的子網(wǎng) VPC,主機(jī)也可以連接到多個(gè)子網(wǎng)之中。這樣,主機(jī)之間的網(wǎng)絡(luò)連通性信息、與網(wǎng)絡(luò)聯(lián)通相關(guān)的推理、傳導(dǎo)都可以在圖上進(jìn)行。 在真實(shí)世界中,這里可能還要考慮 Security Group、Router、Switch 等因素。本示例中我們用到的 OpenStack 是比較簡(jiǎn)化的 L2 only Setup。 我們要獲得與虛機(jī) server_a 同一 VPC 的所有其他虛機(jī)很容易表達(dá):
?
MATCH?(server_a)--(neutron_network)--(`nova_instance`) ????WHERE?id(server_a)?==?"server-0" RETURN?server_b.nova_instance.name?AS?L2_connected_server? 結(jié)果如下:
?
?
?
L2_connected_server |
---|
server-1 |
?
看起來(lái)很初級(jí),接下來(lái)我們?cè)俨樵?xún)與虛機(jī) server_a 同一 VPC、有可能通過(guò)跨網(wǎng)絡(luò)虛機(jī)而互聯(lián)的主機(jī)的所有其他虛機(jī)。這時(shí)候,我們除了共享 neutron network(VPC) 的情況,還要查詢(xún)所有二層直連的虛機(jī)可能通過(guò)其他 VPC 連出去的的虛機(jī)。下面的例子,我們用到了 OPTIONAL MATCH 的表達(dá),表示可能匹配到的模式:
?
MATCH?(server_a)--(neutron_network)--(`nova_instance`) ????WHERE?id(server_a)?==?"server-0" OPTIONAL?MATCH?(server_b)--()--(other_netneutron_port)--(server_c:`nova_instance`) ????WITH?server_a,?server_b?AS?same_subnet_machines,?server_c?AS?routeable_machines?WHERE?routeable_machines?!=?server_a RETURN?same_subnet_machines.nova_instance.name?AS?L2_connected_server, ???????routeable_machines.nova_instance.name?AS?cross_vpc_server? 可以看到結(jié)果里,跨網(wǎng)絡(luò)潛在的相連主機(jī)還有 server-3:
?
?
?
L2_connected_server | cross_vpc_server |
---|---|
server-1 | server-3 |
?
可視化下,同樣,我們修改輸出為路徑 p 和 p1。
?
MATCH?p=(server_a)--(neutron_network)--(`nova_instance`) ????WHERE?id(server_a)?==?"server-0" OPTIONAL?MATCH?p1=(server_b)--()--(other_netneutron_port)--(server_c:`nova_instance`) RETURN?p,?p1? 它可能的連接路徑一目了然了:
有了獲得這些信息的能力,我們可以可編程地連接告警、狀態(tài)、安全風(fēng)控、網(wǎng)絡(luò)等方方面面系統(tǒng)。當(dāng)然這不是本文的重點(diǎn),就不加以贅述了,你有相關(guān)的實(shí)踐想要分享的話,記得來(lái) NebulaGraph 社區(qū)。 下面,我們來(lái)看看存儲(chǔ)相關(guān)的例子。
?
?
鏡像、云盤(pán)、快照的血緣
03
在基礎(chǔ)設(shè)施中,云盤(pán)(iSCSI、Ceph、NFS)、鏡像、快照之間有多重復(fù)雜的關(guān)系,比如:
一個(gè)系統(tǒng)鏡像可能從某一個(gè)虛擬機(jī)掛載的云盤(pán)或者一個(gè)快照創(chuàng)建
一個(gè)云盤(pán)可能是從一個(gè)系統(tǒng)鏡像、一個(gè)快照或者另一個(gè)云盤(pán)創(chuàng)建
一個(gè)快照是從一個(gè)云盤(pán)創(chuàng)建的
這種血緣信息的識(shí)別和管理是很有必要的。下面的查詢(xún)可以獲得指定虛機(jī) server-0?的所有存儲(chǔ)血緣:
?
MATCH?p=(server_a)-[:`attached`|created_from|used_by]-(step1) ????WHERE?id(server_a)?==?"server-0" OPTIONAL?MATCH?p1=(step1)-[:created_from*1..5]-(step2) ????RETURN?p,?p1? 我們可以看到結(jié)果中:
?
?
server-0 ?的啟動(dòng)鏡像(這里它是從本地盤(pán)啟動(dòng)的,沒(méi)有掛載云盤(pán))是從 volume-1 創(chuàng)建的;
volume-1 是從 cirros-0.5.2-x86_64-disk 這個(gè)鏡像創(chuàng)建的;
此外,還有其他有分叉關(guān)系的存儲(chǔ)資源和它們也息息相關(guān):
下面,我們不只考慮存儲(chǔ)資源,看下涉及云盤(pán) cinder_volume 掛載 attached 這層關(guān)系下的血緣關(guān)系:
?
MATCH?p=(server_a)-[:`attached`|created_from|used_by]-(step1) ????WHERE?id(server_a)?==?"server-4" OPTIONAL?MATCH?p1=(step1)-[:created_from|attached*1..5]-(step2) ????RETURN?p,?p1?
我們可以從渲染圖中讀出這樣的洞察:
?
?
server-4 ?的啟動(dòng)鏡像(這里它是從本地盤(pán)啟動(dòng)的)是從? volume-1 ?創(chuàng)建的
而? volume-1 ?現(xiàn)在掛載在? server-6 ?上
volume-1 ?是從? cirros-0.5.2-x86_64-disk ?這個(gè)鏡像創(chuàng)建的
同樣? cirros-0.5.2-x86_64-disk ?鏡像被很多其他虛機(jī)在采用
server-4 ?同時(shí)掛載了數(shù)據(jù)盤(pán)? volume-2 ?
而? volume-2 ?是一個(gè)多掛載的盤(pán),它同時(shí)掛載在? server-3 ?之上
server-3 ?的系統(tǒng)啟動(dòng)盤(pán)是從快照? snapshot-202301111800-volume-1 ?克隆創(chuàng)建的
快照? snapshot-202301111800-volume-1 ?是曾經(jīng)從? volume-1 ?創(chuàng)建的
volume-1 現(xiàn)在掛載在 server-6 上,快照不一定是從 server-6 而來(lái),因?yàn)殓R像可能被重新掛載過(guò)。而這些血緣信息可以被用在資源生命周期管理、根因分析、安全告警、狀態(tài)傳遞上,這里不加以贅述。
高相關(guān)性虛機(jī)預(yù)警
04
下面這個(gè)例子,會(huì)給出一個(gè)節(jié)點(diǎn)相似度的應(yīng)用。在全圖或者子圖上,利用圖算法找到與指定虛機(jī)圖拓?fù)浣Y(jié)構(gòu)最相似的其他虛機(jī),并在這種相關(guān)性基礎(chǔ)上增加新的關(guān)系,做風(fēng)險(xiǎn)事件預(yù)警。 本次實(shí)踐,我們會(huì)按照一個(gè)典型的從「快速子圖驗(yàn)證」到「全圖生產(chǎn)應(yīng)用」的工作流。
子圖快速驗(yàn)證:瀏覽器內(nèi)算法
從 server-0?的三度子圖上做算法的驗(yàn)證:
?
GET?SUBGRAPH?3?STEPS?FROM?"server-0" YIELD?VERTICES?AS?nodes,?EDGES?AS?relationships;? 將結(jié)果渲染在畫(huà)布上,我們可以看到子圖中包含了其他幾個(gè)虛機(jī):
我們利用 Explorer 中的瀏覽器內(nèi)圖算法,可以非常方便地驗(yàn)證我們的想法。這里,我們使用 Jaccard Similarity 相似性算法,讓 server-0?與 server-1,server-3,server-4,server-6 迭代分別得到相似性:
可以看出,在 3 步子圖內(nèi),和 server-0?最近接的虛機(jī)是 server-4。進(jìn)一步,我們可以簡(jiǎn)單在子圖上看看兩者之間的路徑作為相似性的解釋?zhuān)?
在這個(gè)可解釋結(jié)果中,我們知道 server-0?與 server-4 相似的原因可能是:
坐落在同一個(gè)宿主機(jī):node-0
使用同一個(gè)鏡像:cirros_mod_from_volume-1
因此,我們最終落地的預(yù)警機(jī)制可能是,當(dāng) server-0?出現(xiàn)某一問(wèn)題、告警時(shí)候,給相似的 server-4 也設(shè)定預(yù)警,預(yù)警理由就是它們?cè)谕瑯又鳈C(jī)、同樣鏡像。
全圖生產(chǎn)應(yīng)用
有了上面的快速實(shí)驗(yàn),借助 Workflow + NebulaGraph Analytics 把它落地為全圖上的算法,利用 Analytics 分布式能力去執(zhí)行。 在生產(chǎn)上,我們利用 Workflow 的 DAG 編排能力,創(chuàng)建兩個(gè)前后相連的任務(wù):
取臨近虛機(jī)
全圖算相似度
第一個(gè)任務(wù)如下,實(shí)時(shí)從指定虛機(jī)出發(fā)給出其他虛機(jī) vid。這里查詢(xún)語(yǔ)句寫(xiě)死了 server-0,但是在 Workflow 里可以參數(shù)化,并封裝任務(wù)為可被 API 觸發(fā)的異步服務(wù):
?
MATCH?(n)-[*1..5]-(m:`nova_instance`) ????WHERE?id(n)?==?"server-0"?AND?n?!=?m RETURN?distinct?id(m)?
而在 Jaccard Similarity Job 中,我們選擇 ids1 為 server-0,ids2 從上游(上面的 Query Job)取,選擇在 OpenStack 全圖掃描所有邊類(lèi)型。
保存、運(yùn)行。結(jié)果如下,這次它運(yùn)算了更多的目標(biāo)虛機(jī),并且迭代作用范圍是全圖而非一個(gè)子圖??梢钥吹酵洗蔚慕Y(jié)果是一樣,因?yàn)樽訄D上關(guān)聯(lián)度大的點(diǎn)和相近的邊在 Jaccard 算法里起到了更主要的作用。
?
?
安全相關(guān)場(chǎng)景
05
基礎(chǔ)設(shè)施資源中的關(guān)聯(lián)關(guān)系和金融、內(nèi)容系統(tǒng)、電商領(lǐng)域的風(fēng)控場(chǎng)景有相似的地方,很多場(chǎng)景本質(zhì)上利用到了圖譜關(guān)系中的知識(shí),在圖庫(kù)上實(shí)時(shí)獲取這些復(fù)雜但又天然可解釋的安全洞察。
秘鑰泄漏風(fēng)控分析
先看一個(gè)秘鑰泄漏的場(chǎng)景:假設(shè) key-0?被安全部門(mén)確定被泄漏了,我們可以在毫秒內(nèi)獲得如下查詢(xún):
直接使用該密鑰的虛機(jī)
與使用該秘鑰的虛機(jī)網(wǎng)絡(luò)直連的機(jī)器
與使用該秘鑰的虛機(jī)跨網(wǎng)絡(luò)相連的機(jī)器
?
?
MATCH?(key_leaked)-[:`used_by`]->(involved_serverneutron_port)--(netneutron_port)--(server_b:nova_instance) ???????WHERE?id(key_leaked)?==?"key-0" OPTIONAL?MATCH?(server_b)--()--(other_netneutron_port)--(server_c:nova_instance) ????WITH?involved_server,?server_b?AS?same_subnet_machines,?server_c?AS?cross_net_machines ????????WHERE?cross_net_machines?!=?involved_server RETURN?involved_server.nova_instance.name?AS?with_key, ????????same_subnet_machines.nova_instance.name?AS?l2_vms, ????????cross_net_machines.nova_instance.name?AS?cross_vpc_vms貼一下部分結(jié)果,我們知道 server-4 采用了這個(gè) keypair,并且 server-6 和它在同一個(gè)網(wǎng)絡(luò)。同時(shí),有一定幾率通過(guò) server-6、server-1、server-2、server-0、server-5 也受到了影響。針對(duì)這種情況,相關(guān)的機(jī)器可以設(shè)置不同告警級(jí)別來(lái)降低安全事故的影響。
with_key | l2_vms | cross_vpc_vms |
---|---|---|
server-4 | server-6 | server-1 |
server-4 | server-6 | server-2 |
server-4 | server-6 | server-0 |
server-4 | server-6 | server-5 |
這個(gè)查詢(xún)改造為可視化結(jié)果:
MATCH?p=(key_leaked)-[:`used_by`]->(involved_serverneutron_port)--(netneutron_port)--(server_b:nova_instance) ????WHERE?id(key_leaked)?==?"key-0" OPTIONAL?MATCH?p1=(server_b)--()--(other_netneutron_port)--(server_c:nova_instance) RETURN?p,p1? 在 Explorer 中應(yīng)用 Dagre-LR 的布局,相關(guān)的關(guān)聯(lián)關(guān)系可以很清晰地被展示出來(lái)。介于可視化展示的直觀性,我們可以考慮把這個(gè)圖放入安全報(bào)告,隨同其他安全信息一同分發(fā)給虛機(jī)租戶(hù)。
?
?
鏡像、云盤(pán)漏洞范圍分析
類(lèi)似的,一個(gè)鏡像被掃出漏洞,我們可以瞬間查到波及的資源,并做出相應(yīng)應(yīng)對(duì)之策。 鏡像文件有漏洞:
MATCH?p=(image_risky)-[:`created_from`]-(step1) ????WHERE?id(image_risky)?==?"cirros-0.5.2-x86_64-disk" OPTIONAL?MATCH?p1=(step1)-[:created_from*1..5]-(step2) RETURN?p,?p1?
某個(gè)云盤(pán)有漏洞:
MATCH?p=(volume_risky)-[:`created_from`]-(step1) ????WHERE?id(volume_risky)?==?"volume-1" OPTIONAL?MATCH?p1=(step1)-[:created_from*1..5]-(step2) RETURN?p,?p1?
?
?
潛在宿主機(jī)逃離影響范圍分析
最后,我們討論一個(gè)嚴(yán)重的安全問(wèn)題:宿主機(jī)逃離。 在極端的情況下,server-0?發(fā)生了有可能影響宿主機(jī)的安全事件,此時(shí)僅僅關(guān)閉這個(gè)宿主機(jī)是不夠的,因?yàn)槭苡绊懙姆秶赡芤呀?jīng)擴(kuò)大。但我們又不能因?yàn)檫@樣不知影響范圍多廣的安全事件來(lái)關(guān)閉整個(gè)機(jī)房。所以,利用圖譜輔助找出受影響范圍就非常有用了。 下面的查詢(xún)模式是:
找出可能被影響的子網(wǎng)(VPC),標(biāo)記最高級(jí)別風(fēng)險(xiǎn)子網(wǎng)為后續(xù)定位做準(zhǔn)備
找到可能被控制了的宿主機(jī)
從宿主機(jī)觸發(fā),找出同主機(jī)的其他虛機(jī)
從其他虛機(jī)觸發(fā),找到它們的子網(wǎng)(VPC)
從其他虛機(jī)觸發(fā),找到可能已經(jīng)被影響的網(wǎng)盤(pán)。這是為了防止被掛載到其他機(jī)器,這會(huì)擴(kuò)大影響。??
MATCH?(server_escaping_hypervisor)<-[:`contains`]-(hypervisor_compromised:nova_host) ????WHERE?id(server_escaping_hypervisor)?==?"server-0" OPTIONAL?MATCH?(server_escaping_hypervisor)<-[:attached]-(:neutron_port)<-[:contains]-(impacted_subnet_high:neutron_network) OPTIONAL?MATCH?(hypervisor_compromised)-[:`contains`]->(server_same_host:nova_instance) OPTIONAL?MATCH?(server_same_host)<-[:attached]-(:neutron_port)<-[:contains]-(impacted_subnet:neutron_network) OPTIONAL?MATCH?(server_same_host)<-[:attached]-(impacted_volume:cinder_volume) RETURN?impacted_subnet_high.neutron_network.name?AS?impacted_subnet_high, ???????hypervisor_compromised.nova_host.name?AS?hypervisor_compromised, ???????impacted_subnet.neutron_network.name?AS?impacted_subnet, ???????[server_same_host.nova_instance.name,?server_same_host.nova_instance.instance_name]?AS?server_same_host, ???????impacted_volume.cinder_volume.name?AS?impacted_volume
下面的結(jié)果集中,列出了 server-0 被控制之后,考慮宿主機(jī)逃離的情況下可能受影響的擴(kuò)散范圍。
impacted_subnet_high | hypervisor_compromised | impacted_subnet | server_same_host | impacted_volume |
---|---|---|---|---|
shared | node0 | shared | ["server-0", "instance-00000001"] | Empty |
shared | node0 | shared | ["server-1", "instance-00000002"] | ffaeb199-47f4-4d95-89b2-97fba3c1bcfe |
shared | node0 | private | ["server-1", "instance-00000002"] | ffaeb199-47f4-4d95-89b2-97fba3c1bcfe |
shared | node0 | private | ["server-3", "instance-00000005"] | c9db7c2e-c712-49d6-8019-14b82de8542d |
shared | node0 | private | ["server-3", "instance-00000005"] | volume-2 |
shared | node0 | public | ["server-4", "instance-00000006"] | volume-2 |
?
咱們?cè)倏纯此目梢暬Y(jié)果。
?
MATCH?p=(server_escaping_hypervisor)<-[:`contains`]-(hypervisor_compromised:nova_host) ????WHERE?id(server_escaping_hypervisor)?==?"server-0" OPTIONAL?MATCH?p0=(server_escaping_hypervisor)<-[:attached]-(:neutron_port)<-[:contains]-(impacted_subnet_high:neutron_network) OPTIONAL?MATCH?p1=(hypervisor_compromised)-[:`contains`]->(server_same_host:nova_instance) OPTIONAL?MATCH?p2=(server_same_host)<-[:attached]-(:neutron_port)<-[:contains]-(impacted_subnet:neutron_network) OPTIONAL?MATCH?p3=(server_same_host)<-[:attached]-(impacted_volume:cinder_volume) RETURN?p,p0,p1,p2,p3? 還是和之前一樣,我們?cè)诳梢暬瘓D探索工具 Explorer 中選擇 Dagre 布局,它能比較清晰看出影響資源的范圍。從這些可能受影響的虛機(jī)、網(wǎng)絡(luò)、網(wǎng)盤(pán)出發(fā),可以進(jìn)一步采取需要的安全措施了。?
?
?
重點(diǎn)關(guān)注資源檢測(cè)
06
最后,利用 Betweenness Centrality 算法,我們可以獲得基礎(chǔ)設(shè)施中影響面大的那些”脆弱環(huán)節(jié)“。這些資源不一定真的處在危險(xiǎn)的狀態(tài),只是說(shuō),它們處在了比較重要的資源之間的交匯處,一旦它們出問(wèn)題,出問(wèn)題的代價(jià)可能會(huì)非常大。 因此,識(shí)別關(guān)鍵資源后,我們可以考慮下面的安全機(jī)制:
有針對(duì)性采用更激進(jìn)、昂貴的健康檢查策略;
設(shè)定更高的支持、關(guān)注級(jí)別;
主動(dòng)遷移相關(guān)聯(lián)的資源,以降低”脆弱環(huán)節(jié)“對(duì)整體基礎(chǔ)設(shè)施可用性的影響范圍;
在這里,我們只在瀏覽器內(nèi)部的子圖上做算法流程驗(yàn)證。機(jī)智的你,可以自己試著利用開(kāi)源的?NebulaGraph Algorithm?或者付費(fèi)的 NebulaGraph Workflow + Analytics 做全圖上的等價(jià)操作。 首先,我們用之前的方式去掃描圖上 1,000 個(gè)點(diǎn),并且從它們出發(fā),跳一跳,獲得一個(gè)比較隨機(jī)的子圖。實(shí)際上,由于我們的數(shù)據(jù)集并不是很大,這個(gè)操作是撈取了全圖的數(shù)據(jù):
?
OPTIONAL?MATCH?p=(n)--() RETURN?p,?n? 隨機(jī)子圖搞定之后,我們運(yùn)行 Betweenness Centrality 算法,得到 node0?是分值最大的“脆弱一環(huán)”。的確,它是我們當(dāng)前實(shí)驗(yàn)中負(fù)載最大的宿主機(jī),可以想象它確實(shí)是故障之后全局影響最大的一個(gè)資源。
總結(jié)
在海量數(shù)據(jù)、企業(yè)云、混合云的復(fù)雜基礎(chǔ)設(shè)施運(yùn)維場(chǎng)景下,利用圖數(shù)據(jù)庫(kù)圖算法的能力做高效的輔助運(yùn)維工作是一個(gè)十分值得的嘗試與技術(shù)投資。 NebulaGraph 作為高性能、開(kāi)源、分布式的新一代云原生圖數(shù)據(jù)庫(kù),是一個(gè)很值得考慮的圖基礎(chǔ)設(shè)施選型目標(biāo)。 ?
編輯:黃飛
?
評(píng)論
查看更多