├── .gitignore ├── 0x01-云原生的来源.md ├── 0x02-监控系统.md ├── 0x03-搭建测试环境.md ├── 0x04-Prometheus-理论(入门篇).md ├── 0x05-Prometheus-理论(进阶篇).md ├── 0x06-Prometheus-实践(入门篇).md ├── 0x07-Prometheus-实践(进阶篇).md ├── 0x08-Alertmanager-告警系统.md ├── 0x09-高可用-Prometheus.md ├── LICENSE ├── README.md ├── example ├── grafana-docker.json ├── grafana-ingress.json ├── grafana-language-echo.json ├── grafana-node-exporter.json └── grafana-prometheus.json └── images ├── alertmanager-arch.svg ├── alertmanager.png ├── bbox-alert.png ├── bbox-firing.png ├── bbox-pending.png ├── bbox-slack.png ├── bbox-top.png ├── cloudnative.png ├── cncf.png ├── grafana-datasource.png ├── grafana-docker.png ├── grafana-ingress.png ├── grafana-language-echo.png ├── grafana-login.png ├── grafana-node-exporter.png ├── grafana-prometheus.png ├── heartbeat.gif ├── k8s-dashboard.png ├── language-echo-prometheus.png ├── logo.png ├── monitoring.png ├── prometheus-architecture.png ├── prometheus-dashboard-0.jpg ├── prometheus-dashboard-1.jpg ├── prometheus-federation.png ├── prometheus-logo.png ├── prometheus-operator-architecture.png ├── remote-read.png └── remote-write.png /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /0x01-云原生的来源.md: -------------------------------------------------------------------------------- 1 | ## 1. 云原生的来源 2 | 3 | ### 1.1 CNCF 与 CloudNative 4 | 5 | ![cncf](./images/cncf.png) 6 | 7 | [CNCF](https://cncf.io) 全称 Cloud Native Computing Foundation(云原生计算基金会),成立于 2015 年 7月 21 日,其最初的口号是坚持和整合开源技术来让编排容器作为微服务架构的一部分,是致力于云原生应用推广和普及的一支重要力量。 8 | 9 | CNCF 作为一个厂商中立的基金会,致力于 Github 上的快速成长的开源技术的推广,如 Kubernetes、Prometheus、Envoy 等,帮助开发人员更快更好的构建出色的产品。 10 | 11 | 在谈 Prometheus 之前,我们先来谈谈 CloudNative 这个概念,这个概念在最近两年被炒得火热,所以云原生到底是个什么东西。CNCF 给出的定义如下: 12 | 13 | > 云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式 API。 14 | > 15 | > 这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和**可预测**的重大变更。 16 | > 17 | > 云原生计算基金会(CNCF)致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。我们通过将最前沿的模式民主化,让这些创新为大众所用。 18 | 19 | ### 1.2 Heroku 与 12-Factor 20 | 21 | 如果看了上述概念觉得不太懂的话,可以结合 [Heroku](http://www.heroku.com/) 公司提供的 [12factor](https://12factor.net/zh_cn/) 规范指南来理解。12-Factor 为构建如下的 SaaS 应用提供了方法论: 22 | 23 | * 使用标准化流程自动配置,从而使新的开发者花费最少的学习成本加入这个项目。 24 | * 和操作系统之间尽可能的划清界限,在各个系统中提供最大的可移植性。 25 | * 适合部署在现代的云计算平台,从而在服务器和系统管理方面节省资源。 26 | * 将开发环境和生产环境的差异降至最低,并使用持续交付实施敏捷开发。 27 | * 可以在工具、架构和开发流程不发生明显变化的前提下实现扩展。 28 | 29 | #### 12-Factor 内容 30 | 31 | 1. **基准代码**:一份基准代码,多份部署。 32 | 2. **依赖**:显式声明依赖关系。 33 | 3. **配置**:在环境中存储配置。 34 | 4. **后端服务**:把后端服务当作附加资源。 35 | 5. **构建**,发布,运行,严格分离构建和运行。 36 | 6. **进程**:以一个或多个无状态进程运行应用。 37 | 7. **端口绑定**:通过端口绑定提供服务。 38 | 8. **并发**:通过进程模型进行扩展。 39 | 9. **易处理**:快速启动和优雅终止可最大化健壮性。 40 | 10. **开发环境与线上环境等价**:尽可能的保持开发,预发布,线上环境相同。 41 | 11. **日志**:把日志当作事件流。 42 | 12. **管理进程**:后台管理任务当作一次性进程运行。 43 | 44 | ***CloudNative 概念组成*** 45 | 46 | DevOps、Microservices、CI/CD、Containers 这些概念融会贯通后形成 CloudNative 这个大概念。 47 | 48 | ![CloudNative 示意图](./images/cloudnative.png) 49 | 50 | ### 1.3 云原生和监控的关系 51 | 52 | 云原生和监控首先是两个「独立且完整」的概念,云原生的应用强调「可观测性」,而可观测性大致可归纳为三点,**监控**、**日志**、**调用链追踪**。也就是说 **监控应该是云原生概念的一个子集**。 53 | -------------------------------------------------------------------------------- /0x02-监控系统.md: -------------------------------------------------------------------------------- 1 | ## 2. 监控系统 2 | 3 | ![monitoring](./images/monitoring.png) 4 | 5 | ### 2.1 监控的目标 6 | 7 | 技术的进步永远是依靠需求来推动的,监控系统需要解决什么问题决定了它的技术发展方向。我们的目标是: 8 | 9 | * **实时反馈系统当前状态**:监控某个硬件或某个系统,都需要能实时看到当前系统的状态,是正常、异常、或者故障。 10 | * **保证业务持续稳定运行**:监控的目的就是要保证系统、服务、业务正常运行,即使出现故障也能第一时间接收到故障报警,在第一时间处理解决,从而保证业务持续性的稳定运行。 11 | 12 | 监控是服务于系统和业务的,是为了提高系统的鲁棒性,辅助我们更好的掌握系统和服务的当前状态。 13 | 14 | 监控的核心可归纳为四点: 15 | 16 | 1. 发现问题:当系统发生故障报警,我们会收到故障报警的信息。 17 | 2. 定位问题:告警信息里面一般会有错误的原因,我们需要对报警内容进行分析,定位产生故障具体原因。 18 | 3. 解决问题:当分析完故障的原因后,就需要通过故障解决的优先级去修复问题。 19 | 4. 总结问题:当我们解决完重大故障后,需要对故障原因以及防范进行总结归纳,避免以后重复出现。 20 | 21 | ### 2.2 监控的维度和流程 22 | 23 | #### 2.2.1 监控维度 24 | 25 | * **网络**:网络协议:http、dns、tcp、icmp;网络硬件:路由器,交换机等。 26 | * **磁盘**:资源用量。 27 | * **主机**:资源用量。 28 | * **容器**:资源用量。 29 | * **应用**:延迟,错误,QPS,内部状态等。 30 | * **中间件**:资源用量,以及服务状态。 31 | * **编排工具**:集群资源用量,调度等。 32 | 33 | #### 2.2.1 监控流程 34 | 35 | 一般来讲,通用的监控流程可以分为以下几点: 36 | 37 | 1. 数据采集:数据采集对应服务端来说,可能是主动的也可能是被动的(pull/push)。 38 | 2. 数据存储:采集到的样本数据应该落实到本地或远程持久化存储。 39 | 3. 数据分析和展示:提供数据分析工具以及 dashboard 界面,使开发者可以更直观地分析问题。 40 | 5. 监控报警:可以根据开发者提供的自定义告警规则自动监控系统行为,一旦符合规则就发送对应告警信息给接受者。 41 | 6. 报警处理:排查并处理故障问题。 42 | 43 | ### 2.3 四个黄金信号 44 | 45 | Google 的 Google SRE Books 一书中提出了系统监控的四个黄金信号,这个四个黄金信号在任何系统中都是很好地反应系统的性能问题,因此被称为「黄金信号」。 46 | 47 | #### 2.3.1 Latency(延迟) 48 | 49 | 延迟是发起一次服务请求所需要的时间,但是需要明白,成功请求的延迟和失败请求的延迟是需要区分开的。例如由于与数据库或其他关键后端服务的连接断开而触发的 HTTP 500 错误可能很快就会得到解决,但是由于 HTTP 500 错误表示请求失败,因此将所有的 500 错误都计入整体延迟可能会导致计算结果出现较大误差。 50 | 51 | 除此以外,在微服务中通常提倡“快速失败”,开发人员需要特别注意这些延迟较大的错误(可能是 SQL 中的慢查询),因为这些缓慢的错误会明显影响系统的性能,因此追踪这些错误的延迟也是非常重要的。 52 | 53 | #### 2.3.2 Traffic(通讯量) 54 | 55 | 通讯量是一种对系统需求的度量单位,流量对于不同类型的系统而言可能代表不同的含义。 56 | 57 | * Web 服务:每秒 HTTP 请求数。 58 | * 音频流系统:网络 I/O 情况。 59 | * 数据库:查询和写入频率。 60 | 61 | #### 2.3.3 Errors(错误) 62 | 63 | 错误是监控当前系统所有发生的错误请求,用于衡量当前系统错误发生的速率。对于失败的请求而言,大部分是显式的(HTTP 500),而有些是隐式(HTTP 200,实际业务流程依然是失败的)。 64 | 65 | 显式的错误如 HTTP 500 可通过在负载均衡器(如 Nginx)上进行捕获,而对于一些系统内部的异常,则可能需要直接从服务中添加钩子统计并进行获取(日志输出)。 66 | 67 | #### 2.3.4 Saturation(饱和度) 68 | 69 | 饱和度主要强调最能影响服务状态的受限制的资源。如果系统主要受内存影响,那主要关注系统的内存状态,如果系统主要受限与磁盘 I/O,则主要观测磁盘 I/O 的状态。 70 | 71 | 通常情况下,当这些资源达到饱和后,服务的性能会明显下降,会出现比较明显的瓶颈。同时还可以利用饱和度对系统做出预测,比如「磁盘是否可能在 4 个小时候就满了」。 72 | 73 | ### 2.4 RED 法则 74 | 75 | 在「四个黄金信号」的原则下,RED 方法可以有效的帮助用户衡量云原生以及微服务应用下的用户体验问题。 76 | 77 | * **Rate(速率)**:服务每秒接收的请求数。 78 | * **Errors(错误)**:每秒失败的请求数。 79 | * **Duration(耗时)**:每个请求的耗时。 80 | 81 | ### 2.5 USE 法则 82 | 83 | USE,全称(Utilization Saturation and Errors Method),主要用于分析系统性能问题,可以指导用户快速识别资源瓶颈以及错误的方法。 84 | 85 | #### 2.5.1 Utilization(使用率) 86 | 87 | 使用率主要关注系统资源的使用情况。这里的资源主要包括但不限于:CPU、内存、网络、磁盘等。100% 的使用率通常是系统性能瓶颈的标志。 88 | 89 | #### 2.5.2 Saturation(饱和度) 90 | 91 | 饱和度例如 CPU 的平均运行排队长度,任何资源在某种程度上的饱和都可能导致系统性能的下降。 92 | 93 | #### 2.5.3 Errors(错误) 94 | 95 | 错误指的是错误计数。例如「网卡在数据包传输过程中检测到的以太网网络冲突了 14 次」,「数据库连接在 5 分钟中断开了 3 次」。 96 | -------------------------------------------------------------------------------- /0x03-搭建测试环境.md: -------------------------------------------------------------------------------- 1 | ## 3. 搭建测试环境 2 | 3 | ### 3.1 集群环境 4 | 5 | 主要的折腾环境是在 Kubernetes 集群上,集群是在本地搭建的。使用 VMware 虚拟机,系统为 CentOS7,三节点一主两从。本文不对如何搭建 Kubernetes 集群作详细介绍,这不是本文讨论的重点。都 2020 年了,是时候学会自己搭建一个集群啦,其实也不难,参照官网教程即可。 6 | 7 | 🤔 如果不想搭建个多节点的集群,使用 [kubernetes/minikube](https://github.com/kubernetes/minikube) 也是可以的,作为测试也完全足够。 8 | 9 | ### 3.2 集群节点信息 10 | 11 | ```shell 12 | ~ 🐶 which k 13 | k: aliased to kubectl 14 | 15 | ~ 🐶 k get nodes 16 | NAME STATUS ROLES AGE VERSION 17 | master Ready master 95d v1.16.2 18 | node1 Ready 95d v1.16.2 19 | node2 Ready 95d v1.16.2 20 | 21 | ~ 🐶 k top nodes 22 | NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% 23 | master 98m 4% 926Mi 41% 24 | node1 92m 4% 873Mi 50% 25 | node2 113m 5% 921Mi 53% 26 | ``` 27 | 28 | ***Kubernetes Dashboard*** 29 | 30 | ![Kubernetes dashboard](./images/k8s-dashboard.png) 31 | 32 | 推荐几个部署 kubernetes 集群的相关教程 33 | 34 | * [2019 最新 k8s 集群搭建教程 (centos k8s 搭建)](https://juejin.im/post/5cb7dde9f265da034d2a0dba) 35 | * [create-cluster-kubeadm](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/) 36 | * [和我一步步部署 kubernetes 集群](https://github.com/opsnull/follow-me-install-kubernetes-cluster) 37 | -------------------------------------------------------------------------------- /0x04-Prometheus-理论(入门篇).md: -------------------------------------------------------------------------------- 1 | ## 4. Prometheus 理论(入门篇) 2 | 3 |

