图数据库驱动的基础设施运维示例
本文系图技术在大型、复杂基础设施之中 SRE / DevOps 的实践参考,并以 OpenStack 系统之上的图数据库增强的运维案例为例,揭示图数据库、图算法在智能运维上的应用。本文所有示例代码开源。
告警、状态的推理与传导; 网络直连与互联关系; 镜像、云盘、快照血缘管理; 高相关性虚机预警; 秘钥泄漏的图上风控分析; 镜像、云盘漏洞范围分析; 宿主机逃离影响范围分析; 脆弱依赖资源检测;
实验环境搭建
背景知识
Nova 是 OpenStack 的计算服务,用于管理虚拟机; Cinder 是 OpenStack 的块存储服务,用于管理云存储; Neutron 是 OpenStack 的网络服务,用于管理云网络; Glance 是 OpenStack 的镜像服务,用于管理云镜像; Horizon 是 OpenStack 的可视化控制台服务。
Vitrage 是 OpenStack 的一个高级分析和可视化工具,用于分析和可视化 OpenStack 环境中的资源和事件。它可以汇集来自 OpenStack 各个服务的数据,并以可视化的方式呈现。Vitrage 能发现和诊断问题,提高 OpenStack 环境的可用性和可维护性。
环境准备搭建
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 集群
source openrc admin admin
vitrage topology show --all-tenants
{
"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 模式
注意:实际上 Vitrage 服务还提供了推理告警、推理状态、定义决策事件的能力,这里我们并没有采用,后边我们在图上做的一些事情甚至还和它的能力有一些重叠。
# 连到 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 模式
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)
# 连到 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
vertices/ 点数据的文件夹 edges/ 边数据的文件夹
加载数据到 NebulaGraph
加载数据到 NebulaGraph
# DDL from vitrage
cat schema.ngql
# DDL and DML for both push and pull mode data
cat edges/*.ngql
cat vertices/*.ngql
MATCH (n) WITH n LIMIT 1000
OPTIONAL MATCH p=(n)--()
RETURN p, n
基于图谱的基础设施运维示例
告警、状态的推理与传导
收到“宿主机 CPU 过高”的告警情况,根据用户自己设定的不同策略把虚机迁移走,或者采用更高级、复杂的撤离方式,像是开始不接受新流量,创建新的替代 workload,再优雅地关闭这个 workload; “控制面网络故障”告警情况,这时候往往无法成功进行主机的撤离、迁移,故可以考虑触发备份主机、启动新 workload、关机; 其他“亚健康状态”,可以作为负载层面出问题的根因分析 RCA 依据。
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
(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
网络可达检测
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 |
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
L2_connected_server | cross_vpc_server |
---|---|
server-1 | server-3 |
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
镜像、云盘、快照的血缘
一个系统镜像可能从某一个虚拟机挂载的云盘或者一个快照创建 一个云盘可能是从一个系统镜像、一个快照或者另一个云盘创建 一个快照是从一个云盘创建的
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 这个镜像创建的;
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 而来,因为镜像可能被重新挂载过。而这些血缘信息可以被用在资源生命周期管理、根因分析、安全告警、状态传递上,这里不加以赘述。
高相关性虚机预警
子图快速验证:浏览器内算法
GET SUBGRAPH 3 STEPS FROM "server-0"
YIELD VERTICES AS nodes, EDGES AS relationships;
坐落在同一个宿主机:node-0 使用同一个镜像:cirros_mod_from_volume-1
全图生产应用
取临近虚机 全图算相似度
MATCH (n)-[*1..5]-(m:`nova_instance`)
WHERE id(n) == "server-0" AND n != m
RETURN distinct id(m)
安全相关场景
秘钥泄漏风控分析
直接使用该密钥的虚机 与使用该秘钥的虚机网络直连的机器 与使用该秘钥的虚机跨网络相连的机器
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
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
镜像、云盘漏洞范围分析
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
潜在宿主机逃离影响范围分析
找出可能被影响的子网(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
重点关注资源检测
有针对性采用更激进、昂贵的健康检查策略; 设定更高的支持、关注级别; 主动迁移相关联的资源,以降低”脆弱环节“对整体基础设施可用性的影响范围;
OPTIONAL MATCH p=(n)--()
RETURN p, n
总结
🌟 参考文献
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
往期推荐
著名开源贡献者Hax在GitHub公开与360的劳动争议诉讼
我们为何期待Rust 2.0?
微软开源“傻瓜式”类ChatGPT模型训练工具,提速省钱15倍
🌟 活动推荐
2023 年 5 月 27-28 日,GOTC 2023 全球开源技术峰会将在上海张江科学会堂隆重举行。
为期 2 天的开源行业盛会,将以行业展览、主题发言、特别论坛、分论坛、快闪演讲的形式来诠释此次大会主题 ——“Open Source, Into the Future”。与会者将一起探讨元宇宙、3D 与游戏、eBPF、Web3.0、区块链等热门技术主题,以及 OSPO、汽车软件、AIGC、开源教育培训、云原生、信创等热门话题,探讨开源未来,助力开源发展。
长按识别下方二维码立即查看 GOTC 2023 详情/报名。
微信扫码关注该文公众号作者
戳这里提交新闻线索和高质量文章给我们。
来源: qq
点击查看作者最近其他文章