【云原生】Kubernetes----Kubernetes集群部署Prometheus 和Grafana

目录

引言

一、环境准备

二、部署node-exporter

(一)创建命名空间

(二)部署node-exporter

1.获取镜像

2.定义yaml文件

3.创建服务

4.查看监控数据

三、部署Prometheus

(一)创建账号并授权

(二)创建configmap存储卷

(三)部署prometheus

(四)创建svc

(五)添加targets后的重启方法

1.热加载

2.删除后重建

四、部署Grafana

(一)准备镜像

(二)创建Grafana的pod资源

(三)创建Grafana的svc资源

(四)访问Grafana

1.登录grafana

2.配置grafana

3.导入监控模板

3.1 导入node的监控模板

3.2 导入监控容器状态模板

3.3 导入集群监控模板

五、部署kube-state-metrics

(一)部署kube-state-metrics

1.创建sa账号并授权

2.安装kube-state-metrics组件

3.创建service资源

(二)配置Grafana

1.配置k8s群集状态

1.1 获取模板

1.2 添加模板

2.配置kube-state-metrics

2.1 获取模板文件

2.2 添加模板文件

六、部署alertmanager

(一)Alertmanager的工作流程

(二)部署Alertmanager

1.创建alertmanager配置文件

2.创建prometheus和告警规则配置文件

3.安装prometheus和alertmanager

3.1 创建secret资源

3.2 创建资源清单

(三)部署alertmanager的service

(四)访问alertmanager

(五)处理kube-proxy监控告警


引言

在云原生时代,Kubernetes(简称K8s)已经成为了容器编排的事实标准。然而,如何监控这个庞大的集群,确保其稳定运行,是每个运维人员都需要面对的问题。Prometheus和Grafana作为开源的监控和可视化工具,被广泛应用于Kubernetes集群的监控中。本文将详细介绍如何在Kubernetes集群中部署Prometheus和Grafana,以实现对集群的全面监控。

一、环境准备

主机名IP地址主机类型资源配置
master01192.168.83.30控制节点4C4G
node01192.168.83.40工作节点14C4G
node02192.168.83.50工作节点24C4G

二、部署node-exporter

(一)创建命名空间

创建监控namespace

[root@master01 ~]#kubectl create ns monitor-sa
namespace/monitor-sa created
[root@master01 ~]#kubectl get ns monitor-sa 
NAME         STATUS   AGE
monitor-sa   Active   9s

(二)部署node-exporter

1.获取镜像

docker pull的方式下载镜像,可以从hub.docker.com下载,或者使用国内的镜像替代

[root@master01 images]#ls node-exporter.tar
node-exporter.tar
[root@master01 images]#docker load -i node-exporter.tar 
ad68498f8d86: Loading layer [==============================>]  4.628MB/4.628MB
ad8512dce2a7: Loading layer [==============================>]  2.781MB/2.781MB
cc1adb06ef21: Loading layer [==============================>]   16.9MB/16.9MB
Loaded image: prom/node-exporter:v0.16.0
'----------------------------------------------------------------------------'
[root@node01 images]#ls node-exporter.tar
node-exporter.tar
[root@node01 images]#docker load -i node-exporter.tar 
ad68498f8d86: Loading layer [==============================>]  4.628MB/4.628MB
ad8512dce2a7: Loading layer [==============================>]  2.781MB/2.781MB
cc1adb06ef21: Loading layer [==============================>]   16.9MB/16.9MB
Loaded image: prom/node-exporter:v0.16.0
'----------------------------------------------------------------------------'
[root@node02 images]#ls node-exporter.tar
node-exporter.tar
[root@node02 images]#docker load -i node-exporter.tar 
ad68498f8d86: Loading layer [==============================>]  4.628MB/4.628MB
ad8512dce2a7: Loading layer [==============================>]  2.781MB/2.781MB
cc1adb06ef21: Loading layer [==============================>]   16.9MB/16.9MB
Loaded image: prom/node-exporter:v0.16.0
[root@node02 images]#docker images|grep prom/node-exporter
prom/node-exporter           v0.16.0    188af75e2de0   6 years ago     22.9MB

2.定义yaml文件

使用yaml文件,以DaemonSet副本控制器,在每个节点上部署node-exporter

[root@master01 prometheus]#vim node-export.yaml
---
apiVersion: apps/v1
kind: DaemonSet				#可以保证 k8s 集群的每个节点都运行完全一样的 pod
metadata:name: node-exporternamespace: monitor-salabels:name: node-exporter
spec:selector:matchLabels:name: node-exportertemplate:metadata:labels:name: node-exporterspec:hostPID: true                        #允许Pod使用宿主机的 PIDhostIPC: true                        #允许Pod使用宿主机的IPChostNetwork: true                    #允许Pod使用宿主机的网络命名空间containers:- name: node-exporterimage: prom/node-exporter:v0.16.0  #指定镜像ports:- containerPort: 9100              #指定容器暴露端口resources:requests:cpu: 0.15		               #这个容器运行至少需要0.15核cpusecurityContext:privileged: true	               #开启特权模式args:                              #传递给容器的命令行参数- --path.procfs- /host/proc
#通知node-exporter在哪里找到宿主机的/proc文件系统。
#由于node-exporter运行在容器中,不能直接访问宿主机的/proc文件系统,需要通过挂载来访问它- --path.sysfs- /host/sys
#类似地,这个参数告诉node-exporter在哪里找到宿主机的/sys文件系统- --collector.filesystem.ignored-mount-points- '"^/(sys|proc|dev|host|etc)($|/)"'
#这个参数指定以sys等开头文件系统挂载点,被node-exporter的文件系统收集器忽略,volumeMounts:                      #定义了容器内挂载卷的路径- name: devmountPath: /host/dev- name: procmountPath: /host/proc- name: sysmountPath: /host/sys- name: rootfsmountPath: /rootfstolerations:- key: "node-role.kubernetes.io/master"operator: "Exists"effect: "NoSchedule"
#定义了DaemonSet容忍了标记为node-role.kubernetes.io/master的节点上的污点volumes:                             #定义了 Pod 中要使用的卷- name: prochostPath:path: /proc- name: devhostPath:path: /dev- name: syshostPath:path: /sys- name: rootfshostPath:path: /

3.创建服务

[root@master01 prometheus]#kubectl apply -f node-export.yaml 
daemonset.apps/node-exporter created
[root@master01 prometheus]#kubectl get pod -n monitor-sa -o wide
NAME                  READY   STATUS    RESTARTS   AGE   IP              NODE       NOMINATED NODE   READINESS GATES
node-exporter-dvl2v   1/1     Running   0          24s   192.168.83.30   master01   <none>           <none>
node-exporter-nhk4t   1/1     Running   0          24s   192.168.83.40   node01     <none>           <none>
node-exporter-rs8pd   1/1     Running   0          24s   192.168.83.50   node02     <none>           <none>

4.查看监控数据

node-exporter 默认的监听端口是 9100,可以执行 curl http://主机ip:9100/metrics 获取到主机的所有监控数据

比如查看cpu的数据

curl -Ls http://192.168.83.30:9100/metrics | grep node_cpu_seconds

[root@master01 prometheus]#curl -Ls http://192.168.83.30:9100/metrics | grep node_cpu_seconds
# HELP node_cpu_seconds_total Seconds the cpus spent in each mode.
# TYPE node_cpu_seconds_total counter
node_cpu_seconds_total{cpu="0",mode="idle"} 6110.13
node_cpu_seconds_total{cpu="0",mode="iowait"} 5.72
node_cpu_seconds_total{cpu="0",mode="irq"} 0
node_cpu_seconds_total{cpu="0",mode="nice"} 0.05
node_cpu_seconds_total{cpu="0",mode="softirq"} 33.77
node_cpu_seconds_total{cpu="0",mode="steal"} 0
node_cpu_seconds_total{cpu="0",mode="system"} 175.56
node_cpu_seconds_total{cpu="0",mode="user"} 164.87
node_cpu_seconds_total{cpu="1",mode="idle"} 6129.08
node_cpu_seconds_total{cpu="1",mode="iowait"} 4.52
node_cpu_seconds_total{cpu="1",mode="irq"} 0
node_cpu_seconds_total{cpu="1",mode="nice"} 0.05
node_cpu_seconds_total{cpu="1",mode="softirq"} 28.48
node_cpu_seconds_total{cpu="1",mode="steal"} 0
node_cpu_seconds_total{cpu="1",mode="system"} 181.28
node_cpu_seconds_total{cpu="1",mode="user"} 163.54
node_cpu_seconds_total{cpu="2",mode="idle"} 6126.05
node_cpu_seconds_total{cpu="2",mode="iowait"} 4.47
node_cpu_seconds_total{cpu="2",mode="irq"} 0
node_cpu_seconds_total{cpu="2",mode="nice"} 0
node_cpu_seconds_total{cpu="2",mode="softirq"} 38.63
node_cpu_seconds_total{cpu="2",mode="steal"} 0
node_cpu_seconds_total{cpu="2",mode="system"} 175.99
node_cpu_seconds_total{cpu="2",mode="user"} 166.63
node_cpu_seconds_total{cpu="3",mode="idle"} 6132.87
node_cpu_seconds_total{cpu="3",mode="iowait"} 2.5
node_cpu_seconds_total{cpu="3",mode="irq"} 0
node_cpu_seconds_total{cpu="3",mode="nice"} 0
node_cpu_seconds_total{cpu="3",mode="softirq"} 29.81
node_cpu_seconds_total{cpu="3",mode="steal"} 0
node_cpu_seconds_total{cpu="3",mode="system"} 183.06
node_cpu_seconds_total{cpu="3",mode="user"} 167.03

