1. 服务发现简介
prometheus采用pull方式拉取指定目标实例的监控数据,也就是间隔固定的周期去目标实例上抓取metrics数据,每一个被抓取的目标实例都需要暴露一个数据指标API接口,prometheus通过这个暴露的接口就可以获取到其指标数据.
这种方式需要由目标服务决定采集的指标有哪些,prometheus通过配置在scrape_configs中指定目标节点,static_configs(静态配置)无法动态感知新的节点,即如果后面增加了节点或者删除节点,就得手动修promrtheus的配置文件,并重启promethues,因此后期维护很不方便,所以出现了很多不同类型的service discovery即动态服务发现机制.
动态服务发现能够使prometheus自动发现集群中的新目标,并对其进行数据采集,通过服务发现机制使Prometheus能自动获取到需要监控的Target列表,然后轮询这些Target获取监控数据。
2. 服务发现基础以及relabel基础
2.1 Prometheus常用的服务发现类型
官方文档:https://prometheus.io/docs/prometheus/latest/configuration/configuration/
2.1.1 static_configs
静态服务发现,基于prometheus配置文件指定的监控目标。
该方式有很大的缺点,一但监控目标过多,就需要频繁的配置Prometheus和重启(或热更新)。
2.1.2 kubernetes_sd_configs
基于Kubernetes API实现的服务发现(每隔一段时间就去k8s api-server获取监控数据),让prometheus动态发现kubernetes中被监控的新目标。
2.1.3 dns_sd_configs
DNS 服务发现。通过指定的域名去获取监控数据,
2.1.4 consul_sd_configs
Consul 服务发现,基于consul服务动态发现监控目标。
就是把服务注册到Consul中,然后让Prometheus去Consul中获取监控数据。
2.1.5 file_sd_configs
基于指定的文件实现服务发现,基于指定的文件发现监控目标。
有些场景下,不好配置服务发现,但是又想使用Prometheus的动态服务发现功能,那就可以使用文件服务发现,把需要监控的服务写入到文件中,然后由Prometheus读取该文件获取监控数据。
2.2 K8s动态发现类型与流程
2.2.1 动态发现类型
(1)node # node节点
(2)service # 发现svc
(3)pod # 发现pod
(4)endpoints # 基于svc发现endpoints(pod)
(5)Endpointslice # 对endpoint进行切片
(6)ingress # 发现ingress
2.2 发现流程
(1)首先是配置对应的服务发现,然后Prometheus server向k8s api server发起请求,该请求是周期性的,默认15s,该时间不能太长也不能太短,太短了会给apiserver造成很大的压力,具体调整根据集群规模来,并且如果规模较大,最好是根据namespace来做服务发现。
(2)Prometheus收集到数据后,会先进行一些指标数据的过滤、筛选、替换,然后存到存储中。
(3)如果有告警信息,还会推送对应的告警数据到alertmanager,然后alertmanager根据配置的告警通知规则来发送告警通知。
(4)同时,这个时候也能在grafana上进行对应的数据展示。
2.3 Prometheus服务发现-relabe
默认元数据标签官网介绍:https://www.prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config
2.3.1 基本介绍
在Prometheus拉取数据的这个过程中,可能有很多数据是我们不想要的或者需要修改的,那怎么办呢?
Prometheus提供了一个叫relabeling的功能,promethues的relabeling(重新修改标签)功能很强大,它能够在抓取到目标实例之前把目标实例的元数据标签动态重新修改,动态添加或者覆盖标签。
prometheus从Kubernetes API动态发现目标(targer)之后,在被发现的target实例中,都包含一些原始的Metadata标签信息,默认的标签有如下几种(pod、server、ep等都有很多默认的标签,这里就不一一介绍了,可以去官网看):
- __address__:以<host>:<port> 格式显示目标targets的地址。
- __scheme__:采集的目标服务地址的Scheme形式,HTTP或者HTTPS。
- __metrics_path__:采集的目标服务的访问路径。
2.3.2 relabe的两个阶段
为了更好的识别监控指标,便于后期调用数据绘图、告警等需求,prometheus支持对发现后的目标进行label修改,在两个阶段可以重新标记:
(1)relabel_configs
在对target进行数据采集之前(比如在采集数据之前重新定义标签信息,如目的IP、目的端口等信息),可以使用relabel_configs添加、修改或删除一些标签、也可以只采集特定目标或过滤目标。
这种方式也是用的最多的。
(2)metric_relabel_configs
在对target进行数据采集之后,即如果是已经抓取到指标数据时,可以使用metric_relabel_configs做最后的重新标记和过滤。
2.3.3 label类型
- source_labels:源标签,没有经过relabel处理之前的标签名字
- target_label:通过action处理之后的新的标签名字
- regex:给定的值或正则表达式匹配,匹配源标签的值
- replacement:通过分组替换后标签(target_label)对应的/()/() $1:$2,就是引用regex中的分组信息
2.3.3.1 relabel_configs实际运用介绍
scrape_configs: # 监控配置
- job_name: 'kubernetes-node' # 监控名称
kubernetes_sd_configs: # k8s服务发现
- role: node # 指定发现类型。k8s node服务发现
relabel_configs: # 做好服务发现之后,但在数据抓取之前,立即对元数据标签做相关处理。
- source_labels: [__address__] # 匹配原标签
regex: '(.*):10250' # 原标签中的端口
replacement: '${1}:9100' # 把10250替换成9100,ip地址还是用原来的
target_label: __address__ # 要修改的目的标签。将修改后的数据存储到__address__标签中
action: replace # 当 action 设置为 replace 时,Prometheus 会根据 source_labels 和 regex 字段指定的匹配规则,在源标签的基础上进行替换,并将结果存储到目标标签中
- action: labelmap # 创建标签映射,将匹配的标签转换为新的标签
regex: __meta_kubernetes_node_label_(.+) # 匹配以__meta_kubernetes_node_label_ 开头的标签,然后用(.+)中的值生成一个新的标签,但是值和原标签相同
2.4 配置示例
2.4.1 静态配置
- job_name: "prometheus-node"
static_configs:
- targets: ["172.31.2.181:9100","172.31.2.182:9100"]
2.4.2 k8s动态服务发现配置
- job_name: 'kubernetes-apiserver'
kubernetes_sd_configs: # k8s服务发现
- role: endpoints # 服务发现类型
scheme: https # 使用的协议
tls_config: # 证书配置
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt # 容器中的证书路径。api-server发给kubelet,然后kubelet注入到容器中
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token # 这个也是容器中的。这个就是我们之前创建的sa,不然Prometheus没有权限访问api-server
relabel_configs: # 重新修改标签配置
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] # 原标签,就是要操作的标签
action: keep # keep,保留指定的标签,而过滤掉其他标签。
regex: default;kubernetes;https # 指定匹配条件,只发现default名称空间下,kubernetes svc后面的endpoint,并且是port name是https的。
regex这里是和source_labels对应的,__meta_kubernetes_namespace对应default,以此类推。
2.5 action类型
2.5.1 replace
2.5.1.1 replace介绍
将regx正则表达式与连接的 source_labels 进行匹配。然后,将 target_label 设置为 replacement,其中 replacement 中的匹配组引用( 1 、 {1}、 1、{2} 等)将被其值替换。如果正则表达式不匹配,则不进行替换。
2.5.1.2 replace示例
假设我们有以下的 relabel 配置:
- action: replace
source_labels: [instance]
regex: "(.*)-(\d+)"
target_label: instance
replacement: "$1"
在这个示例中,我们使用 replace 操作,并指定 source_labels 为 [instance],regex 为 (.*)-(\d+),target_label 为 instance,replacement 为 $1。这将使用正则表达式匹配 instance 标签的值,并将匹配结果中的第一个捕获组替换为 replacement 的值。
假设我们有以下的指标样本:
metric_name{instance="server1-1"} 42.0
metric_name{instance="server2-2"} 57.0
metric_name{instance="server3-3"} 68.0
应用以上的 relabel 配置后,我们将得到:
metric_name{instance="server1"} 42.0
metric_name{instance="server2"} 57.0
metric_name{instance="server3"} 68.0
可以看到,instance 标签的值被匹配并替换。通过使用捕获组和替换字符串,我们可以根据匹配结果对标签值进行修改、提取或重构。
在正则表达式中,(\d+) 表示一个匹配数字的模式。
\d:表示匹配任意一个数字字符(0-9)。
+:表示匹配前面的模式(这里是 \d)一次或多次。
2.5.2 keep
2.5.2.1 keep介绍
删除regex与连接的source_labels不匹配的目标。
2.5.2.2 keep示例
假设我们有以下的 relabel 配置:
- action: keep
source_labels: [status]
regex: "success"
在这个示例中,我们使用 keep 操作,并指定 source_labels 为 [status],regex 为 "success"。这将保留与正则表达式匹配的目标,并删除与正则表达式不匹配的目标。
假设我们有以下的指标样本:
metric_name{status="success"} 42.0
metric_name{status="failure"} 57.0
metric_name{status="success"} 68.0
应用以上的 relabel 配置后,我们将得到:
metric_name{status="success"} 42.0
metric_name{status="success"} 68.0
可以看到,只有与正则表达式 "success" 匹配的目标样本被保留下来,而与正则表达式不匹配的目标样本被删除了。
2.5.3 drop
2.5.3.1 drop介绍
删除regex与连接的source_labels匹配的目标。
2.5.3.2 drop示例
假设我们有以下的 relabel 配置:
- action: drop
source_labels: [status]
regex: "failure"
在这个示例中,我们使用 drop 操作,并指定 source_labels 为 [status],regex 为 "failure"。这将删除与正则表达式匹配的目标。
假设我们有以下的指标样本:
metric_name{status="success"} 42.0
metric_name{status="failure"} 57.0
metric_name{status="success"} 68.0
应用以上的 relabel 配置后,我们将得到:
metric_name{status="success"} 42.0
metric_name{status="success"} 68.0
可以看到,与正则表达式 "failure" 匹配的目标样本被删除了。
2.5.4 labelmap
2.5.4.1 labelmap介绍
对所有源标签名匹配regex,而不仅仅是source_labels中指定的那些。然后将匹配标签的值复制到标签名称中,替换为匹配组引用( 1 , {1}, 1,{2},…),替换为它们的值。
2.5.4.2 labelmap示例
假设我们有以下的 relabel 配置:
- action: labelmap
regex: "(.*)_value"
在这个示例中,我们使用 labelmap 操作,并指定 regex 为 (.*)_value。这将根据正则表达式匹配规则,从标签名中提取出指定的部分,然后将提取的部分作为新的标签名。
假设我们有以下的指标样本:
metric_name{temperature_value="25"} 42.0
metric_name{humidity_value="60"} 57.0
metric_name{pressure_value="1013"} 68.0
应用以上的 relabel 配置后,我们将得到:
metric_name{temperature="25"} 42.0
metric_name{humidity="60"} 57.0
metric_name{pressure="1013"} 68.0
可以看到,根据正则表达式的匹配规则,_value 部分被移除,并将提取的部分作为新的标签名。
2.5.5 labelkeep
2.5.5.1 labelkeep介绍
对所有标签名称匹配regex。任何不匹配的标签都将从标签集中删除。
2.5.5.2 labelkeep示例
假设有以下relabel 配置:
- action: labelkeep
regex: "^(app|env|version)$"
在这个示例中,我们使用 labelkeep 操作,并指定正则表达式 ^(app|env|version)$。
该正则表达式将与所有标签名称进行匹配,只有与 "app"、"env" 或 "version" 匹配的标签将被保留。
假设我们有以下的指标样本:
metric_name{app="myapp", env="production", version="1.2.3", region="us-west"} 42.0
应用以上的 relabel 配置后,我们将得到:
metric_name{app="myapp", env="production", version="1.2.3"} 42.0
可以看到,只有与正则表达式匹配的标签 "app"、"env" 和 "version" 被保留下来,而不匹配正则表达式的标签 "region" 被删除了。
2.5.6 labeldrop
2.5.6.1 labeldrop介绍
对所有标签名称匹配regex。任何匹配的标签都将从标签集中删除。
2.5.6.2 labeldrop示例
假设我们有以下的 relabel 配置:
- action: labeldrop
regex: "^(app|env|version)$"
在这个示例中,我们使用 labeldrop 操作,并指定正则表达式 ^(app|env|version)$。
该正则表达式将与所有标签名称进行匹配,任何匹配的标签都将从标签集合中删除。
假设我们有以下的指标样本:
metric_name{app="myapp", env="production", version="1.2.3", region="us-west"} 42.0
应用以上的 relabel 配置后,我们将得到:
metric_name{region="us-west"} 42.0
可以看到,与正则表达式匹配的标签 "app"、"env" 和 "version" 被从标签集合中删除,而不匹配正则表达式的标签 "region" 被保留了。
2.5.7 hashmod
2.5.7.1 hashmod介绍
将target_label设置为连接的source_labels的哈希值的模数。
2.5.7.2 hashmod示例
假设我们有以下的 relabel 配置:
- action: hashmod
modulus: 10
source_labels: [instance]
target_label: shard
在这个示例中,我们使用 hashmod 操作,并指定 modulus 为 10,source_labels 为 [instance],target_label 为 shard。这将对 instance 标签的值进行哈希运算,并将哈希值对 10 取模,然后将结果存储到 shard 标签中。
假设我们有以下的指标样本:
metric_name{instance="server1"} 42.0
metric_name{instance="server2"} 57.0
metric_name{instance="server3"} 68.0
应用以上的 relabel 配置后,我们将得到:
metric_name{instance="server1", shard="1"} 42.0
metric_name{instance="server2", shard="2"} 57.0
metric_name{instance="server3", shard="3"} 68.0
可以看到,对于每个样本,instance 标签的值被哈希运算,并且哈希结果对 10 取模后存储到了 shard 标签中。这样,我们可以将指标样本分散到 10 个不同的分片中,以实现负载均衡或其他分片策略。
2.5.8 lowercase
2.5.8.1 lowercase介绍
将连接的source_labels映射为它们的小写。
2.5.8.2 lowercase示例
假设我们有以下的 relabel 配置:
- action: lowercase
source_labels: [environment]
在这个示例中,我们使用 lowercase 操作,并指定 source_labels 为 [environment]。这将将 environment 标签的值转换为小写字母。
假设我们有以下的指标样本:
metric_name{environment="Production"} 42.0
metric_name{environment="Staging"} 57.0
metric_name{environment="Development"} 68.0
应用以上的 relabel 配置后,我们将得到:
metric_name{environment="production"} 42.0
metric_name{environment="staging"} 57.0
metric_name{environment="development"} 68.0
可以看到,environment 标签的值被转换为小写字母。这样,我们可以统一标签的大小写形式,以便在查询、筛选和聚合指标时更加灵活和一致。
2.5.9 uppercase
2.5.9.1 uppercase介绍
将连接的source_labels映射为它们的大写。
2.5.10 keepequal
2.5.10.1 keepequal介绍
官网释义:删除source_labels与target_label不匹配的目标。
2.5.10.2 keepequal示例
假设我们有以下的 relabel 配置:
- action: keepequal
source_labels: [status]
target_label: status
在这个示例中,我们使用 keepequal 操作,并指定 source_labels 为 [status],target_label 为 status。这将保留与 target_label 相匹配的目标,并删除与 target_label 不匹配的目标。
假设我们有以下的指标样本:
metric_name{status="success"} 42.0
metric_name{status="failure"} 57.0
metric_name{status="success"} 68.0
应用以上的 relabel 配置后,我们将得到:
metric_name{status="success"} 42.0
metric_name{status="success"} 68.0
可以看到,只有与 target_label 相匹配的目标样本被保留下来,而与 target_label 不匹配的目标样本被删除了。
2.5.11 dropequal
2.5.11.1 dropequal介绍
删除连接的source_labels与target_label匹配的目标。
2.6 Prometheus内置的容器证书
[root@k8s-master1 monitor]# kubectl exec -it -n monitoring prometheus-server-65688779d8-7j65t -- /bin/bash
I have no name!@prometheus-server-65688779d8-7j65t:/opt/bitnami/prometheus$ ls -l /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
lrwxrwxrwx 1 root root 13 Feb 27 10:38 /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -> ..data/ca.crt
I have no name!@prometheus-server-65688779d8-7j65t:/opt/bitnami/prometheus$ ls -l /var/run/secrets/kubernetes.io/serviceaccount/token
lrwxrwxrwx 1 root root 12 Feb 27 10:38 /var/run/secrets/kubernetes.io/serviceaccount/token -> ..data/token
# 这个证书其实和master节点上的ca证书是同一个,因为当时给sa授权,就是给的cluster-admin权限。
I have no name!@prometheus-server-65688779d8-7j65t:/opt/bitnami/prometheus$ md5sum /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
ee51e88de99ee542c1efd61a3f0bb8d0 /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
I have no name!@prometheus-server-65688779d8-7j65t:/opt/bitnami/prometheus$ exit
[root@k8s-master1 monitor]# md5sum /etc/kubernetes/pki/ca.crt
ee51e88de99ee542c1efd61a3f0bb8d0 /etc/kubernetes/pki/ca.crt
Prometheus就是通过这个公钥证书和api-server进行加密通信的。
2.7 元数据标签查看方式
2.7.1 官网
不同的服务发现方式,都有不同的元数据标签,可以去官网看。
官方文档:https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config
2.7.2 Prometheus web页面查看
低版本的Prometheus可能没有这个下拉箭头,就直接把鼠标移到标签上就能显示
3. 基于api-server、node、pod等实现服务发现
3.1 api-server服务发现
apiserver作为Kubernetes最核心的组件,它的监控也是非常有必要的,对于apiserver的监控,我们可以直接通过kubernetes的service来获取。
公有云托管的K8S集群一般不需要自己监控k8s的几个核心组件,因为没有对外暴露地址,你也看不到。
3.1.1 配置展示
具体的含义就不解释了,上面已经说过了
- job_name: 'kubernetes-apiserver'
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
最终,匹配到api-server的地址,也就是注册到svc中的endpoint。
[root@k8s-master1 prometheus]# kubectl get svc,ep kubernetes
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.200.0.1 <none> 443/TCP 29d
NAME ENDPOINTS AGE
endpoints/kubernetes 10.31.200.100:6443 29d
3.1.2 api-server的主要指标数据
Apiserver组件是k8s集群的入口,所有请求都是从apiserver进来的,所以对apiserver指标做监控可以用来判断集群的健康状况。
以下promQL语句为查询apiserver最近1小时不同方法的请求数量统计,apiserver_request_total为请求各个服务的访问详细统计:
sum(rate(apiserver_request_total[1m])) by (resource,subresource,verb)
3.2 annotation(注解,通过svc完成pod自动发现)
推荐在svc中添加注解的方式来自动发现pod
关于annotation_prometheus_io_scrape及kubernetes_service_annotation_prometheus_io_port:
在k8s中,如果deployment的yaml文件指定了annotation_prometheus_io_scrape(是否允许指标抓取)及kubernetes_service_annotation_prometheus_io_port(抓取的端口),那么基于prometheus的发现规则,需要在被发现的目的target定义注解,匹配annotation_prometheus_io_scrape的值为true和kubernetes_service_annotation_prometheus_io_port对应的端口号如9153,且必须匹配成功该注解才会保留监控target,然后再进行数据抓取并进行标签替换,主要用于精确匹配目的target(过滤掉不匹配的其它target),也就是没写注解的svc,直接被过滤掉。
3.2.1 pod自动发现
这里以coredns为例
3.2.1.1 svc自动发现注解(pod自动发现)
3.2.1.2 Prometheus配置
- job_name: 'kubernetes-service-endpoints' # 监控任务名称
kubernetes_sd_configs: # k8s服务发现
- role: endpoints # 发现类型endpoint
relabel_configs: # 标签重写
# 要过滤的原标签
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
# 删除与原标签不匹配的目标
action: keep
# 使用正则表达式要匹配的标签值
regex: true
# 上述配置含义:匹配原标签__meta_kubernetes_service_annotation_prometheus_io_scrape=true,其他的全部排除。继续向下执行。
# 到这一步,基本上没有配置注解的svc,都会被排除在外不被监控,这也就是为什么在Prometheus监控上只能看到两个endpoint的原因,因为只有coredns加了注解。
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (https?)
# 上述配置含义:正则匹配原标签__meta_kubernetes_service_annotation_prometheus_io_scheme=http或https,然后修改__scheme__=http或https。
# regex: (https?),这是两部分,http和s,?表示匹配前一个字符0次或一次。
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+) # 匹配任意非空字符串。.:表示匹配除换行符外的任意字符。+:表示匹配前面的元素(即 .)一次或多次。
# 上述配置含义:正则匹配原标签_meta_kubernetes_service_annotation_prometheus_io_path=任意非空字符串,然后替换__metrics_path__原来的值为任意非空字符串。
# 这种替换就相当于目标标签值=原标签值
- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
# 上述配置含义:正则匹配原标签值,([^:]+):匹配除了:的任意字符一次或多次。(?::\d+):?:,匹配一个:0次或1次。:\d+匹配:数字一次多次。?;:匹配;0次或1次。(\d+):匹配数字一次或多次。
# 然后后向引用([^:]+)(?::\d+),并赋值给__address__,也就是__address__=([^:]+)(?::\d+),就是地址:端口
- action: labelmap
regex: __meta_kubernetes_service_label_(.+)
# 上述配置含义:正则处理去掉__meta_kubernetes_service_label_,保留(.+)作为标签的名称。
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: kubernetes_namespace
# 上述配置含义:target_label=source_labels
- source_labels: [__meta_kubernetes_service_name]
action: replace
target_label: kubernetes_service_name
# 上述配置含义:target_label=source_labels
3.3 node自动发现
3.3.1 自动发现配置
该方式非常适合监控dameset部署的服务
- job_name: 'kubernetes-node' # 监控名称
kubernetes_sd_configs: # k8s服务发现
- role: node # 发现类型
relabel_configs: # 标签重写
- source_labels: [__address__]
regex: '(.*):10250'
replacement: '${1}:9100'
target_label: __address__
action: replace
# 上述配置含义:把原标签=(.*):10250,修改为目标标签__address__=原标签IP:9100
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
# 上述配置含义:去掉__meta_kubernetes_node_label_部分,保留(.+)部分
3.4 pod自动发现(不依赖svc)
3.4.1 Nginx自动发现配置
插件地址:https://github.com/sysulq/nginx-vts-exporter
[root@k8s-master1 yaml]# cat nginx.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
app: nginx-deployment-label
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx-selector
template:
metadata:
labels:
app: nginx-selector
annotations: # 注意这里添加自动发现的注解
prometheus.io/port: "9913"
prometheus.io/scrape: "true"
spec:
containers:
- name: nginx-container
image: gaciaga/nginx-vts:1.11.12-alpine-vts-0.1.14
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
protocol: TCP
name: http
- containerPort: 443
protocol: TCP
name: https
env:
- name: "password"
value: "123456"
- name: "age"
value: "20"
- name: nginx-exporter-container # 注意这里集成了一个vts-export容器,用于暴露nginx指标数据
image: sophos/nginx-vts-exporter
args:
- '-nginx.scrape-uri=http://127.0.0.1/status/format/json'
ports:
- containerPort: 9913
---
kind: Service
apiVersion: v1
metadata:
labels:
app: nginx-service-label
name: nginx-service
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
nodePort: 30092
- name: https
port: 443
protocol: TCP
targetPort: 443
nodePort: 30093
selector:
app: nginx-selector
[root@k8s-master1 yaml]# kubectl apply -f nginx.yaml
[root@k8s-master1 yaml]# kubectl get po,svc |grep nginx
pod/nginx-deployment-678cd68c88-n5zsn 2/2 Running 0 71m
service/nginx-service NodePort 10.200.241.90 <none> 80:30092/TCP,443:30093/TCP 71m
3.4.2 指标查看
[root@k8s-master1 yaml]# kubectl get po -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-678cd68c88-n5zsn 2/2 Running 0 95m 10.100.2.13 k8s-node2 <none> <none>
[root@k8s-master1 yaml]# curl 10.100.2.13:9913/metrics
# HELP nginx_server_bytes request/response bytes
# TYPE nginx_server_bytes counter
nginx_server_bytes{direction="in",host="*"} 108
nginx_server_bytes{direction="in",host="localhost"} 108
nginx_server_bytes{direction="out",host="*"} 970
nginx_server_bytes{direction="out",host="localhost"} 970
……省略部分内容
3.4.3 配置nginx pod服务发现
3.4.3.1 编辑yaml并应用
[root@k8s-master1 prometheus]# cat cm.yaml
---
kind: ConfigMap
apiVersion: v1
metadata:
labels:
app: prometheus
name: prometheus-config
namespace: monitoring
data:
prometheus.yml: |
global:
scrape_interval: 15s
scrape_timeout: 10s
evaluation_interval: 1m
scrape_configs:
……省略部分内容
- job_name: "k8s-nginx-pods" # 添加监控目标
kubernetes_sd_configs:
- role: pod
namespaces:
names:
- default
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (https?)
- source_labels: [__address__,__meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: k8s_namespace
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: k8s_pod_name
[root@k8s-master1 prometheus]# kubectl apply -f cm.yaml
[root@k8s-master1 prometheus]# kubectl delete po -n monitoring prometheus-server-65688779d8-mvdrx
3.4.3.2 查看监控结果
4. 基于consul、file、dns实现服务发现
4.1 服务发现案例-consul
4.1.1 docker-compose部署consul
[root@k8s-master1 ~]# mkdir consul
[root@k8s-master1 ~]# cd consul
[root@k8s-master1 consul]# cat docker-compose.yaml
version: "3"
services:
consul:
image: consul:latest
container_name: consul-server
#restart: always
#command: agent
command: agent -server -bootstrap -node=node1 -ui -bind=0.0.0.0 -client=0.0.0.0 -datacenter=dc1
ports:
- 8500:8500
volumes:
- /data/consul:/consul/data
- /data/consul/log:/consul/log
[root@k8s-master1 consul]# docker-compose up -d
Starting consul-server ... done
[root@k8s-master1 consul]# docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
consul-server docker-entrypoint.sh agent ... Up 8300/tcp, 8301/tcp, 8301/udp, 8302/tcp, 8302/udp, 0.0.0.0:8500->8500/tcp,:::8500->8500/tcp, 8600/tcp,
8600/udp
4.1.2 访问测试
4.1.3 添加Prometheus监控项
[root@k8s-master1 prometheus]# cat cm.yaml
……省略部分内容
- job_name: "consul"
honor_labels: true # 保留原标签
metrics_path: /metrics
scheme: http
consul_sd_configs:
- server: 10.31.200.100:8500
services: [] # 为空表示所有服务
relabel_configs:
- source_labels: ['__meta_consul_tags']
target_label: 'product'
- source_labels: ['__meta_consul_dc']
target_label: 'idc'
- source_labels: ['__meta_consul_service']
regex: 'consul'
action: drop # 删除是因为consul本身是没有mertics接口的
[root@k8s-master1 prometheus]# kubectl apply -f cm.yaml
[root@k8s-master1 prometheus]# kubectl get po -A |grep promet
monitoring prometheus-server-65688779d8-cppjx 1/1 Running 0 111m
[root@k8s-master1 prometheus]# kubectl delete po -n monitoring prometheus-server-65688779d8-cppjx
pod "prometheus-server-65688779d8-cppjx" deleted
[root@k8s-master1 prometheus]# kubectl get po -A |grep promet
monitoring prometheus-server-65688779d8-l2lp8 1/1 Running 0 3s
4.1.4 向consul写写入数据
4.2 服务发现案例-文件
4.2.1 编辑服务发现文件
支持yaml或json格式
[root@k8s-master1 file_sd]# pwd
/data/k8s_data/file_sd
[root@k8s-master1 file_sd]# cat file_sd.yaml
- targets:
- '10.31.200.100:9100'
- '10.31.200.101:9100'
- '10.31.200.102:9100'
labels:
environment: node_export
4.2.2 配置Prometheus
4.2.2.1 配置服务发现
[root@k8s-master1 file_sd]# cat /root/yaml/monitor/prometheus/cm.yaml
……省略部分输出
- job_name: "file_sd"
file_sd_configs:
- files:
- /apps/prometheus/file_sd.yaml # 注意这里是pod内的路径
refresh_interval: 10s
[root@k8s-master1 file_sd]# kubectl apply -f /root/yaml/monitor/prometheus/cm.yaml
4.2.2.2 挂载服务发现文件到pod中
[root@k8s-master1 file_sd]# cat /root/yaml/monitor/prometheus/deploy.yaml
……省略部分内容
volumeMounts:
- mountPath: /etc/prometheus/prometheus.yml
name: prometheus-config
subPath: prometheus.yml
- mountPath: /prometheus/
name: prometheus-storage-volume
- mountPath: /apps/prometheus/ # 添加挂载路径
name: file-sd
volumes:
- name: prometheus-config
configMap:
name: prometheus-config
items:
- key: prometheus.yml
path: prometheus.yml
mode: 0644
- name: file-sd # 挂载文件服务发现配置文件到pod中
nfs:
server: 10.31.200.100
path: /data/k8s_data/file_sd
- name: prometheus-storage-volume
nfs:
server: 10.31.200.100
path: /data/k8s_data/prometheus
[root@k8s-master1 file_sd]# cd ..
[root@k8s-master1 k8s_data]# chown -R nfsnobody. file_sd # 授权,免得Prometheus没有权限读取
[root@k8s-master1 k8s_data]# kubectl apply -f /root/yaml/monitor/prometheus/deploy.yaml
4.2.3 查看web页面
4.3 服务发现案例-DNS
这个用的不多,略
5. 监控案例
5.1 案例一:监控jvm和tocmat
5.1.1 简介
可以使用tocmat_exporter来监控java服务,官网:https://github.com/nlighten/tomcat_exporter。
如监控ava服务的活跃连接数:
tomcat_connections_active_total{name="http-nio-8080" ,} 2.0
如监控java服务的堆栈内存使用信息:
jvm_memory_bytes_used{area="heap",} 2.4451216E7
5.1.2 构建镜像
[root@k8s-master1 tomcat-image]# pwd
/apps/prometheus/app-monitor-case/tomcat/tomcat-image
[root@k8s-master1 tomcat-image]# cat Dockerfile
FROM tomcat:8.5.73
LABEL maintainer="jack 2973707860@qq.com"
ADD server.xml /usr/local/tomcat/conf/server.xml
RUN mkdir /data/tomcat/webapps -p
ADD myapp /data/tomcat/webapps/myapp
ADD metrics.war /data/tomcat/webapps # 这个war包是提供metrics URL的包
ADD simpleclient-0.8.0.jar /usr/local/tomcat/lib/
ADD simpleclient_common-0.8.0.jar /usr/local/tomcat/lib/ # 其他这些都是监控用的依赖,必须要引入
ADD simpleclient_hotspot-0.8.0.jar /usr/local/tomcat/lib/
ADD simpleclient_servlet-0.8.0.jar /usr/local/tomcat/lib/
ADD tomcat_exporter_client-0.0.12.jar /usr/local/tomcat/lib/
#ADD run_tomcat.sh /apps/tomcat/bin/
EXPOSE 8080 8443 8009
#CMD ["/apps/tomcat/bin/catalina.sh","run"]
#CMD ["/apps/tomcat/bin/run_tomcat.sh"]
[root@k8s-master1 tomcat-image]# cat build-command.sh
#!/bin/bash
#nerdctl build -t harbor.magedu.net/magedu/tomcat-app1:v1 .
#nerdctl push harbor.magedu.net/magedu/tomcat-app1:v1
docker build -t registry.cn-hangzhou.aliyuncs.com/sanhua-k8s/tomcat-app1:v1 .
docker push registry.cn-hangzhou.aliyuncs.com/sanhua-k8s/tomcat-app1:v1
[root@k8s-master1 tomcat-image]# sh build-command.sh
5.1.3 启动容器测试
[root@k8s-master1 tomcat-image]# docker run --rm -d -p 8081:8080 registry.cn-hangzhou.aliyuncs.com/sanhua-k8s/tomcat-app1:v1
8670435b1eee7f22e249b9e6e5e1a48fe50cea93ec78c41138b2885663cd6685
[root@k8s-master1 tomcat-image]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8670435b1eee registry.cn-hangzhou.aliyuncs.com/sanhua-k8s/tomcat-app1:v1 "catalina.sh run" 3 seconds ago Up 1 second 8009/tcp, 8443/tcp, 0.0.0.0:8081->8080/tcp, :::8081->8080/tcp awesome_morse
[root@k8s-master1 tomcat-image]# netstat -lntup |grep 8081
tcp 0 0 0.0.0.0:8081 0.0.0.0:* LISTEN 21006/docker-proxy
tcp6 0 0 :::8081 :::* LISTEN 21012/docker-proxy
5.1.4 访问测试
5.1.5 部署到k8s中
5.1.5.1 编辑yaml并应用
[root@k8s-master1 yaml]# cat tomcat-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-deployment
namespace: default
spec:
selector:
matchLabels:
app: tomcat
replicas: 1
template:
metadata:
labels:
app: tomcat
annotations: # 注意这里的监控注解
prometheus.io/scrape: 'true'
prometheus.io/port: "8080"
spec:
containers:
- name: tomcat
image: registry.cn-hangzhou.aliyuncs.com/sanhua-k8s/tomcat-app1:v1
imagePullPolicy: Always
ports:
- containerPort: 8080
securityContext:
privileged: true
---
kind: Service
apiVersion: v1
metadata:
annotations: # 注意这里的监控注解
prometheus.io/scrape: 'true'
prometheus.io/port: "8080"
name: tomcat-service
spec:
selector:
app: tomcat
ports:
port: 80
protocol: TCP
targetPort: 8080
[root@k8s-master1 yaml]# kubectl apply -f tomcat-deploy.yaml
[root@k8s-master1 yaml]# kubectl get po
NAME READY STATUS RESTARTS AGE
tomcat-deployment-75f58b8b77-744kr 1/1 Running 0 3m41s
5.1.5.2 测试指标暴露
[root@k8s-master1 yaml]# kubectl get svc|grep tomcat
tomcat-service ClusterIP 10.200.216.44 <none> 80/TCP 13m
[root@k8s-master1 yaml]# curl 10.200.216.44/metrics/|head
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 11918 0 11918 0 0 1261k 0 --:--:-- --:--:-- --:--:-- 1454k
# HELP jvm_gc_collection_seconds Time spent in a given JVM garbage collector in seconds.
# TYPE jvm_gc_collection_seconds summary
jvm_gc_collection_seconds_count{gc="Copy",} 9.0
jvm_gc_collection_seconds_sum{gc="Copy",} 0.068
jvm_gc_collection_seconds_count{gc="MarkSweepCompact",} 0.0
jvm_gc_collection_seconds_sum{gc="MarkSweepCompact",} 0.0
# HELP jvm_info JVM version info
# TYPE jvm_info gauge
jvm_info{version="11.0.13+8",vendor="Oracle Corporation",runtime="OpenJDK Runtime Environment",} 1.0
# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
[root@k8s-master1 yaml]#
5.1.6 查看Prometheus监控
这里因为之前就加了pod和svc的自动发现,所以不用额外配置Prometheus了
5.1.7 导入相关grafana模板
https://github.com/nlighten/tomcat_exporter/tree/master/dashboard
5.2 案例二:监控Redis
redis的监控,主要是依赖redis_exporter完成,该插件会暴露一个9121端口,用于暴露指标。
官网:https://prometheus.io/docs/instrumenting/exporters/
插件地址:https://github.com/oliver006/redis_exporter
5.2.1 编辑yaml
[root@k8s-master1 yaml]# cat redis-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:4.0.14
resources:
requests:
cpu: 200m
memory: 156Mi
ports:
- containerPort: 6379
- name: redis-exporter # 在redis pod中加入了一个export,sidecar容器
image: oliver006/redis_exporter:latest
resources:
requests:
cpu: 100m
memory: 128Mi
ports:
- containerPort: 9121
---
kind: Service
apiVersion: v1
metadata:
annotations:
prometheus.io/scrape: 'false'
name: redis-service
spec:
selector:
app: redis
ports:
- name: redis
port: 80
protocol: TCP
targetPort: 6379
---
kind: Service
apiVersion: v1
metadata:
annotations:
prometheus.io/scrape: 'true'
prometheus.io/port: "9121"
name: redis-exporter-service
spec:
selector:
app: redis
ports:
- name: prom
port: 80
protocol: TCP
targetPort: 9121
5.2.2 创建容器
[root@k8s-master1 yaml]# kubectl get po,svc |grep redis
pod/redis-75695879c7-7ff49 2/2 Running 0 99s
service/redis-exporter-service ClusterIP 10.200.53.115 <none> 80/TCP 58s
service/redis-service ClusterIP 10.200.172.226 <none> 80/TCP 58s
5.2.3 验证Redis metrics
[root@k8s-master1 yaml]# curl -s 10.200.53.115/metrics|head
# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 0.000112761
go_gc_duration_seconds{quantile="0.25"} 0.000112761
go_gc_duration_seconds{quantile="0.5"} 0.000112761
go_gc_duration_seconds{quantile="0.75"} 0.000112761
go_gc_duration_seconds{quantile="1"} 0.000112761
go_gc_duration_seconds_sum 0.000112761
go_gc_duration_seconds_count 1
# HELP go_goroutines Number of goroutines that currently exist.
5.2.4 查看Prometheus自动发现情况
上面yaml只添加了export svc的自动发现
5.2.5 导入grafana模板
5.3 案例三:监控MySQL
通过mysqld_exporter可以监控MySQL服务的运行状态。
Prometheus官方提供的插件地址:https://github.com/prometheus/mysqld_exporter
5.3.1 安装mysql
[root@mysql ~]# yum -y install mariadb-server
[root@mysql ~]# systemctl start mariadb.service
[root@mysql ~]# systemctl enable mariadb.service
Created symlink from /etc/systemd/system/multi-user.target.wants/mariadb.service to /usr/lib/systemd/system/mariadb.service.
[root@mysql ~]# netstat -lntup |grep 3306
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 1448/mysqld
# 授权
MariaDB [(none)]> create user 'mysql_exporter'@'localhost' identified by '123456';
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> grant process,replication client,select on *.* to 'mysql_exporter'@'localhost';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> exit
Bye
# 测试链接
[root@k8s-node1 ~]# mysql -umysql_exporter -P 3306 -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 5
Server version: 5.5.68-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.02 sec)
MariaDB [(none)]> exit
Bye
5.3.2 安装mysql-exporter
[root@mysql tmp]# wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.14.0/mysqld_exporter-0.14.0.linux-amd64.tar.gz
[root@mysql tmp]# ll -h mysqld_exporter-0.14.0.linux-amd64.tar.gz
-rw-r--r-- 1 root root 7.2M 3月 5 15:40 mysqld_exporter-0.14.0.linux-amd64.tar.gz
[root@mysql tmp]# tar xf mysqld_exporter-0.14.0.linux-amd64.tar.gz
[root@mysql tmp]# cd mysqld_exporter-0.14.0.linux-amd64/
[root@mysql mysqld_exporter-0.14.0.linux-amd64]# ll
总用量 14824
-rw-r--r-- 1 3434 3434 11357 3月 5 2022 LICENSE
-rwxr-xr-x 1 3434 3434 15163162 3月 5 2022 mysqld_exporter
-rw-r--r-- 1 3434 3434 65 3月 5 2022 NOTICE
[root@mysql mysqld_exporter-0.14.0.linux-amd64]# mv mysqld_exporter /usr/local/bin/
5.3.3 配置export
# 配置免密登录
[root@mysql ~]# cat .my.cnf
[client]
user=mysql_exporter
password=123456
5.3.4 启动mysql-exporter
5.3.4.1 启动测试
[root@mysql ~]# mysqld_exporter --config.my-cnf=/root/.my.cnf
只要日志不报错,web能看到指标,基本就可以了
5.3.4.2 访问web
5.3.5 编写mysql_exporter service文件
[root@mysql ~]# cat /etc/systemd/system/mysqld_exporter.service
[Unit]
Description=Prometheus Node Exporter
After=network.target
[Service]
ExecStart=/usr/local/bin/mysqld_exporter --config.my-cnf=/root/.my.cnf
[Install]
WantedBy=multi-user.target
[root@mysql ~]# systemctl daemon-reload
[root@mysql ~]# systemctl start mysqld_exporter.service
[root@mysql ~]# systemctl enable mysqld_exporter.service
Created symlink from /etc/systemd/system/multi-user.target.wants/mysqld_exporter.service to /etc/systemd/system/mysqld_exporter.service.
[root@mysql ~]# netstat -lntup|grep 9104
tcp6 0 0 :::9104 :::* LISTEN 1698/mysqld_exporte
5.3.6 添加Prometheus监控
[root@k8s-master1 prometheus]# tail -3 cm.yaml
- job_name: 'mysql'
static_configs:
- targets: ['10.31.200.103:9104']
[root@k8s-master1 prometheus]# kubectl apply -f cm.yaml
configmap/prometheus-config configured
[root@k8s-master1 prometheus]# kubectl get po -A|grep prome
monitoring prometheus-server-766f8d8c75-76bkq 1/1 Running 0 4h57m
[root@k8s-master1 prometheus]# kubectl delete po -n monitoring prometheus-server-766f8d8c75-76bkq
pod "prometheus-server-766f8d8c75-76bkq" deleted
5.3.7 导入grafana模板
5.4 案例四:监控HAProxy
通过haproxy_exporter监控haproxy。
插件地址:https://github.com/prometheus/haproxy_exporter
5.4.1 安装haproxy
[root@haproxy ~]# yum install -y haproxy
5.4.2 调整haproxy配置并启动
[root@haproxy ~]# tail -n 8 /etc/haproxy/haproxy.cfg
listen stats # 新增这个状态页面配置
bind :8899
stats enable
#stats hide-version
stats uri /haproxy-status
stats realm HAPorxy\ Stats\ Page
stats auth haadmin:123456
stats auth admin:12345
[root@haproxy ~]# systemctl start haproxy.service
[root@haproxy ~]# systemctl enable haproxy.service
[root@haproxy ~]# systemctl is-active haproxy.service
active
5.4.3 访问测试
5.4.4 部署haproxy_exporter
5.4.4.1 下载
[root@haproxy ~]# cd /usr/local/src/
[root@haproxy src]# wget https://github.com/prometheus/haproxy_exporter/releases/download/v0.14.0/haproxy_exporter-0.14.0.linux-amd64.tar.gz
[root@haproxy src]# ll -h haproxy_exporter-0.14.0.linux-amd64.tar.gz
-rw-r--r-- 1 root root 7.6M 3月 5 17:10 haproxy_exporter-0.14.0.linux-amd64.tar.gz
[root@haproxy src]# tar xf haproxy_exporter-0.14.0.linux-amd64.tar.gz
[root@haproxy src]# cd haproxy_exporter-0.14.0.linux-amd64/
[root@haproxy haproxy_exporter-0.14.0.linux-amd64]# ll
总用量 14964
-rwxr-xr-x 1 1001 122 15306399 11月 29 2022 haproxy_exporter
-rw-r--r-- 1 1001 122 11357 11月 29 2022 LICENSE
-rw-r--r-- 1 1001 122 158 11月 29 2022 NOTICE
[root@haproxy haproxy_exporter-0.14.0.linux-amd64]# cp haproxy_exporter /usr/local/bin/
5.4.4.2 启动
# 方式一:使用socket链接
## socket文件位置看配置文件:stats socket
[root@haproxy ~]# haproxy_exporter --haproxy.scrape-uri=unix:/var/lib/haproxy/stats #
ts=2024-03-05T09:22:47.216Z caller=haproxy_exporter.go:590 level=info msg="Starting haproxy_exporter" version="(version=0.14.0, branch=HEAD, revision=01f3f215eb2a9d7872df6b730d9037d3c68cfe56)"
ts=2024-03-05T09:22:47.216Z caller=haproxy_exporter.go:591 level=info msg="Build context" context="(go=go1.18.8, user=root@3e29e1e15525, date=20221129-13:32:01)"
ts=2024-03-05T09:22:47.217Z caller=tls_config.go:232 level=info msg="Listening on" address=[::]:9101
ts=2024-03-05T09:22:47.217Z caller=tls_config.go:235 level=info msg="TLS is disabled." http2=false address=[::]:9101
# 方式二
[root@haproxy ~]# haproxy_exporter --haproxy.scrape-uri="http://haadmin:123456@127.0.0.1:8899/haproxy-status;csv"
ts=2024-03-05T09:24:14.204Z caller=haproxy_exporter.go:590 level=info msg="Starting haproxy_exporter" version="(version=0.14.0, branch=HEAD, revision=01f3f215eb2a9d7872df6b730d9037d3c68cfe56)"
ts=2024-03-05T09:24:14.204Z caller=haproxy_exporter.go:591 level=info msg="Build context" context="(go=go1.18.8, user=root@3e29e1e15525, date=20221129-13:32:01)"
ts=2024-03-05T09:24:14.204Z caller=tls_config.go:232 level=info msg="Listening on" address=[::]:9101
ts=2024-03-05T09:24:14.204Z caller=tls_config.go:235 level=info msg="TLS is disabled." http2=false address=[::]:9101
5.4.5 访问web页面
5.4.5 添加Prometheus监控项
[root@k8s-master1 prometheus]# tail -3 cm.yaml
- job_name: 'haproxy-exporter'
static_configs:
- targets: ['10.31.200.103:9101']
[root@k8s-master1 prometheus]# kubectl apply -f cm.yaml
configmap/prometheus-config configured
[root@k8s-master1 prometheus]# kubectl get po -A|grep prome
monitoring prometheus-server-766f8d8c75-xs4km 1/1 Running 0 79m
[root@k8s-master1 prometheus]# kubectl delete po -n monitoring prometheus-server-766f8d8c75-xs4km
pod "prometheus-server-766f8d8c75-xs4km" deleted
[root@k8s-master1 prometheus]# kubectl get po -A|grep prome
monitoring prometheus-server-766f8d8c75-dsdvz 1/1 Running 0 3s
5.4.6 查看监控结果
5.4.7 导入grafana模板
id: 367
5.5 案例五:监控编译安装的Nginx
5.5.1 编译安装nginx
主要是编译安装的时候,添加:nginx-module-vts模块,该模块比nginx自带的状态页功能更强大,能收集更多的流量数据。
插件地址:https://github.com/vozlt/nginx-module-vts
5.5.1.1 下载nginx-module-vts模块
[root@nginx ~]# cd /usr/local/src/
[root@nginx src]# git clone https://github.com/vozlt/nginx-module-vts.git
[root@nginx src]# ll -rt
总用量 0
drwxr-xr-x 9 root root 177 3月 6 14:37 nginx-module-vts
5.5.1.2 下载nginx源码包
[root@nginx src]# wget https://nginx.org/download/nginx-1.22.1.tar.gz
[root@nginx src]# ll -h nginx-1.22.1.tar.gz
-rw-r--r-- 1 root root 1.1M 10月 19 2022 nginx-1.22.1.tar.gz
5.5.1.3 编译安装nginx
[root@nginx src]# tar xf nginx-1.22.1.tar.gz
[root@nginx src]# cd nginx-1.22.1
[root@nginx nginx-1.22.1]# ls
auto CHANGES CHANGES.ru conf configure contrib html LICENSE man README src
[root@nginx nginx-1.22.1]# ./configure --prefix=/apps/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-file-aio \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module \
--add-module=/usr/local/src/nginx-module-vts/ # 注意这里,添加的export模块
[root@nginx nginx-1.22.1]# make
[root@nginx nginx-1.22.1]# make install
5.5.1.4 启用插件,并统计指定lcoation的流量
[root@nginx nginx-1.22.1]# cd /apps/nginx/conf/
[root@nginx conf]# cat nginx.conf
……省略部分内容
http {
include mime.types;
default_type application/octet-stream;
vhost_traffic_status_zone; # 启用状态页插件
……省略部分内容
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html; # 显示格式为html格式
}
……省略部分内容
[root@nginx conf]# /apps/nginx/sbin/nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@nginx conf]# /apps/nginx/sbin/nginx
5.5.1.5 访问nginx状态页
5.5.1.6 配置nginx反向代理,制造访问流量
[root@nginx conf]# cat nginx.conf
……省略部分内容
upstream prometheus {
server 10.31.200.100:30090;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://prometheus;
}
……省略部分内容
[root@nginx conf]# /apps/nginx/sbin/nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@nginx conf]# /apps/nginx/sbin/nginx -s reload
5.5.1.7 访问测试
访问nginx 80端口,直接被代理到Prometheus web页面
5.5.1.8 查看nginx状态页
5.5.2 配置Prometheus收集nginx状态数据
这个时候,Prometheus还不能直接去收集nginx的状态数据,还需要部署一个nginx-vts-exporter插件,来把转态页的json数据转换成key value格式的数据。
插件地址:https://github.com/sysulq/nginx-vts-exporter
5.5.2.1 部署nginx-vts-exporter
# 下载二进制文件
[root@nginx conf]# cd /usr/local/src/
[root@nginx src]# wget https://github.com/sysulq/nginx-vts-exporter/releases/download/v0.10.3/nginx-vts-exporter-0.10.3.linux-amd64.tar.gz
[root@nginx src]# ll -h nginx-vts-exporter-0.10.3.linux-amd64.tar.gz
-rw-r--r-- 1 root root 3.3M 3月 6 15:44 nginx-vts-exporter-0.10.3.linux-amd64.tar.gz
# 解压
[root@nginx src]# tar xf nginx-vts-exporter-0.10.3.linux-amd64.tar.gz
[root@nginx src]# mv nginx-vts-exporter-0.10.3.linux-amd64/nginx-vts-exporter /usr/local/bin/
# 测试命令是否可用
[root@nginx src]# nginx-vts-exporter -h
Usage of nginx-vts-exporter:
-insecure
Ignore server certificate if using https (default true)
-metrics.namespace string
Prometheus metrics namespace. (default "nginx")
-nginx.scrape_timeout int
The number of seconds to wait for an HTTP response from the nginx.scrape_uri (default 2)
-nginx.scrape_uri string
URI to nginx stub status page (default "http://localhost/status")
-telemetry.address string
Address on which to expose metrics. (default ":9913")
-telemetry.endpoint string
Path under which to expose metrics. (default "/metrics")
-version
Print version information.
# 启用插件
[root@nginx src]# nginx-vts-exporter -nginx.scrape_uri http://127.0.0.1/status/format/json
2024/03/06 15:49:20 Starting nginx_vts_exporter (version=0.10.3, branch=HEAD, revision=8aa2881c7050d9b28f2312d7ce99d93458611d04)
2024/03/06 15:49:20 Build context (go=go1.10, user=root@56ca8763ee48, date=20180328-05:47:47)
2024/03/06 15:49:20 Starting Server at : :9913
2024/03/06 15:49:20 Metrics endpoint: /metrics
2024/03/06 15:49:20 Metrics namespace: nginx
2024/03/06 15:49:20 Scraping information from : http://127.0.0.1/status/format/json
^C
[root@nginx src]# nohup nginx-vts-exporter -nginx.scrape_uri http://127.0.0.1/status/format/json &
5.5.2.2 访问指标页面
5.5.2.3 配置Prometheus
[root@k8s-master1 ~]# tail -3 yaml/monitor/prometheus/cm.yaml
- job_name: 'nginx-exporter'
static_configs:
- targets: ['10.31.200.103:9913']
[root@k8s-master1 ~]# kubectl apply -f yaml/monitor/prometheus/cm.yaml
configmap/prometheus-config configured
[root@k8s-master1 ~]# kubectl get po -A|grep prome
monitoring prometheus-server-766f8d8c75-dsdvz 1/1 Running 0 23h
[root@k8s-master1 ~]# kubectl delete po -n monitoring prometheus-server-766f8d8c75-dsdvz
pod "prometheus-server-766f8d8c75-dsdvz" deleted
[root@k8s-master1 ~]# kubectl get po -A|grep prome
monitoring prometheus-server-766f8d8c75-llgfm 1/1 Running 0 6s
5.5.2.4 查看Prometheus监控页面
5.5.3 导入grafana模板
5.6 案例六:监控容器安装的Nginx
5.6.1 构建镜像
5.6.1.1 编辑dockerfile
[root@k8s-master1 1.nginx-image]# pwd
/apps/prometheus/app-monitor-case/4.nginx-vts-exporter/1.nginx-image
[root@k8s-master1 1.nginx-image]# cat Dockerfile
FROM ubuntu:22.04
LABEL maintainer="jack 2973707860@qq.com"
ADD nginx-1.22.1.tar.gz /usr/local/src/
ADD nginx-vts-exporter-0.10.3.linux-amd64/nginx-vts-exporter /usr/local/bin/
ADD nginx-module-vts/ /usr/local/src/nginx-module-vts
RUN apt update && apt install -y iproute2 gcc openssh-server lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute iotop unzip zip make
RUN groupadd -r -g 2088 user1 && useradd -r -m -s /sbin/nologin -u 2088 -g 2088 user1
WORKDIR /usr/local/src/
RUN cd nginx-1.22.1/ && ./configure --prefix=/apps/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-file-aio \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module \
--add-module=/usr/local/src/nginx-module-vts/ && make && make install
WORKDIR /root
ADD docker-entrypoint.sh /usr/local/bin/
RUN chmod 777 /usr/local/bin/docker-entrypoint.sh && chmod 777 /usr/local/bin/nginx-vts-exporter
RUN ln -s /usr/local/bin/docker-entrypoint.sh /entrypoint.sh #
ADD nginx.conf /apps/nginx/conf/nginx.conf
EXPOSE 80 443
CMD ["sh", "/entrypoint.sh"]
5.6.1.2 构建镜像
[root@k8s-master1 1.nginx-image]# cat build-command.sh
#!/bin/bash
docker build -t registry.cn-hangzhou.aliyuncs.com/sanhua-k8s/nginx-vts-exporter:v1.22.1 .
docker push registry.cn-hangzhou.aliyuncs.com/sanhua-k8s/nginx-vts-exporter:v1.22.1
[root@k8s-master1 1.nginx-image]# sh build-command.sh
5.6.2 编辑yaml
[root@k8s-master1 1.nginx-image]# cd ../2.nginx-yaml/
[root@k8s-master1 2.nginx-yaml]# cat 1.nginx-deployment.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
app: nginx-deployment-label
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx-selector
template:
metadata:
labels:
app: nginx-selector
project: python
spec:
containers:
- name: nginx-container
image: registry.cn-hangzhou.aliyuncs.com/sanhua-k8s/nginx-vts-exporter:v1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
protocol: TCP
name: http
- containerPort: 443
---
kind: Service
apiVersion: v1
metadata:
labels:
app: nginx-service-label
name: nginx-service
annotations: # 添加监控注解
prometheus.io/scrape: "true"
prometheus.io/port: "9913"
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
- name: https
port: 443
protocol: TCP
targetPort: 443
- name: metrics
port: 9913
protocol: TCP
targetPort: 9913
selector:
app: nginx-selector
5.6.2 创建pod
[root@k8s-master1 2.nginx-yaml]# kubectl apply -f 1.nginx-deployment.yaml
deployment.apps/nginx-deployment created
service/nginx-service configured
[root@k8s-master1 2.nginx-yaml]# kubectl get po,svc|grep nginx
pod/nginx-deployment-54567498ff-jth2j 1/1 Running 0 23s
service/nginx-service NodePort 10.200.236.132 <none> 80:30578/TCP,443:31490/TCP,9913:31232/TCP 23s
5.6.3 访问mertics接口
5.6.4 查看Prometheus自动发现结果
5.7 案例七:监控Ingress-Nginx-Controller
监控ingress控制器不需要额外安装exporter,它有一个10254端口,Prometheus可以通过该端口来抓取指标数据。
5.7.1 访问ingress控制器指标端口
[root@k8s-master1 ingress-controller]# kubectl get svc -A |grep ingress
ingress-nginx ingress-nginx-controller NodePort 10.200.231.176 <none> 80:30191/TCP,10254:30675/TCP,443:31536/TCP 7m51s
ingress-nginx ingress-nginx-controller-admission ClusterIP 10.200.131.129 <none> 443/TCP 7m51s
5.7.2 添加svc注解
这里注意,如果ingress控制器是用daemonset部署,并且共享宿主机网络,那么如下图:
我是deployment部署的,并且也没有共享宿主机网络,直接添加svc或pod注解就行。
5.7.3 查看自动发现结果
5.7.4 导入grafana模板
6. blackbox_exporter(黑盒监控)
6.1 blackbox_exporter简介
官方文档:https://prometheus.io/download/#blackbox_exporter
blackbox_exporter是Prometheus 官方提供的一个exporter,可以监控 HTTP、 HTTPS,、DNS、 TCP、ICMP等目标实例,从而实现对被监控节点进行监控和数据采集。
- HTTP/HTPPS:URL/API可用性检测
- TCP:端口监听检测
- ICMP:主机存活检测
- DNS:域名可用性
6.2 blackbox_exporter架构
首先需要部署一个blackbox_exporter服务,由它来抓取监控数据,但是抓取什么样的数据,并不是由它来决定的,而是由Prometheus来决定(配置在Prometheus中),所以监控规则会由Prometheus server发送给blackbox_exporter,然后blackbox_exporter根据Prometheus server下发的监控规则,来抓取数据。
6.2 部署blackbox_exporter
这里我用二进制安装Prometheus环境来演示。
6.2.1 下载安装包
[root@prometheus-server src]# wget https://github.com/prometheus/blackbox_exporter/releases/download/v0.24.0/blackbox_exporter-0.24.0.linux-amd64.tar.gz
[root@prometheus-server src]# ll -h blackbox_exporter-0.24.0.linux-amd64.tar.gz
-rw-r--r-- 1 root root 11M 3月 6 21:38 blackbox_exporter-0.24.0.linux-amd64.tar.gz
6.2.2 安装
[root@prometheus-server src]# mkdir /apps/blackbox_exporter -p
[root@prometheus-server src]# tar xf blackbox_exporter-0.24.0.linux-amd64.tar.gz -C /apps/blackbox_exporter/
[root@prometheus-server src]# cd /apps/blackbox_exporter/
[root@prometheus-server blackbox_exporter]# ls
blackbox_exporter-0.24.0.linux-amd64
[root@prometheus-server blackbox_exporter]# cd blackbox_exporter-0.24.0.linux-amd64/
[root@prometheus-server blackbox_exporter-0.24.0.linux-amd64]# ll
总用量 20700
-rwxr-xr-x 1 1001 1002 21174366 5月 16 2023 blackbox_exporter
-rw-r--r-- 1 1001 1002 956 5月 16 2023 blackbox.yml # 这是它的配置文件,里面都是一些监控探针配置,不用动它。
-rw-r--r-- 1 1001 1002 11357 5月 16 2023 LICENSE
-rw-r--r-- 1 1001 1002 94 5月 16 2023 NOTICE
[root@prometheus-server blackbox_exporter-0.24.0.linux-amd64]# ln -s /apps/blackbox_exporter/blackbox_exporter-0.24.0.linux-amd64 /apps/blackbox_exporter/blackbox_exporter
6.2.3 启动blackbox exporter
6.2.3.1 创建blackbox exporter启动文件
[root@prometheus-server blackbox_exporter-0.24.0.linux-amd64]# cat /etc/systemd/system/blackbox-exporter.service
[Unit]
Description=Prometheus Blackbox Exporter
After=network.target
[Service]
Type=simple
User=root
Group=root
ExecStart=/apps/blackbox_exporter/blackbox_exporter/blackbox_exporter \
--config.file=/apps/blackbox_exporter/blackbox_exporter/blackbox.yml \
--web.listen-address=:9115
Restart=on-failure
[Install]
WantedBy=multi-user.target
6.2.3.2 启动blackbox exporter
[root@prometheus-server blackbox_exporter-0.24.0.linux-amd64]# systemctl daemon-reload
[root@prometheus-server blackbox_exporter-0.24.0.linux-amd64]# systemctl restart blackbox-exporter.service
[root@prometheus-server blackbox_exporter-0.24.0.linux-amd64]# systemctl is-active blackbox-exporter.service
active
[root@prometheus-server blackbox_exporter-0.24.0.linux-amd64]# systemctl enable blackbox-exporter.service
[root@prometheus-server blackbox_exporter-0.24.0.linux-amd64]# ss -lntup|grep 9115
tcp LISTEN 0 128 [::]:9115 [::]:* users:(("blackbox_export",pid=2014,fd=3))
6.2.3.1 访问测试
6.3 监控案例
6.3.1 实现网站域名监控
6.3.1.1 配置Prometheus
[root@prometheus-server prometheus]# cat prometheus.yml
……省略部分内容
- job_name: 'http_status' # 增加监控配置
metrics_path: /probe # 这里路径就是blackbox的路径,等它抓取到数据后,Prometheus就是通过该接口获取数据的
params:
module: [http_2xx] # 调用的blackbox的这个模块,监控网页2xx状态码。配置文件中可以看到该模块
static_configs:
- targets: ['http://www.xiaomi.com','http://www.magedu.com'] # 监控目标
labels:
instance: http_status # 给监控目标自定义的标签
group: web # 给监控目标自定义的组
relabel_configs: # 标签重写配置
- source_labels: [__address__] # 将__address__(当前监控目标URL地址的标签)修改为__param_target,用于传递给blackbox_exporter
target_label: __param_target # # 标签key为__param_target、value为www.xiaomi.com。key为__param_target、value为www.magedu.com
- source_labels: [__param_target]
target_label: url # __param_target替换成url
- target_label: __address__ # 新添加一个目标__address__,指向blackbox_exporter服务器地址,用于将监控请求发送给指定的blackbox_exporter服务器
replacement: 10.31.200.103:9115 # 指定blackbox_exporter服务器地址
[root@prometheus-server blackbox_exporter]# systemctl restart prometheus.service
6.3.1.2 查看blackbox抓取数据结果
Logs里面有很多网站的详细信息,如dns解析耗时、请求耗时、证书过期时间等
6.3.1.3 导入grafana模版
6.3.2 实现ICMP协议监控
6.3.2.1 配置Prometheus
[root@prometheus-server prometheus]# cat prometheus.yml
……省略部分内容
- job_name: 'ping_status'
metrics_path: /probe
params:
module: [icmp]
static_configs:
- targets: ['10.31.200.100',"10.31.200.101","10.31.200.102"]
labels:
instance: 'ping_status'
group: 'icmp'
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: ip
- target_label: __address__
replacement: 10.31.200.103:9115
[root@prometheus-server prometheus]# systemctl restart prometheus.service
[root@prometheus-server prometheus]# systemctl is-active prometheus.service
active
6.3.2.2 查看blackbox抓取数据结果
6.3.2.3 查看grafana模版
6.3.3 实现端口监控
6.3.3.1 配置Prometheus
[root@prometheus-server prometheus]# cat prometheus.yml
……省略部分内容
- job_name: 'port_status'
metrics_path: /probe
params:
module: [tcp_connect]
static_configs:
- targets: ['10.31.200.100:22','10.31.200.101:22','10.31.200.102:22']
labels:
instance: 'port_status'
group: 'port'
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: ip
- target_label: __address__
replacement: 10.31.200.103:9115
[root@prometheus-server prometheus]# systemctl restart prometheus.service
[root@prometheus-server prometheus]# systemctl is-active prometheus.service
active
6.3.3.2 查看blackbox抓取数据结果