关于运维:图数据库驱动的基础设施运维实操

1次阅读

共计 17037 个字符,预计需要花费 43 分钟才能阅读完成。

本文系图技术在大型、简单基础设施之中 SRE/DevOps 的实际参考,并以 OpenStack 零碎之上的图数据库加强的运维案例为例,揭示图数据库、图算法在智能运维上的利用。本文所有示例代码开源。

最近,有些尚未应用过图技术、DevOps/Infra 畛域的工程师在 NebulaGraph 社区询问是否有「图技术在运维的利用」相干案例参考。于是,我又能够“小题大作”来实际下如何利用图的能力与劣势去帮忙运维工程师们基于简单基础设施上构建辅助运维零碎。如果你对本文有任何认识,欢送评论区或者来论坛和我交换下,非常感谢。

通常,咱们说的简单的基础设施运维环境指的是资源(manifest)繁多且散布在不同层面的零碎。为了让实际更加实在、贴近理论的运维状况,让运维问题简单又可控,这里我抉择了用一个基础设施平台:OpenStack。在 OpenStack 零碎上,我别离利用 Push 和 Pull 两种模式将资源在图模型中对应点、边信息加载到 NebulaGraph 的 Graph ETL 管道的门路中。

在咱们基于运维资源构建的图谱,会做如下用例图摸索:

  • 告警、状态的推理与传导;
  • 网络直连与互联关系;
  • 镜像、云盘、快照血统治理;
  • 高相关性虚机预警;
  • 秘钥透露的图下风控剖析;
  • 镜像、云盘破绽范畴剖析;
  • 宿主机逃离影响范畴剖析;
  • 软弱依赖资源检测;

试验环境搭建

背景常识

OpenStack 是一个开源的云计算平台,提供了相似于 AWS 的云服务。它提供了一组可插拔的模块,包含了计算,存储和网络等性能,能够帮忙用户构建和治理云环境。OpenStack 采纳分布式架构,反对多种操作系统和硬件平台,能够在企业级和服务提供企业级环境中应用。

最后,OpenStack 是由 NASARackspace 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 插件曾经无奈失常工作了。所以,本实际只利用它的资源收集能力。

环境筹备搭建

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-13T08:06:48Z",
      "vitrage_sample_timestamp": "2023-01-13T08:06:49Z",
      "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-12T03:06:48Z",
      "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-12T03:06:48Z",
      "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 模式

这里的 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 模式

反过来,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

咱们只须要在 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 和图技术的了解模拟出以下实例,心愿对你有所帮忙。

告警、状态的推理与传导

受启发于 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(具备图属性的)、简单、独特的工作的,咱们缓缓来看:

网络可达检测

思考下这样的场景,在 OpenStack 中,不同的主机能够连贯到雷同的子网 VPC,主机也能够连贯到多个子网之中。这样,主机之间的网络连通性信息、与网络联通相干的推理、传导都能够在图上进行。

在真实世界中,这里可能还要思考 Security Group、Router、Switch 等因素。本示例中咱们用到的 OpenStack 是比拟简化的 L2 only Setup。

咱们要取得与虚机 server_a 同一 VPC 的所有其余虚机很容易表白:

