11. 可观测性:监控与日志

本文由 CNCF + Alibaba 云原生技术公开课 整理而来

背景

监控和日志是大型分布式系统的重要基础设施,监控可以帮助开发者查看系统的运行状态,而日志可以协助问题的排查和诊断。

在 Kubernetes 中,监控和日志属于生态的一部分,它并不是核心组件,因此大部分的能力依赖上层的云厂商的适配。Kubernetes 定义了介入的接口标准和规范,任何符合接口标准的组件都可以快速集成。

监控

  • 监控类型:

从监控类型上划分,在 Kubernetes 中 可以分成 4 个不同的类型:

1. 资源类型:CPU、内存、磁盘、网络等资源类指标,通常以数值、百分比单位进行统计

2. 性能监控:APM监控,常见的应用性能类的指标,通常通过 HOOK 机制在虚拟机层、字节码执行层隐式调用、应用层显式注入

3. 安全监控:对安全的一系列监控策略,如越权管理、安全漏洞扫描等

4. 事件监控:Kubernetes 的设计理念是基于类似状态机的状态转换,在状态发生转换时就会发生事件,事件监控就是离线这些事件到一个数据中心,对这些事件进行分析并告警
  • 监控演进:

在早期,Kubernetes 使用类似像 Heapster 这样的组件去进行监控的收集,Heapster 的设计原理其实也比较简单。

首先,每一个 Kubernetes 上面有一个包裹好的 cadvisor,这个 cadvisor 是负责数据采集的组件。当 cadvisor 把数据采集完成,Kubernetes 会把 cadvisor 采集到的的数据进行包裹,暴露成相应的 API。在早期实际上是有 3 种不同的 API:

summary 接口

kubelet 接口

prometheus 接口

这三种接口,其实对应的数据源都是 cadvisor,只是数据格式有所不同。而在 Heapster 里面,其实支持了 summary 接口和 kubelet 两种数据采集接口,Heapster 会定期去每一个节点拉取数据,在自己的内存里面进行聚合,然后再暴露相应的 service,供上层的消费者进行使用。在 K8s 中比较常见的消费者,类似像 dashboard,或者是 HPA-Controller,它通过调用 service 获取相应的监控数据,来实现相应的弹性伸缩,以及监控数据的一个展示。

那为什么 Kubernetes 会将 Heapster 放弃掉而转换到 metrics-service 呢?其实主要的一个动力来源是由于 Heapster 在做监控数据接口的标准化。为什么要做监控数据接口标准化呢?

1. 用户的需求是千变万化的,但 Heapster 自身扩展性存在弊端,无法满足用户自定义接口进行数据展示

2. Heapster 里面为了保证数据的离线能力,提供了很多的 sink,而这个 sink 包含了类似像 influxdb、sls、钉钉等等一系列 sink。
   这个 sink 主要做的是把数据采集下来,并且把这个数据离线走,但是后来社区发现,这些 sink 很多时候都是没有人来维护的。
   这也导致整个 Heapster 的项目有很多的 bug,也给社区的项目的活跃度包括项目的稳定性带来了很多的挑战

基于这两点原因,Kubernetes 把 Heapster 进行了 break 掉,然后做了一个精简版的监控采集组件,叫做 metrics-server。

metrics-server 内部结构非常简单,有一个 core 层、中间的 source 层以及简单的 API 层,额外增加了 API Registration 层。API Registration 这一层的作用就是它可以把相应的数据接口注册到 Kubernetes 的 API server 之上,用户不需要通过这个 API 层去访问 metrics-server,而是通过 API server 访问 API Registration 层,再到 metrics-server。这样一来,真正的数据消费方可能感知到的并不是一个 metrics-server,而是说感知到的是实现了这样一个 API 的具体的实现,而这个实现是 metrics-server。这个就是 metrics-server 改动最大的一个地方。

  • 监控接口标准:

在 Kubernetes 里面针对于监控,有三种不同的接口标准。它将监控的数据消费能力进行了标准化和解耦,实现了与社区的融合,社区里面主要分为 3 类:

1. Resource Metrice

对应的接口是 metrics.k8s.io,主要的实现就是 metrics-server,它提供的是资源的监控,比较常见的有节点级别、pod 级别、namespace 级别、class 级别。
这类的监控指标都可以通过 metrics.k8s.io 这个接口获取到。

2. Custom Metrics

对应的 API 是 custom.metrics.k8s.io,主要的实现是 Prometheus。它提供的是资源监控和自定义监控,资源监控和上面的资源监控是有覆盖关系的,
而自定义监控指的是:比如应用上面想暴露一个接口,或者说调用后面的这个数据库的 MySQL 的慢查询。这些其实都是可以在应用层做自定义的,
然后并通过标准的 Prometheus 的 client,暴露出相应的 metrics,然后再被 Prometheus 进行采集。

