diff --git a/README.md b/README.md index 5f1a37aa5ba22217110f9402ca33ceaaf2f4494e..9110b2abe4e7d04a8c99fd82de840b6147410f5a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # 介绍 -gala-ops是一款C/S架构、基于AI的操作系统亚健康诊断工具。其基于eBPF + java agent无侵入观测技术,并以AI技术辅助,实现亚健康故障(比如性能抖动、错误率提升、系统卡顿等问题现象)分钟级诊断,简化IT基础设施的运维过程。 +![](./png/logo.png) + +gala是一款C/S架构、基于AI的操作系统亚健康诊断工具。其基于eBPF + java agent无侵入观测技术,并以AI技术辅助,实现亚健康故障(比如性能抖动、错误率提升、系统卡顿等问题现象)分钟级诊断,简化IT基础设施的运维过程。 # 背景 @@ -12,18 +14,18 @@ gala-ops是一款C/S架构、基于AI的操作系统亚健康诊断工具。其 # 项目简介 -gala-ops的整体架构如图所示,其整体上是一个C/S架构。在生产节点gala-gopher是一个Linux后台程序,其负责提供全场景、全栈(包括Metrics、Events、Tracing等)的数据采集,其支持通过OpenTelemetry开放生态接口(支持prometheus exporter、kafka client等)将数据传递给管理节点。管理节点部署gala-spider、gala-anteater组件,分别负责集群拓扑计算、可视化根因推导; +gala的整体架构如图所示,其整体上是一个C/S架构。在生产节点gala-gopher是一个Linux后台程序,其负责提供全场景、全栈(包括Metrics、Events、Tracing等)的数据采集,其支持通过OpenTelemetry开放生态接口(支持prometheus exporter、kafka client等)将数据传递给管理节点。管理节点部署gala-spider、gala-anteater组件,分别负责集群拓扑计算、可视化根因推导; -gala-ops架构上依赖一些开源中间件(包括prometheus、kafka、Elastic等),但亦可对接至客户IT系统现有的中间件。gala-ops架构设计提供被集成能力,可以由行业客户IT运维系统集成。其提供两类被集成方式: +gala架构上依赖一些开源中间件(包括prometheus、kafka、Elastic等),但亦可对接至客户IT系统现有的中间件。gala架构设计提供被集成能力,可以由行业客户IT运维系统集成。其提供两类被集成方式: - 软件生态集成方式:可以只使用gala-gopher可观测能力(OpenTelemetry方式获取数据),亦可以使用全部能力,通过prometheus、Elastic、kafka等中间件获取观测数据、异常检测结果、可视化推导结果。 -- 工具集成方式:将gala-ops提供的能力以Grafana形式集成至客户IT运维系统内。 +- 工具集成方式:将gala提供的能力以Grafana形式集成至客户IT运维系统内。 ![](./png/gala-arch.png) -gala-ops可以给客户提供如下运维能力: +gala可以给客户提供如下运维能力: - 在线应用性能抖动诊断:提供数据库类应用性能在线诊断能力,包括网络类(丢包、重传、时延、TCP零窗等)问题、I/O类(磁盘慢盘、I/O性能下降等)问题,调度类(包括sysCPU冲高、死锁等)问题、内存类(OOM、泄漏等)问题等。 - 系统性能瓶颈诊断:提供通用场景的TCP、I/O性能抖动问题诊断能力。 @@ -34,7 +36,7 @@ gala-ops可以给客户提供如下运维能力: -gala-ops涉及的关键技术包括如下: +gala涉及的关键技术包括如下: - 融合型非侵入观测技术:融合eBPF、Java agent等不同观测技术优点,实现多语言(支持C/C++、Java、Go等主流语言)、全软件栈(包括内核、系统调用、基础库Glibc、运行时jvm、基础中间件Nginx/Haproxy等)的观测能力。 - 流程拓扑:基于时序化数据(L4/L7层流量等),实时计算生成时序化拓扑结构,动态展现业务集群拓扑变化。 @@ -42,7 +44,7 @@ gala-ops涉及的关键技术包括如下: # 应用场景 -​ gala-ops在openEuler等Linux环境主要面向场景包括数据库、分布式存储、虚拟化、云原生等场景。助力金融、电信、互联网等行业客户在全栈可观测的基础上实现亚健康故障分钟级诊断。 +​ gala在openEuler等Linux环境主要面向场景包括数据库、分布式存储、虚拟化、云原生等场景。助力金融、电信、互联网等行业客户在全栈可观测的基础上实现亚健康故障分钟级诊断。 # 项目代码仓 @@ -58,7 +60,7 @@ https://gitee.com/openeuler/gala-anteater ## 架构 -gala-ops是C/S架构,可以集群方式部署,也可以单机部署。整个架构由[gala-gopher](#gala-gopher)、gala-ops两个软件组成,在集群模式下,gala-gopher安装在生产节点内,gala-ops安装在管理节点内;单机模式两者均安装在生产节点内。 +gala是C/S架构,可以集群方式部署,也可以单机部署。整个架构由[gala-gopher](#gala-gopher)、gala-ops两个软件组成,在集群模式下,gala-gopher安装在生产节点内,gala-ops安装在管理节点内;单机模式两者均安装在生产节点内。 其中,gala-ops软件内包括[gala-spider](#gala-spider)、[gala-anteater](#gala-anteater)、[gala-inference](#gala-inference)组件。 @@ -187,13 +189,13 @@ gala-anteater是一款基于AI的操作系统异常检测平台。主要涵盖 参考[这里](https://gitee.com/openeuler/gala-spider/blob/master/README.md)。 -## gala-ops系统集成 +## gala系统集成 -gala-ops还依赖一些开源软件,包括kafka、arangodb、prometheus等。下图介绍gala-ops系统集成关系,kafka用于传输logs/tracing类数据至ES/logstash/jaeger,prometheus用于存储Metrics数据,Arangodb用于存储实时拓扑数据,grafana用于前端页面展示。 +gala还依赖一些开源软件,包括kafka、arangodb、prometheus等。下图介绍gala系统集成关系,kafka用于传输logs/tracing类数据至ES/logstash/jaeger,prometheus用于存储Metrics数据,Arangodb用于存储实时拓扑数据,grafana用于前端页面展示。 ![](./png/system_integration.png) -## gala-ops系统安装 +## gala系统安装 Gala提供了集成式部署工具[Gala-Deploy-Tools](./deploy)以便用户快速部署gala-gopher、gala-ops(gala-spider/gala-inference/gala-anteater)组件、kafka/prometheus/arangodb/es/logstash/pyroscope中间件、grafana前端页面展示相关组件,并同时支持离线/在线部署两种模式。 - kafka 用于传输 gala 软件数据 @@ -766,18 +768,22 @@ gala-ops支持使用Grafana图形界面用来帮助客户更好的理解性能Pr # Q&A -1. 系统如何快捷部署? +## 如何快速使用 + +系统如何快捷部署? + +社区提供两类快捷部署方式,1)[在线部署](https://gitee.com/struggling-li-xiaozi/gala-docs#%E5%9C%A8%E7%BA%BF%E9%83%A8%E7%BD%B2); 2)[离线部署](https://gitee.com/struggling-li-xiaozi/gala-docs#%E7%A6%BB%E7%BA%BF%E9%83%A8%E7%BD%B2);前者要求用户安装环境可以访问openEuler社区;后者可以要求用户下载软件后,将其拷贝至安装环境; - 社区提供两类快捷部署方式,1)[在线部署](https://gitee.com/struggling-li-xiaozi/gala-docs#%E5%9C%A8%E7%BA%BF%E9%83%A8%E7%BD%B2); 2)[离线部署](https://gitee.com/struggling-li-xiaozi/gala-docs#%E7%A6%BB%E7%BA%BF%E9%83%A8%E7%BD%B2);前者要求用户安装环境可以访问openEuler社区;后者可以要求用户下载软件后,将其拷贝至安装环境; +## 版本配套 -2. gala-gopher支持哪些OS版本? +1. gala-gopher支持哪些OS版本? - openEuler 22.03 SP1及其之后的LTS版本是正式推荐客户使用的版本; - openEuler 22.03 SP1之前的LTS版本也将获得openEuler社区技术支撑,但社区不推荐客户使用; - openEuler 系列的商用OS(比如麒麟V10)也将获得openEuler社区技术支撑,但是商用OS厂商暂未对gala-gopher提供商用维保; - 非openEuler系列的OS(比如SUSE 12,CentOS等)技术上可以安装、部署gala-gopher,但原则上获取不到社区技术支撑; -3. gala-gopher的观测能力支持哪些内核版本? +2. gala-gopher的观测能力支持哪些内核版本? | 内核版本 | 观测能力范围 | | -------- | ------------------------------------------------------------ | @@ -786,41 +792,16 @@ gala-ops支持使用Grafana图形界面用来帮助客户更好的理解性能Pr | 4.19 | 在线性能火焰图、TCP、I/O、应用L7层流量、进程、DNS、Redis(Server侧)时延性能、PG DB(Server侧)时延性能、openGauss(Server侧)时延性能 | | 5.10 | 在线性能火焰图、TCP、I/O、应用L7层流量、进程、DNS、Redis(Server侧)时延性能、PG DB(Server侧)时延性能、openGauss(Server侧)时延性能 | -4. gala-gopher是否支持跨内核版本兼容? +3. gala-gopher是否支持跨内核版本兼容? - 在openEuler 22.03 SP1版本中,gala-gopher不支持跨内核版本兼容; - 规划在openEuler 22.03 SP3版本中,gala-gopher将支持跨Release版本兼容;(即5.10内核版本范围内,不同release版本可以使用同一个gala-gopher组件); - 规划在openEuler 23.03 SP1版本中,gala-gopher将在低内核版本(4.18/4.19)支持跨Release版本兼容性; - 规划在24年,gala-gopher将支持跨内核大版本的兼容性(比如5.10/4.19两个内核版本可以使用相同的gala-gopher软件版本); -5. gala-gopher是否支持容器场景? - - 支持containerd、docker、isula三种容器运行时;可以针对这三种容器运行时场景的容器实例监控。 - -6. gala-gopher是否支持K8S部署、监管? - - gala-gopher支持在K8S环境中以daemonset形式部署,相关的daemonset yaml、容器镜像Dockerfile、容器启动入口脚本请参考: - - https://gitee.com/openeuler/gala-gopher/blob/dev/k8s/daemonset.yaml.tmpl - https://gitee.com/openeuler/gala-gopher/blob/dev/build/Dockerfile_2003_sp1_x86_64 - https://gitee.com/openeuler/gala-gopher/blob/dev/build/Dockerfile_2003_sp1_aarch64 - https://gitee.com/openeuler/gala-gopher/blob/dev/build/entrypoint.sh +## 性能测试 -7. 如何设置监控范围? - - 监控范围由gala-gopher组件控制, 它提供[REST接口](https://gitee.com/openeuler/gala-gopher/blob/dev/config/gala-gopher%E6%94%AF%E6%8C%81%E5%8A%A8%E6%80%81%E9%85%8D%E7%BD%AE%E6%8E%A5%E5%8F%A3%E8%AE%BE%E8%AE%A1_v0.3.md)设置监控范围,并支持运行过程中实时调整监控范围。它存在几个维度的设置方式: - - 1)设置采集的数据类型;(比如设定只采集TCP、I/O的数据) - - 2)设定采集特定数据类型的范围;(比如设定只采集TCP的丢包数据 或者 TCP rtt数据) - - 3)设定采集特定进程、容器实例的范围;(比如通过进程ID、进程名、容器ID、Pod ID 方式设置采集范围) - - ​ 三个维度可以组合使用,且可以在监控过程中实时修改设置; - - 缺省行为:如果不加以任何设置,gala-gopher将不采集任何数据。 - -8. gala-gopher底噪数据? +1. gala-gopher底噪数据? 测试条件: @@ -843,7 +824,7 @@ gala-ops支持使用Grafana图形界面用来帮助客户更好的理解性能Pr | 单独启动 stackprobe 探针 | 平均<1%,最高到1.5%(间隔30s) | | 启动 systeminfo,proc,tcp,io,endpoint,jvm,stackprobe 探针 | 平均5% | -9. gala系统需要多少资源? +2. gala系统需要多少资源? | 组件 | 部署位置 | 资源要求 | | ----------------- | -------- | -------------------------------------------- | @@ -858,120 +839,154 @@ gala-ops支持使用Grafana图形界面用来帮助客户更好的理解性能Pr | arangodb | 管理节点 | 约束:只支持X86架构 | | pyroscope(可选) | 管理节点 | | -10. gala-gopher是否支持openTelemetry统计? +## 支持语言&协议范围 + +| 协议 | 支持 | +| ---------- | ------------------------------------------------------------ | +| HTTP1.X | 语言:C/C++、Java、Go(TO BE)、Rust(TO BE);
加密库:openSSL、JSSE、GoSSL(TO BE)、Rustls(TO BE) | +| PostgreSQL | 语言:C/C++、Java、Go(TO BE)、Rust(TO BE);
加密库:openSSL、JSSE、GoSSL(TO BE)、Rustls(TO BE) | +| MySQL | 语言:C/C++、Java、Go(TO BE)、Rust(TO BE);
加密库:openSSL、JSSE、GoSSL(TO BE)、Rustls(TO BE) | +| Dubbo | 语言:C/C++、Java、Go(TO BE)、Rust(TO BE);
加密库:openSSL、JSSE、GoSSL(TO BE)、Rustls(TO BE) | +| Redis | TO BE | +| Kafka | TO BE | +| HTTP 2.0 | TO BE | +| MongoDB | TO BE | + +## 支持虚机&容器&K8S环境 + +1. 支持多种容器运行时:包括containerd、docker、isula三种容器运行时;可以针对这三种容器运行时场景的容器实例监控。 + +2. gala-gopher是否支持K8S部署、监管? - openTelemetry的统计可以有效降低运维平台的数据存储压力,所以gala-gopher采集的Metrics部分支持openTelemetry Pxx统计[1]。 + gala-gopher支持在K8S环境中以daemonset形式部署,相关的daemonset yaml、容器镜像Dockerfile、容器启动入口脚本请参考: + + https://gitee.com/openeuler/gala-gopher/blob/dev/k8s/daemonset.yaml.tmpl + https://gitee.com/openeuler/gala-gopher/blob/dev/build/Dockerfile_2003_sp1_x86_64 + https://gitee.com/openeuler/gala-gopher/blob/dev/build/Dockerfile_2003_sp1_aarch64 + https://gitee.com/openeuler/gala-gopher/blob/dev/build/entrypoint.sh - [1]: 时延、吞吐量这两类数据支持; +3. 采集的数据、上报的事件均会携带系统上下文标签具体如下: -11. gala-gopher是否支持java语言? + **Node标签**:System ID(集群内唯一),管理IP。 - 支持针对java语言的应用的数据采集,包括三类数据 + **Device标签**:Device Name(比如网卡、磁盘)。 - - java应用的运行堆栈(用于性能火焰图); - - jvm运行时状态数据(比如jvm堆内存、GCC资源等); - - jsse类库数据(用于L7层加密协议的观测); + **进程标签**:进程ID、进程名、cmdline。 -12. gala-gopher支持哪些应用L7层协议? + **网络标签**:TCP clien/server ip、server port、role 标签。 - - 协议范围:HTTP1.X、PostgreSQL、MySQL、Redis、Kafka、HTTP2.0、MongoDB、RocketMQ - - 加密协议:支持openSSL、GoSSL、JSSE等常见加密场景; - - 支持的语言:支持C/C++、Java、Go (TODO) + **容器标签**:容器ID、容器名称。 -13. gala-gopher采集的数据携带哪些公共标签? + **POD标签**:POD ID,POD IP,Pod Name,Pod Namespace标签。 - gala-gopher采集的数据大体划分成Node级、设备级(比如磁盘、网卡)、进程级、TCP级,不同级数据携带不同的标签。 + **用户自定义标签**:采集任务下发时,用户自定义设置的标签。 - - Node级:System ID(集群内唯一),管理IP; - - 设备级:System ID(集群内唯一),管理IP,设备名称; - - 进程级:System ID(集群内唯一),管理IP,进程ID,进程名,容器ID(容器场景),Pod ID(K8S场景),POD IP(K8S场景); - - TCP连接级:System ID(集群内唯一),管理IP,进程ID,进程名,容器ID(容器场景),Pod ID(K8S场景),POD IP(K8S场景),SIP/DIP/SPort/DPort/Role; +## java环境的支持程度 -14. gala是如何构建系统拓扑? +全面支持java环境可观测能力,包括支持[java应用性能Profiling](https://gitee.com/openeuler/gala-gopher/tree/dev/#%E5%9C%BA%E6%99%AF1%E6%8C%81%E7%BB%AD%E6%80%A7%E8%83%BDprofiling)、[java加密应用的网络访问](https://gitee.com/openeuler/gala-gopher/tree/dev/#%E5%9C%BA%E6%99%AF2%E5%BE%AE%E6%9C%8D%E5%8A%A1%E8%AE%BF%E9%97%AE%E6%80%A7%E8%83%BD%E7%9B%91%E6%8E%A7)、[JVM数据采集](https://gitee.com/openeuler/gala-docs/blob/master/gopher_tech.md#jvm%E7%9B%91%E6%8E%A7)。 -15. gala是如何完成异常检测? +## 如何构建系统拓扑 -16. gala是如何完成根因定位? +拓扑构建原理:gala-gopher会提供 L4层网络流、负载分担流、L7层网络流、软件部署拓扑等信息,基于这些信息构建系统3D 拓扑。 -17. gala系统依赖的中间件是否必须或者能否替换? +[1]: 微服务与进程的部署拓扑依赖业务运维系统提供。 - | 中间件 | 功能 | 可替换性分析 | - | ------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | - | prometheus | 时序化存储gala-gopher metrics数据,并对接gala-ops进行数据处理,同时对接grafana页面显示 | 使用拓扑图、异常检测、根因定位功能时必须且不可替换。只需要gala-gopher metrics数据时非必须,可通过修改[gala-gopher配置文件中的metrics输出方式](https://gitee.com/openeuler/gala-gopher/blob/master/doc/conf_introduction.md#gala-gopherconf)为logs替换为从本地目录/var/log/gala-gopher/metrics获取。 | - | kafka | 存储gala-gopher亚健康巡检、观测对象元数据、异常检测输出、根因定位结果等数据供用户或者gala-ops内部组件订阅获取 | 使用拓扑图、异常检测、根因定位功能时必须且不可替换。
使用gala-gopher亚健康巡检功能时非必须,可通过修改[gala-gopher配置文件中的event输出方式](https://gitee.com/openeuler/gala-gopher/blob/master/doc/conf_introduction.md#gala-gopherconf)为logs替换为从本地目录/var/log/gala-gopher/event获取。 | - | elasticsearch | 存储gala-gopher亚健康巡检、异常检测输出、根因定位结果、拓扑图数据并将其展示到 grafana 前端 | 在grafana页面上展示亚健康巡检、异常检测输出、根因定位结果、拓扑图数据时必须且不可替换 | - | logstash | 将kafka消息预处理后存储到elasticsearch | 在grafana页面上展示亚健康巡检、异常检测输出、根因定位结果、拓扑图数据时必须且不可替换 | - | arangodb | 存储 gala-spider 生成的实时拓扑数据 | 使用拓扑图功能时必须且不可替换 | - | pyroscope | 时序化存储 gala-gopher火焰图数据,自带的前端页面提供火焰图实时预览、筛选、横向对比等功能,并对接grafana页面显示火焰图。 | 非必须,火焰图文件可直接在本地目录/var/log/gala-gopher/stackstrace下获取 | +![](./png/topo_theory.png) -18. 如何使用性能Profiling(火焰图)? +系统拓扑用途:主要用于gala因果型AI推导根因定位,基于TCP/RPC拓扑完成故障溯源,基于部署拓扑完成面向应用的drill-down的故障根因定位。 - 1. 性能火焰图启动命令示例(基本): +- 关键问题1:如何解决网络NAT产生的网络流拓扑无法建立? - ```shell - curl -X PUT http://localhost:9999/flamegraph -d json='{ "cmd": {"probe": ["oncpu"] }, "snoopers": {"proc_name": [{ "comm": "cadvisor"}] }, "state": "running"}' - ``` + gala-gopher采集的TCP/RPC流拓扑信息(NAT前的IP/Port信息)会根据linux conntrack表信息,进行NAT转换,上送NAT后的网络流拓扑信息。 - 上述命令是一个最简单的火焰图探针启动命令。该探针采用默认参数对cadvisor进程的cpu占用进行采样,可以周期性在本地生成一个svg格式火焰图。生成的火焰图文件打开如下所示,图中可以看到cadvisor进程的go和c调用栈。 +- 关键问题2:如何建立中间件的网络流拓扑? - + gala-gopher针对Nginx/Haproxy这类网络负载均衡中间件,提供负载分担流监控能力,可以结合TCP信息快速完成负载分担拓扑构建; - ![](./png/cadvisor_flamegraph_svg.png) + gala-gopher针对kafka这类消息总线式中间件,提供[消息体(topic)流监控能力](),可以快速构建消息生产者、消费者拓扑。 - +- 关键问题3:如何建立K8S集群拓扑? - 2. 性能火焰图启动命令示例(进阶): + 待补充。 - 更加完整的启动命令示例如下,通过手动设置各种参数实现对火焰图探针的定制化配置。flamegraph探针的完整可配置参数参见[探针运行参数](https://gitee.com/openeuler/gala-gopher/blob/dev/config/gala-gopher%E6%94%AF%E6%8C%81%E5%8A%A8%E6%80%81%E9%85%8D%E7%BD%AE%E6%8E%A5%E5%8F%A3%E8%AE%BE%E8%AE%A1_v0.3.md#%E6%8E%A2%E9%92%88%E8%BF%90%E8%A1%8C%E5%8F%82%E6%95%B0)。 +## gala依赖的中间件 + +| 中间件 | 功能 | 可替换性分析 | +| ------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| prometheus | 时序化存储gala-gopher metrics数据,并对接gala-ops进行数据处理,同时对接grafana页面显示 | 使用拓扑图、异常检测、根因定位功能时必须且不可替换。只需要gala-gopher metrics数据时非必须,可通过修改[gala-gopher配置文件中的metrics输出方式](https://gitee.com/openeuler/gala-gopher/blob/master/doc/conf_introduction.md#gala-gopherconf)为logs替换为从本地目录/var/log/gala-gopher/metrics获取。 | +| kafka | 存储gala-gopher亚健康巡检、观测对象元数据、异常检测输出、根因定位结果等数据供用户或者gala-ops内部组件订阅获取 | 使用拓扑图、异常检测、根因定位功能时必须且不可替换。
使用gala-gopher亚健康巡检功能时非必须,可通过修改[gala-gopher配置文件中的event输出方式](https://gitee.com/openeuler/gala-gopher/blob/master/doc/conf_introduction.md#gala-gopherconf)为logs替换为从本地目录/var/log/gala-gopher/event获取。 | +| elasticsearch | 存储gala-gopher亚健康巡检、异常检测输出、根因定位结果、拓扑图数据并将其展示到 grafana 前端 | 在grafana页面上展示亚健康巡检、异常检测输出、根因定位结果、拓扑图数据时必须且不可替换 | +| logstash | 将kafka消息预处理后存储到elasticsearch | 在grafana页面上展示亚健康巡检、异常检测输出、根因定位结果、拓扑图数据时必须且不可替换 | +| arangodb | 存储 gala-spider 生成的实时拓扑数据 | 使用拓扑图功能时必须且不可替换 | +| pyroscope | 时序化存储 gala-gopher火焰图数据,自带的前端页面提供火焰图实时预览、筛选、横向对比等功能,并对接grafana页面显示火焰图。 | 非必须,火焰图文件可直接在本地目录/var/log/gala-gopher/stackstrace下获取 | + +## 如何使用性能火焰图 + +1. 性能火焰图启动命令示例(基本): + +```shell +curl -X PUT http://localhost:9999/flamegraph -d json='{ "cmd": {"probe": ["oncpu"] }, "snoopers": {"proc_name": [{ "comm": "cadvisor"}] }, "state": "running"}' +``` + +上述命令是一个最简单的火焰图探针启动命令。该探针采用默认参数对cadvisor进程的cpu占用进行采样,可以周期性在本地生成一个svg格式火焰图。生成的火焰图文件打开如下所示,图中可以看到cadvisor进程的go和c调用栈。 + + + +![](D:/Code/gala-docs/png/cadvisor_flamegraph_svg.png) + + + +1. 性能火焰图启动命令示例(进阶): + +更加完整的启动命令示例如下,通过手动设置各种参数实现对火焰图探针的定制化配置。flamegraph探针的完整可配置参数参见[探针运行参数](https://gitee.com/openeuler/gala-gopher/blob/dev/config/gala-gopher%E6%94%AF%E6%8C%81%E5%8A%A8%E6%80%81%E9%85%8D%E7%BD%AE%E6%8E%A5%E5%8F%A3%E8%AE%BE%E8%AE%A1_v0.3.md#%E6%8E%A2%E9%92%88%E8%BF%90%E8%A1%8C%E5%8F%82%E6%95%B0)。 + +```shell +curl -X PUT http://localhost:9999/flamegraph -d json='{ "cmd": { "check_cmd": "", "probe": ["oncpu", "offcpu", "mem"] }, "snoopers": { "proc_name": [{ "comm": "cadvisor", "cmdline": "", "debugging_dir": "" }, { "comm": "java", "cmdline": "", "debugging_dir": "" }] }, "params": { "perf_sample_period": 100, "svg_period": 300, "svg_dir": "/var/log/gala-gopher/stacktrace", "flame_dir": "/var/log/gala-gopher/flamegraph", "pyroscope_server": "localhost:4040", "multi_instance": 1, "native_stack": 0 }, "state": "running"}' +``` - ```shell - curl -X PUT http://localhost:9999/flamegraph -d json='{ "cmd": { "check_cmd": "", "probe": ["oncpu", "offcpu", "mem"] }, "snoopers": { "proc_name": [{ "comm": "cadvisor", "cmdline": "", "debugging_dir": "" }, { "comm": "java", "cmdline": "", "debugging_dir": "" }] }, "params": { "perf_sample_period": 100, "svg_period": 300, "svg_dir": "/var/log/gala-gopher/stacktrace", "flame_dir": "/var/log/gala-gopher/flamegraph", "pyroscope_server": "localhost:4040", "multi_instance": 1, "native_stack": 0 }, "state": "running"}' - ``` +上述命令可以启动一个火焰图探针,指定以100ms的频率对cadvisor、java进程进行采样,并每隔300s在本地生成三种svg格式火焰图:cpu火焰图,offcpu火焰图,内存火焰图,同时上述火焰图数据通过多进程实例上报到pyroscope服务器。可以实时通过pyroscope查看,也可以在grafana中配置pyroscope数据源,然后在grafana上查看火焰图。 - 上述命令可以启动一个火焰图探针,指定以100ms的频率对cadvisor、java进程进行采样,并每隔300s在本地生成三种svg格式火焰图:cpu火焰图,offcpu火焰图,内存火焰图,同时上述火焰图数据通过多进程实例上报到pyroscope服务器。可以实时通过pyroscope查看,也可以在grafana中配置pyroscope数据源,然后在grafana上查看火焰图。 - - 3. 性能火焰图查看方法示例: +1. 性能火焰图查看方法示例: - 通过上述命令启动火焰图后,即可通过不同的过滤选项实时查看火焰图。下图为某java业务的k8s Pod的内存火焰图查看示例。 +通过上述命令启动火焰图后,即可通过不同的过滤选项实时查看火焰图。下图为某java业务的k8s Pod的内存火焰图查看示例。 - (1)处可以选择machine_id,查看不同主机上的进程火焰图。 +(1)处可以选择machine_id,查看不同主机上的进程火焰图。 - (2)处可以选择进程id,查看不同进程的火焰图。 +(2)处可以选择进程id,查看不同进程的火焰图。 - (3)处可以选择火焰图类型(oncpu/offcpu/mem),查看不同类型的火焰图。 +(3)处可以选择火焰图类型(oncpu/offcpu/mem),查看不同类型的火焰图。 - (6)处为进程的标签,格式为[pid]comm。若为k8s容器内进程,则会有[Pod]name,和[Con]name标签,见(4)(5)处。 +(6)处为进程的标签,格式为[pid]comm。若为k8s容器内进程,则会有[Pod]name,和[Con]name标签,见(4)(5)处。 - (7)处可以选择火焰图的时间段。 +(7)处可以选择火焰图的时间段。 - ![](./png/kafka_client_mem_fg.png) +![](D:/Code/gala-docs/png/kafka_client_mem_fg.png) - - 4. 使用性能火焰图定位性能问题: - 对火焰图的展示形式也可以根据业务需求进行灵活配置。例如云服务灰度发布版本时,环境中同时部署了新老版本的容器。通过同时查看、对比不同版本的容器实例的火焰图,可以快速发现版本间运行差异,迅速定位性能问题。 +1. 使用性能火焰图定位性能问题: - 在下面的实践中,某主机上部署了新旧两个版本的kafka客户端容器,测试发现新版本容器的cpu占用率较老版本略高。 +对火焰图的展示形式也可以根据业务需求进行灵活配置。例如云服务灰度发布版本时,环境中同时部署了新老版本的容器。通过同时查看、对比不同版本的容器实例的火焰图,可以快速发现版本间运行差异,迅速定位性能问题。 - 于是在grafana中同时配置这两个容器的火焰图展示,并选中需要定位的时间段。由图中可以明显发现,新版本(右)比老版本(左)增加了对String.format的调用,从而定位到新版本容器是由于代码中增加了序列化操作,从而导致cpu占用率升高。 +在下面的实践中,某主机上部署了新旧两个版本的kafka客户端容器,测试发现新版本容器的cpu占用率较老版本略高。 - ![](./png/compare_fg.png) +于是在grafana中同时配置这两个容器的火焰图展示,并选中需要定位的时间段。由图中可以明显发现,新版本(右)比老版本(左)增加了对String.format的调用,从而定位到新版本容器是由于代码中增加了序列化操作,从而导致cpu占用率升高。 -19. 如何完成网络问题诊断? +![](./png/compare_fg.png) - 参考[这里](https://gitee.com/openeuler/gala-docs/blob/master/network_diag.md) +## 如何使用进行网络问题诊断 -20. 如何完成I/O问题诊断? +参考[这里](https://gitee.com/openeuler/gala-docs/blob/master/network_diag.md) - 参考[这里](https://gitee.com/openeuler/gala-docs/blob/master/io_diag.md) +## 如何进行I/O问题诊断 -21. 如何完成死锁问题诊断? +参考[这里](https://gitee.com/openeuler/gala-docs/blob/master/io_diag.md) +## 如何进行JAVA OOM问题诊断 -# 用户案例 +待补充 # 合作厂商 diff --git a/gopher_tech.md b/gopher_tech.md index 698ecc5dde7b09a5ed895f976428cb4cd9cec57a..b7838ee2660730c5c0d622456acf436965997f6e 100644 --- a/gopher_tech.md +++ b/gopher_tech.md @@ -214,32 +214,31 @@ 实体名:tcp_link -| metrics_name | table_name | metrics_type | unit | metrics description | -| ------------ | -------------- | ------------ | ----- | ----------------------------------- | -| tgid | | key | | 进程ID | -| role | | key | | 客户端/服务端 | -| client_ip | | key | | 客户端:本地IP;服务端:对端IP | -| server_ip | | key | | 客户端:对端IP;服务端:本地IP | -| server_port | | key | | 客户端:对端端口;服务端:本地端口 | -| protocol | | key | | 协议族(IPv4、IPv6) | -| rx_bytes | tcp_tx_rx(0x8) | Gauge | bytes | rx bytes | -| tx_bytes | tcp_tx_rx(0x8) | Gauge | bytes | tx bytes | -| segs_in | tcp_tx_rx(0x8) | Counter | segs | total number of segments received | -| segs_out | tcp_tx_rx(0x8) | Counter | segs | total number of segments sent | +| metrics_name | table_name | metrics_type | unit | metrics description | +| ------------ | -------------- | ------------ | ----- | ------------------------------------------------------------ | +| tgid | | key | | 进程ID | +| role | | key | | 客户端/服务端 | +| client_ip | | key | | 客户端:本地IP;服务端:对端IP
备注:如果存在NAT,此IP为NAT后的IP | +| server_ip | | key | | 客户端:对端IP;服务端:本地IP
备注:如果存在NAT,此IP为NAT后的IP | +| server_port | | key | | 客户端:对端端口;服务端:本地端口
备注:如果存在NAT,此Port为NAT后的Port | +| protocol | | key | | 协议族(IPv4、IPv6) | +| rx_bytes | tcp_tx_rx(0x8) | Gauge | bytes | rx bytes | +| tx_bytes | tcp_tx_rx(0x8) | Gauge | bytes | tx bytes | +| segs_in | tcp_tx_rx(0x8) | Counter | segs | total number of segments received | +| segs_out | tcp_tx_rx(0x8) | Counter | segs | total number of segments sent | ## DNS访问监控 实体名:dns -| metrics_name | table_name | metrics_type | unit | metrics description | Support | -| ------------ | ---------- | ------------ | ---- | ------------------- | ------- | -| tgid | dns | key | | 进程ID | | -| domain | dns | key | | 进程访问的DNS域名 | | -| dns_ip | dns | lable | | DNS域名对应的IP地址 | | -| delay_avg | dns | Gauge | ms | DNS访问平均时延 | TO BE | -| max_delay | dns | Gauge | ms | DNS访问最大时延 | TO BE | -| error_ratio | dns | Gauge | % | DNS访问错误率 | TO BE | -| count | dns | Gauge | | DNS访问次数 | TO BE | +| metrics_name | table_name | metrics_type | unit | metrics description | +| ------------ | ---------- | ------------ | ---- | ------------------- | +| tgid | dns | key | | 进程ID | +| domain | dns | key | | 进程访问的DNS域名 | +| delay_avg | dns | Gauge | ms | DNS访问平均时延 | +| max_delay | dns | Gauge | ms | DNS访问最大时延 | +| error_ratio | dns | Gauge | % | DNS访问错误率 | +| count | dns | Gauge | | DNS访问次数 | ## TCP/IP监控 @@ -303,23 +302,23 @@ 实体名:l7 -| metrics_name | table_name | metrics_type | unit | metrics description | Support | -| --------------- | ---------- | ------------ | ---- | ------------------------------------------------------ | -------------------------- | -| tgid | | key | | Process ID of l7 session. | openSSL 1.1.1, Go SSL,JSSE | -| remote_ip | | key | | Remote IP address of l7 session. | | -| remote_port | | key | | Remote port of l7 session. | | -| l4_role | | key | | Role of l4 protocol(TCP Client/Server or UDP) | | -| l7_role | | key | | Role of l7 protocol(Client or Server) | | -| protocol | | key | | Name of l7 protocol(http/http2/mysql...) | | -| pod_ip | | label | | IP address of pod which l7 session belongs. | | -| ssl | | label | | Indicates whether an SSL-encrypted l7 session is used. | | -| bytes_sent | l7_link | gauge | | Number of bytes sent by a l7 session. | | -| bytes_recv | l7_link | gauge | | Number of bytes recv by a l7 session. | | -| throughput_req | l7_rpc | histogram | qps | Request throughput of l7 session. | | -| throughput_resp | l7_rpc | histogram | qps | Response throughput of l7 session. | | -| latency_avg | l7_rpc | gauge | ns | Average l7 session latency. | | -| latency | l7_rpc | histogram | ns | L7 session P50 latency. | | -| err_ratio | l7_rpc | gauge | % | L7 session error rate. | | +| metrics_name | table_name | metrics_type | unit | metrics description | Support | +| --------------- | ---------- | ------------ | ---- | ------------------------------------------------------------ | -------------------------- | +| tgid | | key | | Process ID of l7 session. | openSSL 1.1.1, Go SSL,JSSE | +| client_ip | | key | | Client IP address of l7 session.
备注:如果存在NAT,此IP为NAT后的IP | | +| server_ip | | key | | Server IP address of l7 session.
备注:如果存在NAT,此IP为NAT后的IP | | +| server_port | | key | | Server Port of l7 session.
备注:如果存在NAT,此Port为NAT后的Port | | +| l4_role | | key | | Role of l4 protocol(TCP Client/Server or UDP) | | +| l7_role | | key | | Role of l7 protocol(Client or Server) | | +| protocol | | key | | Name of l7 protocol(http/http2/mysql...) | | +| ssl | | label | | Indicates whether an SSL-encrypted l7 session is used. | | +| bytes_sent | l7_link | gauge | | Number of bytes sent by a l7 session. | | +| bytes_recv | l7_link | gauge | | Number of bytes recv by a l7 session. | | +| throughput_req | l7_rpc | histogram | qps | Request throughput of l7 session. | | +| throughput_resp | l7_rpc | histogram | qps | Response throughput of l7 session. | | +| latency_avg | l7_rpc | gauge | ns | Average l7 session latency. | | +| latency | l7_rpc | histogram | ns | L7 session P50 latency. | | +| err_ratio | l7_rpc | gauge | % | L7 session error rate. | | # 应用性能监控 @@ -365,8 +364,8 @@ | remote_ip | | key | | 对端IP地址 | | | port | | key | | 客户端:对端Port;服务端:本地Port; | | | role | | key | | 客户端/服务端 | | -| tx_delay | proc_flow_perf | histogram | us | Delay in the Tx direction of the application TCP link. | TO BE | -| rx_delay | proc_flow_perf | histogram | us | Delay in the Rx direction of the application TCP link. | TO BE | +| tx_delay | proc_flow_perf | histogram | us | Delay in the Tx direction of the application TCP link. | | +| rx_delay | proc_flow_perf | histogram | us | Delay in the Rx direction of the application TCP link. | | | tx_throughput | proc_flow_perf | histogram | bps | Throughput in the Tx direction of the application TCP link. | TO BE | | rx_throughput | proc_flow_perf | histogram | bps | Throughput in the Rx direction of the application TCP link. | TO BE | @@ -377,8 +376,8 @@ | metrics_name | table_name | metrics_type | unit | metrics description | Support | | ------------- | ---------- | ------------ | ---- | ----------------------------------- | ------- | | tgid | | key | | Process ID | | -| tx_delay | proc_perf | histogram | us | TCP delay in the Tx direction. | TO BE | -| rx_delay | proc_perf | histogram | us | TCP delay in the Rx direction. | TO BE | +| tx_delay | proc_perf | histogram | us | TCP delay in the Tx direction. | | +| rx_delay | proc_perf | histogram | us | TCP delay in the Rx direction. | | | tx_throughput | proc_perf | histogram | bps | TCP throughput in the Tx direction. | TO BE | | rx_throughput | proc_perf | histogram | bps | TCP throughput in the Rx direction. | TO BE | @@ -514,8 +513,8 @@ | buffer_pool_used_buffers | jvm_buf_pool | gauge | | 给定JVM缓冲池的已用缓冲区数 | | buffer_pool_capacity_bytes | jvm_buf_pool | gauge | bytes | 给定JVM缓冲池的字节容量 | | gc | jvm_gc | label | | 垃圾回收器名字 | -| gc_coll_secs_count | jvm_gc | summary | | 给定的垃圾回收器已发生的GC总次数 | -| gc_coll_secs_sum | jvm_gc | summary | s | 在给定的垃圾回收器花费的总时间 | +| gc_coll_secs_count | jvm_gc | gauge | | 给定的垃圾回收器已发生的GC总次数 | +| gc_coll_secs_sum | jvm_gc | gauge | s | 在给定的垃圾回收器花费的总时间 | # Kafka监控 @@ -649,6 +648,12 @@ | active_open | connect | Gauge | | tcp主动发起的建链次数(只有connect对象存在) | | active_open_failed | connect | Gauge | | tcp主动发起的建链失败次数(只有connect对象存在) | +## 负载分担流拓扑构建 + +通过针对TCP连接、Nginx/haproxy负载分担流监控,可以有效构建出前后端应用之间事件TCP拓扑流,如下图所示: + +![](./png/nginx_flow.png) + # Redis/PostgreSQL监控 diff --git a/network_diag.md b/network_diag.md index 89d802a9e0f230b87854cc6c4d7304e7616e7406..59d4e10d47436f1c02720cc073ac966b6fe97ea6 100644 --- a/network_diag.md +++ b/network_diag.md @@ -19,119 +19,17 @@ - **问题发现**:容器内应用访问吞吐量、时延下降的情况,可以查看Prometheus metrics获取信息如下: -| metrics_name | metrics_type | unit | metrics description | -| -------------- | ------------ | ---- | -------------------------------------- | -| tgid | lable | | 进程号 | -| comm | lable | | 进程名 | -| container_id | lable | | 容器ID | -| pod_id | lable | | Pod ID | -| remote_ip | lable | | Pod访问的远端IP | -| remote_port | lable | | Pod访问的远端Port | -| pod_ip | lable | | POD IP地址 | -| role | lable | | L7层协议访问的角色(客户端 or 服务端) | -| protocol | lable | | L7层协议类型(比如HTTP、RPC、MySql等) | -| req_throughput | Gauge | x/s | L7连接request吞吐量 | -| rsp_throughput | Gauge | x/s | L7连接response吞吐量 | -| latency | Gauge | ms | L7连接request访问时延 | -| p50_latency | Gauge | ms | L7连接P50 request访问时延 | -| p90_latency | Gauge | ms | L7连接P90 request访问时延 | -| p99_latency | Gauge | ms | L7连接P99 request访问时延 | -| error_rate | Gauge | % | L7连接Request访问错误率 | - -- **可能原因1**:服务之间访问通常需要通过DNS发现对端服务地址,DNS发现过程如果出现问题,会导致服务访问性能下降,可以通过Prometheus Metrics获取DNS访问性能: - -| metrics_name | metrics_type | unit | metrics description | -| ------------------ | ------------ | ---- | --------------------------------- | -| tgid | lable | | 进程号 | -| comm | lable | | 进程名 | -| container_id | lable | | 容器ID | -| pod_id | lable | | Pod ID | -| ns_gethostname | Gauge | ns | 进程获取DNS域名对应的地址,单位ns | -| gethostname_failed | Gauge | | 进程获取DNS域名失败次数 | - - - -- **可能原因2**:LB Node发生建链失败的情况(比如超出链接规格),导致服务访问失败率增加 - -| metrics_name | metrics_type | unit | metrics description | -| ------------------- | ------------ | ---- | ---------------------------------------- | -| tgid | lable | | 进程号 | -| comm | lable | | 进程名 | -| container_id | lable | | 容器ID | -| pod_id | lable | | Pod ID | -| accept_overflow | Gauge | | TCP accept丢弃次数(只有listen对象存在) | -| syn_overflow | Gauge | | TCP accept队列溢出次数 | -| passive_open_failed | Gauge | | tcp被动发起的建链失败次数 | -| lost_synacks | Gauge | | TCP synack报文丢失导致的建链失败次数 | -| active_open_failed | Gauge | | tcp主动发起的建链失败次数 | -| listendrop | Gauge | | TCP accept丢弃次数 | - - - -- **可能原因3**:基础网络发生拥塞、丢包现象,导致TCP层发生重传现象。如果确认TCP层出现这类问题,可以根据TCP五元组继续排查基础网络设施。 - -| metrics_name | metrics_type | unit | metrics description | -| --------------------- | ------------ | ---- | ---------------------------------- | -| tgid | lable | | 进程号 | -| comm | lable | | 进程名 | -| container_id | lable | | 容器ID | -| pod_id | lable | | Pod ID | -| client_ip | lable | | 客户端:本地IP;服务端:对端IP | -| server_ip | lable | | 客户端:对端IP;服务端:本地IP | -| client_port | lable | | 客户端:本地端口;服务端:对端端口 | -| server_port | lable | | 客户端:对端端口;服务端:本地端口 | -| role | lable | | TCP连接角色(客户端 or 服务端) | -| retran_packets | Gauge | | TCP重传包数量 | -| retran_ratio | Gauge | | TCP重传率 | -| lost_out | Gauge | | 发生TCP拥塞导致的丢包数量 | -| sacked_out | Gauge | | TCP乱序的包数量 | -| srtt(P50/P90/P99) | Gauge | us | TCP smooth RTT | -| syn_srtt(P50/P90/P99) | Gauge | us | TCP建立时长(服务端才有意义) | - - - -- **可能原因4**:某些应用误触发发送RST报文,导致访问链路断开。如果确认是对端误发送RST报文,可以根据TCP五元组,找到发送者(具体某个微服务),继续排查原因。 - -| metrics_name | metrics_type | unit | metrics description | -| ------------ | ------------ | ---- | ---------------------------------- | -| tgid | lable | | 进程号 | -| comm | lable | | 进程名 | -| container_id | lable | | 容器ID | -| pod_id | lable | | Pod ID | -| client_ip | lable | | 客户端:本地IP;服务端:对端IP | -| server_ip | lable | | 客户端:对端IP;服务端:本地IP | -| client_port | lable | | 客户端:本地端口;服务端:对端端口 | -| server_port | lable | | 客户端:对端端口;服务端:本地端口 | -| role | lable | | TCP连接角色(客户端 or 服务端) | -| send_rsts | Gauge | | 发送出去的RST报文数量 | -| receive_rsts | Gauge | | 接收到的RST报文数量 | - - - -- **可能原因5**:TCP出现零窗问题,如果出现这种问题,一般发送者太快,或者接收者太慢。当出现这类问题时,通常伴随着系统CPU冲高这类问题现象。 - -| metrics_name | metrics_type | unit | metrics description | -| -------------------------- | ------------ | ----- | ----------------------------------------------- | -| tgid | lable | | 进程号 | -| comm | lable | | 进程名 | -| container_id | lable | | 容器ID | -| pod_id | lable | | Pod ID | -| client_ip | lable | | 客户端:本地IP;服务端:对端IP | -| server_ip | lable | | 客户端:对端IP;服务端:本地IP | -| client_port | lable | | 客户端:本地端口;服务端:对端端口 | -| server_port | lable | | 客户端:对端端口;服务端:本地端口 | -| role | lable | | TCP连接角色(客户端 or 服务端) | -| zero_snd_wnd_ratio | Gauge | | 发送窗口0窗比例(发送窗口零窗次数/发送bytes数) | -| zero_rcv_wnd_ratio | Gauge | | 接收窗口0窗比例(接收窗口零窗次数/接收bytes数) | -| snd_cwnd(P50/P90/P99) | Gauge | | TCP拥塞窗口大小 | -| reordering(P50/P90/P99) | Gauge | | TCP待重新排序的包数量 | -| notsent_bytes(P50/P90/P99) | Gauge | bytes | TCP窗口内待发送数据的bytes数量 | -| notack_bytes(P50/P90/P99) | Gauge | bytes | TCP窗口内未收到ACK数据的bytes数量 | -| snd_wnd(P50/P90/P99) | Gauge | | TCP发送窗口大小 | -| rcv_wnd(P50/P90/P99) | Gauge | | TCP接收窗口大小 | -| avl_snd_wnd(P50/P90/P99) | Gauge | | TCP发送可用窗口大小 | + 详细内容参考[这里](https://gitee.com/openeuler/gala-docs/blob/master/gopher_tech.md#%E5%BA%94%E7%94%A8%E5%BE%AE%E6%9C%8D%E5%8A%A1%E8%AE%BF%E9%97%AE%E6%80%A7%E8%83%BD)。 +- **可能原因1**:服务之间访问通常需要通过DNS发现对端服务地址,DNS发现过程如果出现问题,会导致服务访问性能下降,可以通过Prometheus Metrics获取[DNS访问性能](https://gitee.com/openeuler/gala-docs/blob/master/gopher_tech.md#dns%E8%AE%BF%E9%97%AE%E7%9B%91%E6%8E%A7)。 +- **可能原因2**:LB Node发生建链失败的情况(比如超出链接规格),导致服务访问失败率增加,可观测数据参考[这里](https://gitee.com/openeuler/gala-docs/blob/master/gopher_tech.md#socket%E7%9B%91%E6%8E%A7-1)。 + +- **可能原因3**:基础网络发生拥塞、丢包现象,[导致TCP层发生重传现象](https://gitee.com/openeuler/gala-docs/blob/master/gopher_tech.md#tcp%E6%80%A7%E8%83%BD)。如果确认TCP层出现这类问题,可以根据TCP五元组继续排查基础网络设施。 + +- **可能原因4**:某些[应用误触发发送RST报文](https://gitee.com/openeuler/gala-docs/blob/master/gopher_tech.md#tcp%E5%BC%82%E5%B8%B8%E7%9B%91%E6%8E%A7),导致访问链路断开。如果确认是对端误发送RST报文,可以根据TCP五元组,找到发送者(具体某个微服务),继续排查原因。 + +- **可能原因5**:[TCP出现零窗问题](https://gitee.com/openeuler/gala-docs/blob/master/gopher_tech.md#tcp%E6%80%A7%E8%83%BD),如果出现这种问题,一般发送者太快,或者接收者太慢。当出现这类问题时,通常伴随着系统CPU冲高这类问题现象。 上述所有Metrics可以通过Grafana查看,如下图查看TCP rtt、drop两个Metrics指标。Grafana界面可以根据自身需要,按需调取查看不同的Metrics。 diff --git a/png/logo.png b/png/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..38e6835af8dca8abf9cc0081688b859ba9162b5a Binary files /dev/null and b/png/logo.png differ diff --git a/png/nginx_flow.png b/png/nginx_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..6f9b6de5608d1f57f34236b232aced4b1c8afaaf Binary files /dev/null and b/png/nginx_flow.png differ diff --git a/png/topo_theory.png b/png/topo_theory.png new file mode 100644 index 0000000000000000000000000000000000000000..537378a52cd4e2a5ea9680097bc39a4d80a1758d Binary files /dev/null and b/png/topo_theory.png differ