三、部署Prometheus

(一)创建账号并授权

创建一个管理账号,并绑定admin用户,admin用户拥有所有资源的所有权限

[root@master01 prometheus]#kubectl create serviceaccount monitor -n monitor-sa
serviceaccount/monitor created
[root@master01 prometheus]#kubectl create clusterrolebinding monitor-clusterrolebinding -n monitor-sa --clusterrole=cluster-admin  --serviceaccount=monitor-sa:monitor
clusterrolebinding.rbac.authorization.k8s.io/monitor-clusterrolebinding created
#指定管理的命名空间

(二)创建configmap存储卷

在ConfigMap中,需要定义Prometheus的全局配置以及数据采集规则。数据采集规则包括从Kubernetes API Server、node-exporter等组件中收集指标数据的规则

[root@master01 prometheus]#cat  prometheus-cfg.yaml
apiVersion: v1
kind: ConfigMap
metadata:labels:app: prometheusname: prometheus-confignamespace: monitor-sa
data:prometheus.yml: |   #Prometheus 配置文件的内容
#-----------------------------全局设置-------------------------------------------global:                     #指定prometheus的全局配置,比如采集间隔,抓取超时时间等scrape_interval: 15s      #采集目标主机监控数据的时间间隔,默认为1mscrape_timeout: 10s       #数据采集超时时间,默认10sevaluation_interval: 1m 	#触发告警生成alert的时间间隔,默认是1mscrape_configs:             #配置数据源,称为target,每个target用job_name命名。
#-------------------第一个服务发现:监控 Kubernetes 集群中的节点------------------------- job_name: 'kubernetes-node'kubernetes_sd_configs:    #指定的是k8s的服务发现- role: node              #使用node角色,它使用默认的kubelet提供的http端口来发现集群中每个node节点relabel_configs:	        #重新标记,修改目标地址- source_labels: [__address__]    #配置的原始标签,匹配地址regex: '(.*):10250'             #匹配带有10250端口的urlreplacement: '${1}:9100'        #把匹配到的ip:10250的ip保留,类似与sed的后向引用target_label: __address__       #新生成的url是${1}获取到的ip:9100action: replace         
#动作替换,从默认的kubelet端口(10250)更改为Prometheus Node Exporter 的端口(9100)- action: labelmapregex: __meta_kubernetes_node_label_(.+)    #匹配到下面正则表达式的标签会被保留,如果不做regex正则的话,默认只是会显示instance标签
#--------------第二个服务发现:监控 Kubernetes 集群中每个节点的 cAdvisor-----------------
#抓取cAdvisor数据,是获取kubelet上/metrics/cadvisor接口数据来获取容器的资源使用情况- job_name: 'kubernetes-node-cadvisor'    kubernetes_sd_configs:- role:  nodescheme: https   #定义了与cAdvisor服务通信时使用HTTPS协议tls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt  #CA证书文件的路径bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token #指定了包含用于与Kubernetes API服务器进行身份验证的Bearer令牌的文件路径relabel_configs:- action: labelmap    #把匹配到的标签保留regex: __meta_kubernetes_node_label_(.+)    #保留匹配到的具有__meta_kubernetes_node_label的标签- target_label: __address__                   #获取到的地址:__address__="192.168.80.20:10250"replacement: kubernetes.default.svc:443     #把获取到的地址替换成新的地址kubernetes.default.svc:443- source_labels: [__meta_kubernetes_node_name]regex: (.+)                                 #把原始标签中__meta_kubernetes_node_name值匹配到target_label: __metrics_path__              #获取__metrics_path__对应的值replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor	#把metrics替换成新的值api/v1/nodes/k8s-master1/proxy/metrics/cadvisor#${1}是__meta_kubernetes_node_name获取到的值#新的url就是https://kubernetes.default.svc:443/api/v1/nodes/k8s-master1/proxy/metrics/cadvisor
#------------------第三个服务发现:监控Kubernetes API服务器---------------------------- job_name: 'kubernetes-apiserver'kubernetes_sd_configs:- role: endpoints     #使用k8s中的endpoint服务发现,采集apiserver6443端口获取到的数据scheme: httpstls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenrelabel_configs:- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]    
#[endpoint这个对象的名称空间,endpoint对象的服务名,exnpoint的端口名称]action: keep    #采集满足条件的实例,其他实例不采集regex: default;kubernetes;https    #正则匹配到的默认空间下的service名字是kubernetes,协议是https的endpoint类型保留下来
#-----------------------------第四个服务发现--------------------------------------- job_name: 'kubernetes-service-endpoints'kubernetes_sd_configs:- role: endpointsrelabel_configs:- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]action: keepregex: true
#重新打标仅抓取到的具有"prometheus.io/scrape: true"的annotation的端点
#意思是说如果某个service具有prometheus.io/scrape = true的annotation声明则抓取
#annotation本身也是键值结构, 所以这里的源标签设置为键
#而regex设置值true,当值匹配到regex设定的内容时则执行keep动作也就是保留,其余则丢弃。- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]action: replacetarget_label: __scheme__regex: (https?)
#重新设置scheme,匹配源标签__meta_kubernetes_service_annotation_prometheus_io_scheme
#也就是prometheus.io/scheme annotation
#如果源标签的值匹配到regex,则把值替换为__scheme__对应的值。- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]action: replacetarget_label: __metrics_path__regex: (.+)
#应用中自定义暴露的指标,也许你暴露的API接口不是/metrics这个路径,
#那么你可以在这个POD对应的service中做一个 "prometheus.io/path = /mymetrics" 声明,
#上面的意思就是把你声明的这个路径赋值给__metrics_path__, 
#其实就是让prometheus来获取自定义应用暴露的metrices的具体路径, 
#不过这里写的要和service中做好约定,
#如果service中这样写 prometheus.io/app-metrics-path: '/metrics' 
#那么这里写__meta_kubernetes_service_annotation_prometheus_io_app_metrics_path- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]action: replacetarget_label: __address__regex: ([^:]+)(?::\d+)?;(\d+)replacement: $1:$2
#暴露自定义的应用的端口,就是把地址和你在service中定义的 "prometheus.io/port = <port>" 
#声明做一个拼接, 然后赋值给__address__,这样prometheus就能获取自定义应用的端口,
#然后通过这个端口再结合__metrics_path__来获取指标,
#如果__metrics_path__值不是默认的/metrics那么就要使用上面的标签替换来获取真正暴露的具体路径- action: labelmap        #保留下面匹配到的标签regex: __meta_kubernetes_service_label_(.+)- source_labels: [__meta_kubernetes_namespace]action: replace        #替换__meta_kubernetes_namespace变成kubernetes_namespacetarget_label: kubernetes_namespace- source_labels: [__meta_kubernetes_service_name]action: replacetarget_label: kubernetes_name

创建服务

[root@master01 prometheus]#kubectl apply -f prometheus-cfg.yaml 
configmap/prometheus-config created
[root@master01 prometheus]#kubectl get configmaps -n monitor-sa 
NAME                DATA   AGE
kube-root-ca.crt    1      26h
prometheus-config   1      77s

(三)部署prometheus

通过 deployment 部署prometheus
将 prometheus 调度到node1节点,在 node1 节点创建 prometheus 数据存储目录

首先在节点上预加载镜像,防止因为网络问题,导致镜像加载失败

或者可以使用国内的镜像代替

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/prometheus:v2.30.3

[root@node01 images]#ls prometheus.tar 
prometheus.tar
[root@node01 images]#docker load -i prometheus.tar 
6a749002dd6a: Loading layer [==================================================>]  1.338MB/1.338MB
5f70bf18a086: Loading layer [==================================================>]  1.024kB/1.024kB
1692ded805c8: Loading layer [==================================================>]  2.629MB/2.629MB
035489d93827: Loading layer [==================================================>]  66.18MB/66.18MB
8b6ef3a2ab2c: Loading layer [==================================================>]   44.5MB/44.5MB
ff98586f6325: Loading layer [==================================================>]  3.584kB/3.584kB
017a13aba9f4: Loading layer [==================================================>]   12.8kB/12.8kB
4d04d79bb1a5: Loading layer [==================================================>]  27.65kB/27.65kB
75f6c078fa6b: Loading layer [==================================================>]  10.75kB/10.75kB
5e8313e8e2ba: Loading layer [==================================================>]  6.144kB/6.144kB
Loaded image: prom/prometheus:v2.2.1

定义yaml文件