而这类自定义的接口一旦采集上来也是可以通过类似像 custom.metrics.k8s.io 这样一个接口的标准来进行数据消费的,
也就是说现在如果以这种方式接入的 Prometheus,那你就可以通过 custom.metrics.k8s.io 这个接口来进行 HPA,进行数据消费。

3. External Metrics

External Metrics 其实是比较特殊的一类,因为 Kubernetes 现在已经成为了云原生接口的一个实现标准,很多时候在云上打交道的是云服务,
比如说在一个应用里面前面用到的是消息队列,后面的是 RBS 数据库。那有时在进行数据消费的时候,同时需要去消费一些云产品的监控指标,
类似像消息队列中消息的数目,或者是接入层 SLB 的 connection 数目,SLB 上层的 200 个请求数目等这些监控指标。

那怎么去消费呢?也是在 Kubernetes 里面实现了一个标准 external.metrics.k8s.io。主要的实现厂商就是各个云厂商的 provider,
通过这个 provider 可以通过云资源的监控指标。在阿里云上面也实现了 cloud metrics adapter,用来提供这个标准的 external.metrics.k8s.io 的一个实现。
  • Promethues-开源社区的监控“标准”:

Prometheus 目前已经成为开源社区的监控标准。Prometheus 为什么能成为开源社区的监控标准呢?

首先,Prometheus 是 CNCF 云原生社区的一个毕业项目;

其次,有越来越多的开源项目都以 Prometheus 作为监控标准,如比较常见的 Spark、Tensorflow、Flink 这些项目,其实它都有标准的 Prometheus 的采集接口;

最后,对于常见的数据库、中间件,如 ETCD、Zookeeper、MySQL 或者说 PostgreSQL,它都有相应的 Prometheus 采集客户端。如果没有,社区里面也会有相应的 exporter 实现监控的接口。

Prometheus 的大致结构:

在这里插入图片描述

Prometheus 有 3 种不同的数据采集链路:

1. push 的方式,通过 pushgateway 进行数据采集,数据先到 pushgateway,然后 Prometheus 再通过 pull 的方式去 pushgateway 去拉数据。
   一旦数据声明周期短于数据的采集周期,比如采集周期是 30s,而任务可能运行 15s 就完了。这种场景之下,可能会造成数据漏采。对于这种场景可以采用 push 的方式
 
2. 标准的 pull 模式,它是直接通过拉模式去对应的数据的任务上面去拉取数据
 
3. Prometheus on Prometheus,通过另一个 Prometheus 来去同步数据到这个 Prometheus

从数据源上面,除了标准的静态配置,Prometheus 也支持 service discovery,它可以通过一些服务发现的机制,动态地去发现一些采集对象。在 Kubernetes 里面就用到了动态发现机制,只需要配置一些 annotation,它就可以自动地来配置采集任务来进行数据采集,是非常方便的。

在报警上面,Prometheus 提供了一个外置组件叫 Alentmanager,它可以将相应的报警信息通过邮件或者短信的方式进行数据的一个告警。在数据消费上面,可以通过上层的 API clients,可以通过 web UI,可以通过 Grafana 进行数据的展现和数据的消费。

总结起来 Prometheus 有如下五个特点:

1. 简单强大的接入标准,开发者只需要实现 Prometheus Client 的接口标准,就可以直接实现数据采集;

2. 多种的数据采集、离线的方式。可以通过 push、pull、Prometheus on Prometheus的方式来进行数据的采集和离线;

3. 和 Kubernetes 兼容;

4. 丰富的插件机制与生态;

5. 是 Prometheus Operator 的一个助力,Prometheus Operator 可能是目前所有的 Operator 里面做的最复杂的,但是它也是把 Prometheus 的动态能力做到淋漓尽致的一个 Operator,
   如果在 Kubernetes 里面使用 Prometheus,比较推荐大家使用 Prometheus Operator 的方式来去进行部署和运维。
  • kube-eventer-Kubernetes 事件离线工具:

kube-eventer 是阿里云容器服务开源出的一个组件,它可以将 Kubernetes 里面的 Pod eventerNode eventer、核心组件的 eventer、crd 的 eventer 等一系列的 eventer,通过 API Sever 的这个 Watch 机制离线到类似像 SLS、Dingtalk、kafka、InfluxDB,然后通过这种离线的机制进行一个时间的审计、监控和告警。

11. 可观测性:监控与日志_第1张图片

上面就是 Dingtalk 的一个告警图。可以看见里面有一个 warning 的事件,这个事件是在 kube-system namespace 之下,具体的这个 Pod 重启失败了,reason 是 backoff,然后具体发生事件是什么时间。可以通过这个信息来做到一个检查。


