Prometheus 是一套开源的系统监控报警框架。和Kubernetes类似,它也发源于Google的Borg体系,其原型为Borgmon,是一个几乎与Borg同时诞生的内部监控系统,由工作在SoundCloud的Google前员工在 2012年创建。之后作为社区开源项目进行开发,并于2015年正式发布。
2016年,Prometheus正式加入CNCF(Cloud Native Computing Foundation),是仅次于Kubernetes的第二个项目,目前已经全面接管了 Kubernetes项目的整套监控体系。
github地址:https://github.com/prometheus-operator/kube-prometheus/releases
其版本与k8s版本有对应关系:
优点:
缺点:
metrics,衡量指标;韵律学;量度;指标
基本架构如下:
数据库:prometheus;其他的都是数据采集插件; grafana读取数据并制成图表展示;Alertmanager告警插件
Prometheus Server: 用于收集监控的数据,存储及查询。
是Prometheus架构中的核心部分,负责实现对监控数据的获取、存储及查询。Prometheus Server可以通过静态配置管理监控目标,也可以配合使用Service Discovery的方式动态管理监控目标,并从这些监控目标中获取数据。
其次Prometheus Server本身也是一个时序数据库,将采集到的监控数据按照时间序列的方式存储在本地磁盘当中。
Prometheus Server对外提供了自定义的PromQL,实现对数据的查询以及分析。
以下3个插件主要收集(cpu,磁盘使用率,容器的状态信息)
Pushgateway: 用于prometheus无法直接pull的监控部分支持.
service discovery: 服务发现
PromQL: 用于查询和展示
Exporter 提供监控数据的来源:
Exporter分为两类:
一类Exporter直接内置了对Prometheus监控的支持,如Kubernetes、etcd等;
另一类是因为原有监控目标并不直接支持Prometheus,需要通过Prometheus提供的Client Library编写该监控目标的监控采集程序,如Mysql、JMX等。
对于Exporter,Prometheus Server采用pull的方式来采集数据。
PushGateway :同样是监控数据的来源。对于由于特定原因,如网络环境不允许等,Prometheus Server不能直接与Exporter进行通信时,可以使用PushGateway来进行中转。内部网络的监控数据主动Push到Gateway中,而和对Exporter一样,Prometheus Server也利用pull的方式从PushGateway采集数据。
Alertmanager :Prometheus体系中的告警处理中心。
在Prometheus Server中可以设定门限与警报规则。当采集到的数据满足相关规则后,就会产生一条告警。
Alertmanager从 Prometheus Server接收到告警后,会根据事先设定的路径,向外发出告警。
常见的告警发送路径有:电子邮件、PagerDuty、Webhook、Slack等。
数据展示与输出:
Prometheus Server有内置的UI用于展示采集到的监控数据。在该UI上,可以通过各种内置的数学公式对原始数据进行加工,并通过图形化的方式展现出来。
Prometheus Server原生UI的展示方式还是比较基础和单薄,所以目前更多的是通过对接Grafana来进行数据的展示,可以得到更好的展示效果。
此外,Prometheus Server也提供API的方式来实现对监控数据的访问。
组件说明:
Metrics Server
是Kubernetes中资源使用情况的聚合器,收集数据给kubernetes集群内使用。
Metrics Server从Kubelets收集资源指标,并通过Metrics API将它们暴露在Kubernetes apiserver中,供水平Pod Autoscaler和垂直Pod Autoscaler使用。
kubectl top还可以访问Metrics API,这使得调试自动伸缩管道变得更容易。
Metrics Server不是用于非自动伸缩的目的。例如,不要将其用于将指标转发给监视解决方案,或者作为监视解决方案指标的来源。在这种情况下,请直接从Kubelet /metrics/resource端点收集度量。
Metrics Server提供
Metrics与k8s各版本之间关系:
Prometheus Operator
prometheus-operator官方地址:https://github.com/prometheus-operator/prometheus-operator
是运行在Kubernetes之上的监控和告警工具。
部署时不用创建和修改prometheus的配置文件,所有的操作通过创建prometheus自己的资源对象来实现。对于监控配置的修改可以做到实时生效。
Prometheus Operator的本职就是一组用户自定义的CRD资源以及Controller的实现,Prometheus Operator负责监听这些自定义资源的变化,并且根据这些资源的定义自动化的完成如Prometheus Server自身以及配置的自动化管理工作。
Prometheus Operator提供了以下功能:
创建/毁坏。在Kubernetes namespace中更容易启动一个Prometheus实例,一个特定的应用程序或团队更容易使用的Operator。
简单配置。配Prometheus的基础东西,比如在Kubernetes的本地资源versions, persistence,retention policies和replicas。
Target Services通过标签。基于常见的Kubernetes label查询,自动生成监控target配置;不需要学习Prometheus特定的配置语言
以下是Prometheus Operator的架构图:
架构中的各组成部分以不同的资源方式运行在Kubernetes集群中,它们各自有不同的作用:
Operator:Operator资源会根据自定义资源(Custom Resource Definition,CRD。 /ˈkʌstəm,定做(制)的/)来部署和管理Prometheus Server,同时监控这些自定义资源事件的变化来做相应的处理,是整个系统的控制中心。
Prometheus: Prometheus资源是声明性地描述Prometheus部署的期望状态。
Prometheus Server: Operator根据自定义资源Prometheus类型中定义的内容而部署的Prometheus Server集群,这些自定义资源可以看作用来管理Prometheus Server 集群的StatefulSets资源。
ServiceMonitor:ServiceMonitor也是一个自定义资源,它描述了一组被Prometheus监控的target列表。该资源通过标签来选取对应的Service Endpoint,让Prometheus Server通过选取的Service来获取Metrics信息。
Service:Service资源主要用来对应Kubernetes集群中的Metrics Server Pod,提供给ServiceMonitor选取,让Prometheus Server来获取信息。简单说就是Prometheus监控的对象,例如Node Exporter Service、Mysql Exporter Service等。
Alertmanager:Alertmanager也是一个自定义资源类型,由Operator根据资源描述内容来部署Alertmanager集群。
prometheus Operator的自定义资源(CustomResourceDefinitions CRD)有:
Grafana
支持多种图形和Dashboard的展示。是一个跨平台的开源的度量分析和可视化工具,可以查询采集的数据进行可视化展示,并及时通知。
特点:
Prometheus:
采用pull方式apiserver、scheduler、controller-manager、kubelet组件数据,通过http协议传输
kubeStateMetrics:
kube-state-metrics收集kubernetes集群内资源对象数据,制定告警规则。
它并不聚焦于k8s集群整体及相关组件的监控,而是更加关注deployments, nodes and pods等内部对象的状态。
NodeExporter:
用于各node的关键度量指标状态数据
按顺序部署Prometheus、kube-state-metrics、node-exporter以及Grafana。以下展示了各个组件的调用关系:
在Kubernetes Node上部署Node exporter,获取该节点物理机或者虚拟机的监控信息,在Kubernetes Master上部署kube-state-metrics获取Kubernetes集群的状态。所有信息汇聚到Prometheus进行处理和存储,然后通过Grafana进行展示。
部署对外可访问Prometheus,首先需要创建Prometheus所在命名空间,然后创建Prometheus使用的RBAC规则,创建Prometheus的configmap来保存配置文件。
创建service进行固定集群IP访问,创建deployment部署带有Prometheus容器的pod,最后创建ingress实现外部域名访问Prometheus。
部署顺序如图:
Step1:创建monitoring命名空间
编辑YAML文件,使用的apiVersion版本是v1,kind是Namespace,命名空间的名字是monitoring
# vi ns-monitoring.yaml
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
创建名为monitoring命名空间,相关对象都部署到该命名空间,使用以下命令创建命名空间:
# kubectl apply -f ns-monitoring.yaml
# kubectl get ns|grep monitoring
Step2、3、4:创建RBAC规则
创建RBAC规则,包含ServiceAccount、ClusterRole、ClusterRoleBinding三类YAML文件。Service Account 是面向命名空间的,ClusterRole、ClusterRoleBinding是面向整个集群所有命名空间的,可以看到ClusterRole、ClusterRoleBinding对象并没有指定任何命名空间。ServiceAccount中可以看到,名字是prometheus-k8s,在monitoring命名空间下。ClusterRole一条规则由apiGroups、resources、verbs共同组成。ClusterRoleBinding中subjects是访问API的主体,subjects包含users、groups、service accounts三种类型,我们使用的是ServiceAccount类型
编辑清单# vi prometheus-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus-k8s
namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus
rules:
- apiGroups: [""]
resources: ["nodes", "services", "endpoints", "pods"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get"]
- nonResourceURLs: ["/metrics"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: prometheus-k8s
namespace: monitoring
使用以下命令创建RBAC:
# kubectl apply -f prometheus-rbac.yaml
# kubectl get sa prometheus-k8s -n monitoring
# kubectl get clusterrole
# kubectl get clusterrolebinding prometheus
Step5:创建ConfigMap配置文件
使用ConfigMap方式创建Prometheus配置文件,YAML文件中使用的类型是ConfigMap,命名空间为monitoring,名称为prometheus-core,apiVersion是v1,data数据中包含prometheus.yaml文件,内容是prometheus.yaml: |这行下面的内容。使用以下命令创建Prometheus的配置文件
vi prometheus-core-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: null
name: prometheus-core
namespace: monitoring
data:
prometheus.yaml: |
global:
scrape_interval: 15s
scrape_timeout: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets: ["10.254.127.110:9093"]
rule_files:
- "/etc/prometheus-rules/*.yml"
scrape_configs:
- job_name: 'kubernetes-apiservers'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: default;kubernetes;https
注:由于篇幅有限,该配置文件只有一个名为kubernetes-apiservers的job,完整配置请查看源码文件。
使用以下命令查看已创建的配置文件prometheus-core:
# kubectl apply -f prometheus-core-cm.yaml
# kubectl get cm -n monitoring prometheus-core 或加-o yaml查看详细信息
创建prometheus rules配置文件,使用ConfigMap方式创建prometheus rules配置文件,包含的内容是两个文件,分别是node-up.yml和cpu-usage.yml。
使用以下命令创建Prometheus的另外两个配置文件:
# vi prometheus-rules-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-rules
namespace: monitoring
data:
node-up.yml: |
groups:
- name: server_rules
rules:
- alert: 机器宕机
expr: up{compOnent="node-exporter"} != 1
for: 1m
labels:
severity: "warning"
instance: "{{ $labels.instance }}"
annotations:
summary: "机器 {{ $labels.instance }} 处于down的状态"
description: "{{ $labels.instance }} of job {{ $labels.job }}
已经处于down状态超过1分钟,请及时处理"
cpu-usage.yml: |
groups:
- name: cpu_rules
rules:
- alert: cpu 剩余量过低
expr: 100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
for: 1m
labels:
severity: "warning"
instance: "{{ $labels.instance }}"
annotations:
summary: "机器 {{ $labels.instance }} cpu 已用超过设定值"
description: "{{ $labels.instance }} CPU 用量已超过 85% (current value is: {{ $value }}),请及时处理。"
本节的配置文件是Prometheus告警信息的配置文件,篇幅有限,可在文件后继续增加告警信息文件。
使用以下命令查看已下发的配置文件prometheus-core:
# kubectl apply -f prometheus-rules-cm.yaml
# kubectl get cm -n monitoring prometheus-rules
Step6:创建SVC
创建prometheus svc,会生成一个CLUSTER-IP进行集群内部的访问,CLUSTER-IP也可以自己指定。
# vi prometheus-service.yaml
apiVersion: v1
kind: Service
metadata:
name: prometheus
namespace: monitoring
labels:
app: prometheus
component: core
annotations:
prometheus.io/scrape: 'true'
spec:
ports:
- port: 9090
targetPort: 9090
protocol: TCP
name: webui
selector:
app: prometheus
component: core
使用以下命令创建Prometheus要用的service
# kubectl apply -f prometheus-service.yaml
# kubectl get svc prometheus -n monitoring
Step7:创建Deployment
使用deployment方式创建prometheus实例,命令如下
# vi prometheus-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus-core
namespace: monitoring
labels:
app: prometheus
component: core
spec:
replicas: 1
selector:
matchLabels:
app: prometheus
component: core
template:
metadata:
name: prometheus-main
labels:
app: prometheus
component: core
spec:
serviceAccountName: prometheus-k8s
nodeSelector:
kubernetes.io/hostname: k8s-node01 #使用ip报错,找不到该节点
containers:
- name: prometheus
image: quay.io/prometheus/prometheus:v2.36.1
imagePullPolicy: IfNotPresent
args:
- '--storage.tsdb.retention=15d'
- '--config.file=/etc/prometheus/prometheus.yaml'
- '--storage.tsdb.path=/home/prometheus_data'
- '--web.enable-lifecycle'
ports:
- name: webui
containerPort: 9090
resources:
requests:
cpu: 20000m
memory: 20000M
limits:
cpu: 20000m
memory: 20000M
securityContext:
privileged: true
volumeMounts:
- name: data
mountPath: /home/prometheus_data
- name: config-volume
mountPath: /etc/prometheus
- name: rules-volume
mountPath: /etc/prometheus-rules
- name: time
mountPath: /etc/localtime
volumes:
- name: data
hostPath:
path: /home/cdnadmin/prometheus_data
- name: config-volume
configMap:
name: prometheus-core
- name: rules-volume
configMap:
name: prometheus-rules
- name: time
hostPath:
path: /etc/localtime
创建实例
# kubectl apply -f prometheus-deploy.yaml
# kubectl get deployment prometheus-core -n monitoring
下载yaml
# git clone https://github.com/prometheus-operator/kube-prometheus.git
# cd ~/kube-prometheus/manifests/ 进入yaml模板目录
将service改为NodePort类型
grafana默认的服务使用Cluster IP,修改使用nodePort发布服务:
修改资源文件文件grafana-service.yaml,改服务类型位NodePort,指定端口号30091
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: grafana
app.kubernetes.io/name: grafana
app.kubernetes.io/part-of: kube-prometheus
app.kubernetes.io/version: 8.5.6
name: grafana
namespace: monitoring
spec:
type: NodePort
ports:
- name: http
port: 3000
targetPort: http
nodePort: 30091
selector:
app.kubernetes.io/component: grafana
app.kubernetes.io/name: grafana
app.kubernetes.io/part-of: kube-prometheus
或直接修改已运行的服务
# kubectl edit svc grafana -n monitoring -o yaml
编辑文件prometheus-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: prometheus
app.kubernetes.io/instance: k8s
app.kubernetes.io/name: prometheus
app.kubernetes.io/part-of: kube-prometheus
app.kubernetes.io/version: 2.36.1
name: prometheus-k8s
namespace: monitoring
spec:
type: NodePort
ports:
- name: web
port: 9090
targetPort: web
nodePort: 30400
- name: reloader-web
port: 8080
targetPort: reloader-web
nodePort: 30500
selector:
app.kubernetes.io/component: prometheus
app.kubernetes.io/instance: k8s
app.kubernetes.io/name: prometheus
app.kubernetes.io/part-of: kube-prometheus
sessionAffinity: ClientIP
编辑文件alertmanager-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: alert-router
app.kubernetes.io/instance: main
app.kubernetes.io/name: alertmanager
app.kubernetes.io/part-of: kube-prometheus
app.kubernetes.io/version: 0.24.0
name: alertmanager-main
namespace: monitoring
spec:
type: NodePort
ports:
- name: web
port: 9093
targetPort: web
nodePort: 30200
- name: reloader-web
port: 8080
targetPort: reloader-web
nodePort: 30300
selector:
app.kubernetes.io/component: alert-router
app.kubernetes.io/instance: main
app.kubernetes.io/name: alertmanager
app.kubernetes.io/part-of: kube-prometheus
sessionAffinity: ClientIP
创建资源
# kubectl create -f ~/kube-prometheus/manifests/setup/ #准备基本安装环境
# kubectl apply -f ~/kube-prometheus/manifests/
# kubectl get pod -n monitoring -w
注:创建时会下载很多镜像,有些镜像无法直接下载,需要通过其他方式下载后改名为清单中使用的镜像
docker pull selina5288/prometheus-adapter:v0.9.1
docker image tag selina5288/prometheus-adapter:v0.9.1 k8s.gcr.io/prometheus-adapter/prometheus-adapter:v0.9.1
docker rmi selina5288/prometheus-adapter:v0.9.1
---
docker pull bitnami/node-exporter:1.3.1
docker tag bitnami/node-exporter:1.3.1 quay.io/prometheus/node-exporter:v1.3.1
docker rmi bitnami/node-exporter:1.3.1
---
docker pull grafana/grafana
docker tag grafana/grafana:latest grafana/grafana:8.5.6
docker rmi grafana/grafana:latest
---
docker pull bitnami/kube-state-metrics:2.5.0
docker tag bitnami/kube-state-metrics:2.5.0 k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.5.0
docker rmi bitnami/kube-state-metrics:2.5.0
---
docker save -o kube-rbac-proxy.tar.gz quay.io/brancz/kube-rbac-proxy:v0.12.0
scp -r /root/kube-rbac-proxy.tar.gz root@192.168.6.21:/root/.
scp -r kube-rbac-proxy.tar.gz root@192.168.6.10:/root/
docker load -i kube-rbac-proxy.tar.gz
查看custom metrics api
# kubectl get apiservices -n monitoring | grep metrics
查看pod启动状态和服务
# kubectl get pod -n monitoring -owide
# kubectl get svc -n monitoring
资源收集:kube-state-metrics、node-exporter、prometheus-adapter
监控插件:alertmanager-main-xxxx
web展示插件:grafana
grafana模版和测试
ip:30200/#/status查看报警配置
ip:30400查看prometheus
ip:30091查看grafana模版
查看prometheus暴露的端口号
# kubectl get service -n monitoring | grep prometheus-k8s
prometheus 对应的 nodeport 端口为 30400,访问 http://MasterIP:30400,在status的targets菜单可看到所有节点状态,如果都是Up代表成功部署。
通过访问 http://MasterIP:30400/target 可以看到 prometheus 已经成功连接上了 k8s 的 apiserver。
查看服务发现
prometheus的WEB界面上提供了基本的查询K8S集群中每个POD的CPU使用情况,查询条件如下:
sum by (pod_name)( rate(container_cpu_usage_seconds_total{image!="", pod_name!=""}[1m] ) )
上述的查询有出现数据,说明 node-exporter 往 prometheus 中写入数据正常,接下来我们就可以部署grafana 组件,实现更友好的 webui 展示数据了。
# kubectl get service -n monitoring | grep grafana
如上可以看到grafana的端口号是30091,浏览器访问 http://MasterIP:30091用户名密码默认admin/admin
发现这里默认已经添加好了
点击最下面的test测试
参考文档:
Kubernetes上的“火眼金睛”——Prometheus的安装实录
http://blog.itpub.net/69954434/viewspace-2678108/
k8s安装prometheus+grafana(第二弹:prometheus-operator,安装redis、mysql等监控)
https://blog.csdn.net/u014756339/article/details/123074765