[root@master01 prometheus]#vim prometheus-deploy.yaml
[root@master01 prometheus]#cat prometheus-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: prometheus-server   #部署的名称namespace: monitor-sa     #指定命名空间labels:app: prometheus
spec:replicas: 1selector:matchLabels:app: prometheuscomponent: servertemplate:metadata:labels:app: prometheuscomponent: serverannotations:prometheus.io/scrape: 'false'  #Pod的注解,表示Prometheus不从此端点抓取数据spec:nodeName: node01                 #指定Pod应调度到的节点名称serviceAccountName: monitor      #指定Pod使用的ServiceAccount的名称containers:- name: prometheusimage: prom/prometheus:v2.2.1  #要使用的容器镜像和标签imagePullPolicy: IfNotPresentcommand:- prometheus                 #启动命令- --config.file=/etc/prometheus/prometheus.yml   #指定加载的配置文件- --storage.tsdb.path=/prometheus                #数据存储目录- --storage.tsdb.retention=720h                  #数据保存时长- --web.enable-lifecycle                         #开启热加载ports:- containerPort: 9090protocol: TCPvolumeMounts:- mountPath: /etc/prometheus/prometheus.ymlname: prometheus-configsubPath: prometheus.yml- mountPath: /prometheus/name: prometheus-storage-volumevolumes:- name: prometheus-configconfigMap:                                     #指定挂载的configMap资源name: prometheus-configitems:- key: prometheus.ymlpath: prometheus.ymlmode: 0644- name: prometheus-storage-volumehostPath:path: /datatype: Directory

在node01节点创建挂载目录

[root@node01 ~]#mkdir /data && chmod 777 /data

创建服务

[root@master01 prometheus]#kubectl apply -f prometheus-deploy.yaml
deployment.apps/prometheus-server created
[root@master01 prometheus]#kubectl get pod prometheus-server-75fb7f8fc6-smgjl -o wide -n monitor-sa 
NAME                                 READY   STATUS    RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATES
prometheus-server-75fb7f8fc6-smgjl   1/1     Running   5          21s     10.244.1.56   node01   <none>           <none>

进入pod查看配置文件

[root@master01 prometheus]#kubectl exec -it prometheus-server-75fb7f8fc6-smgjl -n monitor-sa sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/prometheus $ cat /etc/prometheus/prometheus.yml 
global:scrape_interval: 15sscrape_timeout: 10sevaluation_interval: 1m
scrape_configs:
- job_name: 'kubernetes-node'kubernetes_sd_configs:- role: noderelabel_configs:- source_labels: [__address__]regex: '(.*):10250'replacement: '${1}:9100'target_label: __address__action: replace- action: labelmapregex: __meta_kubernetes_node_label_(.+)
- job_name: 'kubernetes-node-cadvisor'kubernetes_sd_configs:- role:  nodescheme: httpstls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenrelabel_configs:- action: labelmap
......

(四)创建svc

[root@master01 prometheus]#vim prometheus-svc.yaml
[root@master01 prometheus]#cat prometheus-svc.yaml
apiVersion: v1
kind: Service
metadata:name: prometheusnamespace: monitor-salabels:app: prometheus
spec:type: NodePortports:- port: 9090targetPort: 9090protocol: TCPnodePort: 31000selector:app: prometheuscomponent: server
[root@master01 prometheus]#kubectl apply -f prometheus-svc.yaml 
service/prometheus created
[root@master01 prometheus]#kubectl get svc -n monitor-sa 
NAME         TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
prometheus   NodePort   10.96.218.105   <none>        9090:31000/TCP   3s

使用web浏览器访问节点的31000端口

监控apiserver

确保集群健康:apiserver是Kubernetes集群的核心组件,负责处理所有与集群相关的API请求。通过Prometheus监控apiserver,可以实时获取其性能指标,如请求延迟、错误率等,从而确保集群的健康状态。

服务发现:Prometheus支持基于Kubernetes服务发现(Service Discovery)的自动配置,可以自动发现apiserver作为监控目标,无需手动配置。

问题诊断:一旦apiserver出现性能问题或故障,Prometheus可以提供详细的历史数据和告警信息,帮助管理员快速定位问题并进行处理。

监控nodes

资源利用率:Prometheus可以监控节点(nodes)的资源利用率,包括CPU、内存、磁盘等,从而评估集群的负载情况和扩展需求。

节点状态:通过监控节点的状态信息,可以及时发现节点故障或异常情况,并采取相应的措施进行处理,避免影响集群的整体稳定性。

监控cAdvisor

容器性能:cAdvisor是Kubernetes中的一个组件,用于收集容器性能数据。Prometheus可以集成cAdvisor,实时获取容器的CPU、内存、网络等性能指标,从而了解容器的运行状况。

资源优化:通过监控容器性能数据,管理员可以分析资源使用情况,优化容器的资源配置,提高资源利用率和集群的整体性能。

监控kube-dns

服务发现:kube-dns是Kubernetes集群中的DNS服务器,负责为服务提供DNS解析。通过Prometheus监控kube-dns,可以确保其稳定运行,从而保障服务发现功能的正常使用。

性能监控:Prometheus可以监控kube-dns的性能数据,如查询延迟、缓存命中率等,从而评估其性能状态并采取相应的优化措施

查询每一分钟每个pod的CPU使用率

sum by (name)( rate(container_cpu_usage_seconds_total{image!="", name!=""}[1m] ) )

container_cpu_usage_seconds_total

这是一个由cAdvisor暴露的metrics,它表示容器使用的CPU秒数。这是一个累积计数器,意味着它的值会随着时间的推移而增加。

{image!="", name!=""}

这是一个标签选择器(label selector),它用于过滤出那些image和name标签都不为空(即存在)的metrics。这通常是为了避免监控那些没有具体名称或镜像的容器(可能是系统或临时容器)。

[1m]

这是一个时间窗口选择器,表示选择过去1分钟的数据。这通常用于与rate函数结合,以计算每秒的速率。

rate(...)

rate函数用于计算计数器在给定时间窗口内的平均每秒增长率。在这个例子中,它计算了container_cpu_usage_seconds_total在过去1分钟内的平均每秒CPU使用率。

sum by (name)

sum by是一个聚合操作符,它会对指定的标签进行分组,并对每个组内的值进行求和。这意味着你会得到一个结果列表,其中每个结果都代表一个具有特定name标签的容器的CPU使用率总和(以每秒CPU秒数为单位)

(五)添加targets后的重启方法

1.热加载

每次修改配置文件可以热加载prometheus,也就是不停止prometheus,就可以使配置生效

curl -X POST -Ls http://Prometheus-IP/-/reload

2.删除后重建

修改完yaml文件后,使用kubectl delete删除之后再重新创建

kubectl delete -f prometheus-cfg.yaml
kubectl delete -f prometheus-deploy.yaml
kubectl apply -f prometheus-cfg.yaml
kubectl apply -f prometheus-deploy.yaml

注释:项目上线后最好使用热加载的方式,避免监控数据丢失

四、部署Grafana

(一)准备镜像

同样的,在节点上预加载镜像,防止因为网络问题,导致镜像加载失败

[root@node01 images]#docker load -i grafana.tar 
8fad67424c4e: Loading layer [=============================>]  129.3MB/129.3MB
5f70bf18a086: Loading layer [=============================>]  1.024kB/1.024kB
07ea00da69ad: Loading layer [=============================>]  179.7MB/179.7MB
2fd837eb56b5: Loading layer [=============================>]  3.584kB/3.584kB
Loaded image: grafana/grafana:5.0.4

或者使用docker pull直接下载

[root@node01 ~]#docker pull grafana/grafana:7.1.5
7.1.5: Pulling from grafana/grafana
Digest: sha256:579044d31fad95f015c78dff8db25c85e2e0f5fdf37f414ce850eb045dd47265
Status: Downloaded newer image for grafana/grafana:7.1.5
docker.io/grafana/grafana:7.1.5

(二)创建Grafana的pod资源

[root@master01 prometheus]#cat grafana.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: monitoring-grafananamespace: kube-system
spec:replicas: 1selector:matchLabels:task: monitoringk8s-app: grafanatemplate:metadata:labels:task: monitoringk8s-app: grafanaspec:containers:- name: grafanaimage: grafana/grafana:5.0.4ports:- containerPort: 3000protocol: TCPvolumeMounts:                     #定义了如何挂载卷到容器中- mountPath: /etc/ssl/certsname: ca-certificatesreadOnly: true- mountPath: /var/lib/grafana/name: grafana-storageenv:                               #定义容器内的环境变量- name: INFLUXDB_HOSTvalue: monitoring-influxdb
#指定了Grafana连接到的InfluxDB数据库的主机名或IP地址- name: GF_SERVER_HTTP_PORTvalue: "3000"
#指定了Grafana HTTP服务器监听的端口- name: GF_AUTH_BASIC_ENABLEDvalue: "false"
#用于启用或禁用Grafana的基本认证,false表示禁用- name: GF_AUTH_ANONYMOUS_ENABLEDvalue: "true"
#用于启用或禁用Grafana的匿名访问,true表示启用- name: GF_AUTH_ANONYMOUS_ORG_ROLEvalue: Admin
#当匿名访问被启用时,这个环境变量定义了匿名用户所拥有的组织角色,Admin表示具有管理员权限- name: GF_SERVER_ROOT_URLvalue: /
#定义了Grafana服务器的根URLvolumes:                              #定义了要挂载到Pod中的卷- name: ca-certificateshostPath:path: /etc/ssl/certs- name: grafana-storageemptyDir: {}

