Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
isno committed Dec 28, 2024
1 parent 4b88d94 commit 323a7df
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 48 deletions.
22 changes: 16 additions & 6 deletions Observability/signals.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,31 @@

业界将系统输出的数据总结为三种独立的类型:指标(metrics)、日志(logs)和链路追踪(traces),它们被称为可观测性的“三大支柱”。

- **指标(metrics)**量化、评估系统性能、健康状况的数据。它们通过对特定事件或活动的统计聚合,提供对系统状态的直观理解。指标通常度量内容(描述所监测的具体内容,如请求数量)、数值(度量的实际值)、时间点(该数据的收集时间)组成。常见的指标有 QPS、API 响应延迟、某接口的失败次数等。指标是发现问题的起点,例如你收到一条告警:“12 点 22 分,接口请求成功率下降到 10%”,这表明系统出现了问题。接着,你结合链路追踪和日志数据深入分析,找到问题的根本原因并进行修复。
- **指标(metrics)**量化系统性能和状态的“数据点”,每个数据点包含度量对象(描述监控内容,如请求数)、度量值(具体数值,如 100 次/秒)和时间戳(采集时刻),例如,“2024-12-27 10:00:00,CPU 使用率为 75%”。多个连续的数据点便可以分析系统性能的趋势和变化规律。指标是发现问题的起点,例如你收到一条告警:“12 点 22 分,接口请求成功率下降到 10%”,这表明系统出现了问题。接着,你结合链路追踪和日志数据深入分析,找到问题的根本原因并进行修复。

- **日志(logs)**:系统运行过程中生成的文本数据,用于记录离散事件,提供系统在特定点或阶段的详细信息。如果“指标”告诉你应用程序出现了问题,那么“日志”则解释了问题的原因。日志通常包含系统对某一对象执行的操作、操作结果及其时间戳。当系统发生故障时,分析日志是工程师定位问题的最直接手段。
- **日志(logs)**:系统运行过程中,记录离散事件的文本数据,每条日志详细描述事件操作对象、操作结果、操作时间。例如下面的日志,提供了时间戳、日志级别(ERROR)以及事件描述。
```bash
[2024-12-27 14:35:22] ERROR: Failed to connect to database. Retry attempts exceeded.
```
日志为问题诊断提供了精准的上下文信息,与指标形成互补。当系统故障时,“指标”告诉你应用程序出现了问题,“日志”则解释了问题出现的原因。

- **链路追踪(traces)**链路追踪用于记录请求在分布式系统中的执行过程。当一个请求进入系统后,处理过程中的每个组件都会生成一个处理片段,称为 Span。多个 Span 通过相同的请求 ID 关联,形成一条完整的追踪链路。这条链路实际上是由多个 Span 组成的有向无环图,代表一次分布式请求的完整路径。通过链路追踪,能够有效分析系统中的异常点,帮助在复杂的分布式环境中定位问题
- **链路追踪(traces)**记录单个请求在多个服务之间的传播路径(Trace),包括流经的节点(span)、耗时分布及相关上下文信息。链路追踪以追踪树(Trace Tree)的形式直观呈现请求的调用链路,帮助工程师在复杂的分布式系统中快速定位异常点和性能瓶颈

上述三类数据虽然各自侧重不同,但并非孤立存在,在可观测领域有天然的交集与互补。如通过指标监控(告警)发现问题,再结合日志和链路追踪深入定位问题根源。这三者之间的关系,如下图 9-2 的韦恩图所示。
```bash
// 追踪树
Trace ID: 12345
└── Span ID: 1 - API Gateway (Duration: 50ms)
└── Span ID: 2 - User Service (Duration: 30ms)
└── Span ID: 3 - Database Service (Duration: 20ms)
```

上述三类数据各自侧重不同,但并非孤立存在,有着天然的交集与互补,例如,指标监控(告警)可帮助发现问题,日志和链路追踪则进一步帮助定位根本原因。这三者之间的关系,如下图 9-2 的韦恩图所示。

