使用 Prometheus 监控 Kubernetes 集群


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

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

话说回来,如果拥抱了 Kubernetes,那么我们所追求的 “可观测性” 是什么样子呢?对于微服务架构,我认为有几个方面可以作为及格线:
  1. 集群和应用状态的可观测性
  2. 集群和应用的日志
  3. 应用间流量、调用关系和请求状态的可观测性


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

Prometheus

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

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 的特性早已不局限于此。
2.png

从 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)的变动,并执行后续管理逻辑,入下图:
3.jpg

通过创建类型为 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 应用的监控信息:
4.png

集群监控

通过这个自定义的 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

0 个评论

要回复文章请先登录注册