4 | 5 | ### 4.1 Prometheus 是什么? 6 | 7 | [Prometheus](https://prometheus.io) 是由 SoundCloud 公司开源和维护的监控和告警的解决方案。项目始于 2012 年,目前已有多家公司将 Prometheus 投入于生产环境中。Prometheus 是继 Kubernetes 之后第二个从 [CNCF](https://www.cncf.io/) 毕业的项目,在这个 CloudNative 盛行的时代,Prometheus 已经成为最热门的监控方案。Prometheus 有着良好的社区氛围,在社区的驱动下,项目正在如火如荼的开发迭代中。 8 | 9 | 作为新一代的监控框架,Prometheus 具有以下特性: 10 | 11 | * 强大的多维度数据模型,时间序列数据通过 metric 名和键值对来区分,并且所有的 metrics 都可以设置任意的多维标签。 12 | * 灵活的查询语句(PromQL),在同一个查询语句,可以对多个 metrics 进行乘法、加法、连接、取分数位等操作。 13 | * 部署方便,Prometheus server 是一个单独的二进制文件,可直接在本地工作,不依赖于分布式存储。 14 | * 采样高效,一个 Prometheus server 可以处理数百万的 metrics。 15 | * 解耦客户端和服务端,使用 pull 模式采集时间序列数据,由服务端主动配置和抓取客户端 metrics。不过也可以采用 push gateway 的方式把 metrics 数据推送至服务端。 16 | * 支持多种服务发现机制。 17 | * 丰富的可视化图形界面。 18 | 19 | prometheus 组件 20 | 21 | * [Prometheus server](https://github.com/prometheus/prometheus): Prometheus 服务端,负责采集来自客户端的时间序列数据。 22 | * [client libraries](https://prometheus.io/docs/instrumenting/clientlibs/): 不同语言的 SDK 客户端。 23 | * [push gateway](https://github.com/prometheus/pushgateway): 主动推送网关,用于采集短时间或瞬时任务,这种情况在一个 Prometheus 采集周期可能会被忽略,所以需要自己主动推送数据。 24 | * [alertmanger](https://github.com/prometheus/alertmanager): 处理告警信息,将警告通知给指定的接受者。 25 | * [exporters](https://prometheus.io/docs/instrumenting/exporters/): exporters 是 Prometheus 的一类采集数据的客户端组件,比如数据库数据采集,主机节点数据采集等等。 26 | 27 | ***prometheus 架构*** 28 | 29 | ![Prometheus 架构图](./images/prometheus-architecture.png) 30 | 31 | ### 4.2 Prometheus 目标 32 | 33 | **prometheus 适合干什么?** 34 | 35 | Prometheus 天生就是为记录纯数字时间序列数据而准备的。它既适合监控主机级别的数据,也适合于高度动态的面向服务的数据的监控。在微服务领域对多维数据收集和查询的支持是非常强大的特性。Prometheus 的设计旨在提高可靠性,以便我们能快速地发现和排查系统的问题。每个 Prometheus 服务都是独立的,不依赖于网络存储或其他远程服务。 36 | 37 | **prometheus 不适合干什么?** 38 | 39 | Prometheus 强调可靠性,即使在故障情况下也始终可以查看有关系统的可用统计信息。但是如果需要 100% 的准确性(例如审计系统),则 Prometheus 并不是一个好的选择,因为其所收集的数据不够详细和完整(数据压缩也会丢失精度)。在这种情况下,使用传统的关系型数据库会是一个更好的选择。 40 | 41 | ### 4.3 prometheus 数据类型 42 | 43 | Prometheus 有四种基本的数据类型,Counter、Gauge、Histogram、Summary。 44 | 45 | #### 4.3.1 Counter(计数器) 46 | 47 | Counter 单调递增,违反单调性时重置为 0。可以用于统计某些事件出现的次数,或者服务的 uptime。指标名称一般以 `_total` 作为后缀。 48 | 49 | #### 4.3.2 Gauge(仪表盘) 50 | 51 | Gauge 记录瞬时值,可以用于记录系统当下时刻的状态,比如 CPU 使用率,使用内存大小,网络 IO 情况。 52 | 53 | #### 4.3.3 Histogram(直方图) 54 | 55 | Histogram 由 `_bucket{le=""}`,`_bucket{le="+Inf"}`, `_sum`,`_count` 组成,主要用于表示一段时间范围内对数据进行采样(通常是请求持续时间或响应大小),并能够对其指定区间以及总数进行统计,通常它采集的数据展示为直方图。例如 Prometheus server 中 prometheus_local_storage_series_chunks_persisted, 表示 Prometheus 中每个时序需要存储的 chunks 数量,我们可以用它计算待持久化的数据的分位数。(主要计算消耗在服务端) 56 | 57 | #### 4.3.4 Summary(摘要) 58 | 59 | Summary 和 Histogram 类似,由 `{quantile="<φ>"}`,`_sum`,`_count` 组成,主要用于表示一段时间内数据采样结果(通常是请求持续时间或响应大小),它直接存储了 quantile 数据,而不是根据统计区间计算出来的(主要计算消耗在客户端)。例如 Prometheus server 中 prometheus_target_interval_length_seconds。 60 | 61 | 关于 Histogram 和 Summary 的详细对比,可参考文档:[practices/histograms](https://prometheus.io/docs/practices/histograms/) 。 62 | -------------------------------------------------------------------------------- /0x05-Prometheus-理论(进阶篇).md: -------------------------------------------------------------------------------- 1 | ## 5. Prometheus 理论(进阶篇) 2 | 3 | ### 5.1 存储格式 4 | 5 | Prometheus 按照两个小时为一个时间窗口,将两小时内产生的数据存储在一个块(Block)中。每个块都是一个单独的目录,里面含该时间窗口内的所有样本数据(chunks),元数据文件(meta.json)以及索引文件(index)。 6 | 7 | 其中索引文件会将指标名称和标签索引到样板数据的时间序列中。此期间如果通过 API 删除时间序列,删除记录会保存在单独的逻辑文件 tombstone 当中。 8 | 9 | 当前样本数据所在的块会被直接保存在内存中,不会持久化到磁盘中。为了确保 Prometheus 发生崩溃或重启时能够恢复数据,Prometheus 启动时会通过预写日志(write-ahead-log(WAL))重新播放记录,从而恢复数据。预写日志文件保存在 wal 目录中,每个文件大小为 128MB。wal 文件包括还没有被压缩的原始数据,所以比常规的块文件大得多。 10 | 11 | 一般情况下,Prometheus 会保留三个 wal 文件,但如果有些高负载服务器需要保存两个小时以上的原始数据,wal 文件的数量就会大于 3 个。 12 | 13 | Prometheus 保存块数据的目录结构如下所示: 14 | ``` 15 | ├── 01DVSBTTWHKTAZDJEZKS0KZR07 16 | │   ├── chunks 17 | │   │   └── 000001 18 | │   ├── index 19 | │   ├── meta.json 20 | │   └── tombstones 21 | ├── lock 22 | ├── queries.active 23 | └── wal 24 | ├── 00000086 25 | ├── 00000087 26 | ├── 00000088 27 | ├── 00000089 28 | ├── 00000090 29 | └── checkpoint.000085 30 | └── 00000000 31 | 32 | 4 directories, 12 files 33 | ``` 34 | 35 | 本地存储细节可参考文章:[容器监控实践—Prometheus 存储机制](https://segmentfault.com/a/1190000018479963)。 36 | 37 | ### 5.2 PromQL 38 | 39 | #### 5.2.1 数据格式 40 | 41 | 时间序列是由样本构成的,每个样本包括: 42 | 43 | * float64 精度的数值 44 | * 毫秒精度的时间戳 45 | * 标签(label) 46 | 47 | Prometheus label 可能包含 ASCII 字母,数字和下划线。label 必须与正则表达式 `[a-zA-Z_:][a-zA-Z0-9_:]*.` 相匹配。以 `__` 作为前缀的 label 保留供内部使用,如 Kubernetes_sd 中的 `__meta_*`。label 值可以包含任何 Unicode 字符且空 label 等同于该 label 不存在。 48 | 49 | 样本形式如下 50 | ``` 51 | {