创建资源

[root@master01 prometheus]#kubectl apply -f grafana.yaml
deployment.apps/monitoring-grafana created
[root@master01 prometheus]#kubectl get pod monitoring-grafana-5ccc887d98-ldbb4 -n kube-system 
NAME                                  READY   STATUS    RESTARTS   AGE
monitoring-grafana-5ccc887d98-ldbb4   1/1     Running   0          7s

(三)创建Grafana的svc资源

[root@master01 prometheus]#vim grafana-service.yaml 
[root@master01 prometheus]#cat grafana-service.yaml 
apiVersion: v1
kind: Service
metadata:labels:kubernetes.io/cluster-service: 'true'kubernetes.io/name: monitoring-grafananame: monitoring-grafananamespace: kube-system
spec:ports:- port: 80targetPort: 3000selector:k8s-app: grafanatype: NodePort
[root@master01 prometheus]#kubectl apply -f grafana-service.yaml 
service/monitoring-grafana created
[root@master01 prometheus]#kubectl get svc monitoring-grafana -n kube-system 
NAME                 TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
monitoring-grafana   NodePort   10.96.32.173   <none>        80:32071/TCP   66s

(四)访问Grafana

1.登录grafana

浏览器访问http://192.168.83.40:32071,登陆 grafana

2.配置grafana

【Name】设置成 Prometheus
【Type】选择  Prometheus
【URL】设置成 http://10.96.218.105:9090    

#使用service的集群内部端口配置服务端地址,kubectl get svc -n monitor-sa查看
点击 【Save & Test】

3.导入监控模板

官方链接:https://grafana.com/dashboards?dataSource=prometheus&search=kubernetes

选择适合的面板,点击 Copy ID 或者 Download JSON

3.1 导入node的监控模板

3.1.1 获取监控模板

下载json文件

3.2.2 导入模板

监控 node 状态
点击左侧+号选择【Import】
点击【Upload .json File】导入下载的模板文件
【Prometheus】选择 Prometheus
点击【Import】

3.2 导入监控容器状态模板

3.2.1 获取模板

点击左侧+号选择【Import】
点击【Upload .json File】导入下载的模板文件
【Prometheus】选择 Prometheus
点击【Import】

3.3 导入集群监控模板

3.3.1 获取模板

点击左侧+号选择【Import】
点击【Upload .json File】导入下载的模板文件
【Prometheus】选择 Prometheus
点击【Import】

五、部署kube-state-metrics

kube-state-metrics是一个Kubernetes集群中的重要组件,它的主要作用是收集和暴露Kubernetes资源的状态指标,以便于监控和分析。具体来说,kube-state-metrics的功能可以概括为以下几点:

1.指标收集
kube-state-metrics定期查询Kubernetes API Server,获取集群中各种资源的最新状态,如Pods、Deployments、ReplicaSets、StatefulSets、Jobs、CronJobs、Services、Nodes、DaemonSets、PersistentVolumes、PersistentVolumeClaims、ReplicationControllers等,并将这些信息转换为Prometheus监控系统的指标格式。

2.Prometheus兼容性
收集到的指标是以Prometheus监控系统可以解析的格式输出的,这意味着kube-state-metrics充当了一个Prometheus exporter的角色。Prometheus server可以定期抓取这些指标,进行存储和分析。

3.资源状态可视化
除了被Prometheus抓取之外,kube-state-metrics也可以直接通过HTTP服务器暴露这些指标,便于其他监控工具或前端仪表板(如Grafana)可视化展示资源状态。

4.异常统计
kube-state-metrics还提供了一些关于自身运行状况的指标,比如资源查询失败的次数,这对于监控kube-state-metrics自身的健康状况很有帮助。

资源数量统计:
它还统计并报告各种Kubernetes资源的实例数量,这对于容量规划和资源管理非常有用。

5.事件与状态
kube-state-metrics能够捕获Kubernetes资源的事件和状态变化,如Pod的启动、终止、重启次数,Deployment的滚动更新状态,以及Job的运行情况等

(一)部署kube-state-metrics

1.创建sa账号并授权

创建serviceaccount用户账号,并授予指定组的权限,使其对k8s资源有管理的权限,能够收集到资源信息

[root@master01 prometheus]#vim kube-state-metrics-rbac.yaml
[root@master01 prometheus]#cat kube-state-metrics-rbac.yaml
#创建账号
apiVersion: v1
kind: ServiceAccount
metadata:name: kube-state-metricsnamespace: kube-system
---
#创建集群角色,并指定角色权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: kube-state-metrics
rules:
- apiGroups: [""]resources: ["nodes", "pods", "services", "resourcequotas", "replicationcontrollers", "limitranges", "persistentvolumeclaims", "persistentvolumes", "namespaces", "endpoints"]verbs: ["list", "watch"]
- apiGroups: ["extensions"]resources: ["daemonsets", "deployments", "replicasets"]verbs: ["list", "watch"]
- apiGroups: ["apps"]resources: ["statefulsets"]verbs: ["list", "watch"]
- apiGroups: ["batch"]resources: ["cronjobs", "jobs"]verbs: ["list", "watch"]
- apiGroups: ["autoscaling"]resources: ["horizontalpodautoscalers"]verbs: ["list", "watch"]
---
#对用户与集群角色进行绑定,使创建的用户有一定的权限去管理,并获取资源信息
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: kube-state-metrics
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: kube-state-metrics
subjects:
- kind: ServiceAccountname: kube-state-metricsnamespace: kube-system

创建并查看信息

[root@master01 prometheus]#kubectl apply -f kube-state-metrics-rbac.yaml
serviceaccount/kube-state-metrics created
clusterrole.rbac.authorization.k8s.io/kube-state-metrics created
clusterrolebinding.rbac.authorization.k8s.io/kube-state-metrics created
[root@master01 prometheus]#kubectl get sa kube-state-metrics -n kube-system 
NAME                 SECRETS   AGE
kube-state-metrics   1         42s
[root@master01 prometheus]#kubectl get clusterrolebindings kube-state-metrics -n kube-system
NAME                 ROLE                             AGE
kube-state-metrics   ClusterRole/kube-state-metrics   58s

2.安装kube-state-metrics组件

2.1 获取镜像

[root@node01 images]#docker load -i kube-state-metrics.tar 
932da5156413: Loading layer [================================>]  3.062MB/3.062MB
bd8df7c22fdb: Loading layer [================================>]     31MB/31MB
Loaded image: quay.io/coreos/kube-state-metrics:v1.9.0

或者使用docker pull下载

docker pull quay.io/coreos/kube-state-metrics

2.2 创建服务

[root@master01 prometheus]#vim kube-state-metrics-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: kube-state-metricsnamespace: kube-system
spec:replicas: 1selector:matchLabels:app: kube-state-metricstemplate:metadata:labels:app: kube-state-metricsspec:serviceAccountName: kube-state-metricscontainers:- name: kube-state-metricsimage: quay.io/coreos/kube-state-metrics:v1.9.0ports:- containerPort: 8080[root@master01 prometheus]#kubectl get pod kube-state-metrics-58d4957bc5-m94fv -o wide -n kube-system
NAME                                  READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
kube-state-metrics-58d4957bc5-m94fv   1/1     Running   0          24s   10.244.1.59   node01   <none>           <none>

3.创建service资源

[root@master01 prometheus]#vim  kube-state-metrics-svc.yaml 
[root@master01 prometheus]#cat  kube-state-metrics-svc.yaml 
apiVersion: v1
kind: Service
metadata:annotations:prometheus.io/scrape: 'true'   #注解信息,表示从此端点抓取数据name: kube-state-metricsnamespace: kube-systemlabels:app: kube-state-metrics
spec:ports:- name: kube-state-metricsport: 8080protocol: TCPselector:app: kube-state-metrics
[root@master01 prometheus]#kubectl apply -f kube-state-metrics-svc.yaml 
service/kube-state-metrics created
[root@master01 prometheus]#kubectl get svc kube-state-metrics -o wide -n kube-system
NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE   SELECTOR
kube-state-metrics   ClusterIP   10.96.80.21   <none>        8080/TCP   16s   app=kube-state-metrics

(二)配置Grafana

1.配置k8s群集状态

配置k8s群集状态的监控信息

1.1 获取模板

1.2 添加模板

点击左侧+号选择【Import】
点击【Upload .json File】导入下载的模板文件
【Prometheus】选择 Prometheus
点击【Import】

2.配置kube-state-metrics

2.1 获取模板文件

2.2 添加模板文件

点击左侧+号选择【Import】
点击【Upload .json File】导入下载的模板文件
【Prometheus】选择 Prometheus
点击【Import】

六、部署alertmanager

Alertmanager是一个开源的告警管理工具,主要用于处理来自于监控系统(如Prometheus)的告警。其设计目标是提供一个统一的告警处理平台,能够集中管理告警的路由、去重、分组和通知等操作。在现代云服务架构中,Alertmanager扮演着至关重要的角色,确保关键系统和服务的可靠性和稳定性

