使用 Prometheus 监控 Kubernetes 集群

当你考虑基于 Kubernetes 的能力为自己的应用锦上添花的时候,就仿佛打开了一个潘多拉魔盒,你不知道这个盒子里到底有什么,就像你不知道你所依赖的 Kubernetes 集群和集群上的应用正在、将要发生什么。

无论选择什么架构,底层基于什么运行时,可观测性始终拥有极高的优先级。有一种说法是:如果你不知道怎么运维,就不要去尝试部署。这也算是一种非常朴实的,以终为始的思考方式。 如果你想和更多 Prometheus 技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态

话说回来,如果拥抱了 Kubernetes,那么我们所追求的 “可观测性” 是什么样子呢?对于微服务架构,我认为有几个方面可以作为及格线:

  1. 集群和应用状态的可观测性
  2. 集群和应用的日志
  3. 应用间流量、调用关系和请求状态的可观测性

简单来说,就是:监控、日志、跟踪,而 Prometheus 就是在 Kubernetes 监控比较成熟的解决方案。

Prometheus

Prometheus 一款基于时序数据库的开源监控告警系统,诞生自 SoundCloud 公司。Prometheus 的基本工作原理是通过 HTTP 协议,周期性的抓取被监控组件的状态,因此被监控组件只需要实现符合规范的 HTTP 接口便可以接入,对于默认没有提供 HTTP 接口的组件,比如 Linux、MySQL 等,Prometheus 支持使用 exporter 来收集信息,并代为提供 metrics 接口。

SoundCloud 公司博客上有一篇文章简单讲解了 Prometheus 架构以及工作原理。文章中认为 Prometheus 满足的四个特性:

  1. A multi-dimensional data model(多维度数据模型)
  2. Operational simplicity(方便的部署和维护)
  3. Scalable data collection and decentralized architecture(灵活的数据采集)
  4. A powerful query language(强大的查询语言)

第一项和第四项也是时序数据库的特点,但 Prometheus 为了方便部署,默认并没有内置任何额外的存储,而是选择自己实现,对于第四个特性 Prometheus 实现了 PromQL 查询语言,可以实现强大的查询规则。

随着版本的迭代,Prometheus 的特性早已不局限于此。

从 Prometheus 的架构图可以看到,有 4 个主要组件:

  1. Prometheus Server
  2. PushGateway
  3. AlertManager
  4. WebUI

其中只有 Prometheus Server 是最重要的组件,承担着数据的采集,Prometheus 采用 pull 的方式对被监控对象进行数据采集,但是如果需要被监控对象通过 Push 将自身的状态推送给 Prometheus,可以引入 PushGateway,被监控对象将主动的将状态 Push 到 PushGateway 上,而 Prometheus Server 定期去 PushGateway 采集。

AlertManager 和 WebUI 都不是必须组件,前者可以基于采集的数据设置报警,后者可以通过 Web 界面的方式实时展示监控数据。

Prometheus Operator

Prometheus 的部署方式非常多,得益于其简单的工作原理,因此只需要将 Prometheus Server 部署到能访问到被监控对象的环境里即可。

