Prometheus服务发现与监控案例-Day 02

news2024/11/28 6:43:12

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 35 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 35 2022 LICENSE
-rwxr-xr-x 1 3434 3434 15163162 35 2022 mysqld_exporter
-rw-r--r-- 1 3434 3434       65 35 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 35 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 1129 2022 haproxy_exporter
-rw-r--r-- 1 1001 122    11357 1129 2022 LICENSE
-rw-r--r-- 1 1001 122      158 1129 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 36 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 1019 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 36 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 36 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 516 2023 blackbox_exporter
-rw-r--r-- 1 1001 1002      956 516 2023 blackbox.yml # 这是它的配置文件,里面都是一些监控探针配置,不用动它。
-rw-r--r-- 1 1001 1002    11357 516 2023 LICENSE
-rw-r--r-- 1 1001 1002       94 516 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抓取数据结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.3.3.3 查看grafana模版

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1577011.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL基础练习题:习题2-3

这部分主要是为了帮助大家回忆回忆MySQL的基本语法&#xff0c;数据库来自于MySQL的官方简化版&#xff0c;题目也是网上非常流行的35题。这些基础习题基本可以涵盖面试中需要现场写SQL的问题。上期帮助大家建立数据库&#xff0c;导入数据&#xff0c;接下来让我们继续练习。 …

51单片机入门_江协科技_17~18_OB记录的笔记

17. 定时器 17.1. 定时器介绍&#xff1a;51单片机的定时器属于单片机的内部资源&#xff0c;其电路的连接和运转均在单片机内部完成&#xff0c;无需占用CPU外围IO接口&#xff1b; 定时器作用&#xff1a; &#xff08;1&#xff09;用于计时系统&#xff0c;可实现软件计时&…

【LeetCode热题100】74. 搜索二维矩阵(二分)

一.题目要求 给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true &#xff1b;否则&#xff0c;…

GD32F470_US-016 模拟电压输出 双量程 模拟量 超声波测距模块 高精度

2.18 US-016电压式超声波测距传感器 US-016是市场上唯有的一款模拟量输出的超声波测距模块&#xff0c;输出的模拟电压和距离值成正比&#xff0c;可以方便的和其他系统相连&#xff0c;US-016工作稳定可靠。 US-016超声波测距模块可实现2cm~3m的非接触测距功能&#xff0c;供…

Android 9.0 framework层实现app默认全屏显示

1.前言 在9.0的系统rom产品定制化开发中,在对于第三方app全屏显示的功能需求开发中,需要默认app全屏显示,针对这一个要求,就需要在系统启动app 的过程中,在绘制app阶段就设置全屏属性,接下来就实现这个功能 效果图如下: 2.framework层实现app默认全屏显示的核心类 fram…

红黑树深度解析:RB-DELETE操作的理论与实践

红黑树深度解析&#xff1a;RB-DELETE操作的理论与实践 一、前言二、红黑树的核心性质三、RB-DELETE的过程四、RB-DELETE的实现细节五、RB-DELETE的复杂性分析六、维护红黑树性质的重要性七、代码示例7.1 伪代码7.2 C代码示例 八、结论 一、前言 在现代计算机科学中&#xff0…

备忘,LangChain建立本地知识库的几个要点

本地知识库可以解决本地资源与AI结合的问题&#xff0c;为下一步应用管理已有资产奠定基础。 本地知识库的建立可参考LangChain结合通义千问的自建知识库 &#xff08;二&#xff09;、&#xff08;三&#xff09;、&#xff08;四&#xff09; 本文主要记录两个方面的问题 1 搭…

抖音引流私域转化模式1.0现场视频,从抖音源源不断把人加到私域买单

抖音-引流私域转化模式1.0现场视频&#xff0c;从抖音源源不断把人加到私域&#xff0c;让加到私域的粉丝买单 课程内容&#xff1a;抖音引流私域转化模式1.0现场视频&#xff0c;从抖音源源不断把人加到私域买单 - 百创网-源码交易平台_网站源码_商城源码_小程序源码 01.第一…

武汉星起航:运营经验打造行业标杆,形成可持续稳健业务增长路径