具体来说,Alertmanager的作用包括:

  1. 接收告警数据:从Prometheus等客户端接收告警信息。
  2. 告警处理:对接收到的告警信息进行去重、降噪、分组等处理,确保告警的及时性和准确性。
  3. 告警通知:根据路由规则将告警信息分发给指定的接收渠道,如邮件、Slack、Webhook等,支持多种通知方式。
  4. 告警优化:提供静默和告警抑制机制,对告警通知行为进行优化。

(一)Alertmanager的工作流程

Prometheus报警处理流程
1)Prometheus Server 监控目标主机上暴露的 http接口(假设接口A),通过Promethes配置的'scrape_interval' 定义的时间间隔, 定期采集目标主机上监控数据。

2)当接口A不可用的时候,Server 端会持续的尝试从接口中取数据,直到 "scrape_timeout" 时间后停止尝试。 这时候把接口的状态变为 "DOWN"。

3)Prometheus 同时根据配置的 evaluation_interval 的时间间隔,定期(默认1min)的对 Alert Rule 进行评估; 当到达评估周期的时候,发现接口A为 DOWN,即 UP=0 为真,激活 Alert,进入 PENDING 状态,并记录当前 active 的时间;

4)当下一个 alert rule 的评估周期到来的时候,发现 UP=0 继续为真,然后判断警报 Active 的时间是否已经超出 rule 里的 for 持续时间,如果未超出,则进入下一个评估周期;如果时间超出,则 alert 的状态变为 FIRING;同时调用 Alertmanager 接口, 发送相关报警数据。

5)AlertManager 收到报警数据后,会将警报信息进行分组,然后根据 alertmanager 配置的 group_wait 时间先进行等待。等 wait 时间过后再发送报警信息。

6)属于同一个 Alert Group的警报,在等待的过程中可能进入新的 alert,如果之前的报警已经成功发出,那么间隔 group_interval 的时间间隔后再重新发送报警信息。比如配置的是邮件报警,那么同属一个 group 的报警信息会汇总在一个邮件里进行发送。

7)如果 Alert Group里的警报一直没发生变化并且已经成功发送,等待 repeat_interval 时间间隔之后再重复发送相同的报警邮件; 如果之前的警报没有成功发送,则相当于触发第6条条件,则需要等待 group_interval 时间间隔后重复发送。

8)同时最后至于警报信息具体发给谁,满足什么样的条件下指定警报接收人,设置不同报警发送频率,这里使用 alertmanager 的 route 路由规则进行配置。

(二)部署Alertmanager

1.创建alertmanager配置文件

以ConfigMap的形式,创建alertmanager的配置文件,即报警规则,用于全局的,邮件的发送端与接收端。而后再将alertmanager的ConfigMap文件,添加到生成Prometheus服务即配置文件的yaml文件当中,重新创建

[root@master01 prometheus]#vim alertmanager-cm.yaml
[root@master01 prometheus]#cat alertmanager-cm.yaml
kind: ConfigMap
apiVersion: v1
metadata:name: alertmanagernamespace: monitor-sa
data:alertmanager.yml: |-global:                                     #设置发件人邮箱信息resolve_timeout: 1m                       #告警被标记为已解决之前等待的时间smtp_smarthost: 'smtp.qq.com:25'          #SMTP 服务器地址和端口,用于发送电子邮件smtp_from: '1234567890@qq.com'            #发送电子邮件时使用的发件人地址smtp_auth_username: '123456789@qq.com'    #SMTP 认证的用户名smtp_auth_password: 'ygljeciudfinbchf'    #SMTP 认证的密码,为QQ邮箱的授权码smtp_require_tls: false                   #关闭TLS连接route:                                      #告警路由配置group_by: [alertname]                     #用于分组告警的字段列表group_wait: 10s                           #等待10s来合并新的告警,以便将它们一起发送group_interval: 10s                       #发送一组新的告警后,等待10s来合并新的告警repeat_interval: 10m                      #尚未解决的告警,重新发送通知的间隔时间receiver: default-receiver                #默认的接收者名称receivers:                                  #接收者列表信息- name: 'default-receiver'                  #接收者的名称与上述一致email_configs:                            #电子邮件接收者配置- to: '987654321@139.com'                 #接收告警通知的电子邮件地址send_resolved: true                     #当告警被标记为已解决时,发送通知
[root@master01 prometheus]#kubectl apply -f alertmanager-cm.yaml 
configmap/alertmanager created
[root@master01 prometheus]#kubectl get configmaps alertmanager -n monitor-sa 
NAME           DATA   AGE
alertmanager   1      16s

2.创建prometheus和告警规则配置文件

