Prometheus Operator

prometheus-operator

promethues-operator是一个通过监听K8s内CRD资源的变更操作事件来自动创建,配置并管理prometheus监控系统的一个控制器,可以理解成是一个类似于controller-manager的东西,只不过它的管理对象不是ds/deploy/sts/svc等

官网/github


整套方案包括以下组件

  • prometheus

    prometheus是一个开源的监控告警系统,具有由度量名称和键/值对标识的时间序列数据的多维数据模型、灵活的查询语言,监控模式是通过HTTP主动去拉取exporters上基于时间序列的监控采集数据,同时也能通过中间网关来支持推送型的监控数据收集,所有的监控目标都是通过配置型的或是服务发现,或是静态配置,提供了HTTP页面支持图形和仪表盘的展示。

  • alertmanager

    alertmanager处理由客户端应用程序发送的prometheus警报,将重复的告警信息通过特定的标签去分组,并将它们路由到正确的接收方,特点是能够grouping、抑制、设置静默等。

  • 一个简单的钉钉机器人

    从alertmanager通过webhook的方式发送告警信息,将payload渲染成配置好的模板,并发送到指定的钉钉机器人

  • grafana

    有了prometheus去收集数据,那我们还需要将这些metrics通过web页面展示出来,那grafana就是这样的一个工具,它支持多种数据源,能让你查询、展示或者基于这些告警数据来发送警报(虽然也支持prometheus数据源但是我们并没有使用到),最实用的是它在社区有维护了很多开箱即用的面板模板,只需要少少的修改就能展示出一个很详细的展示面板出来。当然,它也实现了自己的一套DSL语言。

  • node-exporter

    一个golang写的能够采集硬件以及OS信息的收集器,采集目标包括cpu/硬盘/conntrack/文件系统/负载/网络连接信息/硬件信息等,在K8S内使用daemonSet的方式运行,保证每台节点主机都能监控起自身的信息

  • cadvisor

    示例中的prometheus-operator生成的监控目标包含了cadvisor
    虽然K8S组件kubelet编译包含了cadvisor,但是默认是不启用的。
    cadvisor也是通过HTTP的方式暴露了节点主机上的资源使用率、性能指标以及运行的容器信息

  • kube-state-metrics

    这个插件通过去APISERVER获取K8S内对象并生成对象对应的监控数据,例如nodes、pods、deployments等,具体可查阅[文档][10]

  • 当然还有各个组件自带的metrics

其实倒数四个都是属于采集器,负责收集对应系统组件的信息。

部署

git clone https://github.com/coreos/prometheus-operator
cd prometheus-operator/contrib/kube-prometheus/
bash hack/cluster-monitoring/deploy

架构设计

prometheus-operator使用了k8s1.8+引入的CRD(custom resource definitions),实现了controller的功能,通俗点来说,它负责将resource definition转换成K8S里的statefulset或者是promethues的配置对象。

  • Prometheus

    OperatorListWatch集群内的Prometheus CRD来创建一个合适的statefulsetmonitoring(.metadata.namespace指定)命名空间,并且挂载了一个名为prometheus-k8sSecret为Volume到/etc/prometheus/config目录,Secret的data包含了以下内容

    • configmaps.json指定了rule-files在configmap的名字
    • prometheus.yaml为主配置文件
  • ServiceMonitor

    这个允许动态地监听K8S里的Service,会将生成的job更新到上面的prometheus-k8s这个SecretData.**prometheus.yaml**里,然后prometheus这个pod里的sidecar容器prometheus-config-reloader当检测到挂载路径的文件发生改变后自动去执行HTTPPost请求到/api/-reload-路径去reload配置

  • Alertmanager

    这个将生成一个statefulset类型对象,并挂载了名为alertmanager-mainsecret资源到容器内部的/etc/alertmanager/config/alertmanager.yaml路径。当需要更新配置文件时需要将alertmanager.yaml内容base64encode后更新到alertmanager-mainData属性或者直接patch secret from file

比较疑惑的地方

默认的namespacemonitoring,假如我把deployment/svc/servicemonitor都创建在其他命名空间例如default,operator并不会将这个servicemonitor配置到prometheus.yaml中,有两个原因导致

  1. 由于Prometheusobject的配置
serviceMonitorSelector:
matchExpressions:
- key: k8s-app
operator: Exists

假如servicemonitor(以下简写sm)的.metadata.labels不包含k8s-app这个label的话会被忽略,处理方法修改sm添加label以及添加prometheus的serviceMonitorSelector

  1. createConfig函数中首先用LabelSelector去List出匹配的sm,具体逻辑在selectServiceMonitors,当ServiceMonitorNamespaceSelector为nil或Size为0时仅查找当前namespace。
    如果想List所有ns的sm,则简单添加serviceMonitorNamespaceSelector: {}