:::center
![](../assets/observability.jpg)<br/>
图 9-2 指标、链路追踪、日志三者之间的关系 [图片来源](https://peter.bourgon.org/blog/2017/02/21/metrics-tracing-and-logging.html)
:::

可观测系统建设的目标之一:是将日志、指标和链路追踪紧密结合,构建统一的监控平台,帮助我们从宏观到微观、从整体到细节,全方位地了解系统运行的状态。


现在,CNCF 发布的可观测性白皮书中[^1],将系统输出的各类观测数据统一称为信号(Signals)。主要的信号除了 指标、日志、链路追踪之外又增加了性能剖析(Profiling)和核心转储(Core dump)。

Expand Down
49 changes: 21 additions & 28 deletions application-centric/Controller.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,9 @@ Kubernetes 中有多种类型的控制器,例如 Deployment Controller、Repli

“控制器模式”体系的理论基础,是一种叫做 IaD(Infrastructure as Data,基础设施即数据)的思想。

IaD 思想主张,基础设施的管理应脱离特定的编程语言或配置方式,而采用纯粹、格式化、系统可读的数据形式。这些数据能够完整地描述用户期望的系统状态。这种思想的优势在于,对基础设施的所有操作本质上等同于对数据的“增、删、改、查”。更重要的是,这些操作的实现方式与基础设施本身无关,不受限于特定的编程语言、远程调用协议或 SDK只要生成符合格式要求的“数据”,便可以“随心所欲”地采用任何你偏好的方式管理基础设施。
IaD 思想主张,基础设施的管理应该脱离特定的编程语言或配置方式,而采用纯粹、格式化、系统可读的数据,描述用户期望的系统状态。这种思想的优势在于,对基础设施的所有操作本质上等同于对数据的“增、删、改、查”。更重要的是,这些操作的实现方式与基础设施本身无关,不依赖于特定编程语言、协议或 SDK只要生成符合格式要求的“数据”,便可以“随心所欲”地采用任何你偏好的方式管理基础设施。

IaD 思想在 Kubernetes 上的体现,就是执行任何操作,只需要提交一个 YAML 文件,然后对 YAML 文件增、删、查、改即可,而不是必须使用 Kubernetes SDK 或者 Restful API。这个 YAML 文件其实就对应了 IaD 中的 Data。

Kubernetes 把所有的功能都定义为“API 对象”,其实就是一个 Data。既然 Kubernetes 要处理这些数据,那么 Data 本身也应该有一个固定的“格式”,这样 Kubernetes 才能解析。这里的格式在 Kubernetes 中就叫做 API 对象的 Schema。

```YAML
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25.3
ports:
- containerPort: 80
```
从这个角度来讲,Kubernetes 暴露出来的各种 API 对象,实际上就是一张张预先定义好 Schema 的表(Table)。唯一跟传统数据库不太一样的是,Kubernetes 在拿到这些数据之后,并不以把这些数据持久化起来为目的,而是监控数据变化来驱动“控制器”执行某些操作。
IaD 思想在 Kubernetes 上的体现,就是执行任何操作,只需要提交一个 YAML 文件,然后对 YAML 文件增、删、查、改即可,而不是必须使用 Kubernetes SDK 或者 Restful API。这个 YAML 文件其实就对应了 IaD 中的 Data。从这个角度来看,Kubernetes 暴露出来的各种 API 对象,一张张预先定义好 Schema 的“表”(table)。唯一跟传统数据库不太一样的是,Kubernetes 并不以持久化这些数据为目标,而是监控数据变化驱动“控制器”执行相应操作。

|关系型数据库|Kubernetes (as a database)|说明|
|:--|:--|:--|
Expand All @@ -53,15 +34,27 @@ spec:
|COLUMN|property|表里面的列,有 string、boolean 等多种类型|
|rows|resources|表中的一个具体记录|

所以说,Kubernetes v1.7 版本引入了 CRD(自定义资源定义)功能,实质上赋予用户创建和管理自定义“数据”、将特定业务需求抽象为 Kubernetes 原生对象的能力。

所以说,Kubernetes v1.7 版本支持 CRD(Custom Resource Definitions,自定义资源定义),实质上是允许用户定义自己的资源类型,,扩展 Kubernetes API,将复杂的业务需求抽象为 Kubernetes 的原生对象
例如,用户定义一个 CRD 来描述持续交付流程中的任务

有了 CRD,用户便不再受制于 Kubernetes 内置资源的表达能力,自定义出数据库、Task Runner、消息总线、数字证书...。加上自定义的“控制器”,便可把“能力”移植到 Kubernetes 中,并以 Kubernetes 统一的方式暴漏给上层用户。
```yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: example-task
spec:
steps:
- name: echo-hello
image: alpine:3.14
script: |
#!/bin/sh
echo "Hello, Tekton!"
```
有了 CRD,工程师不再受限于 Kubernetes 内置资源的表达能力,可以根据需求自定义出数据库、CI/CD 流程、消息队列、数字证书等等资源类型。再加上自定义的“控制器”,便可把特定的业务逻辑和基础设施能力无缝集成到 Kubernetes 中。更重要的是,使用者只需理解 CRD 定义的 Schema,即可通过标准的 API 对象操作方式管理和使用这些资源。
## 构建上层抽象
:::center
![](../assets/CRD.webp)<br/>
图 10-10 CRD
:::
至此,相信读者已经理解了:IaD 思想中的 Data 具体表现其实就是声明式的 Kubernetes API 对象,而 Kubernetes 中的控制循环确保系统状态始终跟这些 Data 所描述的状态保持一致。从这一点讲,Kubernetes 的本质是一个以“数据”(Data)表达系统的设定值,通过“控制器”(Controller)的动作来让系统维持在设定值的“调谐”系统。
8 changes: 3 additions & 5 deletions application-centric/OAM.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
# 10.3.5 OAM

前面介绍的 Helm、Kustomize、CRD + Operator 在各自领域很好的承载一个“组件”的概念。但对于一个完整的“应用”,即面向具体业务场景的定义、部署和运行需求,仍旧缺乏系统化的解决方案
2019 年 10 月,阿里云与微软在上海 QCon 大会上联合发布了开源项目 Open Application Model(OAM)。该项目以“关注点分离”(Separation of Concerns)为核心理念,为云原生应用的完整 DevOps 流程提供了高度抽象和封装

OAM 的全称为开放应用模型(Open Application Model),由阿里巴巴联合微软共同推出,提供了一种大家都可以遵循的、标准化的方式来定义更高层级的应用层抽象,并且把“关注点分离”(Separation of Concerns)作为这个应用模型的核心思想。

OAM 有两个部分:OAM 规范、OAM 规范的 Kubernetes 实现。
OAM 项目有两个部分,OAM 规范(spec)和 OAM 规范的 Kubernetes 实现。

详细的说,OAM 规范是基于自定义资源讲原先 All-in-One 的复杂配置做了一定层次的解耦,它强调一个现代应用是多个“组件”(Component)的集合,而非一个简单的工作负载或者 K8s Operator。更进一步的,OAM 把这个应用所需的“运维策略”(Trait)也认为是一个应用的一部分,在 OAM 中,一个应用程序包含三个核心理念:
- 第一个核心理念是组成应用程序的组件(Component),它可能包含微服务集合、数据库和云负载均衡器;
Expand All @@ -15,7 +13,7 @@ OAM 有两个部分:OAM 规范、OAM 规范的 Kubernetes 实现。

:::center
![](../assets/OAM-app.png)<br/>
图 4-0 OAM
图 4-0 OAM 应用开放模型
:::

OAM 在社区的众多用户呼声下诞生。KubeVela 在“关注点分离”的核心思想之上,把平台的用户分成两种角色:
Expand Down
5 changes: 3 additions & 2 deletions application-centric/Operator.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ Operator 的概念由 CoreOS 于 2016 年提出,它并非一个具体的工具
理解 Operator 所做的工作,需要先弄清楚“无状态应用”和“有状态应用”的含义。



如果使用 Operator,情况就简单得多。Etcd 的 Operator 提供了 EtcdCluster 自定义资源,在它的帮助下,仅用几十行代码,安装、启动、停止等基础的运维操作。但对于其他高级运维操作,例如升级、扩容、备份、恢复、监控和故障转移,如下面代码所示。

```yaml
Expand Down Expand Up @@ -46,4 +45,6 @@ Red Hat 今天与 AWS、Google Cloud 和 Microsoft 合作推出了 OperatorHub.i
现在很多复杂分布式系统都有了官方或者第三方提供的 Operator,从数据库(如 MySQL、PostgreSQL、MongoDB)到消息队列(如 RabbitMQ、Kafka),再到监控系统(如 Prometheus)。
这些 Operator 提供了 Kubernetes 集群中各种服务和应用程序的生命周期管理,
这些 Operator 提供了 Kubernetes 集群中各种服务和应用程序的生命周期管理。
无论是 Helm、Kustomize 或者是 CRD + Operator ,它们其实在自领域承载一个“组件”的概念。但对于一个完整的“应用”,即面向具体业务场景的定义、部署和运行需求,仍旧缺乏思想指导和有效的解决手段。
6 changes: 2 additions & 4 deletions application-centric/PaaS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,15 @@

为了解决这个问题,很多公司落地 Kubernetes 的时候采用了 “PaaS” 化的思路,即在 Kubernetes 之上,开发一个类 PaaS 平台。

但这个设计,跟 Kubernetes “以应用为中心”的设计不一致,Kubernetes 一旦退化成“类IaaS 基础设施”,它的声明式 API、容器设计模式、控制器模式根本无法发挥原本的实力,也很难接入更广泛的生态。

这个问题在 PaaS 系统上的体现就是不具备扩展性。假设我们要满足以下诉求:
但这个设计,跟 Kubernetes “以应用为中心”的设计不一致,Kubernetes 一旦退化成“类IaaS 基础设施”,它的声明式 API、容器设计模式、控制器模式根本无法发挥原本的实力,也很难与广泛的生态对接。这个问题在 PaaS 系统上的体现就是不具备扩展性。假设我们要满足以下诉求:

- 能不能帮我运行一个定时任务
- 能不能帮我运运行一个 MySQL Operator
- 能不能根据自定义 metrics 定义水平扩容策略
- 能不能基于 Istio 来帮我做渐进式灰度发布
- 能不能...

这里的关键点在于,上述能力在 Kubernetes 生态中都是非常常见的的能力,有的甚至是 Kubernetes 内置就可以支持。但是到了 PaaS 这里,要支持上述任何一个能力,都必须对 PaaS 进行一轮开发。而且由于先前的一些假设和设计,甚至很可能需要大规模的重构。
这里的关键点在于,上述能力在 Kubernetes 生态中都是非常常见的的能力,有的甚至是 Kubernetes 内置就可以支持。但是到了 PaaS 这里,要支持上述任何一个能力,必须进行一轮开发。而且由于先前的一些假设和设计,甚至很可能需要大规模的重构。

具体来说,以“应用为中心”的基础设施:

Expand Down
4 changes: 1 addition & 3 deletions application-centric/app-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,4 @@ port: 80
```
也就是说,业务工程师实际上想要的是:我要部署一个容器,容器的镜像是 nginx:latest,这个容器对外开放 80 端口。至于容器启用后有多少个副本、如何扩缩容、如何对接存储、如何设置安全策略,这是运维工程师关心的事情,跟业务工程师并没有关系。
将这样的对象暴漏给最终用户是不是简介很多了呢!
这种设计“简化版”的 API 对象,就叫做“构建上层抽象”。接下来,笔者将介绍几种主流的思路供你参考。
将这样的对象暴漏给最终用户是不是简介很多了呢!这种设计“简化版”的 API 对象,就叫做“构建上层抽象”。接下来,笔者将介绍几种主流的思路供你参考。

0 comments on commit 323a7df

Please sign in to comment.