Kube Prometheus项目地址
https://github.com/coreos/kube-prometheus
项目的Helm安装包地址
https://github.com/helm/charts/blob/master/stable/prometheus-operator
Prometheus官网地址
https://prometheus.io/
Prometheus Operator项目地址
https://github.com/coreos/prometheus-operator/
一个部署样例
https://github.com/coreos/kube-prometheus/blob/master/examples/example-app/
Prometheus Operator是什么
Prometheus Operator是运行在Kubernetes之上的监控和告警工具。部署时不用创建和修改prometheus的配置文件,所有的操作通过创建prometheus自己的资源对象来实现。对于监控配置的修改可以做到实时生效。
Prometheus Operator的自定义资源(CustomResourceDefinitions CRD)
- Prometheus: 定义Prometheus监控系统的部署。
- ServiceMonitor:监控一组service。该service需要暴露监控数据,供prometheus收集。
- PodMonitor:监控一组pod。
- PrometheusRule:Prometheus的规则文件。包含告警规则。
- AlertManager:定义告警管理器的部署。
QuickStart
下载kube-prometheus项目。
git clone https://github.com/coreos/kube-prometheus.git
执行:
# Create the namespace and CRDs, and then wait for them to be availble before creating the remaining resources
kubectl create -f manifests/setup
# 下面命令为等待setup过程运行完毕
until kubectl get servicemonitors --all-namespaces ; do date; sleep 1; echo ""; done
kubectl create -f manifests/
移除Kube Prometheus
执行:
kubectl delete --ignore-not-found=true -f manifests/ -f manifests/setup
访问仪表盘
可以使用port forward方式访问仪表盘。
访问Prometheus
$ kubectl --namespace monitoring port-forward svc/prometheus-k8s 9090
访问Grafana
$ kubectl --namespace monitoring port-forward svc/grafana 3000
访问Alert Manager
$ kubectl --namespace monitoring port-forward svc/alertmanager-main 9093
这些服务的端口可以通过localhost访问到。
注意:如果需要通过其他地址访问,需要增加address参数。举例如下:
$ kubectl --namespace monitoring port-forward --address 0.0.0.0 svc/prometheus-k8s 9090
手动部署prometheus operator
上面步骤使用的是Kube Prometheus。该项目内置了一系列prometheus operator的资源对象配置,可以做到一键安装。
Prometheus operator也可以手工方式部署。
安装Prometheus Operator
- Git下载Prometheus Operator项目
git clone https://github.com/coreos/prometheus-operator.git
- 执行命令,创建prometheus-operator对象和相关CRD
kubectl apply -f bundle.yaml
- 启用prometheus资源对象的RBAC规则
创建ServiceAccount:
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus
创建ClusterRole:
apiVersion: rbac.authorization.k8s.io/v1beta1
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"]
创建ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus
subjects:
- kind: ServiceAccount
name: prometheus
namespace: default
- 创建prometheus资源对象
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: prometheus
spec:
serviceAccountName: prometheus
serviceMonitorSelector:
matchLabels:
team: frontend
podMonitorSelector:
matchLabels:
team: frontend
resources:
requests:
memory: 400Mi
enableAdminAPI: false
通过serviceMonitorSelector
和podMonitorSelector
决定哪些ServiceMonitor和PodMonitor生效。如果选择器为空({}
)意味着会选择所有的对象。
- 部署自己的应用。
下面举一个例子:
创建一个Deployment
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
这里假定我们的监控数据在8080端口暴露。
再创建一个service,即访问监控数据的service。
kind: Service
apiVersion: v1
metadata:
name: example-app
labels:
app: example-app
spec:
selector:
app: example-app
ports:
- name: web
port: 8080
- 创建ServiceMonitor
这一步我们需要Prometheus读取上一步创建的service暴露的监控数据。需要借助于ServiceMonitor完成。
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: example-app
labels:
team: frontend
spec:
selector:
matchLabels:
app: example-app
endpoints:
- port: web
注意:
- 这里的selector需要匹配上一步创建出来的service。
- endpoints的port只能配置为service中的命名端口,不能使用数字。
- 需要确保prometheus对象的
serviceMonitorSelector
和serviceMonitorNamespaceSelector
匹配这一步创建出的ServiceMonitor对象。
- 暴露prometheus端口
如果需要暴露prometheus端口可以在集群外访问,需要执行此步骤。
apiVersion: v1
kind: Service
metadata:
name: prometheus
spec:
type: NodePort
ports:
- name: web
nodePort: 30900
port: 9090
protocol: TCP
targetPort: web
selector:
prometheus: prometheus
这里使用创建了一个使用NodePort的Service。
Prometheus资源对象
Prometheus资源对象的作用相当于整个Prometheus的配置中心。
Prometheus资源对象描述文件如下:
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
creationTimestamp: "2020-02-12T04:38:38Z"
generation: 1
labels:
prometheus: k8s
name: k8s
namespace: monitoring
resourceVersion: "3745"
selfLink: /apis/monitoring.coreos.com/v1/namespaces/monitoring/prometheuses/k8s
uid: 3d66375e-b8fb-453b-bcd2-a9ef1fd75387
spec:
alerting:
alertmanagers:
- name: alertmanager-main
namespace: monitoring
port: web
baseImage: quay.io/prometheus/prometheus
nodeSelector:
kubernetes.io/os: linux
podMonitorNamespaceSelector: {}
podMonitorSelector: {}
replicas: 2
resources:
requests:
memory: 400Mi
ruleSelector:
matchLabels:
prometheus: k8s
role: alert-rules
securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 1000
serviceAccountName: prometheus-k8s
serviceMonitorNamespaceSelector: {}
serviceMonitorSelector: {}
version: v2.15.2
其中,限制监控范围的配置有如下四个:
- podMonitorNamespaceSelector:扫描哪个namespace下的PodMonitor,如果为空,则扫描所有的namespace。
- serviceMonitorNamespaceSelector:扫描哪个namespace下的ServiceMonitor,如果为空,则扫描所有的namespace。
- podMonitorSelector:通过selector配置扫描哪些PodMonitor。如果为空,则扫描所有PodMonitor。
- serviceMonitorSelector:通过selector配置扫描哪些ServiceMonitor。如果为空,则扫描所有ServiceMonitor。
除此之外还有一个ruleSelector
,只有匹配该selector的PrometheusRules才会被读取。因此我们如是用默认的prometheus配置,自己创建的PrometheusRules需要有如下两个标签:
prometheus: k8s
role: alert-rules
指定Prometheus的远程存储
生产环境Prometheus的监控数据需要落地到数据库中。
建议使用Influx数据库。它和Prometheus的兼容性最好。
安装InfluxDB
InfluxDB官网链接:https://www.influxdata.com/
下载安装并启动服务即可。
# 启动InfluxDB
systemctl start influxdb
# 进入InfluxDB
influx
创建一个名为prometheus
的数据库:
curl -XPOST http://localhost:8086/query --data-urlencode "q=CREATE DATABASE prometheus"
编译并运行Remote storage adapter
Prometheus使用Influx作为远程存储需要一个remote_storage_adapter
。remote_storage_adapter
可以支持Graphite, Influxdb和Opentsdb。其中Influxdb支持READ和WRITE模式。
源代码链接如下:https://github.com/prometheus/prometheus/tree/master/documentation/examples/remote_storage/remote_storage_adapter
使用Git clone源代码之后,执行go build
命令编译。
接下来运行Remote storage adapter
./remote_storage_adapter --influxdb-url=http://localhost:8086/ --influxdb.database=prometheus --influxdb.retention-policy=autogen
注意:这里Influxdb默认端口是8086,使用的数据库名为prometheus。
配置prometheus资源对象
涉及的配置项解释如下:
- remoteRead 获取数据的URL
- remoteWrite 写入数据的URL
修改prometheus资源对象的配置文件,增加:
spec:
remoteRead:
- url: "http://localhost:9201/read"
remoteWrite:
- url: "http://localhost:9201/write"
注意:9201端口是remote_storage_adapter
默认监听的端口。
PS:prometheus原生配置文件的配置方法如下:
# Remote write configuration (for Graphite, OpenTSDB, or InfluxDB).
remote_write:
- url: "http://localhost:9201/write"
# Remote read configuration (for InfluxDB only at the moment).
remote_read:
- url: "http://localhost:9201/read"
ServiceMonitor资源资源对象
配置Prometheus从一个Service读取监控信息。
首先配置一个service,用来指定监控信息暴露端口。
kind: Service
apiVersion: v1
metadata:
name: example-app
labels:
app: example-app
spec:
selector:
app: example-app
ports:
- name: web
port: 8080
监控信息从这个pod的8080端口暴露。
再创建一个ServiceMonitor:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: example-app
labels:
team: frontend
spec:
selector:
matchLabels:
app: example-app
endpoints:
- port: web
port这个地方必须使用命名端口。
PodMonitor
配置Prometheus从一个Pod读取监控信息。
注意:目前配置项作用尚未明确,这里给出部分配置项。
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: example-pod-monitor
namespace: default
labels:
app: example
spec:
podMetricsEndpoints:
selector:
podTargetLabels:
sampleLimit:
jobLabel:
PrometheusRule
用于配置告警规则。
示例如下:
kind: PrometheusRule
metadata:
labels:
prometheus: k8s
role: alert-rules
name: prometheus-k8s-rules
spec:
groups:
- name: k8s.rules
rules:
- alert: KubeletDown
annotations:
message: Kubelet has disappeared from Prometheus target discovery.
expr: |
absent(up{job="kubelet"} == 1)
for: 15m
labels:
severity: critical
和Ingress配合使用
除了使用NodePort暴露prometheus服务到集群外,我们还可以使用Ingress的方式暴露服务。
Ingress的配置如下所示:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: monitoring
annotations:
nginx.ingress.kubernetes.io/rewrite-target: "/$1"
spec:
rules:
- http:
paths:
- backend:
serviceName: prometheus
servicePort: 9090
path: /prometheus/(.*)
该Ingress将/prometheus/
映射为prometheus
这个service。此时可以通过http://hostname/prometheus/
访问到Prometheus server。但有个问题,页面的静态资源没法加载。
为了解决这个问题,接下来需要为Prometheus server添加一个context path的配置。
Prometheus对象有一个externalUrl
的配置项,它包含了context path的功能,需要配置为完整的对外暴露的URL。如下所示:
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: main
spec:
replicas: 2
version: v2.15.2
externalUrl: http://hostname/prometheus/
resources:
requests:
memory: 400Mi
更详细的使用方式可参考:
https://coreos.com/operators/prometheus/docs/latest/user-guides/exposing-prometheus-and-alertmanager.html
使用示例
https://github.com/coreos/kube-prometheus/blob/master/examples/example-app/
参考文档
https://github.com/coreos/prometheus-operator/blob/master/Documentation/user-guides/getting-started.md
https://coreos.com/operators/prometheus/docs/latest/user-guides/exposing-prometheus-and-alertmanager.html