Prometheus1.6.0监控——部署篇
大家好,我是Linux运维工程师 Linke 。技术过硬,从不挖坑~这篇文档来记录一下我新部署的监控软件Prometheus吧~~记得刚刚上了 k8s 时,我还是用的老套筒式监控,当时不知道有prometheus这个东西,2017年的时候,prometheus大概还不为业内所用,所以不知道。。。好吧,这是我不知道的理由~当时pod状态、副本数等都是python写的监控插件,因为当时主监控服务...
大家好,我是Linux运维工程师 Linke 。技术过硬,从不挖坑~
这篇文档来记录一下我新部署的监控软件Prometheus ,grafana 和 alatermanager 放在下一篇文章中~~
记得刚刚上了 k8s 时,我还是用的老套筒式监控,当时不知道有prometheus这个东西,2017年的时候,prometheus大概还不为业内所用,所以不知道。。。好吧,这是我不知道的理由~
当时pod状态、副本数等都是python写的监控插件,因为当时主监控服务用的小米监控——open-falcon 。 open-falcon 总体还是不错的,用的也可以,我个人感觉比zabbix 、 nagios 强多了,但是监控 k8s 就有些吃力了,大部分监控都要自己再开发。我也就这么一直晃悠的用,维护起来很操蛋的。而且容器中跑java应用的话,jvm用小米的那套重量太大,所以干脆我就不监控 jvm 了,pod 因为 OOM 挂了我就加内存。直到有一天,有个应用不管怎么加都挂,于是就和同桌研究怎么监控 JVM ,然后他看到有人用 prometheus 监控 k8s ,而且能拿到 jvm ,然后我们就研究使用这个。上线后,k8s 各指标监控完美抓取,妈妈再也不用担心我的学习了。
下面开始进入部署环节,还是老样子,不扯原理,无非就是数据从哪里来,到哪里去,没啥好说的,用两把就都知道了。
不监控 k8s 的话,感觉还是 open-falcon 使的方便,因为我到现在还没时间看如何回调接口。也没找到。自定义监控倒是研究明白了,因为 prometheus没有端口监控,草不操蛋,然后我自己写了个,看这个文档:
https://blog.csdn.net/qq_31547771/article/details/103263288
本文介绍在 k8s 上部署 prometheus ,源码安装的俺也没试过。
前提先要有个 kubernates 集群,当然能撸到这篇文档的同行们我相信早已拥有了自己的 k8s 集群。没有也没关系,兄弟我提供一条龙服务,请看文档:
https://blog.csdn.net/qq_31547771/article/details/100699573
服务器划分
k8s集群角色 | ip | 调度 |
---|---|---|
master101 | 192.168.7.101 | 不跑业务应用 |
master102 | 192.168.7.102 | 不跑业务应用 |
master103 | 192.168.7.103 | 不跑业务应用 |
node104 | 192.168.7.104 | 调度 prometheus 到此节点,不跑其他应用 |
node105 | 192.168.7.105 | 跑其他业务应用 |
其余节点都如 node105 ,跑业务应用
另外本例中还加入了一组 es 的监控
192.168.7.41
192.168.7.42
192.168.7.43
k8s操作节点配置prometheus的yaml文件
我把用来操作 k8s 的系统叫做 k8s 操作节点,这里我用的是 192.168.7.101 ,生产环境不建议使用 master 节点做操作节点,建议单独弄一个系统,装了 kubelet ,使用 k8s 的秘钥文件连接 k8s 。
下面所有的文件都放在 /home/scripts/prometheus 路径下
先编辑第一个主要文件: configmap.yaml
这个文件是 prometheus 主服务要使用的,监控规则、监控分组等都写在这个文件中了。
如果闲报警规则和监控组写到一个文件太多,可以把 rules.yaml 文件移出去,加一个 rule_files: - “/etc/prometheus/prometheus.rules.yml” ,指定到一个文件。但要记得挂载进去。本例中,我是写到一起的、
cat > configmap.yaml << EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
namespace: monitor
data:
#被引用到/etc/prometheus/prometheus.yml
prometheus.yml: |
global:
#每15s采集一次数据和15s做一次告警检测
scrape_interval: 15s
evaluation_interval: 15s
#指定加载的告警规则文件
rule_files:
- /etc/prometheus/rules.yml
#将报警送至何地进行报警
alerting:
alertmanagers:
- static_configs:
- targets: ["192.168.7.107:9093"]
#指定prometheus要监控的目标
scrape_configs:
- job_name: 'k8s-node'
scrape_interval: 10s
static_configs:
- targets:
- '192.168.7.101:31672'
- '192.168.7.102:31672'
- '192.168.7.103:31672'
- '192.168.7.104:31672'
- '192.168.7.105:31672'
- job_name: 'es-node'
scrape_interval: 10s
static_configs:
- targets:
- '192.168.7.41:31672'
- '192.168.7.42:31672'
- '192.168.7.43:31672'
#自定义获取监控数据,每个 job_name 都是独立的,以下的语法难的一逼,可能只有老天爷知道
- job_name: 'tomcat-pods'
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape, __meta_kubernetes_service_annotation_prometheus_io_jvm_scrape]
regex: true;true
action: keep
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_app_metrics_patn]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__meta_kubernetes_pod_ip, __meta_kubernetes_service_annotation_prometheus_io_app_metrics_port]
action: replace
target_label: __address__
regex: (.+);(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: kubernetes_pod_name
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- source_labels: [__meta_kubernetes_pod_host_ip]
action: replace
target_label: kubernetes_host_ip
- 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
- job_name: 'kubernetes-nodes'
kubernetes_sd_configs:
- role: node
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:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- target_label: __address__
replacement: kubernetes.default.svc:443
- source_labels: [__meta_kubernetes_node_name]
regex: (.+)
target_label: __metrics_path__
replacement: /api/v1/nodes/${1}/proxy/metrics
- job_name: 'kubernetes-cadvisor'
kubernetes_sd_configs:
- role: node
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:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- target_label: __address__
replacement: kubernetes.default.svc:443
- source_labels: [__meta_kubernetes_node_name]
regex: (.+)
target_label: __metrics_path__
replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
- job_name: 'kubernetes-service-endpoints'
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (https?)
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
- action: labelmap
regex: __meta_kubernetes_service_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_service_name]
action: replace
target_label: kubernetes_name
- job_name: 'kubernetes-services'
kubernetes_sd_configs:
- role: service
metrics_path: /probe
params:
module: [http_2xx]
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe]
action: keep
regex: true
- source_labels: [__address__]
target_label: __param_target
- target_label: __address__
replacement: blackbox-exporter.example.com:9115
- source_labels: [__param_target]
target_label: instance
- action: labelmap
regex: __meta_kubernetes_service_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_service_name]
target_label: kubernetes_name
- job_name: 'kubernetes-ingresses'
kubernetes_sd_configs:
- role: ingress
relabel_configs:
- source_labels: [__meta_kubernetes_ingress_annotation_prometheus_io_probe]
action: keep
regex: true
- source_labels: [__meta_kubernetes_ingress_scheme,__address__,__meta_kubernetes_ingress_path]
regex: (.+);(.+);(.+)
replacement: ${1}://${2}${3}
target_label: __param_target
- target_label: __address__
replacement: blackbox-exporter.example.com:9115
- source_labels: [__param_target]
target_label: instance
- action: labelmap
regex: __meta_kubernetes_ingress_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_ingress_name]
target_label: kubernetes_name
- 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
# 监控规则文件,被引用到/etc/prometheus/rules.yml
rules.yml: |
groups:
- name: test-rule
rules:
############# k8s-Node监控 #############
- alert: k8s-node状态异常
expr: up{job="k8s-node"} != 1
for: 3m
labels:
severity: 非常严重
annotations:
summary: "k8s节点可能宕了"
description: "{{$labels.instance}}: Node节点状态异常"
- alert: k8s-node节点CPU使用率
expr: (1 - avg(irate(node_cpu_seconds_total{job="k8s-node",mode="idle"}[1m])) by (instance)) * 100 > 95
for: 3m
labels:
severity: 一般
annotations:
summary: "Node节点CPU使用率超过95%"
description: "{{$labels.instance}}: Node节点当前CPU使用率为: {{ $value }}"
- alert: k8s-node节点根磁盘使用率
expr: (node_filesystem_size_bytes{mountpoint="/",job="k8s-node"} - node_filesystem_avail_bytes{mountpoint="/",job="k8s-node"}) / node_filesystem_size_bytes{mountpoint="/",job="k8s-node"} * 100 > 70
for: 3m
labels:
team: k8s-node
annotations:
summary: "根磁盘使用率为: {{ $value }}"
description: "Node服务器[[ {{$labels.instance}} ]] 的 {{$labels.mountpoint}} 磁盘空间使用率超过70%,超过85%后pod将迁移,请尽快处理"
- alert: k8s-node节点内存使用率
expr: (node_memory_MemTotal_bytes{job="k8s-node"} - (node_memory_Buffers_bytes{job="k8s-node"} + node_memory_Cached_bytes{job="k8s-node"} + node_memory_MemFree_bytes{job="k8s-node"})) / node_memory_MemTotal_bytes{job="k8s-node"} * 100 > 95
for: 3m
labels:
team: k8s-node
annotations:
summary: "当前内存使用率超过95%"
description: "Node服务器[[ {{$labels.instance}} ]] 内存使用率为: {{ $value }}"
############# es-Node监控 #############
- alert: es-node状态异常
expr: up{job="es-node"} != 1
for: 3m
labels:
severity: 非常严重
annotations:
summary: "elasticsearch节点可能宕了"
description: "{{$labels.instance}}: elasticsearch节点状态异常"
- alert: es-node节点数据磁盘使用率
expr: (node_filesystem_size_bytes{mountpoint="/data",job="es-node"} - node_filesystem_avail_bytes{mountpoint="/data",job="es-node"}) / node_filesystem_size_bytes{mountpoint="/data",job="es-node"} * 100 > 70
for: 3m
labels:
severity: 严重
annotations:
summary: "/data 磁盘使用率为: {{ $value }}"
description: "Node服务器[[ {{$labels.instance}} ]] 的 {{$labels.mountpoint}} 磁盘空间使用率超过70%,超过85%后pod将迁移,请尽快处理"
EOF
我这么负责,这里要说一下某些没加注释的地方
- alert: 报警组
expr: 报警规则设置,这里的数据源在 prometheus 的 UI 界面都能搜索到,并且在 UI 界面都可以用语法取到想要的值,监控规则必须得在 UI 界面能一样运行取值,否则无法监控。例如 up{job=“es-node”} 直接在 UI 界面输入是可以拿到值的。
for:触发报警后等待时间
labels: 设置报警级别,此处还有别的功能,没研究
annotations: 报警信息的描述,这里可以从报警信息中过滤想要的内容,使报警内容更加易读
summary: 翻译一下,总结; 概括; 概要; 如我上面所写,你懂得。
description: 翻译一下,描述,描写,说明,你懂得。这两个随便怎么用都行。
建议报警规则按照各个类型分开,以服务种类划分,本人跟监控打了三年交道,我觉得越细越好、因为各种服务有各种自己的阈值,它可以让磁盘到 90% 再报警,但另一个80%就得报警,因此越细越好。跑题了。。。
rbac 文件
这个文件不得了,有了他,就可以连接到 k8s master ,获取到 k8s 的集群信息,即获得 k8s api ,这个文件不用改,直接拿去用。
cat > rbac-setup.yaml << EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus
rules:
- apiGroups: [""]
resources:
- nodes
- nodes/proxy
- services
- endpoints
- pods
verbs: ["get", "list", "watch"]
- apiGroups:
- extensions
resources:
- ingresses
verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
verbs: ["get"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus
namespace: monitor
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus
subjects:
- kind: ServiceAccount
name: prometheus
namespace: monitor
EOF
pod 的配置文件 prometheus-deploy.yaml
来吧,下面让我们一鼓作气创建完,然后是启动 pod 的配置文件 prometheus-deploy.yaml ,有两点需要注意:
1、修改一下数据目录的挂在点为自己的路径,宿主机此数据路径给 777 权限。
2、我给 prometheus 的 pod 加了调度方式,只能在有 prometheus 标签的节点上启动,即下面的这个配置
nodeSelector:
nodetype: prometheus
具体怎么做,请看这篇文档:
https://blog.csdn.net/qq_31547771/article/details/100742202
这个文件。。。能撸到此文的,相信对 k8s 的 yaml 文件已经相当熟悉了。不熟悉的话,Linke 在这儿有详解:
https://blog.csdn.net/qq_31547771/article/details/102526403
cat > prometheus-deploy.yaml << EOF
---
apiVersion: apps/v1beta2
kind: Deployment
metadata:
labels:
name: prometheus-deployment
name: prometheus
namespace: monitor
spec:
replicas: 1
selector:
matchLabels:
app: prometheus
template:
metadata:
labels:
app: prometheus
spec:
containers:
- image: prom/prometheus:v2.6.0
name: prometheus
command:
- "/bin/prometheus"
args:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/home/prometheus"
- "--storage.tsdb.retention=15d"
- "--web.enable-lifecycle"
ports:
- containerPort: 9090
protocol: TCP
volumeMounts:
- mountPath: "/home/prometheus"
name: data
- mountPath: "/etc/prometheus"
name: config-volume
- mountPath: "/etc/localtime"
readOnly: false
name: localtime
resources:
requests:
cpu: 500m
memory: 3180Mi
limits:
cpu: 1000m
memory: 4180Mi
serviceAccountName: prometheus
nodeSelector:
nodetype: prometheus
volumes:
- name: data
hostPath:
path: "/opt/prometheus/data"
- name: config-volume
configMap:
name: prometheus-config
- name: localtime
hostPath:
path: "/etc/localtime"
type: File
EOF
然后是对外(集群外部访问)用的 service 配置文件
prometheus-service.yaml ,即使用 nodeport 将端口映射到集群外,然后用浏览器访问。
cat > prometheus-service.yaml << EOF
---
kind: Service
apiVersion: v1
metadata:
labels:
app: prometheus
name: prometheus
namespace: monitor
spec:
type: NodePort
ports:
- port: 9090
targetPort: 9090
nodePort: 30003
selector:
app: prometheus
EOF
最后是创建 namespace 的配置文件 monitor_namespace.yaml
以上 service 和 pod 都规划到 monitor 命名空间中
cat > monitor_namespace.yaml << EOF
apiVersion: v1
kind: Namespace
metadata:
name: monitor
labels:
name: monitor
EOF
然后是。然后prometheus就启动了。。顺序, 先创建命名空间——> 创建 confimap ——> 创建 rbac ——> 启动 prometheus pod ——> 创建 prometheus service
kubectk create -f monitor_namespace.yaml
kubectk create -f configmap.yaml
kubectk create -f rbac-setup.yaml
kubectk create -f prometheus-deploy.yaml
kubectk create -f prometheus-service.yaml
kubectl get po -n monitor
一顿操作下去,查看prometheus pod 是否启动正常。然后浏览器输入 192.168.7.104:30003 ,就可以访问 prometheus 的 UI 界面了。在这里可以搜索关键字,如输入 pod ,会自动补充,但是下面还要启动一个 kube-state-metrics 才能抓到 pod 的数据。 因此,接的往下看。
下面这两个图是 我现在的,上面的 confimap.yaml 我把多余的都删了,否则太多。箭头指出来的,是这个文档例子中 confimap 会显示的
点击 Alerts ,就可以看到自己设置的报警规则,可以尝试触发一个报警,看看这页的状态。
现在已经有了cadvisor、heapster、metric-server,几乎容器运行的所有指标都能拿到,但是下面这种情况却无能为力抓不到, k8s 的 pod 数据,还需要启动一个从k8s中掏数据的组件,即 kube-state-metrics ,这个插件其实就是将 k8s api 中的 pod 数据取出来,然后处理成了 prometheus 监控数据的格式。
直接从 github 把这个项目下载下来:
https://github.com/kubernetes/kube-state-metrics
将一个版本的下载下来,如果有的数据抓不到,或者有问题,就换个版本。我这里用的是 kube-state-metrics:v1.3.1 ,去年装的,一直没时间升级。
将项目下载来了后,解压开 tar 包后,我们用 k8s 启动,所以只需要项目中的 kubernetes 目录和下面的所以 yaml 文件就可以了,然后将各个文件中的 namespace: 的值改成 monitor ,不改也可以 。然后挨个创建一下:
cd kubernetes
for i in *;do kubectk create -f $i ;done
kubectl get po -n monitor
等待一分钟,此时再刷新一下浏览器,然后在Graph 那一页搜索: pod ,会补出抓到的pod 数据。如图,我们选择 kube_pod_info
然后可以使用 prometheus 的语法将数据缩小范围,监控也是这个意思,自己多测几遍就懂了:
未完,请见下面两篇文章。
Prometheus监控之Grafana——部署篇
https://blog.csdn.net/qq_31547771/article/details/103433097
Prometheus监控之altermanager——部署篇
https://blog.csdn.net/qq_31547771/article/details/103433737
更多推荐
所有评论(0)