为了能够动态服务发现,并自动加入prometheus的监控中,一般的方法有:
- 使用consul + consul-template 中service 或 kv
- confd + etcd ,由于k8s已经有etcd,使用confd读取etcd中你想要的服务;
- 自动读取k8s中的service, pod,container,node
下面以kubernetes为例子:
假设kubernetes中每个pod已经实现了metrics是接口,如果使用静态方式,每次在k8s中增加一个服务,手工增加监控,当服务多起来的,配置文件显得非常大,并每次增加后,需要reload一次prometheus,这样的方式不够方便。
kubernetes中的metrics service:
$ kubectl get svc |grep test-metrics
test1-test-metrics 10.254.94.58 <none> 5000/TCP 8d
...
一、prometheus 在kubernetes中,静态配置服务发现
- job_name: test1
static_configs:
- targets:
- test1-test-metrics:5000
...
二、prometheus 在kubernetes中,配置自动服务发现
1. prometheus server 配置(prometheus.yml) (使用helm安装prometheus自动已经带有这个配置):
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
regex: (.+):(?:\d+);(\d+)
replacement: ${1}:${2}
target_label: __address__
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: kubernetes_pod_name
2.1 创建测试容器
该容器定义了指标: request_count,当访问一次容器,该指标+1。
$ cat start.py
import prometheus_client
from prometheus_client import Counter
from prometheus_client.core import CollectorRegistry
from flask import Response, Flask
app = Flask(__name__)
requests_total = Counter("request_count", "Total request cout of the host")
@app.route("/metrics")
def requests_count():
requests_total.inc()
# requests_total.inc(2)
return Response(prometheus_client.generate_latest(requests_total),
mimetype="text/plain")
@app.route('/')
def index():
requests_total.inc()
return "Hello World"
if __name__ == "__main__":
app.run(host="0.0.0.0")
$ cat Dockerfile
FROM python
RUN apt-get update
#安装flask prometheus_client 库
RUN pip install flask prometheus_client
# Install source files
COPY /start.py /start.py
WORKDIR /
EXPOSE 5000
ENTRYPOINT []
CMD ["python", "start.py"]
打包测试容器,并上传到docker hub
docker build --tag koza/prometheus-metrics:latest .
docker push koza/prometheus-metrics:latest
2.2 在deployment加入以下 annotations 部分,就能让 Prometheus 自动发现此 Pod 并采集监控数据了:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: test-metrics
spec:
replicas: 1
template:
metadata:
labels:
app: echo
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "5000"
spec:
containers:
- name: test-metrices
image: koza/prometheus-metrics:latest
ports:
- containerPort: 5000
3. 在prometheus 的控制面板target标签看到该pod自动进入监控:
查看该Pod的指标: request_count
注意:
1. 在deployment加入 annotations 部分后,指标参数(request_count)会自动加上kubernetes的多个标签,如:app="echo",instance="$POD_IPADDRESS"等等。这些标签非常用,如果deployment有多个副本,你可以根据这些标签区分这些指标是属于哪个POD的,这样就可以在grafana的图表中叠加这些指标得到一个汇总。
2. 最好不要从service中获取指标,如果deployment有多个副本,service会随机从后端的副本获取指标,造成指标数据不完整以及没法区分这些指标是哪个pod的以及不能汇总多个副本的指标。
参考:
自动检测k8s中的pod,并加入监控 :https://xizhibei.github.io/2017/08/19/deploy-prometheus-in-k8s/
annotation 使用方法:https://jimmysong.io/kubernetes-handbook/concepts/annotation.html
prometheus中文文档:https://github.com/yunlzheng/prometheus-book
https://github.com/xizhibei/blog/issues/55
prometheus metric types 参考:
https://prometheus.io/docs/concepts/metric_types/
https://github.com/prometheus/client_python