?
?
本文系圖技術在大型、復雜基礎設施之中 SRE / DevOps 的實踐參考,并以 OpenStack 系統之上的圖數據庫增強的運維案例為例,揭示圖數據庫、圖算法在智能運維上的應用。本文所有示例代碼開源。
最近,有些尚未使用過圖技術、DevOps / Infra 領域的工程師在 NebulaGraph 社區詢問是否有「圖技術在運維的應用」相關案例參考。于是,我又可以“借題發揮”來實踐下如何利用圖的能力與優勢去幫助運維工程師們基于復雜基礎設施上構建輔助運維系統。如果你對本文有任何看法,歡迎評論區或者來論壇 https://discuss.nebula-graph.com.cn/ 交流,非常感謝。 通常,我們說的復雜的基礎設施運維環境指的是資源(manifest)繁多且分布在不同層面的系統。為了讓實踐更加真實、貼近實際的運維情況,讓運維問題復雜又可控,這里我選擇了用一個基礎設施平臺:OpenStack。在 OpenStack 系統上,我分別利用 Push 和 Pull 兩種模式將資源在圖模型中對應點、邊信息加載到 NebulaGraph 的 Graph ETL 管道的路徑中。 在我們基于運維資源構建的圖譜,會做如下用例圖探索:
告警、狀態的推理與傳導;
網絡直連與互聯關系;
鏡像、云盤、快照血緣管理;
高相關性虛機預警;
秘鑰泄漏的圖上風控分析;
鏡像、云盤漏洞范圍分析;
宿主機逃離影響范圍分析;
脆弱依賴資源檢測;
實驗環境搭建
背景知識
01
OpenStack 是一個開源的云計算平臺,提供了類似于 AWS 的云服務。它提供了一組可插拔的模塊,包括了計算,存儲和網絡等功能,可以幫助用戶構建和管理云環境。OpenStack 采用分布式架構,支持多種操作系統和硬件平臺,可以在企業級和服務提供企業級環境中使用。
最初,OpenStack 是由 NASA 和 Rackspace Inc. 發起的 Nova(虛擬化計算項目)和 Swift(兼容 S3 的對象存儲)項目組成。隨著項目的發展,OpenStack 現在已經有非常多不同的子項目:
本次實踐中涉及到 OpenStack 的主要項目有:
Nova 是 OpenStack 的計算服務,用于管理虛擬機;
Cinder 是 OpenStack 的塊存儲服務,用于管理云存儲;
Neutron 是 OpenStack 的網絡服務,用于管理云網絡;
Glance 是 OpenStack 的鏡像服務,用于管理云鏡像;
Horizon 是 OpenStack 的可視化控制臺服務。
除此之外,我還引入了 Vitrage 項目輔助我們收集部分資源數據:
Vitrage 是 OpenStack 的一個高級分析和可視化工具,用于分析和可視化 OpenStack 環境中的資源和事件。它可以匯集來自 OpenStack 各個服務的數據,并以可視化的方式呈現。Vitrage 能發現和診斷問題,提高 OpenStack 環境的可用性和可維護性。
得益于 OpenStack Decouple 的設計理念,Vitrage 可以很容易、無侵入式(只用修改要收集的服務的兩行配置)就可以在 OpenStack 的消息隊列中訂閱資源信息的 Push 消息。 不過,介于 Vitrage 許久沒有大更新,且維護維艱,比如:在 zed 里 Vitrage Dashboard 作為 Horizon 插件已經無法正常工作了。所以,本實踐只利用它的資源收集能力。
環境準備搭建
02
NebulaGraph 集群
快速試玩 NebulaGraph 的話,安裝有這么幾個選項:
30 天免費試用的阿里云上的 NebulaGraph 企業版,含有配套的可視化周邊工具。復制鏈接開啟試用: https://market.aliyun.com/isv-nebulagraph ?
有 Docker 環境,Nebula-Up 一鍵安裝: https://github.com/wey-gu/nebula-up ?
RPM、TAR 包、源碼編譯等安裝方式,可參考文檔: https://docs.nebula-graph.com.cn/ ?
OpenStack 集群
本文需要的 OpenStack 集群是一個多機的環境,因此我在 Linux Server 上用 Libvirt 和 Linux Bridge 搭建了多個虛擬機來模擬 OpenStack 的物理機。得益于 CPU 的嵌套虛擬化和 QEMU,我們完全可以在虛擬機搭建的實驗環境中模擬可正常工作的 OpenStack Nova instance 虛機。 虛擬機搭建完成后,還需要模擬真實的多資源 Infra 環境。這邊略去具體的操作步驟,感興趣的小伙伴可以閱讀本文的參考文獻,當中有詳細的實踐過程。 完成 OpenStack 環境的搭建后,我們通過 Horizon Dashboard 查看集群和資源: 虛擬機情況:
網盤情況,其中四個掛載在不同的虛擬機上
集群租戶的網絡拓撲:
通過 OpenStack Vitrage 的 API/CLI 可獲得部分主要資源的拓撲:
source?openrc?admin?admin vitrage?topology?show?--all-tenants? 這個結果是一個 JSON,數據已經是邊(links)和點(nodes)的序列化圖結構了。
{ ??"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 服務中的虛擬機實例,每個 nova instance 都有自己的配置信息(如 CPU、內存、磁盤等),有時候我們就叫它 server 或者 VM、虛機。
nova host 是 Nova 服務中的物理主機,是 nova instance 運行的物理環境。nova host 上面會運行 nova-compute 服務,這個服務負責管理和調度 nova instance。nova host 上面還可能運行其他服務,如網絡服務等。
nova keypair 是 Nova 服務中的密鑰對,用于訪問 nova instance。
cinder volume 是 Cinder 服務中的云存儲卷,可以 attach 到 nova instance 上做為硬盤。
cinder snapshot 是 Cinder 服務中的云存儲快照,可以在 cinder volume 上做快照。
glance image 是 Glance 服務中的鏡像,可以作為創建 nova instance 時候的啟動硬盤。
neutron network 是 Neutron 服務中的網絡,可以用于配置 nova instance 的網絡連接。
neutron port 是 Neutron 服務中的端口,用來連接 nova instance 和 neutron network 之間。在 nova instance 虛擬機上,如果不是 trunk port 的話,一個 port 常常對應一個網卡。
它們之間的關系如下:
基礎設施圖 ETL
接下來我們解決從基礎設施中抽取資源元數據的問題:
push 模式
01
這里的 push 指的是以基礎設施為出發點,通過事件驅動主動地發出資源變動的信息。它的好處是實時掌握資源情況,壞處是過于依賴基礎設施,很多非常瘦的、軟件定義 / 可編程程度不高的組件、某些硬件設備是沒有 push 機制的。比如:有些年份的軟件系統不一定能存在 push 的接口,改造起來有侵入性。 前面提及過,OpenStack 自身是存在 Push Hook 機制的,它的子項目 vitrage 就利用這個機制很優雅地收集系統資源、告警等信息進入圖中,類似的機制在其他平臺中也是可以實現的。 本實驗中我們就利用 vitrage 的機制去收集一部分圖譜中的資源信息,如下圖,可以看到 vitrage 會在 OpenStack message bus 中訂閱 nova / cinder / neutron 等服務中的資源時間,把事件傳入 Entity Queue,經過處理,存儲到 Entity Graph 中。 在此之上,我們可以通過 vitrage API 獲取圖譜的拓撲,來消費它。
注意:實際上 Vitrage 服務還提供了推理告警、推理狀態、定義決策事件的能力,這里我們并沒有采用,后邊我們在圖上做的一些事情甚至還和它的能力有一些重疊。
這里我只是用它來展示 push 模式的工作機制,如果沒有 Virtrage 這個項目存在,我們也可以比較容易通過 OpenStack 的 oslo.messaging 這個庫很容易寫出在 Message Bus(可能是 Kafka, RabbitMQ 等不同底層實現)上訂閱資源時間的應用,然后把事件通過 Flink / Kafka / Pulsar 等方式接駁 NebulaGraph。 因為 Vitrage 的存在,我就偷懶不用去實現這部分邏輯,只消寫一小部分代碼調用 Vitrage API 取這個數據就可以了,諷刺的是,從這個角度來看,這其實是一種 pull 的模式了,不用拘泥它本質上算是哪一種方式,至少在資源發起測,我們把它當做 push 模式的例子看待吧。 這部分從 Vitrage 抓取的代碼我放在 https://github.com/wey-gu/openstack-graph/blob/main/utils/vitrage_to_graph.py 了,調用方式很簡單,在有 OpenStack 客戶端的環境中,執行它就可以了,比如:
?
#?連到?node0?上 ssh?stack@node0_ip #?進入?devstack?目錄 cd?devstack #?下載?vitrage?中圖數據,解析為?NeublaGraph?DML/DQL?的工具 wget?https://raw.githubusercontent.com/wey-gu/openstack-graph/main/utils/vitrage_to_graph.py #?執行它 python3?vitrage_to_graph.py? 執行之后,會生成如下文件:
?
?
schema.ngql ? ? 圖數據的 Schema 定義
vertices/ ?點數據的文件夾
edges/ ?邊數據的文件夾
pull?模式
02
反過來,pull 模式是從資源外部定期或者事件驅動地拉取資源,存入圖譜的方式。剛好,本實驗中 Vitrage 抓取的資源是有限,部分額外的資源單獨寫了 Python 的代碼來主動全量抓取。pull 模式的好處是對資源方沒有任何侵入性,只需要調用它的接口獲取信息就可以,壞處則是有的系統不太容易獲得增量變化,可能只能全量去取。 這部分我抓取的關系如下:
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。在真實場景下,我們可能會用 Apache Airflow、Dagster 甚至是 Cron Job 等方式定期執行它。 手動執行的方式也很簡單:
?
#?連到?node0?上 ssh?stack@node0_ip #?進入?devstack?目錄 cd?devstack #?下載抓取?OpenStack?資源,生成?NeublaGraph?DML/DQL?的工具 wget?https://raw.githubusercontent.com/wey-gu/openstack-graph/main/utils/pull_resources_to_graph.py.py #?執行它 python3?pull_resources_to_graph.py? 執行之后,會生成點、邊的 nGQL 語句在兩個文件夾下:
?
?
vertices/ ?點數據的文件夾
edges/ ?邊數據的文件夾
加載數據到?NebulaGraph
03
加載數據到 NebulaGraph
我們只需要在 NebulaGraph Studio Console,Explorer Console 或者 NebulaGraph 命令行 Console 中執行上邊生成的 .ngql 文件就好了:
?
#?DDL?from?vitrage cat?schema.ngql #?DDL?and?DML?for?both?push?and?pull?mode?data cat?edges/*.ngql cat?vertices/*.ngql? 之后,在 NebulaGraph 中我們會有一個叫做 openstack 的圖空間,用這個查詢可以查到所有數據:
MATCH?(n)?WITH?n?LIMIT?1000 OPTIONAL?MATCH?p=(n)--() RETURN?p,?n? 在 NebulaGraph Explorer 中渲染,手動設置一下數據的圖標,就可以看到 OpenStack 集群里的所有租戶的資源圖了:
接下來,我們終于可以在圖上看看有意思的洞察了!
?
?
基于圖譜的基礎設施運維示例
作為非 SRE、DevOps 人員,我嘗試藉由自己在 OpenStack 和圖技術的理解模擬出以下實例,希望對你有所幫助。
告警、狀態的推理與傳導
01
受啟發于 Vitrage 項目,我們可以借助資源圖譜實時圖查詢、圖計算甚至圖可視化能力,在圖上推理、傳導信息,把重要的事件藉由圖上組織好的知識分發給需要收到通知的人、組織、系統。 一個簡單的例子,我們在 nova host(虛擬機的宿主機、Hypervisor 機器,以下簡稱宿主機)中獲得了一個告警、事件的時候,可能是網卡失敗、物理硬盤預警、CPU 占用過高之類的告警。借助圖譜查詢獲得所有相關聯的虛機后,再把 WARN 級別的告警發出去或者設置它們為亞健康 unhealthy 狀態。 獲得通知的對象,往往是一些用戶系統,它們可以根據預先定義好的策略做些自動化運維,或者通知 Hook:
收到“宿主機 CPU 過高”的告警情況,根據用戶自己設定的不同策略把虛機遷移走,或者采用更高級、復雜的撤離方式,像是開始不接受新流量,創建新的替代 workload,再優雅地關閉這個 workload;
“控制面網絡故障”告警情況,這時候往往無法成功進行主機的撤離、遷移,故可以考慮觸發備份主機、啟動新 workload、關機;
其他“亞健康狀態”,可以作為負載層面出問題的根因分析 RCA 依據。
這里給出一個在圖譜上進行告警、狀態傳遞的查詢例子。假設 vid 為 node0?的宿主機出現了高 CPU 告警,下面這個查詢可以得到所有該宿主機上的虛機,獲得時間、告警通知列表:
?
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? 這條語句的查詢圖模式是從 host_CPU_high 這個 nova_host 向外經由 contains 這個關系指向 vm 這個 nova_instance 的。
(vm:nova_instance)<-[:`contains`]-(host_CPU_high:nova_host)? 它的結果是:
?
?
?
VM_to_raise_CPU_alarms |
---|
server-4 |
server-3 |
server-1 |
server-0 |
?
如果我們把查詢改動一下,選擇輸出全路徑,則可以看到這個信息傳遞的方向:
?
MATCH?p=(vm:nova_instance)<-[:`contains`]-(host_CPU_high:nova_host) ????WHERE?id(host_CPU_high)?==?"node0" RETURN?p? 我們在 Explorer 中渲染下,點擊 N 跳檢測:
這個例子比較簡單,甚至用不到圖能力。因為一跳查詢在表結構中也能很輕松地用一、兩個 nova API call 搞定。實際上,圖上是可以做很多更 Graphy(具有圖屬性的)、復雜、獨特的工作的,我們慢慢來看:
?
?
網絡可達檢測
02
考慮下這樣的場景,在 OpenStack 中,不同的主機可以連接到相同的子網 VPC,主機也可以連接到多個子網之中。這樣,主機之間的網絡連通性信息、與網絡聯通相關的推理、傳導都可以在圖上進行。 在真實世界中,這里可能還要考慮 Security Group、Router、Switch 等因素。本示例中我們用到的 OpenStack 是比較簡化的 L2 only Setup。 我們要獲得與虛機 server_a 同一 VPC 的所有其他虛機很容易表達:
?
MATCH?(server_a)--(neutron_network)--(`nova_instance`) ????WHERE?id(server_a)?==?"server-0" RETURN?server_b.nova_instance.name?AS?L2_connected_server? 結果如下:
?
?
?
L2_connected_server |
---|
server-1 |
?
看起來很初級,接下來我們再查詢與虛機 server_a 同一 VPC、有可能通過跨網絡虛機而互聯的主機的所有其他虛機。這時候,我們除了共享 neutron network(VPC) 的情況,還要查詢所有二層直連的虛機可能通過其他 VPC 連出去的的虛機。下面的例子,我們用到了 OPTIONAL MATCH 的表達,表示可能匹配到的模式:
?
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? 可以看到結果里,跨網絡潛在的相連主機還有 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? 它可能的連接路徑一目了然了:
有了獲得這些信息的能力,我們可以可編程地連接告警、狀態、安全風控、網絡等方方面面系統。當然這不是本文的重點,就不加以贅述了,你有相關的實踐想要分享的話,記得來 NebulaGraph 社區。 下面,我們來看看存儲相關的例子。
?
?
鏡像、云盤、快照的血緣
03
在基礎設施中,云盤(iSCSI、Ceph、NFS)、鏡像、快照之間有多重復雜的關系,比如:
一個系統鏡像可能從某一個虛擬機掛載的云盤或者一個快照創建
一個云盤可能是從一個系統鏡像、一個快照或者另一個云盤創建
一個快照是從一個云盤創建的
這種血緣信息的識別和管理是很有必要的。下面的查詢可以獲得指定虛機 server-0?的所有存儲血緣:
?
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? 我們可以看到結果中:
?
?
server-0 ?的啟動鏡像(這里它是從本地盤啟動的,沒有掛載云盤)是從 volume-1 創建的;
volume-1 是從 cirros-0.5.2-x86_64-disk 這個鏡像創建的;
此外,還有其他有分叉關系的存儲資源和它們也息息相關:
下面,我們不只考慮存儲資源,看下涉及云盤 cinder_volume 掛載 attached 這層關系下的血緣關系:
?
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 ?的啟動鏡像(這里它是從本地盤啟動的)是從? volume-1 ?創建的
而? volume-1 ?現在掛載在? server-6 ?上
volume-1 ?是從? cirros-0.5.2-x86_64-disk ?這個鏡像創建的
同樣? cirros-0.5.2-x86_64-disk ?鏡像被很多其他虛機在采用
server-4 ?同時掛載了數據盤? volume-2 ?
而? volume-2 ?是一個多掛載的盤,它同時掛載在? server-3 ?之上
server-3 ?的系統啟動盤是從快照? snapshot-202301111800-volume-1 ?克隆創建的
快照? snapshot-202301111800-volume-1 ?是曾經從? volume-1 ?創建的
volume-1 現在掛載在 server-6 上,快照不一定是從 server-6 而來,因為鏡像可能被重新掛載過。而這些血緣信息可以被用在資源生命周期管理、根因分析、安全告警、狀態傳遞上,這里不加以贅述。
高相關性虛機預警
04
下面這個例子,會給出一個節點相似度的應用。在全圖或者子圖上,利用圖算法找到與指定虛機圖拓撲結構最相似的其他虛機,并在這種相關性基礎上增加新的關系,做風險事件預警。 本次實踐,我們會按照一個典型的從「快速子圖驗證」到「全圖生產應用」的工作流。
子圖快速驗證:瀏覽器內算法
從 server-0?的三度子圖上做算法的驗證:
?
GET?SUBGRAPH?3?STEPS?FROM?"server-0" YIELD?VERTICES?AS?nodes,?EDGES?AS?relationships;? 將結果渲染在畫布上,我們可以看到子圖中包含了其他幾個虛機:
我們利用 Explorer 中的瀏覽器內圖算法,可以非常方便地驗證我們的想法。這里,我們使用 Jaccard Similarity 相似性算法,讓 server-0?與 server-1,server-3,server-4,server-6 迭代分別得到相似性:
可以看出,在 3 步子圖內,和 server-0?最近接的虛機是 server-4。進一步,我們可以簡單在子圖上看看兩者之間的路徑作為相似性的解釋:
在這個可解釋結果中,我們知道 server-0?與 server-4 相似的原因可能是:
坐落在同一個宿主機:node-0
使用同一個鏡像:cirros_mod_from_volume-1
因此,我們最終落地的預警機制可能是,當 server-0?出現某一問題、告警時候,給相似的 server-4 也設定預警,預警理由就是它們在同樣主機、同樣鏡像。
全圖生產應用
有了上面的快速實驗,借助 Workflow + NebulaGraph Analytics 把它落地為全圖上的算法,利用 Analytics 分布式能力去執行。 在生產上,我們利用 Workflow 的 DAG 編排能力,創建兩個前后相連的任務:
取臨近虛機
全圖算相似度
第一個任務如下,實時從指定虛機出發給出其他虛機 vid。這里查詢語句寫死了 server-0,但是在 Workflow 里可以參數化,并封裝任務為可被 API 觸發的異步服務:
?
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 全圖掃描所有邊類型。
保存、運行。結果如下,這次它運算了更多的目標虛機,并且迭代作用范圍是全圖而非一個子圖。可以看到同上次的結果是一樣,因為子圖上關聯度大的點和相近的邊在 Jaccard 算法里起到了更主要的作用。
?
?
安全相關場景
05
基礎設施資源中的關聯關系和金融、內容系統、電商領域的風控場景有相似的地方,很多場景本質上利用到了圖譜關系中的知識,在圖庫上實時獲取這些復雜但又天然可解釋的安全洞察。
秘鑰泄漏風控分析
先看一個秘鑰泄漏的場景:假設 key-0?被安全部門確定被泄漏了,我們可以在毫秒內獲得如下查詢:
直接使用該密鑰的虛機
與使用該秘鑰的虛機網絡直連的機器
與使用該秘鑰的虛機跨網絡相連的機器
?
?
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貼一下部分結果,我們知道 server-4 采用了這個 keypair,并且 server-6 和它在同一個網絡。同時,有一定幾率通過 server-6、server-1、server-2、server-0、server-5 也受到了影響。針對這種情況,相關的機器可以設置不同告警級別來降低安全事故的影響。
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 |
這個查詢改造為可視化結果:
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 中應用 Dagre-LR 的布局,相關的關聯關系可以很清晰地被展示出來。介于可視化展示的直觀性,我們可以考慮把這個圖放入安全報告,隨同其他安全信息一同分發給虛機租戶。
?
?
鏡像、云盤漏洞范圍分析
類似的,一個鏡像被掃出漏洞,我們可以瞬間查到波及的資源,并做出相應應對之策。 鏡像文件有漏洞:
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?
某個云盤有漏洞:
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?
?
?
潛在宿主機逃離影響范圍分析
最后,我們討論一個嚴重的安全問題:宿主機逃離。 在極端的情況下,server-0?發生了有可能影響宿主機的安全事件,此時僅僅關閉這個宿主機是不夠的,因為受影響的范圍可能已經擴大。但我們又不能因為這樣不知影響范圍多廣的安全事件來關閉整個機房。所以,利用圖譜輔助找出受影響范圍就非常有用了。 下面的查詢模式是:
找出可能被影響的子網(VPC),標記最高級別風險子網為后續定位做準備
找到可能被控制了的宿主機
從宿主機觸發,找出同主機的其他虛機
從其他虛機觸發,找到它們的子網(VPC)
從其他虛機觸發,找到可能已經被影響的網盤。這是為了防止被掛載到其他機器,這會擴大影響。??
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
下面的結果集中,列出了 server-0 被控制之后,考慮宿主機逃離的情況下可能受影響的擴散范圍。
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 |
?
咱們再看看它的可視化結果。
?
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? 還是和之前一樣,我們在可視化圖探索工具 Explorer 中選擇 Dagre 布局,它能比較清晰看出影響資源的范圍。從這些可能受影響的虛機、網絡、網盤出發,可以進一步采取需要的安全措施了。?
?
?
重點關注資源檢測
06
最后,利用 Betweenness Centrality 算法,我們可以獲得基礎設施中影響面大的那些”脆弱環節“。這些資源不一定真的處在危險的狀態,只是說,它們處在了比較重要的資源之間的交匯處,一旦它們出問題,出問題的代價可能會非常大。 因此,識別關鍵資源后,我們可以考慮下面的安全機制:
有針對性采用更激進、昂貴的健康檢查策略;
設定更高的支持、關注級別;
主動遷移相關聯的資源,以降低”脆弱環節“對整體基礎設施可用性的影響范圍;
在這里,我們只在瀏覽器內部的子圖上做算法流程驗證。機智的你,可以自己試著利用開源的?NebulaGraph Algorithm?或者付費的 NebulaGraph Workflow + Analytics 做全圖上的等價操作。 首先,我們用之前的方式去掃描圖上 1,000 個點,并且從它們出發,跳一跳,獲得一個比較隨機的子圖。實際上,由于我們的數據集并不是很大,這個操作是撈取了全圖的數據:
?
OPTIONAL?MATCH?p=(n)--() RETURN?p,?n? 隨機子圖搞定之后,我們運行 Betweenness Centrality 算法,得到 node0?是分值最大的“脆弱一環”。的確,它是我們當前實驗中負載最大的宿主機,可以想象它確實是故障之后全局影響最大的一個資源。
總結
在海量數據、企業云、混合云的復雜基礎設施運維場景下,利用圖數據庫圖算法的能力做高效的輔助運維工作是一個十分值得的嘗試與技術投資。 NebulaGraph 作為高性能、開源、分布式的新一代云原生圖數據庫,是一個很值得考慮的圖基礎設施選型目標。 ?
編輯:黃飛
?
評論
查看更多