日志

  • 日志的场景:

日志在 Kubernetes 里面主要分为 4 个大的场景:

1. 主机内核的日志

2. Runtime 的日志

3. 核心组件的日志

4. 部署应用的日志
  • 日志的采集:

从采集位置上划分,需要支持以下 3 种:

1. 宿主机文件。通过 Volume 挂载把日志文件写到宿主机之上,宿主机通过日志轮转策略进行日志的轮转,然后再通过宿主机上的 agent 进行采集

2. 容器内日志文件。通过 sidecar 转写到 stdout,通过 stdout 写到相应的日志文件,然后再通过本地的一个日志轮转,然后通过外部的 agent 采集

3. stdout。直接写到 stdout ,可以通过 agent 采集到远端,或者通过类似 sls 的标准 API 采集到远端

社区里面推荐的是使用 Fluentd 的一个采集方案,Fluentd 是在每一个集群节点上面都会启动一个 agent,然后这个 agent 会把数据汇集到一个 Fluentd 的一个 server,这个 server 里面可以将数据离线到相应的类似像 elasticsearch,然后再通过 kibana 做展现;或者是离线到 influxdb,然后通过 Grafana 做展现。


阿里云容器服务监控体系

  • 监控体系组件介绍:

11. 可观测性:监控与日志_第2张图片

上面右侧的几个产品和监控、日志有比较紧密的相关:

SLS
    SLS 就是日志服务,在阿里云容器服务里面,可以通过 API server 采集到审计的日志,然后可以通过类似 service mesh 或者 ingress controller 采集到接入层的日志,
    以及相应的应用层采集到应用的日志

ARMS
    ARMS 是应用的性能监控。性能监控上面,可以通过 ARMS 来进行查看。ARMS 目前支持的 JAVA、PHP 两种语言,可以通过 ARMS 来做应用的性能诊断和问题的调优

AHAS
    AHAS 是架构感知的监控。在 Kubernetes 里面,大多数时候都是通过微服务的架构进行部署的。微服务带来的问题就是组件及其副本数都会变的非常多,这就导致在拓扑管理上面的复杂性
    
    AHAS 的作用就是通过网络栈的一个监控,可以绘制出整个 Kubernetes 中应用的一个拓扑关系,相应的资源监控和网络的带宽监控、流量的监控,以及异常事件的诊断

Cloud Monitor

    Cloud Monitor 就是基础的云监控。它可以采集标准的 Resource Metrics Monitoring,来进行监控数据的一个展现,可以实现 node、pod 等等监控指标的一个展现和告警
  • 阿里云增强的功能:
1. 首先是 metrics-server,阿里云继续保留了常见的维护率比较高的 sink,帮助实现将监控数据离线之类的目的

2. 阿里云的 metrics-server,完成了完整的监控组件的消费的兼容。因为在 Kubernetes 里面整合的一个生态的发展并不是以同样的节奏进行演进的。

   例如 Dashboard 的发布,并不是和 Kubernetes 的大版本进行匹配的,阿里云在 metrics-server 上面做了完整的 Heapster 兼容

3. 针对 kube-eventer 这个组件做了很多增强。在 npd 上面,增加了很多监控和检测项,类似像 kernel Hang、npd 的一个检测、出入网的监控、snat 的一个检测。

   然后类似像 fd 的 check,开发者可以直接部署 npd 的一个 check,就可以实现节点诊断的一个告警,然后并通过 eventer 离线上的 kafka 或者是 Dingtalk
   
4. Prometheus 生态里面,在存储层可以让开发者对接,阿里云的 HiTSDB 以及 InfluxDB,然后在采集层提供了优化的 node-exporter,以及一些场景化监控的 exporter,

   类似像 Spark、TensorFlow、Argo 这类场景化的 exporter。还有就是针对于 GPU,阿里云做了很多额外的增强,类似于像支持 GPU 的单卡监控以及 GPU share 的监控

5. 在 Prometheus 上面,连同 ARMS 团队推出了托管版的 Prometheus,开发者可以使用开箱即用的 helm chats,不需要手动部署 Prometheus server

6. 针对日志,在采集方式上做到了完整的兼容。可以采集 pod log 日志、核心组件日志、docker engine 日志、kernel 日志,以及类似一些中间件的日志,都收集到 SLS。
   
   收集到 SLS 之后,通过数据离线到 OSS 或 Max Compute,做一个数据的离线和归档,以及离线预算
   
7. 对于一些数据的实时消费,可以到 Opensearch、E-Map、Flink,来做到一个日志的搜索和上层的消费。在日志展现上面,既对接开源的 Grafana,也可以对接DataV,

   实现一个完整的数据链路的采集和消费

你可能感兴趣的:(云原生,kubernetes)