MATCH (server_a)--(:neutron_port)--(:neutron_network)--(:neutron_port)--(server_b:`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_port)--(net:neutron_network)--(:neutron_port)--(server_b:`nova_instance`)
    WHERE id(server_a) == "server-0"
OPTIONAL MATCH (server_b)--()--(other_net:neutron_network)--(:neutron_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

可视化下,同样,咱们批改输入为门路 pp1

MATCH p=(server_a)--(:neutron_port)--(net:neutron_network)--(:neutron_port)--(server_b:`nova_instance`)
    WHERE id(server_a) == "server-0"
OPTIONAL MATCH p1=(server_b)--()--(other_net:neutron_network)--(:neutron_port)--(server_c:`nova_instance`)
RETURN p, p1

它可能的连贯门路高深莫测了:

有了取得这些信息的能力,咱们能够可编程地连贯告警、状态、平安风控、网络等方方面面零碎。当然这不是本文的重点,就不加以赘述了,你有相干的实际想要分享的话,记得来 NebulaGraph 社区。

上面,咱们来看看存储相干的例子。

镜像、云盘、快照的血统

在基础设施中,云盘(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 而来,因为镜像可能被从新挂载过。而这些血统信息能够被用在资源生命周期治理、根因剖析、平安告警、状态传递上,这里不加以赘述。

高相关性虚机预警

上面这个例子,会给出一个节点类似度的利用。在全图或者子图上,利用图算法找到与指定虚机图拓扑构造最类似的其余虚机,并在这种相关性根底上减少新的关系,做危险事件预警。

本次实际,咱们会依照一个典型的从「疾速子图验证」到「全图生产利用」的工作流。

子图疾速验证:浏览器内算法

server-0 的三度子图上做算法的验证:

GET SUBGRAPH 3 STEPS FROM "server-0"
YIELD VERTICES AS nodes, EDGES AS relationships;

将后果渲染在画布上,咱们能够看到子图中蕴含了其余几个虚机:

咱们利用 Explorer 中的浏览器内图算法,能够十分不便地验证咱们的想法。这里,咱们应用 Jaccard Similarity 相似性算法,让 server-0server-1,server-3,server-4,server-6 迭代别离失去相似性:

能够看出,在 3 步子图内,和 server-0 最近接的虚机是 server-4。进一步,咱们能够简略在子图上看看两者之间的门路作为相似性的解释:

在这个可解释后果中,咱们晓得 server-0server-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 算法里起到了更次要的作用。

平安相干场景

基础设施资源中的关联关系和金融、内容零碎、电商畛域的风控场景有类似的中央,很多场景实质上利用到了图谱关系中的常识,在图库上实时获取这些简单但又人造可解释的平安洞察。

秘钥透露风控剖析

先看一个秘钥透露的场景:假如 key-0 被安全部门确定被透露了,咱们能够在毫秒内取得如下查问:

  • 间接应用该密钥的虚机
  • 与应用该秘钥的虚机网络直连的机器
  • 与应用该秘钥的虚机跨网络相连的机器
MATCH (key_leaked)-[:`used_by`]->(involved_server:nova_instance)--(:neutron_port)--(net:neutron_network)--(:neutron_port)--(server_b:nova_instance)
       WHERE id(key_leaked) == "key-0"
OPTIONAL MATCH (server_b)--()--(other_net:neutron_network)--(:neutron_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_server:nova_instance)--(:neutron_port)--(net:neutron_network)--(:neutron_port)--(server_b:nova_instance)
    WHERE id(key_leaked) == "key-0"
OPTIONAL MATCH p1=(server_b)--()--(other_net:neutron_network)--(:neutron_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 布局,它能比拟清晰看出影响资源的范畴。从这些可能受影响的虚机、网络、网盘登程,能够进一步采取须要的安全措施了。

重点关注资源检测

最初,利用 Betweenness Centrality 算法,咱们能够取得基础设施中影响面大的那些”软弱环节“。这些资源不肯定真的处在危险的状态,只是说,它们处在了比拟重要的资源之间的交汇处,一旦它们出问题,出问题的代价可能会十分大。

因而,辨认要害资源后,咱们能够思考上面的平安机制:

  • 有针对性采纳更激进、低廉的健康检查策略;
  • 设定更高的反对、关注级别;
  • 被动迁徙相关联的资源,以升高”软弱环节“对整体基础设施可用性的影响范畴;

在这里,咱们只在浏览器外部的子图上做算法流程验证。机智的你,能够本人试着利用开源的 NebulaGraph Algorithm 或者付费的 NebulaGraph Workflow + Analytics 做全图上的等价操作。

首先,咱们用之前的形式去扫描图上 1,000 个点,并且从它们登程,跳一跳,取得一个比拟随机的子图。实际上,因为咱们的数据集并不是很大,这个操作是捞取了全图的数据:

OPTIONAL MATCH p=(n)--()
RETURN p, n

随机子图搞定之后,咱们运行 Betweenness Centrality 算法,失去 node0 是分值最大的”软弱一环“。确实,它是咱们以后试验中负载最大的宿主机,能够设想它的确是故障之后全局影响最大的一个资源。

总结

在海量数据、企业云、混合云的简单基础设施运维场景下,利用图数据库图算法的能力做高效的辅助运维工作是一个非常值得的尝试与技术投资。

NebulaGraph 作为高性能、开源、分布式的新一代云原生图数据库,是一个很值得思考的图基础设施选型指标。

欢送大家在文末留言探讨,本文的可复现环境和示例的 ETL 管道的代码、示例数据全都在 https://github.com/wey-gu/openstack-graph/ 开源,欢送大家来一起欠缺。

本文用到的可视化图摸索工具为 NebulaGraph Explorer,目前能够收费试用 30 天。

此外,我把本试验中的图谱放在了 NebulaGraph Studio/Explorer 的示例数据集中,大家也能够在里边下载试玩。

参考文献

  • OpenStack 环境搭建:https://github.com/wey-gu/openstack-graph/#environment-setup
  • Infra 资源创立:https://github.com/wey-gu/openstack-graph/#create-resources-on-openstack
  • Vitrage 示例文档:https://github.com/openstack/vitrage/blob/master/doc/source/contributor/vitrage-templates.rst

谢谢你读完本文 (///▽///)

NebulaGraph Desktop,Windows 和 macOS 用户装置图数据库的绿色通道,10s 拉起搞定海量数据的图服务。通道传送门:http://c.nxw.so/7CcNV

想看源码的小伙伴能够返回 GitHub 浏览、应用、(^з^)-☆ star 它 -> GitHub;和其余的 NebulaGraph 用户一起交换图数据库技术和利用技能,留下「你的名片」一起游玩呢~

正文完
 0