[root@master01 prometheus]#cat prometheus-alertmanager-cfg.yaml
kind: ConfigMap
apiVersion: v1
metadata:labels:app: prometheusname: prometheus-confignamespace: monitor-sa
data:prometheus.yml: |rule_files:- "rules.yml"alerting:alertmanagers:- static_configs:- targets: ["localhost:9093"]global:scrape_interval: 15sscrape_timeout: 10sevaluation_interval: 1mscrape_configs:- job_name: 'kubernetes-node'kubernetes_sd_configs:- role: noderelabel_configs:- source_labels: [__address__]regex: '(.*):10250'replacement: '${1}:9100'target_label: __address__action: replace- action: labelmapregex: __meta_kubernetes_node_label_(.+)- job_name: 'kubernetes-node-cadvisor'kubernetes_sd_configs:- role:  nodescheme: httpstls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenrelabel_configs:- action: labelmapregex: __meta_kubernetes_node_label_(.+)- target_label: __address__replacement: kubernetes.default.svc:443- source_labels: [__meta_kubernetes_node_name]regex: (.+)target_label: __metrics_path__replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor- job_name: 'kubernetes-apiserver'kubernetes_sd_configs:- role: endpointsscheme: httpstls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenrelabel_configs:- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]action: keepregex: default;kubernetes;https- job_name: 'kubernetes-service-endpoints'kubernetes_sd_configs:- role: endpointsrelabel_configs:- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]action: keepregex: true- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]action: replacetarget_label: __scheme__regex: (https?)- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]action: replacetarget_label: __metrics_path__regex: (.+)- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]action: replacetarget_label: __address__regex: ([^:]+)(?::\d+)?;(\d+)replacement: $1:$2- action: labelmapregex: __meta_kubernetes_service_label_(.+)- source_labels: [__meta_kubernetes_namespace]action: replacetarget_label: kubernetes_namespace- source_labels: [__meta_kubernetes_service_name]action: replacetarget_label: kubernetes_name - job_name: 'kubernetes-pods'kubernetes_sd_configs:- role: podrelabel_configs:- action: keepregex: truesource_labels:- __meta_kubernetes_pod_annotation_prometheus_io_scrape- action: replaceregex: (.+)source_labels:- __meta_kubernetes_pod_annotation_prometheus_io_pathtarget_label: __metrics_path__- action: replaceregex: ([^:]+)(?::\d+)?;(\d+)replacement: $1:$2source_labels:- __address__- __meta_kubernetes_pod_annotation_prometheus_io_porttarget_label: __address__- action: labelmapregex: __meta_kubernetes_pod_label_(.+)- action: replacesource_labels:- __meta_kubernetes_namespacetarget_label: kubernetes_namespace- action: replacesource_labels:- __meta_kubernetes_pod_nametarget_label: kubernetes_pod_name- job_name: 'kubernetes-schedule'scrape_interval: 5sstatic_configs:- targets: ['192.168.83.30:10251']     #masterIP地址的kubernetes-controlle端口- job_name: 'kubernetes-controller-manager'scrape_interval: 5sstatic_configs:- targets: ['192.168.83.30:10252']     #masterIP地址的kubernetes-controlle端口- job_name: 'kubernetes-kube-proxy'scrape_interval: 5sstatic_configs:- targets: ['192.168.83.30:10249','192.168.83.40:10249','192.168.83.50:10249']
#所有节点的kube-proxy端口- job_name: 'kubernetes-etcd'scheme: httpstls_config:ca_file: /var/run/secrets/kubernetes.io/k8s-certs/etcd/ca.crtcert_file: /var/run/secrets/kubernetes.io/k8s-certs/etcd/server.crtkey_file: /var/run/secrets/kubernetes.io/k8s-certs/etcd/server.keyscrape_interval: 5sstatic_configs:- targets: ['192.168.83.30:2379']rules.yml: |groups:- name: examplerules:- alert: kube-proxy的cpu使用率大于80%expr: rate(process_cpu_seconds_total{job=~"kubernetes-kube-proxy"}[1m]) * 100 > 80for: 2slabels:severity: warnningannotations:description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过80%"- alert:  kube-proxy的cpu使用率大于90%expr: rate(process_cpu_seconds_total{job=~"kubernetes-kube-proxy"}[1m]) * 100 > 90for: 2slabels:severity: criticalannotations:description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过90%"- alert: scheduler的cpu使用率大于80%expr: rate(process_cpu_seconds_total{job=~"kubernetes-schedule"}[1m]) * 100 > 80for: 2slabels:severity: warnningannotations:description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过80%"- alert:  scheduler的cpu使用率大于90%expr: rate(process_cpu_seconds_total{job=~"kubernetes-schedule"}[1m]) * 100 > 90for: 2slabels:severity: criticalannotations:description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过90%"- alert: controller-manager的cpu使用率大于80%expr: rate(process_cpu_seconds_total{job=~"kubernetes-controller-manager"}[1m]) * 100 > 80for: 2slabels:severity: warnningannotations:description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过80%"- alert:  controller-manager的cpu使用率大于90%expr: rate(process_cpu_seconds_total{job=~"kubernetes-controller-manager"}[1m]) * 100 > 0for: 2slabels:severity: criticalannotations:description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过90%"- alert: apiserver的cpu使用率大于80%expr: rate(process_cpu_seconds_total{job=~"kubernetes-apiserver"}[1m]) * 100 > 80for: 2slabels:severity: warnningannotations:description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过80%"- alert:  apiserver的cpu使用率大于90%expr: rate(process_cpu_seconds_total{job=~"kubernetes-apiserver"}[1m]) * 100 > 90for: 2slabels:severity: criticalannotations:description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过90%"- alert: etcd的cpu使用率大于80%expr: rate(process_cpu_seconds_total{job=~"kubernetes-etcd"}[1m]) * 100 > 80for: 2slabels:severity: warnningannotations:description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过80%"- alert:  etcd的cpu使用率大于90%expr: rate(process_cpu_seconds_total{job=~"kubernetes-etcd"}[1m]) * 100 > 90for: 2slabels:severity: criticalannotations:description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过90%"- alert: kube-state-metrics的cpu使用率大于80%expr: rate(process_cpu_seconds_total{k8s_app=~"kube-state-metrics"}[1m]) * 100 > 80for: 2slabels:severity: warnningannotations:description: "{{$labels.instance}}的{{$labels.k8s_app}}组件的cpu使用率超过80%"value: "{{ $value }}%"threshold: "80%"      - alert: kube-state-metrics的cpu使用率大于90%expr: rate(process_cpu_seconds_total{k8s_app=~"kube-state-metrics"}[1m]) * 100 > 0for: 2slabels:severity: criticalannotations:description: "{{$labels.instance}}的{{$labels.k8s_app}}组件的cpu使用率超过90%"value: "{{ $value }}%"threshold: "90%"      - alert: coredns的cpu使用率大于80%expr: rate(process_cpu_seconds_total{k8s_app=~"kube-dns"}[1m]) * 100 > 80for: 2slabels:severity: warnningannotations:description: "{{$labels.instance}}的{{$labels.k8s_app}}组件的cpu使用率超过80%"value: "{{ $value }}%"threshold: "80%"      - alert: coredns的cpu使用率大于90%expr: rate(process_cpu_seconds_total{k8s_app=~"kube-dns"}[1m]) * 100 > 90for: 2slabels:severity: criticalannotations:description: "{{$labels.instance}}的{{$labels.k8s_app}}组件的cpu使用率超过90%"value: "{{ $value }}%"threshold: "90%"      - alert: kube-proxy打开句柄数>600expr: process_open_fds{job=~"kubernetes-kube-proxy"}  > 600for: 2slabels:severity: warnningannotations:description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>600"value: "{{ $value }}"- alert: kube-proxy打开句柄数>1000expr: process_open_fds{job=~"kubernetes-kube-proxy"}  > 1000for: 2slabels:severity: criticalannotations:description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>1000"value: "{{ $value }}"- alert: kubernetes-schedule打开句柄数>600expr: process_open_fds{job=~"kubernetes-schedule"}  > 600for: 2slabels:severity: warnningannotations:description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>600"value: "{{ $value }}"- alert: kubernetes-schedule打开句柄数>1000expr: process_open_fds{job=~"kubernetes-schedule"}  > 1000for: 2slabels:severity: criticalannotations:description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>1000"value: "{{ $value }}"- alert: kubernetes-controller-manager打开句柄数>600expr: process_open_fds{job=~"kubernetes-controller-manager"}  > 600for: 2slabels:severity: warnningannotations:description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>600"value: "{{ $value }}"- alert: kubernetes-controller-manager打开句柄数>1000expr: process_open_fds{job=~"kubernetes-controller-manager"}  > 1000for: 2slabels:severity: criticalannotations:description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>1000"value: "{{ $value }}"- alert: kubernetes-apiserver打开句柄数>600expr: process_open_fds{job=~"kubernetes-apiserver"}  > 600for: 2slabels:severity: warnningannotations:description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>600"value: "{{ $value }}"- alert: kubernetes-apiserver打开句柄数>1000expr: process_open_fds{job=~"kubernetes-apiserver"}  > 1000for: 2slabels:severity: criticalannotations:description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>1000"value: "{{ $value }}"- alert: kubernetes-etcd打开句柄数>600expr: process_open_fds{job=~"kubernetes-etcd"}  > 600for: 2slabels:severity: warnningannotations:description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>600"value: "{{ $value }}"- alert: kubernetes-etcd打开句柄数>1000expr: process_open_fds{job=~"kubernetes-etcd"}  > 1000for: 2slabels:severity: criticalannotations:description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>1000"value: "{{ $value }}"- alert: corednsexpr: process_open_fds{k8s_app=~"kube-dns"}  > 600for: 2slabels:severity: warnning annotations:description: "插件{{$labels.k8s_app}}({{$labels.instance}}): 打开句柄数超过600"value: "{{ $value }}"- alert: corednsexpr: process_open_fds{k8s_app=~"kube-dns"}  > 1000for: 2slabels:severity: criticalannotations:description: "插件{{$labels.k8s_app}}({{$labels.instance}}): 打开句柄数超过1000"value: "{{ $value }}"- alert: kube-proxyexpr: process_virtual_memory_bytes{job=~"kubernetes-kube-proxy"}  > 2000000000for: 2slabels:severity: warnningannotations:description: "组件{{$labels.job}}({{$labels.instance}}): 使用虚拟内存超过2G"value: "{{ $value }}"- alert: schedulerexpr: process_virtual_memory_bytes{job=~"kubernetes-schedule"}  > 2000000000for: 2slabels:severity: warnningannotations:description: "组件{{$labels.job}}({{$labels.instance}}): 使用虚拟内存超过2G"value: "{{ $value }}"- alert: kubernetes-controller-managerexpr: process_virtual_memory_bytes{job=~"kubernetes-controller-manager"}  > 2000000000for: 2slabels:severity: warnningannotations:description: "组件{{$labels.job}}({{$labels.instance}}): 使用虚拟内存超过2G"value: "{{ $value }}"- alert: kubernetes-apiserverexpr: process_virtual_memory_bytes{job=~"kubernetes-apiserver"}  > 2000000000for: 2slabels:severity: warnningannotations:description: "组件{{$labels.job}}({{$labels.instance}}): 使用虚拟内存超过2G"value: "{{ $value }}"- alert: kubernetes-etcdexpr: process_virtual_memory_bytes{job=~"kubernetes-etcd"}  > 2000000000for: 2slabels:severity: warnningannotations:description: "组件{{$labels.job}}({{$labels.instance}}): 使用虚拟内存超过2G"value: "{{ $value }}"- alert: kube-dnsexpr: process_virtual_memory_bytes{k8s_app=~"kube-dns"}  > 2000000000for: 2slabels:severity: warnningannotations:description: "插件{{$labels.k8s_app}}({{$labels.instance}}): 使用虚拟内存超过2G"value: "{{ $value }}"- alert: HttpRequestsAvgexpr: sum(rate(rest_client_requests_total{job=~"kubernetes-kube-proxy|kubernetes-kubelet|kubernetes-schedule|kubernetes-control-manager|kubernetes-apiservers"}[1m]))  > 1000for: 2slabels:team: adminannotations:description: "组件{{$labels.job}}({{$labels.instance}}): TPS超过1000"value: "{{ $value }}"threshold: "1000"   - alert: Pod_restartsexpr: kube_pod_container_status_restarts_total{namespace=~"kube-system|default|monitor-sa"} > 0for: 2slabels:severity: warnningannotations:description: "在{{$labels.namespace}}名称空间下发现{{$labels.pod}}这个pod下的容器{{$labels.container}}被重启,这个监控指标是由{{$labels.instance}}采集的"value: "{{ $value }}"threshold: "0"- alert: Pod_waitingexpr: kube_pod_container_status_waiting_reason{namespace=~"kube-system|default"} == 1for: 2slabels:team: adminannotations:description: "空间{{$labels.namespace}}({{$labels.instance}}): 发现{{$labels.pod}}下的{{$labels.container}}启动异常等待中"value: "{{ $value }}"threshold: "1"   - alert: Pod_terminatedexpr: kube_pod_container_status_terminated_reason{namespace=~"kube-system|default|monitor-sa"} == 1for: 2slabels:team: adminannotations:description: "空间{{$labels.namespace}}({{$labels.instance}}): 发现{{$labels.pod}}下的{{$labels.container}}被删除"value: "{{ $value }}"threshold: "1"- alert: Etcd_leaderexpr: etcd_server_has_leader{job="kubernetes-etcd"} == 0for: 2slabels:team: adminannotations:description: "组件{{$labels.job}}({{$labels.instance}}): 当前没有leader"value: "{{ $value }}"threshold: "0"- alert: Etcd_leader_changesexpr: rate(etcd_server_leader_changes_seen_total{job="kubernetes-etcd"}[1m]) > 0for: 2slabels:team: adminannotations:description: "组件{{$labels.job}}({{$labels.instance}}): 当前leader已发生改变"value: "{{ $value }}"threshold: "0"- alert: Etcd_failedexpr: rate(etcd_server_proposals_failed_total{job="kubernetes-etcd"}[1m]) > 0for: 2slabels:team: adminannotations:description: "组件{{$labels.job}}({{$labels.instance}}): 服务失败"value: "{{ $value }}"threshold: "0"- alert: Etcd_db_total_sizeexpr: etcd_debugging_mvcc_db_total_size_in_bytes{job="kubernetes-etcd"} > 10000000000for: 2slabels:team: adminannotations:description: "组件{{$labels.job}}({{$labels.instance}}):db空间超过10G"value: "{{ $value }}"threshold: "10G"- alert: Endpoint_readyexpr: kube_endpoint_address_not_ready{namespace=~"kube-system|default"} == 1for: 2slabels:team: adminannotations:description: "空间{{$labels.namespace}}({{$labels.instance}}): 发现{{$labels.endpoint}}不可用"value: "{{ $value }}"threshold: "1"- name: 物理节点状态-监控告警rules:- alert: 物理节点cpu使用率expr: 100-avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by(instance)*100 > 90for: 2slabels:severity: ccriticalannotations:summary: "{{ $labels.instance }}cpu使用率过高"description: "{{ $labels.instance }}的cpu使用率超过90%,当前使用率[{{ $value }}],需要排查处理" - alert: 物理节点内存使用率expr: (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes)) / node_memory_MemTotal_bytes * 100 > 90for: 2slabels:severity: criticalannotations:summary: "{{ $labels.instance }}内存使用率过高"description: "{{ $labels.instance }}的内存使用率超过90%,当前使用率[{{ $value }}],需要排查处理"- alert: InstanceDownexpr: up == 0for: 2slabels:severity: criticalannotations:   summary: "{{ $labels.instance }}: 服务器宕机"description: "{{ $labels.instance }}: 服务器延时超过2分钟"- alert: 物理节点磁盘的IO性能expr: 100-(avg(irate(node_disk_io_time_seconds_total[1m])) by(instance)* 100) < 60for: 2slabels:severity: criticalannotations:summary: "{{$labels.mountpoint}} 流入磁盘IO使用率过高!"description: "{{$labels.mountpoint }} 流入磁盘IO大于60%(目前使用:{{$value}})"- alert: 入网流量带宽expr: ((sum(rate (node_network_receive_bytes_total{device!~'tap.*|veth.*|br.*|docker.*|virbr*|lo*'}[5m])) by (instance)) / 100) > 102400for: 2slabels:severity: criticalannotations:summary: "{{$labels.mountpoint}} 流入网络带宽过高!"description: "{{$labels.mountpoint }}流入网络带宽持续5分钟高于100M. RX带宽使用率{{$value}}"- alert: 出网流量带宽expr: ((sum(rate (node_network_transmit_bytes_total{device!~'tap.*|veth.*|br.*|docker.*|virbr*|lo*'}[5m])) by (instance)) / 100) > 102400for: 2slabels:severity: criticalannotations:summary: "{{$labels.mountpoint}} 流出网络带宽过高!"description: "{{$labels.mountpoint }}流出网络带宽持续5分钟高于100M. RX带宽使用率{{$value}}"- alert: TCP会话expr: node_netstat_Tcp_CurrEstab > 1000for: 2slabels:severity: criticalannotations:summary: "{{$labels.mountpoint}} TCP_ESTABLISHED过高!"description: "{{$labels.mountpoint }} TCP_ESTABLISHED大于1000%(目前使用:{{$value}}%)"- alert: 磁盘容量expr: 100-(node_filesystem_free_bytes{fstype=~"ext4|xfs"}/node_filesystem_size_bytes {fstype=~"ext4|xfs"}*100) > 80for: 2slabels:severity: criticalannotations:summary: "{{$labels.mountpoint}} 磁盘分区使用率过高!"description: "{{$labels.mountpoint }} 磁盘分区使用大于80%(目前使用:{{$value}}%)"

