【云原生】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.1 导入node的监控模板)

[3.2 导入监控容器状态模板](#3.2 导入监控容器状态模板)

[3.3 导入集群监控模板](#3.3 导入集群监控模板)

五、部署kube-state-metrics

(一)部署kube-state-metrics

1.创建sa账号并授权

2.安装kube-state-metrics组件

3.创建service资源

(二)配置Grafana

1.配置k8s群集状态

[1.1 获取模板](#1.1 获取模板)

[1.2 添加模板](#1.2 添加模板)

2.配置kube-state-metrics

[2.1 获取模板文件](#2.1 获取模板文件)

[2.2 添加模板文件](#2.2 添加模板文件)

六、部署alertmanager

(一)Alertmanager的工作流程

(二)部署Alertmanager

1.创建alertmanager配置文件

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

3.安装prometheus和alertmanager

[3.1 创建secret资源](#3.1 创建secret资源)

[3.2 创建资源清单](#3.2 创建资源清单)

(三)部署alertmanager的service

(四)访问alertmanager

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


引言

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

一、环境准备

|----------|---------------|----------|----------|
| 主机名 | IP地址 | 主机类型 | 资源配置 |
| master01 | 192.168.83.30 | 控制节点 | 4C4G |
| node01 | 192.168.83.40 | 工作节点1 | 4C4G |
| node02 | 192.168.83.50 | 工作节点2 | 4C4G |

二、部署node-exporter

(一)创建命名空间

创建监控namespace

cs 复制代码
[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下载,或者使用国内的镜像替代

cs 复制代码
[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

cs 复制代码
[root@master01 prometheus]#vim node-export.yaml
---
apiVersion: apps/v1
kind: DaemonSet				#可以保证 k8s 集群的每个节点都运行完全一样的 pod
metadata:
  name: node-exporter
  namespace: monitor-sa
  labels:
    name: node-exporter
spec:
  selector:
    matchLabels:
     name: node-exporter
  template:
    metadata:
      labels:
        name: node-exporter
    spec:
      hostPID: true                        #允许Pod使用宿主机的 PID
      hostIPC: true                        #允许Pod使用宿主机的IPC
      hostNetwork: true                    #允许Pod使用宿主机的网络命名空间
      containers:
      - name: node-exporter
        image: prom/node-exporter:v0.16.0  #指定镜像
        ports:
        - containerPort: 9100              #指定容器暴露端口
        resources:
          requests:
            cpu: 0.15		               #这个容器运行至少需要0.15核cpu
        securityContext:
          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: dev
          mountPath: /host/dev
        - name: proc
          mountPath: /host/proc
        - name: sys
          mountPath: /host/sys
        - name: rootfs
          mountPath: /rootfs
      tolerations:
      - key: "node-role.kubernetes.io/master"
        operator: "Exists"
        effect: "NoSchedule"
#定义了DaemonSet容忍了标记为node-role.kubernetes.io/master的节点上的污点
      volumes:                             #定义了 Pod 中要使用的卷
        - name: proc
          hostPath:
            path: /proc
        - name: dev
          hostPath:
            path: /dev
        - name: sys
          hostPath:
            path: /sys
        - name: rootfs
          hostPath:
            path: /

3.创建服务

cs 复制代码
[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

cs 复制代码
[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用户拥有所有资源的所有权限

cs 复制代码
[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等组件中收集指标数据的规则

cs 复制代码
[root@master01 prometheus]#cat  prometheus-cfg.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    app: prometheus
  name: prometheus-config
  namespace: monitor-sa
data:
  prometheus.yml: |   #Prometheus 配置文件的内容
#-----------------------------全局设置-------------------------------------------
    global:                     #指定prometheus的全局配置,比如采集间隔,抓取超时时间等
      scrape_interval: 15s      #采集目标主机监控数据的时间间隔,默认为1m
      scrape_timeout: 10s       #数据采集超时时间,默认10s
      evaluation_interval: 1m 	#触发告警生成alert的时间间隔,默认是1m
    scrape_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端口的url
        replacement: '${1}:9100'        #把匹配到的ip:10250的ip保留,类似与sed的后向引用
        target_label: __address__       #新生成的url是${1}获取到的ip:9100
        action: replace         
#动作替换,从默认的kubelet端口(10250)更改为Prometheus Node Exporter 的端口(9100)
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)    #匹配到下面正则表达式的标签会被保留,如果不做regex正则的话,默认只是会显示instance标签
#--------------第二个服务发现:监控 Kubernetes 集群中每个节点的 cAdvisor-----------------
#抓取cAdvisor数据,是获取kubelet上/metrics/cadvisor接口数据来获取容器的资源使用情况
    - job_name: 'kubernetes-node-cadvisor'    
      kubernetes_sd_configs:
      - role:  node
      scheme: 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: 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]    
#[endpoint这个对象的名称空间,endpoint对象的服务名,exnpoint的端口名称]
        action: keep    #采集满足条件的实例,其他实例不采集
        regex: default;kubernetes;https    #正则匹配到的默认空间下的service名字是kubernetes,协议是https的endpoint类型保留下来
#-----------------------------第四个服务发现--------------------------------------
    - job_name: 'kubernetes-service-endpoints'
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
        action: keep
        regex: true
#重新打标仅抓取到的具有"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: replace
        target_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: replace
        target_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: replace
        target_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_namespace
        target_label: kubernetes_namespace
      - source_labels: [__meta_kubernetes_service_name]
        action: replace
        target_label: kubernetes_name

创建服务

cs 复制代码
[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

cs 复制代码
[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文件

cs 复制代码
[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: 1
  selector:
    matchLabels:
      app: prometheus
      component: server
  template:
    metadata:
      labels:
        app: prometheus
        component: server
      annotations:
        prometheus.io/scrape: 'false'  #Pod的注解,表示Prometheus不从此端点抓取数据
    spec:
      nodeName: node01                 #指定Pod应调度到的节点名称
      serviceAccountName: monitor      #指定Pod使用的ServiceAccount的名称
      containers:
      - name: prometheus
        image: prom/prometheus:v2.2.1  #要使用的容器镜像和标签
        imagePullPolicy: IfNotPresent
        command:
          - prometheus                 #启动命令
          - --config.file=/etc/prometheus/prometheus.yml   #指定加载的配置文件
          - --storage.tsdb.path=/prometheus                #数据存储目录
          - --storage.tsdb.retention=720h                  #数据保存时长
          - --web.enable-lifecycle                         #开启热加载
        ports:
        - containerPort: 9090
          protocol: TCP
        volumeMounts:
        - mountPath: /etc/prometheus/prometheus.yml
          name: prometheus-config
          subPath: prometheus.yml
        - mountPath: /prometheus/
          name: prometheus-storage-volume
      volumes:
        - name: prometheus-config
          configMap:                                     #指定挂载的configMap资源
            name: prometheus-config
            items:
              - key: prometheus.yml
                path: prometheus.yml
                mode: 0644
        - name: prometheus-storage-volume
          hostPath:
           path: /data
           type: Directory

在node01节点创建挂载目录

cs 复制代码
[root@node01 ~]#mkdir /data && chmod 777 /data

创建服务

cs 复制代码
[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查看配置文件

cs 复制代码
[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: 15s
  scrape_timeout: 10s
  evaluation_interval: 1m
scrape_configs:
- job_name: 'kubernetes-node'
  kubernetes_sd_configs:
  - role: node
  relabel_configs:
  - source_labels: [__address__]
    regex: '(.*):10250'
    replacement: '${1}:9100'
    target_label: __address__
    action: replace
  - action: labelmap
    regex: __meta_kubernetes_node_label_(.+)
- job_name: 'kubernetes-node-cadvisor'
  kubernetes_sd_configs:
  - role:  node
  scheme: https
  tls_config:
    ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
  bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
  relabel_configs:
  - action: labelmap
......

(四)创建svc

cs 复制代码
[root@master01 prometheus]#vim prometheus-svc.yaml
[root@master01 prometheus]#cat prometheus-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: prometheus
  namespace: monitor-sa
  labels:
    app: prometheus
spec:
  type: NodePort
  ports:
    - port: 9090
      targetPort: 9090
      protocol: TCP
      nodePort: 31000
  selector:
    app: prometheus
    component: 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

(一)准备镜像

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

cs 复制代码
[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直接下载

cs 复制代码
[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资源

cs 复制代码
[root@master01 prometheus]#cat grafana.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: monitoring-grafana
  namespace: kube-system
spec:
  replicas: 1
  selector:
    matchLabels:
      task: monitoring
      k8s-app: grafana
  template:
    metadata:
      labels:
        task: monitoring
        k8s-app: grafana
    spec:
      containers:
      - name: grafana
        image: grafana/grafana:5.0.4
        ports:
        - containerPort: 3000
          protocol: TCP
        volumeMounts:                     #定义了如何挂载卷到容器中
        - mountPath: /etc/ssl/certs
          name: ca-certificates
          readOnly: true
        - mountPath: /var/lib/grafana/
          name: grafana-storage
        env:                               #定义容器内的环境变量
        - name: INFLUXDB_HOST
          value: monitoring-influxdb
#指定了Grafana连接到的InfluxDB数据库的主机名或IP地址
        - name: GF_SERVER_HTTP_PORT
          value: "3000"
#指定了Grafana HTTP服务器监听的端口
        - name: GF_AUTH_BASIC_ENABLED
          value: "false"
#用于启用或禁用Grafana的基本认证,false表示禁用
        - name: GF_AUTH_ANONYMOUS_ENABLED
          value: "true"
#用于启用或禁用Grafana的匿名访问,true表示启用
        - name: GF_AUTH_ANONYMOUS_ORG_ROLE
          value: Admin
#当匿名访问被启用时,这个环境变量定义了匿名用户所拥有的组织角色,Admin表示具有管理员权限
        - name: GF_SERVER_ROOT_URL
          value: /
#定义了Grafana服务器的根URL
      volumes:                              #定义了要挂载到Pod中的卷
      - name: ca-certificates
        hostPath:
          path: /etc/ssl/certs
      - name: grafana-storage
        emptyDir: {}

创建资源

cs 复制代码
[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资源

cs 复制代码
[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-grafana
  name: monitoring-grafana
  namespace: kube-system
spec:
  ports:
  - port: 80
    targetPort: 3000
  selector:
    k8s-app: grafana
  type: 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资源有管理的权限,能够收集到资源信息

cs 复制代码
[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-metrics
  namespace: 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.io
  kind: ClusterRole
  name: kube-state-metrics
subjects:
- kind: ServiceAccount
  name: kube-state-metrics
  namespace: kube-system

创建并查看信息

cs 复制代码
[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 获取镜像

cs 复制代码
[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 创建服务

cs 复制代码
[root@master01 prometheus]#vim kube-state-metrics-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kube-state-metrics
  namespace: kube-system
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kube-state-metrics
  template:
    metadata:
      labels:
        app: kube-state-metrics
    spec:
      serviceAccountName: kube-state-metrics
      containers:
      - name: kube-state-metrics
        image: quay.io/coreos/kube-state-metrics:v1.9.0
        ports:
        - 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资源

cs 复制代码
[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-metrics
  namespace: kube-system
  labels:
    app: kube-state-metrics
spec:
  ports:
  - name: kube-state-metrics
    port: 8080
    protocol: TCP
  selector:
    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文件当中,重新创建

cs 复制代码
[root@master01 prometheus]#vim alertmanager-cm.yaml
[root@master01 prometheus]#cat alertmanager-cm.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: alertmanager
  namespace: 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和告警规则配置文件

cs 复制代码
[root@master01 prometheus]#cat prometheus-alertmanager-cfg.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  labels:
    app: prometheus
  name: prometheus-config
  namespace: monitor-sa
data:
  prometheus.yml: |
    rule_files:
     - "rules.yml"
    alerting:
      alertmanagers:
      - static_configs:
        - targets: ["localhost:9093"]
    global:
      scrape_interval: 15s
      scrape_timeout: 10s
      evaluation_interval: 1m
    scrape_configs:
    - job_name: 'kubernetes-node'
      kubernetes_sd_configs:
      - role: node
      relabel_configs:
      - source_labels: [__address__]
        regex: '(.*):10250'
        replacement: '${1}:9100'
        target_label: __address__
        action: replace
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
    - job_name: 'kubernetes-node-cadvisor'
      kubernetes_sd_configs:
      - role:  node
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
      - target_label: __address__
        replacement: kubernetes.default.svc:443
      - source_labels: [__meta_kubernetes_node_name]
        regex: (.+)
        target_label: __metrics_path__
        replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
    - job_name: 'kubernetes-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
    - job_name: 'kubernetes-service-endpoints'
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
        action: replace
        target_label: __scheme__
        regex: (https?)
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
        action: replace
        target_label: __address__
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
      - action: labelmap
        regex: __meta_kubernetes_service_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: kubernetes_namespace
      - source_labels: [__meta_kubernetes_service_name]
        action: replace
        target_label: kubernetes_name 
    - job_name: 'kubernetes-pods'
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - action: keep
        regex: true
        source_labels:
        - __meta_kubernetes_pod_annotation_prometheus_io_scrape
      - action: replace
        regex: (.+)
        source_labels:
        - __meta_kubernetes_pod_annotation_prometheus_io_path
        target_label: __metrics_path__
      - action: replace
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
        source_labels:
        - __address__
        - __meta_kubernetes_pod_annotation_prometheus_io_port
        target_label: __address__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - action: replace
        source_labels:
        - __meta_kubernetes_namespace
        target_label: kubernetes_namespace
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: kubernetes_pod_name
    - job_name: 'kubernetes-schedule'
      scrape_interval: 5s
      static_configs:
      - targets: ['192.168.83.30:10251']     #masterIP地址的kubernetes-controlle端口
    - job_name: 'kubernetes-controller-manager'
      scrape_interval: 5s
      static_configs:
      - targets: ['192.168.83.30:10252']     #masterIP地址的kubernetes-controlle端口
    - job_name: 'kubernetes-kube-proxy'
      scrape_interval: 5s
      static_configs:
      - targets: ['192.168.83.30:10249','192.168.83.40:10249','192.168.83.50:10249']
#所有节点的kube-proxy端口
    - job_name: 'kubernetes-etcd'
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/k8s-certs/etcd/ca.crt
        cert_file: /var/run/secrets/kubernetes.io/k8s-certs/etcd/server.crt
        key_file: /var/run/secrets/kubernetes.io/k8s-certs/etcd/server.key
      scrape_interval: 5s
      static_configs:
      - targets: ['192.168.83.30:2379']
  rules.yml: |
    groups:
    - name: example
      rules:
      - alert: kube-proxy的cpu使用率大于80%
        expr: rate(process_cpu_seconds_total{job=~"kubernetes-kube-proxy"}[1m]) * 100 > 80
        for: 2s
        labels:
          severity: warnning
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过80%"
      - alert:  kube-proxy的cpu使用率大于90%
        expr: rate(process_cpu_seconds_total{job=~"kubernetes-kube-proxy"}[1m]) * 100 > 90
        for: 2s
        labels:
          severity: critical
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过90%"
      - alert: scheduler的cpu使用率大于80%
        expr: rate(process_cpu_seconds_total{job=~"kubernetes-schedule"}[1m]) * 100 > 80
        for: 2s
        labels:
          severity: warnning
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过80%"
      - alert:  scheduler的cpu使用率大于90%
        expr: rate(process_cpu_seconds_total{job=~"kubernetes-schedule"}[1m]) * 100 > 90
        for: 2s
        labels:
          severity: critical
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过90%"
      - alert: controller-manager的cpu使用率大于80%
        expr: rate(process_cpu_seconds_total{job=~"kubernetes-controller-manager"}[1m]) * 100 > 80
        for: 2s
        labels:
          severity: warnning
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过80%"
      - alert:  controller-manager的cpu使用率大于90%
        expr: rate(process_cpu_seconds_total{job=~"kubernetes-controller-manager"}[1m]) * 100 > 0
        for: 2s
        labels:
          severity: critical
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过90%"
      - alert: apiserver的cpu使用率大于80%
        expr: rate(process_cpu_seconds_total{job=~"kubernetes-apiserver"}[1m]) * 100 > 80
        for: 2s
        labels:
          severity: warnning
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过80%"
      - alert:  apiserver的cpu使用率大于90%
        expr: rate(process_cpu_seconds_total{job=~"kubernetes-apiserver"}[1m]) * 100 > 90
        for: 2s
        labels:
          severity: critical
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过90%"
      - alert: etcd的cpu使用率大于80%
        expr: rate(process_cpu_seconds_total{job=~"kubernetes-etcd"}[1m]) * 100 > 80
        for: 2s
        labels:
          severity: warnning
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}组件的cpu使用率超过80%"
      - alert:  etcd的cpu使用率大于90%
        expr: rate(process_cpu_seconds_total{job=~"kubernetes-etcd"}[1m]) * 100 > 90
        for: 2s
        labels:
          severity: critical
        annotations:
          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 > 80
        for: 2s
        labels:
          severity: warnning
        annotations:
          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 > 0
        for: 2s
        labels:
          severity: critical
        annotations:
          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 > 80
        for: 2s
        labels:
          severity: warnning
        annotations:
          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 > 90
        for: 2s
        labels:
          severity: critical
        annotations:
          description: "{{$labels.instance}}的{{$labels.k8s_app}}组件的cpu使用率超过90%"
          value: "{{ $value }}%"
          threshold: "90%"      
      - alert: kube-proxy打开句柄数>600
        expr: process_open_fds{job=~"kubernetes-kube-proxy"}  > 600
        for: 2s
        labels:
          severity: warnning
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>600"
          value: "{{ $value }}"
      - alert: kube-proxy打开句柄数>1000
        expr: process_open_fds{job=~"kubernetes-kube-proxy"}  > 1000
        for: 2s
        labels:
          severity: critical
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>1000"
          value: "{{ $value }}"
      - alert: kubernetes-schedule打开句柄数>600
        expr: process_open_fds{job=~"kubernetes-schedule"}  > 600
        for: 2s
        labels:
          severity: warnning
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>600"
          value: "{{ $value }}"
      - alert: kubernetes-schedule打开句柄数>1000
        expr: process_open_fds{job=~"kubernetes-schedule"}  > 1000
        for: 2s
        labels:
          severity: critical
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>1000"
          value: "{{ $value }}"
      - alert: kubernetes-controller-manager打开句柄数>600
        expr: process_open_fds{job=~"kubernetes-controller-manager"}  > 600
        for: 2s
        labels:
          severity: warnning
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>600"
          value: "{{ $value }}"
      - alert: kubernetes-controller-manager打开句柄数>1000
        expr: process_open_fds{job=~"kubernetes-controller-manager"}  > 1000
        for: 2s
        labels:
          severity: critical
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>1000"
          value: "{{ $value }}"
      - alert: kubernetes-apiserver打开句柄数>600
        expr: process_open_fds{job=~"kubernetes-apiserver"}  > 600
        for: 2s
        labels:
          severity: warnning
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>600"
          value: "{{ $value }}"
      - alert: kubernetes-apiserver打开句柄数>1000
        expr: process_open_fds{job=~"kubernetes-apiserver"}  > 1000
        for: 2s
        labels:
          severity: critical
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>1000"
          value: "{{ $value }}"
      - alert: kubernetes-etcd打开句柄数>600
        expr: process_open_fds{job=~"kubernetes-etcd"}  > 600
        for: 2s
        labels:
          severity: warnning
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>600"
          value: "{{ $value }}"
      - alert: kubernetes-etcd打开句柄数>1000
        expr: process_open_fds{job=~"kubernetes-etcd"}  > 1000
        for: 2s
        labels:
          severity: critical
        annotations:
          description: "{{$labels.instance}}的{{$labels.job}}打开句柄数>1000"
          value: "{{ $value }}"
      - alert: coredns
        expr: process_open_fds{k8s_app=~"kube-dns"}  > 600
        for: 2s
        labels:
          severity: warnning 
        annotations:
          description: "插件{{$labels.k8s_app}}({{$labels.instance}}): 打开句柄数超过600"
          value: "{{ $value }}"
      - alert: coredns
        expr: process_open_fds{k8s_app=~"kube-dns"}  > 1000
        for: 2s
        labels:
          severity: critical
        annotations:
          description: "插件{{$labels.k8s_app}}({{$labels.instance}}): 打开句柄数超过1000"
          value: "{{ $value }}"
      - alert: kube-proxy
        expr: process_virtual_memory_bytes{job=~"kubernetes-kube-proxy"}  > 2000000000
        for: 2s
        labels:
          severity: warnning
        annotations:
          description: "组件{{$labels.job}}({{$labels.instance}}): 使用虚拟内存超过2G"
          value: "{{ $value }}"
      - alert: scheduler
        expr: process_virtual_memory_bytes{job=~"kubernetes-schedule"}  > 2000000000
        for: 2s
        labels:
          severity: warnning
        annotations:
          description: "组件{{$labels.job}}({{$labels.instance}}): 使用虚拟内存超过2G"
          value: "{{ $value }}"
      - alert: kubernetes-controller-manager
        expr: process_virtual_memory_bytes{job=~"kubernetes-controller-manager"}  > 2000000000
        for: 2s
        labels:
          severity: warnning
        annotations:
          description: "组件{{$labels.job}}({{$labels.instance}}): 使用虚拟内存超过2G"
          value: "{{ $value }}"
      - alert: kubernetes-apiserver
        expr: process_virtual_memory_bytes{job=~"kubernetes-apiserver"}  > 2000000000
        for: 2s
        labels:
          severity: warnning
        annotations:
          description: "组件{{$labels.job}}({{$labels.instance}}): 使用虚拟内存超过2G"
          value: "{{ $value }}"
      - alert: kubernetes-etcd
        expr: process_virtual_memory_bytes{job=~"kubernetes-etcd"}  > 2000000000
        for: 2s
        labels:
          severity: warnning
        annotations:
          description: "组件{{$labels.job}}({{$labels.instance}}): 使用虚拟内存超过2G"
          value: "{{ $value }}"
      - alert: kube-dns
        expr: process_virtual_memory_bytes{k8s_app=~"kube-dns"}  > 2000000000
        for: 2s
        labels:
          severity: warnning
        annotations:
          description: "插件{{$labels.k8s_app}}({{$labels.instance}}): 使用虚拟内存超过2G"
          value: "{{ $value }}"
      - alert: HttpRequestsAvg
        expr: sum(rate(rest_client_requests_total{job=~"kubernetes-kube-proxy|kubernetes-kubelet|kubernetes-schedule|kubernetes-control-manager|kubernetes-apiservers"}[1m]))  > 1000
        for: 2s
        labels:
          team: admin
        annotations:
          description: "组件{{$labels.job}}({{$labels.instance}}): TPS超过1000"
          value: "{{ $value }}"
          threshold: "1000"   
      - alert: Pod_restarts
        expr: kube_pod_container_status_restarts_total{namespace=~"kube-system|default|monitor-sa"} > 0
        for: 2s
        labels:
          severity: warnning
        annotations:
          description: "在{{$labels.namespace}}名称空间下发现{{$labels.pod}}这个pod下的容器{{$labels.container}}被重启,这个监控指标是由{{$labels.instance}}采集的"
          value: "{{ $value }}"
          threshold: "0"
      - alert: Pod_waiting
        expr: kube_pod_container_status_waiting_reason{namespace=~"kube-system|default"} == 1
        for: 2s
        labels:
          team: admin
        annotations:
          description: "空间{{$labels.namespace}}({{$labels.instance}}): 发现{{$labels.pod}}下的{{$labels.container}}启动异常等待中"
          value: "{{ $value }}"
          threshold: "1"   
      - alert: Pod_terminated
        expr: kube_pod_container_status_terminated_reason{namespace=~"kube-system|default|monitor-sa"} == 1
        for: 2s
        labels:
          team: admin
        annotations:
          description: "空间{{$labels.namespace}}({{$labels.instance}}): 发现{{$labels.pod}}下的{{$labels.container}}被删除"
          value: "{{ $value }}"
          threshold: "1"
      - alert: Etcd_leader
        expr: etcd_server_has_leader{job="kubernetes-etcd"} == 0
        for: 2s
        labels:
          team: admin
        annotations:
          description: "组件{{$labels.job}}({{$labels.instance}}): 当前没有leader"
          value: "{{ $value }}"
          threshold: "0"
      - alert: Etcd_leader_changes
        expr: rate(etcd_server_leader_changes_seen_total{job="kubernetes-etcd"}[1m]) > 0
        for: 2s
        labels:
          team: admin
        annotations:
          description: "组件{{$labels.job}}({{$labels.instance}}): 当前leader已发生改变"
          value: "{{ $value }}"
          threshold: "0"
      - alert: Etcd_failed
        expr: rate(etcd_server_proposals_failed_total{job="kubernetes-etcd"}[1m]) > 0
        for: 2s
        labels:
          team: admin
        annotations:
          description: "组件{{$labels.job}}({{$labels.instance}}): 服务失败"
          value: "{{ $value }}"
          threshold: "0"
      - alert: Etcd_db_total_size
        expr: etcd_debugging_mvcc_db_total_size_in_bytes{job="kubernetes-etcd"} > 10000000000
        for: 2s
        labels:
          team: admin
        annotations:
          description: "组件{{$labels.job}}({{$labels.instance}}):db空间超过10G"
          value: "{{ $value }}"
          threshold: "10G"
      - alert: Endpoint_ready
        expr: kube_endpoint_address_not_ready{namespace=~"kube-system|default"} == 1
        for: 2s
        labels:
          team: admin
        annotations:
          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 > 90
        for: 2s
        labels:
          severity: ccritical
        annotations:
          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 > 90
        for: 2s
        labels:
          severity: critical
        annotations:
          summary: "{{ $labels.instance }}内存使用率过高"
          description: "{{ $labels.instance }}的内存使用率超过90%,当前使用率[{{ $value }}],需要排查处理"
      - alert: InstanceDown
        expr: up == 0
        for: 2s
        labels:
          severity: critical
        annotations:   
          summary: "{{ $labels.instance }}: 服务器宕机"
          description: "{{ $labels.instance }}: 服务器延时超过2分钟"
      - alert: 物理节点磁盘的IO性能
        expr: 100-(avg(irate(node_disk_io_time_seconds_total[1m])) by(instance)* 100) < 60
        for: 2s
        labels:
          severity: critical
        annotations:
          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) > 102400
        for: 2s
        labels:
          severity: critical
        annotations:
          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) > 102400
        for: 2s
        labels:
          severity: critical
        annotations:
          summary: "{{$labels.mountpoint}} 流出网络带宽过高!"
          description: "{{$labels.mountpoint }}流出网络带宽持续5分钟高于100M. RX带宽使用率{{$value}}"
      - alert: TCP会话
        expr: node_netstat_Tcp_CurrEstab > 1000
        for: 2s
        labels:
          severity: critical
        annotations:
          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) > 80
        for: 2s
        labels:
          severity: critical
        annotations:
          summary: "{{$labels.mountpoint}} 磁盘分区使用率过高!"
          description: "{{$labels.mountpoint }} 磁盘分区使用大于80%(目前使用:{{$value}}%)"

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

cs 复制代码
[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 相关资

cs 复制代码
[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

cs 复制代码
[root@master01 prometheus]#cat prometheus-alertmanager-deploy.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus-server
  namespace: monitor-sa
  labels:
    app: prometheus
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
      component: server
  template:
    metadata:
      labels:
        app: prometheus
        component: server
      annotations:
        prometheus.io/scrape: 'false'
    spec:
      nodeName: node01
      serviceAccountName: monitor
      containers:
      - name: prometheus
        image: prom/prometheus:v2.2.1
        imagePullPolicy: IfNotPresent
        command:
        - "/bin/prometheus"
        args:
        - "--config.file=/etc/prometheus/prometheus.yml"
        - "--storage.tsdb.path=/prometheus"
        - "--storage.tsdb.retention=24h"
        - "--web.enable-lifecycle"
        ports:
        - containerPort: 9090
          protocol: TCP
        volumeMounts:
        - mountPath: /etc/prometheus
          name: prometheus-config
        - mountPath: /prometheus/
          name: prometheus-storage-volume
        - name: k8s-certs
          mountPath: /var/run/secrets/kubernetes.io/k8s-certs/etcd/
        - name: localtime
          mountPath: /etc/localtime
      - name: alertmanager
        image: prom/alertmanager:v0.14.0
        imagePullPolicy: IfNotPresent
        args:
        - "--config.file=/etc/alertmanager/alertmanager.yml"
        - "--log.level=debug"
        ports:
        - containerPort: 9093
          protocol: TCP
          name: alertmanager
        volumeMounts:
        - name: alertmanager-config
          mountPath: /etc/alertmanager
        - name: alertmanager-storage
          mountPath: /alertmanager
        - name: localtime
          mountPath: /etc/localtime
      volumes:
        - name: prometheus-config
          configMap:
            name: prometheus-config
        - name: prometheus-storage-volume
          hostPath:
           path: /data
           type: Directory
        - name: k8s-certs
          secret:
           secretName: etcd-certs
        - name: alertmanager-config
          configMap:
            name: alertmanager
        - name: alertmanager-storage
          hostPath:
           path: /data/alertmanager
           type: DirectoryOrCreate
        - name: localtime
          hostPath:
           path: /usr/share/zoneinfo/Asia/Shanghai

创建资源

cs 复制代码
[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

cs 复制代码
[root@master01 prometheus]#cat alertmanager-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  labels:
    name: prometheus
    kubernetes.io/cluster-service: 'true'
  name: alertmanager
  namespace: monitor-sa
spec:
  ports:
  - name: alertmanager
    nodePort: 30066
    port: 9093
    protocol: TCP
    targetPort: 9093
  selector:
    app: prometheus
  sessionAffinity: None
  type: 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 上的,需要改成监听到物理节点上

原先的监听地址

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

修改kube-proxy监控地址

cs 复制代码
[root@master01 prometheus]#kubectl edit configmap kube-proxy -n kube-system
......
    kind: KubeProxyConfiguration
    metricsBindAddress: "0.0.0.0:10249"
    mode: ipvs
......

重新启动kube-proxy

cs 复制代码
[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即可看到

邮箱查看

告警信息一致

相关推荐
大熊程序猿1 小时前
K8s证书过期
云原生·容器·kubernetes
魏 无羡10 小时前
linux CentOS系统上卸载docker
linux·kubernetes·centos
Karoku06611 小时前
【k8s集群应用】kubeadm1.20高可用部署(3master)
运维·docker·云原生·容器·kubernetes
凌虚12 小时前
Kubernetes APF(API 优先级和公平调度)简介
后端·程序员·kubernetes
探索云原生16 小时前
在 K8S 中创建 Pod 是如何使用到 GPU 的: nvidia device plugin 源码分析
ai·云原生·kubernetes·go·gpu
启明真纳16 小时前
elasticache备份
运维·elasticsearch·云原生·kubernetes
jwolf218 小时前
基于K8S的微服务:一、服务发现,负载均衡测试(附calico网络问题解决)
微服务·kubernetes·服务发现
nangonghen18 小时前
在华为云通过operator部署Doris v2.1集群
kubernetes·华为云·doris·operator
福大大架构师每日一题18 小时前
37.1 prometheus管理接口源码讲解
ios·iphone·prometheus
会飞的土拨鼠呀20 小时前
chart文件结构
运维·云原生·kubernetes