在跨境电商的浪潮中&#xff0c;武汉星起航电子商务有限公司以其专注于提供一站式解决方案而在行业内崭露头角&#xff0c;成为创业者成功进入市场的得力伙伴。公司不仅仅是服务提供商&#xff0c;更是创业者的导航者&#xff0c;通过全方位的支持和专业指导&#xff0c;致力于…

javaWeb影视创作论坛的设计与实现

摘要 随着时代的发展&#xff0c;互联网的出现&#xff0c;给传统影视行业带来的最大便利就是&#xff0c;方便了影视从业人员以及爱好者的交流和互动&#xff0c;而为用户提供一个书写影评&#xff0c;阅读影评以及回复影评的平台&#xff0c;以影评为载体来使用户感受影评、…

android-自定义TextView在文字内容末尾添加图片icon、可以添加间距

样式示意图 自定义属性 style.xml <declare-styleable name"IconLabelTextView"><attr name"iconSrc" format"reference"/><attr name"iconPaddingStart" format"dimension"/><attr name"iconPad…

小红不想做模拟题 线段树

无脑线段树 #include<iostream> using namespace std; const int N 1e510; int a[N],b[N];struct Segment{int l,r;int s,s1,s2;int lz1,lz2; }tr[N<<2];void pushdown(int u){if(tr[u].lz1){tr[u<<1].lz1 tr[u<<1|1].lz1 1;tr[u].lz1 0;tr[u<&…

2024/4/1—力扣—两数相除

代码实现&#xff1a; 思路&#xff1a;用减法模拟除法 // 用减法模拟除法 int func(int a, int b) { // a、b均为负数int ans 0;while (a < b) { // a的绝对值大于等于b&#xff0c;表示此时a够减int t b;int count 1; // 用来计数被减的次数// t > INT_MIN / 2:防止…

ArcGISPro 如何升级某项Python库且不影响其运行

升级包scipy 可以看出scipy当前版本是1.6.2 利用不依赖包升级 pip install --upgrade scipy --no-deps 结果 但是显示还是之前的版本

使用高德微信小程序插件实现精准获取打卡位置

由于微信小程序的 getFuzzyLocation 误差太大 不得不改用高德微信sdk 使用方法&#xff1a; 一、下载 sdk 相关下载-微信小程序插件 | 高德地图API 二、引入 sdk //引入 var amapFile require(../../libs/amap-wx.js); Page({onLoad: function() {var that this;va…

go的orm框架-Gorm

官网文档 特点 全功能 ORM 关联 (拥有一个&#xff0c;拥有多个&#xff0c;属于&#xff0c;多对多&#xff0c;多态&#xff0c;单表继承) Create&#xff0c;Save&#xff0c;Update&#xff0c;Delete&#xff0c;Find 中钩子方法 支持 Preload、Joins 的预加载 事务&…

Vue.js【组件基础(上)】

选项式API和组合式API 选项式API 选项式API是一种通过包含多个选项的对象来描述组件逻辑的API&#xff0c;其常用的选项包括data、methods、computed、watch等。 组合式API 相比于选项式API&#xff0c;组合式API是将组件中的数据、方法、计算属性、侦听器等代码全部组合在…

sigmoid函数实例

sigmoid实例案例&#xff1a;&#xff08;sigmoid作用就是把传统线性回归中的z 投射到分类问题&#xff08;0&#xff0c;1&#xff09;的概率中&#xff09; 交叉熵损失函数扩充解释&#xff1a; 为什么二分类和多分类的不一样 因为在二分类问题中 每个样本得值是0或1 一组数据…

使用spring模拟转账,并实现异常事务回滚

1、数据库准备 使用配置类配置数据源、模板、事务回滚 package cn.edu.aaa.utils;import java.beans.PropertyVetoException;import javax.sql.DataSource;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotati…

iterrows方法使dataframe显示完整

这样一个excel文件&#xff0c;由于行数太多显示不全。 直接读取显示&#xff1a; 该如何处理&#xff1f;方法有很多&#xff0c;这次讲解用dataframe.iterrows()方法。 DataFrame.iterrows()方法&#xff1a; 返回值是一个由索引和Series组成的元组。 关于这个方法的两个注…