删除之前的配置,更新配置

[root@master01 prometheus]#kubectl delete -f prometheus-cfg.yaml
configmap "prometheus-config" deleted
[root@master01 prometheus]#kubectl get configmaps -n monitor-sa 
NAME               DATA   AGE
alertmanager       1      10m
kube-root-ca.crt   1      47h
[root@master01 prometheus]#kubectl apply -f prometheus-alertmanager-cfg.yaml
configmap/prometheus-config created
[root@master01 prometheus]#kubectl get configmaps -n monitor-sa 
NAME                DATA   AGE
alertmanager        1      10m
kube-root-ca.crt    1      47h
prometheus-config   2      3s

3.安装prometheus和alertmanager

3.1 创建secret资源

生成一个 secret 资源 etcd-certs,这个在部署 prometheus 需要,用于监控 etcd 相关资

[root@master01 prometheus]#kubectl -n monitor-sa create secret generic etcd-certs --from-file=/etc/kubernetes/pki/etcd/server.key  --from-file=/etc/kubernetes/pki/etcd/server.crt --from-file=/etc/kubernetes/pki/etcd/ca.crt
secret/etcd-certs created
[root@master01 prometheus]#kubectl get secret etcd-certs -n monitor-sa 
NAME         TYPE     DATA   AGE
etcd-certs   Opaque   3      33s
3.2 创建资源清单

更新资源清单 yaml 文件,安装 prometheus 和 alertmanage

[root@master01 prometheus]#cat prometheus-alertmanager-deploy.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:name: prometheus-servernamespace: monitor-salabels:app: prometheus
spec:replicas: 1selector:matchLabels:app: prometheuscomponent: servertemplate:metadata:labels:app: prometheuscomponent: serverannotations:prometheus.io/scrape: 'false'spec:nodeName: node01serviceAccountName: monitorcontainers:- name: prometheusimage: prom/prometheus:v2.2.1imagePullPolicy: IfNotPresentcommand:- "/bin/prometheus"args:- "--config.file=/etc/prometheus/prometheus.yml"- "--storage.tsdb.path=/prometheus"- "--storage.tsdb.retention=24h"- "--web.enable-lifecycle"ports:- containerPort: 9090protocol: TCPvolumeMounts:- mountPath: /etc/prometheusname: prometheus-config- mountPath: /prometheus/name: prometheus-storage-volume- name: k8s-certsmountPath: /var/run/secrets/kubernetes.io/k8s-certs/etcd/- name: localtimemountPath: /etc/localtime- name: alertmanagerimage: prom/alertmanager:v0.14.0imagePullPolicy: IfNotPresentargs:- "--config.file=/etc/alertmanager/alertmanager.yml"- "--log.level=debug"ports:- containerPort: 9093protocol: TCPname: alertmanagervolumeMounts:- name: alertmanager-configmountPath: /etc/alertmanager- name: alertmanager-storagemountPath: /alertmanager- name: localtimemountPath: /etc/localtimevolumes:- name: prometheus-configconfigMap:name: prometheus-config- name: prometheus-storage-volumehostPath:path: /datatype: Directory- name: k8s-certssecret:secretName: etcd-certs- name: alertmanager-configconfigMap:name: alertmanager- name: alertmanager-storagehostPath:path: /data/alertmanagertype: DirectoryOrCreate- name: localtimehostPath:path: /usr/share/zoneinfo/Asia/Shanghai

创建资源

[root@master01 prometheus]#kubectl delete -f prometheus-deploy.yaml
deployment.apps "prometheus-server" deleted
[root@master01 prometheus]#kubectl apply -f prometheus-alertmanager-deploy.yaml
deployment.apps/prometheus-server created
[root@master01 prometheus]#kubectl get pod prometheus-server-6dcf7665cc-g95ld -n monitor-sa 
NAME                                 READY   STATUS    RESTARTS   AGE
prometheus-server-6dcf7665cc-g95ld   2/2     Running   0          19s

(三)部署alertmanager的service

[root@master01 prometheus]#cat alertmanager-svc.yaml 
apiVersion: v1
kind: Service
metadata:labels:name: prometheuskubernetes.io/cluster-service: 'true'name: alertmanagernamespace: monitor-sa
spec:ports:- name: alertmanagernodePort: 30066port: 9093protocol: TCPtargetPort: 9093selector:app: prometheussessionAffinity: Nonetype: NodePort
[root@master01 prometheus]#kubectl apply -f alertmanager-svc.yaml
service/alertmanager created
[root@master01 prometheus]#kubectl get svc alertmanager -n monitor-sa 
NAME           TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
alertmanager   NodePort   10.96.181.208   <none>        9093:30066/TCP   13s

(四)访问alertmanager

浏览器访问 http://192.168.83.40:30066/#/alerts ,登陆 alertmanager

查看接收到的邮件报警,可以发现与 alertmanager 显示的告警一致

(五)处理kube-proxy监控告警

因为 kube-proxy 默认端口10249是监听在 127.0.0.1 上的,需要改成监听到物理节点上

原先的监听地址

[root@master01 prometheus]#ss -natp |grep 10249
LISTEN     0      128    127.0.0.1:10249                    *:*                   users:(("kube-proxy",pid=3966,fd=14))