但对于 Kubernetes 来言,因为集群内的网络环境相对封闭、 Pod 的 IP 易变等特点,CoreOS 开源了通过 Operator(CRD) 的方式管理和部署 Prometheus ( https://github.com/coreos/prometheus-operator )。

之前介绍 CRD 的文章( 如何使用 CRD 拓展 Kubernetes 集群 )也讲到,CRD 提供的能力取决于 CRD Controller,Prometheus Operator 便是这么一种 Controller,承担了监听自定义资源的变更,并完成后续的管理工作的职责。

安装 Operator

Prometheus Operator 的安装非常简单,在 Git 仓库的根目录下,直接 kubectl apply 其中的 bundle.yaml(镜像在 quay.io 下,需要科学上网):

git clone https://github.com/coreos/prometheus-operator.git

kubectl apply -f prometheus-operator/bundle.yaml

基本概念

Prometheus Operator 将会托管 Prometheus 的部署、管理工作,而且基于 Kubernetes 中的 CRD,Prometheus Operator 新引入了若干 CR(自定义资源):

  1. Prometheus:描述将要部署的 Prometheus Server 集群
  2. ServiceMonitor/PodMonitor:描述了 Prometheus Server 的 Target 列表
  3. Alertmanager:描述 Alertmanager 集群
  4. PrometheusRule:描述 Prometheus 的告警规则

Prometheus Operator 的设计理念可以参考文档: https://github.com/coreos/prom ... gn.md

工作原理

Prometheus Operator 通过监听上面的自定义资源(CR)的变动,并执行后续管理逻辑,入下图:

通过创建类型为 Prometheus 的资源(此处的 Prometheus 指的是 Prometheus Operator 定义的自定义资源),该 Prometheus 会通过 label selector 选择相关的 ServiceMonitor,而 ServiceMonitor 通过定义选择 Service 的 label selector 来选定需要监控的 Service ,并通过该 Service 对应的 Endpoints 获得需要监控的 Pod ip 列表。

监控应用 Demo

我们根据官方 User Guides 简单介绍一下如何使用 prometheus-operator 对应用进行监控,更多细节可以参考: https://github.com/coreos/prom ... ed.md

部署被监控对象

通过 Deployment 部署有 3 个副本的应用:

apiVersion: apps/v1

kind: Deployment

metadata:

name: example-app

spec:

replicas: 3

selector:

matchLabels:

  app: example-app

template:

metadata:

  labels:

    app: example-app

spec:

  containers:

  - name: example-app

    image: fabxc/instrumented_app

    ports:

    - name: web

      containerPort: 8080

然后创建 Service 使得该服务可以提供稳定访问入口:

kind: Service

apiVersion: v1

metadata:

name: example-app

labels:

app: example-app

spec:

selector:

app: example-app

ports:

- name: web

port: 8080

注意 Service 中定义了 app=example-app 的 label,这是 ServiceMonitor 的选择依据。

部署监控

根据 Service 中定义的 Label,我们可以定义 ServiceMonitor:

apiVersion: monitoring.coreos.com/v1

kind: ServiceMonitor

metadata:

name: example-app

labels:

team: frontend

spec:

selector:

matchLabels:

  app: example-app

endpoints:

- port: web

ServiceMonitor 定义了 team=frontend 的 label,这也是 Prometheus 选择 ServiceMonitor 的依据。因此可以创建 Prometheus:

apiVersion: monitoring.coreos.com/v1

kind: Prometheus

metadata:

name: prometheus

spec:

serviceAccountName: prometheus

serviceMonitorSelector:

matchLabels:

  team: frontend

resources:

requests:

  memory: 400Mi

enableAdminAPI: false

这时就发现,已经有 prometheus 实例被启动了:

# kubectl get po

NAME                                   READY   STATUS    RESTARTS   AGE

example-app-66db748757-bfqx4           1/1     Running   0          103m

example-app-66db748757-jqsh5           1/1     Running   0          103m

example-app-66db748757-jtbpc           1/1     Running   0          103m

prometheus-operator-7447bf4dcb-lzbf4   1/1     Running   0          18h

prometheus-prometheus-0                3/3     Running   0          100m

prometheus 本身提供了 WebUI,因此我们可以创建 SVC 是其暴露到集群外部访问(最好不要在公网环境做这样的操作):

apiVersion: v1

kind: Service

metadata:

name: prometheus

spec:

type: NodePort

ports:

- name: web

nodePort: 30900

port: 9090

protocol: TCP

targetPort: web

selector:

prometheus: prometheus

这时就可以看到集群内,Demo 应用的监控信息:

集群监控

通过这个自定义的 Demo 应该可以了解到,Prometheus 是通过 SVC 发起 HTTP 访问来获取数据,而集群监控,只不过是让 Prometheus 有能力获得 Kubernetes 组件的监控接口。同时,Prometheus 也支持以 DaemonSet 的形式部署 Node exporter,来直接收集集群节点信息。

而 Kubernetes 组件的监控数据的采集形式,则取决于集群的部署方式。如果是二进制文件方式部署,可以直接在 Node 上安装 Prometheus 并采集数据;而如果是容器部署,可以为 Kubernetes 组件创建 SVC,后续操作便和集群应用的监控方式一致了,相关文档可以参考: https://coreos.com/operators/p ... .html

原文链接: https://mp.weixin.qq.com/s/ONL1uaYQHm_yEUGcB76hBA

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章