修改kube-proxy监控地址

[root@master01 prometheus]#kubectl edit configmap kube-proxy -n kube-system
......kind: KubeProxyConfigurationmetricsBindAddress: "0.0.0.0:10249"mode: ipvs
......

重新启动kube-proxy

[root@master01 prometheus]#kubectl get pods -n kube-system | grep kube-proxy |awk '{print $1}' | xargs kubectl delete pods -n kube-system
pod "kube-proxy-psdnv" deleted
pod "kube-proxy-zmh82" deleted
pod "kube-proxy-zwnx2" deleted
#删除之后daemonsets控制器会在每个节点上重新创建一个
[root@master01 prometheus]#kubectl get daemonsets.apps  -n kube-system 
NAME         DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
kube-proxy   3         3         3       3            3           kubernetes.io/os=linux   30d//在节点进行查看
[root@master01 prometheus]#ss -natp |grep 10249
LISTEN     0      128         :::10249                   :::*                   users:(("kube-proxy",pid=68880,fd=14)

alert 查看
点击 prometheus 页面的 Alerts,点开一个告警项,FIRING 表示 prometheus 已经将告警发给alertmanager,在 Alertmanager 中可以看到有一个alert。登录到浏览器访问 http://192.168.83.40:30066/#/alerts ,登陆alertmanager即可看到

邮箱查看

告警信息一致

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

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

相关文章

厂里资讯之app端文章查看

文章列表加载 需求分析 文章布局展示 表结构分析 ap_article 文章基本信息表 ap_article_config 文章配置表 ap_article_content 文章内容表 三张表关系分析 根据数据库设计的表生成对应的实体类 ap_article文章表对应实体 package com.kjz.model.article.pojos;import co…

2024.6.16 机器学习周报

目录 引言 Abstract 文献阅读 1、题目 2、引言 3、创新点 4、匹配问题 5、SuperGlue架构 5.1、注意力图神经网络&#xff08;Attentional Graph Neural Network&#xff09; 5.2、最佳匹配层&#xff08;Optimal matching layer&#xff09; 5.3、损失 6、实验 6.…

【教程】Linux设置进程的优先级

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 关键指令 sudo chrt -f <优先级> <指令> 示例脚本 当然也可以不是启动Python脚本&#xff0c;普通的指令都可以&#xff0c;可自行适当修…

38、基于卷积神经网络(CNN)的车牌自动识别系统(matlab)

1、原理及流程 1&#xff09;原理 CNN&#xff08;卷积神经网络&#xff09;是一种深度学习模型&#xff0c;可以用于图像识别和分类任务。车牌自动识别系统的原理基本上就是使用CNN模型对车牌图像进行处理和识别。 首先&#xff1a;系统需要收集大量的含有车牌的图像数据作…

平板消解加热台-温度均匀,防腐蚀-实验室化学分析

DBF系列防腐电热板 是精致路合金加热板块表面经进口高纯实验级PFATeflon氟塑料防腐不粘处理&#xff0c;专为实验室设计的电加热产品&#xff0c;是样品前处理中&#xff0c;加热、消解、煮沸、蒸酸、赶酸等处理的得力助手。可以满足物理、化学、生物、环保、制药、食品、饮品…

黑马头条Minio报错non-xml response from server错误的解决方法

今天在写项目的时候&#xff0c;想测试minio上传文件功能是否正常&#xff0c; 但是每次都出现non-xml response from server的错误。 自己也在网上找了很多解决方法&#xff0c;大部分是说用户名和密码的配置问题&#xff0c;但是检查后发现并没有错误。 最后发现是自己的dock…

Bio-Info每日一题:Rosalind-07-Mendel‘s First Law(孟德尔第一定律 python实现)

&#x1f389; 进入生物信息学的世界&#xff0c;与Rosalind一起探索吧&#xff01;&#x1f9ec; Rosalind是一个在线平台&#xff0c;专为学习和实践生物信息学而设计。该平台提供了一系列循序渐进的编程挑战&#xff0c;帮助用户从基础到高级掌握生物信息学知识。无论你是初…

53. QT插件开发--插件(动态库so)的调用与加载

1. 说明 在使用QT进行插件库的开发之后,还需要将这个插件库程序生成的so动态链接库加载到主程序框架中进行使用,才能达到主程序的模块化开发的效果。在前一篇文章插件创建中介绍了如何在QT中开发插件库,并提供外部接口调用。本篇博客的主要作用是模拟在主程序框架中加载动态…

深度学习Day-20:DenseNet算法实战 乳腺癌识别

&#x1f368; 本文为&#xff1a;[&#x1f517;365天深度学习训练营] 中的学习记录博客 &#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制] 一、 基础配置 语言环境&#xff1a;Python3.8编译器选择&#xff1a;Pycharm深度学习环境&#xff1a; torch1.12.1c…

在表格中渲染轮播图的方法;

效果图&#xff1a;代码&#xff1a; shop()function shop() {// render()$.ajax({url: "http://jingxun.zhbbll.asia/pc/Commodity/shop_list", //要请求的后端地址type: "GET", //数据发送的方式(POST或者GET)dataType: JSON,headers: {token: token,id…

双Token方案实现Token自动续期(基于springboot+vue前后端分离项目)

文章目录 前言一、双Token方案介绍1. 令牌类型与功能2.双Token方案的优点3.实现流程 二、具体实现1.后端实现1.1 jwt工具类1.2 响应工具类1.3 实体类1.4 过滤器1.5 controller1.6 启动类 2、前端实现2.1 登录页面2.2 index页面2.3 请求拦截器和响应拦截器 效果展示 前言 更多j…

【星座运势】本周财运分析,巨蟹座财富潜力大开!

大家好&#xff01;今天我们来谈谈巨蟹座本周的财富运势。经过调查和数据分析&#xff0c;我发现巨蟹座这周的财运潜力很大&#xff01;接下来&#xff0c;我将用通俗易懂的语言&#xff0c;通过代码说明&#xff0c;向大家展示巨蟹座的财富运势。 首先&#xff0c;我们需要通…

人工智能对零售业的影响

机器人、人工智能相关领域 news/events &#xff08;专栏目录&#xff09; 本文目录 一、人工智能如何改变零售格局二、利用人工智能实现购物体验自动化三、利用人工智能改善库存管理四、通过人工智能解决方案增强客户服务五、利用人工智能分析消费者行为六、利用 AI 打造个性化…

【javaEE-有关CPU进程和线程实现的并发编程及二者的区别】

&#x1f525;&#x1f525;&#x1f525;有关进程并发编程开发的成本问题 这次之前其实我们所有的写的程序都是使用单核心来运行的&#xff0c;但是一般我们的计算机都有很多核心&#xff0c;如果我们编程的时候&#xff0c;只使用一个核心的话&#xff0c;其实这是一个非常大…

使用源代码编译方式升级内核【笔记】

为什么要升级内核 升级内核有多个重要的原因,主要包括以下几点: 安全性:随着技术的发展,旧版本的内核可能会存在安全漏洞。黑客或恶意用户可能会利用这些漏洞进行攻击。升级内核可以修复这些已知的安全漏洞,从而提高系统的安全性。性能优化:新版本的内核通常会包含对性能…

打造成功的人力RPO项目:赢得市场赚取利润

人力资源外包(RPO)项目是当今企业在招聘和人才管理方面越来越倾向的选择。想要通过人力RPO项目赚钱&#xff0c;以下是一些关键的策略和步骤&#xff0c;帮助您进入这个市场并取得成功。 1. 建立专业的人力RPO服务 首先&#xff0c;要想在人力RPO项目中赚钱&#xff0c;必须建立…

9. 文本三剑客之awk

文章目录 9.1 什么是awk9.2 awk命令格式9.3 awk执行流程9.4 行与列9.4.1 取行9.4.2 取列 9.1 什么是awk 虽然sed编辑器是非常方便自动修改文本文件的工具&#xff0c;但其也有自身的限制。通常你需要一个用来处理文件中的数据的更高级工具&#xff0c;它能提供一个类编程环境来…

【CT】LeetCode手撕—20. 有效的括号

题目 原题连接&#xff1a;20. 有效的括号 1- 思路 模式识别 模式1&#xff1a;括号左右匹配 ——> 借助栈来实现 ——> Deque<Character> deque new LinkedList<>()模式2&#xff1a;顺序匹配 ——> 用 if 判断 具体思路 1.遇到左括号 直接入栈相应…

FPGA IO_BANK、IO_STANDARD

描述 Xilinx 7系列FPGA和UltraScale体系结构提供了高性能&#xff08;HP&#xff09;和 高范围&#xff08;HR&#xff09;I/O组。I/O库是I/O块&#xff08;IOB&#xff09;的集合&#xff0c;具有可配置的 SelectIO驱动程序和接收器&#xff0c;支持多种标准接口 单端和差分。…

JS中的延时操作setTimeout()和setInterval()

JS中&#xff0c;给我们提供两种延时操作的内置方法setTimeout()和setInterval()。setTimeout和setInterval方法都是挂载在javascript的window对象下&#xff0c;通过两个参数控制&#xff0c;第一个参数控制运行的表达式或方法&#xff0c;第二个参数表示延时的时间&#xff0…