百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

集群外部署Prometheus+Grafana监控K8S解析

zhezhongyun 2025-05-08 22:24 5 浏览

简介

Prometheus+Grafana作为监控K8S的解决方案,大都是在K8S集群内部部署,这样可以直接调用集群内的cert及各种监控url,但是增加了集群的资源开销。因此在资源有限的情况下,我更倾向于K8S集群外独立部署Prometheus+Grafana。

无论哪种部署方式,都需要通过exporter收集各种维度的监控指标,其维度如下:

大家可能在此有疑问,为什么kube-state-metrics没有监控url?
其实从上表可以看出,监控url并不完整,因为prometheus的动态发现会基于标签进行自动补全,补全格式为:
__scheme__://__address____metrics_path__
。其中标签的值都可以通过Prometheus的relabel_config拼接成最终的监控url。

正是基于以上原因,集群外部署Prometheus和集群内部署Prometheus是不一样的,因为集群内的Prometheus有的监控使用的是集群私有ip,而集群外Prometheus使用默认自动拼接的监控url是无法访问的,此时需要自行构造apiserver proxy URLs,可以参考Manually constructing apiserver proxy URLs。通过proxy url集群外Prometheus就可以访问监控url来拉取监控指标了。

上表中Pod性能和Node性能的监控url其实都是自行构造的proxy url,而K8S资源使用默认的监控url,就会发现其endpoint都是K8S集群内部的私有ip,因此所有的状态都是down的。

但如果通过自行改造的proxy url访问,则所有的状态则是up的。

构造apiserver proxy url

通过Accessing services running on the cluster了解到在k8s集群中nodes、pods、services都有自己的私有IP,但是无法从集群外访问;但K8S提供以下几种方式来访问:

  • 通过public IPs访问service
  • 通过proxy 访问node、pod、service
  • 通过集群内的node或pod间接访问

而通过kubectl cluster-info可以查看kube-system命令空间的proxy url:

# kubectl cluster-info 
Kubernetes master is running at https://192.168.3.217:6443
KubeDNS is running at https://192.168.3.217:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Metrics-server is running at https://192.168.3.217:6443/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy

其默认的构造规则为:

# 访问node
https://${other_apiserver_address}/api/v1/nodes/node_name:[port_name]/proxy/metrics
# 访问service
https://${other_apiserver_address}/api/v1/namespaces/service_namespace/services/http:service_name[:port_name]/proxy/metrics
# 访问pod
https://${other_apiserver_address}/api/v1/namespaces/pod_namespace/pods/http:pod_name[:port_name]/proxy/metrics

在了解如何构造proxy url后,我们就可以通过集群外Prometheus的relabel_config自行构造proxy url了。

apiserver授权

要访问K8S apiserver需要先进行授权,而集群内部Prometheus可以使用集群内默认配置进行访问,而集群外访问需要使用token+客户端cert进行认证,因此需要先进行RBAC授权。

由于我们需要访问不同的namespace,因此我们最好分配cluster-admin,以免权限不足。具体步骤如下:

# 1.创建serviceaccounts
kubectl create sa jenkins
# 2.创建prometheus角色并对其绑定cluster-admin
kubectl create clusterrolebinding prometheus --clusterrole cluster-admin --serviceaccount=devops:jenkins

虽创建了serviceaccount,但访问apiserver并不是直接使用serviceaccount,而是通过token。因此我们需要获取serviceaccount:prometheus对应的token,而此token是经过base64加密过的,必须解密后才能使用。

# 1.查看sa,在默认namespace
# kubectl get sa 
NAME      SECRETS   AGE
default   1         113m
prometheus   1         19m

# 2.查看secret
# kubectl get sa prometheus -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: "2020-07-28T08:27:55Z"
  name: prometheus
  namespace: default
  resourceVersion: "14403390"
  selfLink: /api/v1/namespaces/default/serviceaccounts/prometheus
  uid: 43a98176-faa1-43f7-ad91-0352ca2dce2c
secrets:
- name: prometheus-token-44jkm

# 3.获取token,从yaml中得到token
# kubectl get secret  prometheus-token-44jkm -o yaml
...省略...
token: ZXlKaGJHY2lPaUpTV...
...省略...

# 4.token解密
# 由于此token是经过base64加密的,我们需要通过base64解密获取token值
# echo "xxxxxxxx" |base64 -d

通过一系列操作获得的token,可以作为bearer_token访问apiserver。

好了,了解以上几点后,接下来我们按以下顺序来介绍:

  1. 使用exporter收集各种K8S监控指标;
  2. Prometheus如何构造exporter的监控url;
  3. Grafana的图形化展示;

监控指标收集

1.node性能

通过node-exporter采集集群node节点的服务器层面的数据,如cpu、内存、磁盘、网络流量等,其监控url为"
http://node_ip:9100/metrics"。

node-exporter可以独立部署在node节点服务器上,但Prometheus需要通过static_config静态配置手动添加监控,在集群扩展情况下,还需要再手动安装node-exporter。因此将node-exporter以DaemonSet形式部署,配合Prometheus动态发现更加方便。

# 1.vim node-exporter.yaml
kind: DaemonSet
apiVersion: apps/v1
metadata:
  name: node-exporter
  annotations:
    prometheus.io/scrape: 'true'
spec:
  selector:
    matchLabels:
      app: node-exporter
  template:
    metadata:
      labels:
        app: node-exporter
      name: node-exporter
    spec:
      containers:
      - image: quay.io/prometheus/node-exporter:latest
        name: node-exporter
        ports:
        - containerPort: 9100
          hostPort: 9100
          name: node-exporter
      hostNetwork: true
      hostPID: true
      tolerations:
      - key: "node-role.kubernetes.io/master"
        operator: "Exists"
        effect: "NoSchedule"

---
kind: Service
apiVersion: v1
metadata:
  annotations:
    prometheus.io/scrape: 'true'
  labels:
    app: node-exporter
  name: node-exporter
spec:
  type: ClusterIP
  clusterIP: None
  ports:
  - name: node-exporter
    port: 9100
    protocol: TCP
  selector:
    app: node-exporter

# 2.部署
kubectl apply -f node-exporter.yaml

注意:

  1. node-exporter以DaemonSet部署并且设置为hostNetwork,可通过宿主机ip+9100直接访问,因此我认为Service可以不创建,经测试是可以的
  2. node-exporter需要收集集群内所有节点,而master节点默认有NoSchedule污点,即不参与任何调度;因此我们需要单独设置toleration来使master节点也可以部署node-exporter;
  3. 添加prometheus.io/scrape: 'true’用于自动发现;

2.pod性能

cAdvisor 是一个开源的分析容器资源使用率和性能特性的代理工具,集成到 Kubelet中,当Kubelet启动时会同时启动cAdvisor,且一个cAdvisor只监控一个Node节点的信息。cAdvisor 自动查找所有在其所在节点上的容器,自动采集 CPU、内存、文件系统和网络使用的统计信息。cAdvisor 通过它所在节点机的 Root 容器,采集并分析该节点机的全面使用情况。

当然kubelet也会输出一些监控指标数据,因此pod的监控数据有kubelet和cadvisor,监控url分别为

https://NodeIP:10250/metrics和
https://NodeIP:10250/metrics/cadvisor。

由于kubelet天然存在,因此直接远程访问即可,无需做其他配置。

3.K8S资源对象

kube-state-metrics是一个简单的服务,它监听Kubernetes API服务器并生成关联对象的指标。 它不关注单个Kubernetes组件的运行状况,而是关注内部各种对象(如deployment、node、pod等)的运行状况。

# 1.下载部署文件
https://github.com/kubernetes/kube-state-metrics/tree/master/examples/standard

# 2.部署
kubectl apply -f service-account.yaml
kubectl apply -f cluster-role.yaml
kubectl apply -f cluster-role-binding.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

4.小结

监控数据的指标采集比较简单,按需部署即可。重点的是Prometheus如何配置k8s自动发现、通过构造apiserver proxy url拉取metrics,因为K8S中的资源都是动态的。

Prometheus

1.部署

Prometheus使用docker部署在K8S集群外。

# 1.创建持久化数据目录并授权
mkdir -p /App/prometheus/etc
# 默认启动的容器用户信息为:uid=65534(nobody) gid=65534(nogroup),如果不改成777 ,容器启动失败
chmod -R 777 /APP/prometheus

# 2.docker启动 
docker run -d -p 9090:9090 -v /App/prometheus/etc/prometheus.yml:/etc/prometheus/prometheus.yml -v /App/prometheus:/prometheus prom/prometheus

在后期我们可能要删除一些metric,此时需要调用API,默认是关闭的,可在容器启动时开启,因此我们使用docker-compose部署更合适:

# 1.编辑docker-compose.yaml
version: '3'
services:
prometheus:
image: prom/prometheus
container_name: prometheus
restart: always
ports:
- "9090:9090"
volumes:
- /App/prometheus/etc/prometheus.yml:/etc/prometheus/prometheus.yml
- /App/prometheus:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.enable-admin-api' # 控制对admin HTTP API的访问,其中包括删除时间序列等功能
- '--web.enable-lifecycle' # 支持热更新,直接执行localhost:9090/-/reload立即生效

# 2.启动
docker-compose up -d

# 3.删除metric
# curl -X POST -g 'http://localhost:9090/api/v1/admin/tsdb/delete_series?match[]={job="kubernetes-kube-state"}'
{"status":"error","errorType":"unavailable","error":"admin APIs disabled"}

2.自动发现

kubernetes_sd_config从Kubernetes的REST API查找并拉取指标,并始终与集群状态保持同步。
可自动发现的几种role

  • node
    自动发现每个集群节点发现一个target,其地址默认为Kubelet的HTTP端口,如"https://192.168.3.217:10250/metrics"
  • service
    自动发现每个服务的每个服务端口的target。
  • pod
    自动发现所有容器及端口
  • endpoints
    自动发现service中的endpoint,如图
  • ingrsss
    自动发现ingress中path

本次我们主要用到了node和endpoint,分别对应node级别和endpoint级别,但是默认情况自动生成的url有时是不可用的,这就需要我们通过以下内容学习relabel_configs如何使用了。

3.拉取node监控指标

通过relabel_configs构造如下:

注意:tls_config和bearer_token_file 必须在job内和kubernetes_sd_configs都存在,否则会导致认证失败。

scrape_configs:
- job_name: "kube-state-metrics"
  scheme: https
  tls_config:
    insecure_skip_verify: true
  #使用apiserver授权部分解密的token值,以文件形式存储
  bearer_token_file: /prometheus/k8s_token
  # k8s自动发现具体配置
  kubernetes_sd_configs:
  # 使用endpoint级别自动发现
  - role: endpoints
    api_server: "https://192.168.3.217:6443"
    tls_config:
      insecure_skip_verify: true
    bearer_token_file: /prometheus/k8s_token
  relabel_configs:
  - source_labels: [__meta_kubernetes_service_name]
    # 只保留指定匹配正则的标签,不匹配则删除
    action: keep
    regex: '^(kube-state-metrics)#39;
  - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
    # 只保留指定匹配正则的标签,不匹配则删除
    action: keep
    regex: true
  - source_labels: [__address__]
    action: replace
    target_label: instance
  - target_label: __address__
    # 使用replacement值替换__address__默认值
    replacement: 192.168.3.217:6443
  - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_pod_name, __meta_kubernetes_pod_container_port_number]
    # 正则匹配
    regex: ([^;]+);([^;]+);([^;]+)
    # 使用replacement值替换__metrics_path__默认值
    target_label: __metrics_path__
    # 自行构建的apiserver proxy url
    replacement: /api/v1/namespaces/${1}/pods/http:${2}:${3}/proxy/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
    # 将标签__meta_kubernetes_service_name修改为service_name
    target_label: service_name

最终的效果如下:

4.拉取pod监控指标

kubelet

advisor

通过relabel_configs构造如下:

# kubelet
- job_name: "kube-node-kubelet"
  scheme: https
  tls_config:
    insecure_skip_verify: true
  bearer_token_file: /prometheus/k8s_token
  kubernetes_sd_configs:
  - role: node
    api_server: "https://192.168.3.217:6443"
    tls_config:
      insecure_skip_verify: true
    bearer_token_file: /prometheus/k8s_token
  relabel_configs:
  - target_label: __address__
    # 使用replacement值替换__address__默认值
    replacement: 192.168.3.217:6443
  - source_labels: [__meta_kubernetes_node_name]
    regex: (.+)
    # 使用replacement值替换__metrics_path__默认值
    target_label: __metrics_path__
    replacement: /api/v1/nodes/${1}:10250/proxy/metrics
  - 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: service_name

# advisor    
- job_name: "kube-node-cadvisor"
  scheme: https
  tls_config:
    insecure_skip_verify: true
  bearer_token_file: /prometheus/k8s_token
  kubernetes_sd_configs:
  - role: node
    api_server: "https://192.168.3.217:6443"
    tls_config:
      insecure_skip_verify: true
    bearer_token_file: /prometheus/k8s_token
  relabel_configs:
  - target_label: __address__
    # 使用replacement值替换__address__默认值
    replacement: 192.168.3.217:6443
  - source_labels: [__meta_kubernetes_node_name]
    regex: (.+)
    # 使用replacement值替换__metrics_path__默认值
    target_label: __metrics_path__
    replacement: /api/v1/nodes/${1}:10250/proxy/metrics/cadvisor
  - 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: service_name

5.拉取K8S资源监控指标

通过relabel_configs构造如下:

scrape_configs:
- job_name: "kube-state-metrics"
  scheme: https
  tls_config:
    insecure_skip_verify: true
  bearer_token_file: /prometheus/k8s_token
  kubernetes_sd_configs:
  - role: endpoints
    api_server: "https://192.168.3.217:6443"
    tls_config:
      insecure_skip_verify: true
    bearer_token_file: /prometheus/k8s_token
  relabel_configs:
  - source_labels: [__meta_kubernetes_service_name]
    action: keep
    regex: '^(kube-state-metrics)#39;
  - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
    action: keep
    regex: true
  - source_labels: [__address__]
    action: replace
    target_label: instance
  - target_label: __address__
    # 使用replacement值替换__address__默认值
    replacement: 192.168.3.217:6443
  - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_pod_name, __meta_kubernetes_pod_container_port_number]
    regex: ([^;]+);([^;]+);([^;]+)
    # 使用replacement值替换__metrics_path__默认值
    target_label: __metrics_path__
    replacement: /api/v1/namespaces/${1}/pods/http:${2}:${3}/proxy/metrics
  - 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: service_name

Grafana

Grafana从prometheus数据源读取监控指标并进行图形化展示,可通过以下几种方式进行展示:

1.grafana dashboard模板

Grafana Dashboard提供了很多模板供我们下载使用,针对以上不同维度的监控指标,我们可以自行选择喜欢的模板直接导入Dashboard id使用。

  1. node性能
    Dashboard id:8919

Dashboard id:9276

  1. pod性能

Dashboard id:8588

  1. K8S资源
    Dashboard id:3119

Dashboard id:6417

注意: 如果Dashboard没有数据,需要具体查看相关指标或标签是否存在,因为有的模板是几年前上传的,没有更新。

2.grafana plugin

通过Dashboard 模板我们需要自行选择并组合,灵活有余但规范不足。而grafana自带专门针对Kubernetes集群监控的插件grafana-kubernetes-app,它包括4个仪表板,集群,节点,Pod /容器和部署。但是这个插件已经3年+没有更新了,有很多的metrics和label没有更新。

在此特推荐KubeGraf,是grafana-kubernetes-app升级版本,该插件可以用来可视化和分析 Kubernetes 集群的性能,通过各种图形直观的展示了 Kubernetes 集群的主要服务的指标和特征,还可以用于检查应用程序的生命周期和错误日志。

  1. 安装
# 1.安装
grafana-cli plugins install devopsprodigy-kubegraf-app
# 2.重启grafana
systemctl restart grafana-server
  1. 配置
    “Add New Cluster” 后,我们就可以进行以下配置
  • URL:填写K8S apiserver地址
  • TLS Client Auth:使用tls认证
  • Skip TLS Verify:不会检查服务器凭证的有效性,这会导致HTTPS链接不安全
  • With CA Cert:不开启,将不使用CA Cert
  • CA Cert:和With CA Cert同时使用
    填入解密的内容
# 从/root/.kube/config 获取certificate-authority-data 值并解密
echo "xxxx" |base64 -d
  • Client Cert
    填入解密的内容
# 从/root/.kube/config 获取client-certificate-data 值并解密
echo "xxxx" |base64 -d
  • Client Key
    填入解密的内容
# 从/root/.kube/config 获取client-key-data 值并解密
echo "xxxx" |base64 -d
  1. 展示效果

集群状态

node状态

Deployment状态

DaemonSet 状态

pod状态

总结

监控K8S一定要提前规划好Prometheus的位置,熟悉RBAC授权及apiserver proxy url,这样我们在部署过程中能够快速定位问题。

至于Prometheus部署在集群外还是集群内,大家见仁见智,根据自己的实际需求进行部署。建议多个小集群可通过集群外Prometheus统一监控;大集群则避免Prometheus中心化,还是每个集群内部单独部署。

参考文章:

https://cloud.tencent.com/developer/article/1402436
https://cloud.tencent.com/developer/article/1449803
https://blog.rj-bai.com/post/159.html
https://help.aliyun.com/document_detail/123394.html

相关推荐

十字军之王3作弊码有哪些 王国风云3全控制台代码分享

王国风云3作弊码有什么?王国风云3游戏里我们可以使用作弊码来进行游戏,一些特别的玩法是不会少了这方面的内容的。不过具体的作弊码是很多的玩家不清楚的,为了让大家都能用游戏里的作弊码,这里就一起来看看小编...

SpringBoot的Restful的请求路径参数@PathVariable注解的使用

1.介绍1.1介绍大家都知道RESTFul风格的接口的URI路径和普通的接口是不一样的,根据RESTFul的规范请求的URI路径里需要指向一个具体的资源(Resource),这个URI路径里面可以...

Nacos源码—2.Nacos服务注册发现分析四

大纲5.服务发现—服务之间的调用请求链路分析6.服务端如何维护不健康的微服务实例7.服务下线时涉及的处理8.服务注册发现总结7.服务下线时涉及的处理(1)Nacos客户端服务下线的源码(2)Nacos...

JavaScript矩阵快速计算方法(如何用java计算矩阵相乘)

有很多方法可以在JS中表示矩阵数学。有些方法可读性强,有些方法速度快。我想探索一下这些差异。某些技术实际上能为我节省多少时间?为此,我将只研究一个操作:逐元素加法以减少总案例数,但差异操作可能会稍...

如何在前端通过JavaScript创建修改CAD图形

背景在之前的博文CAD图DWG解析WebGIS可视化技术分析总结、CAD_DWG图Web可视化一站式解决方案-唯杰地图-vjmap中讲解了如何把CAD的DWG格式的图纸Web可视化的方案,那在Web前...

如何写一个webpack插件(一)(webpack插件怎么写)

前言最近由于用着html-webpack-plugin觉得很不爽,于是乎想自己动手写一个插件。原以为像gulp插件一样半天上手一天写完,但令人郁闷的是完全找不到相关的文章。一进官方文档却是被吓傻了。首...

如何用Go写一个benchmark 解析器及Web UI 数据可视化?

简介用Go编写的benchmark输出解析器,功能如下读取gotest-bench=.-benchmem的输出文件(如benchmark.txt)解析出每行数据写入成CSV文件...

k8s实践(八):ConfigMap and Secret

一、概述1.ConfigMap在实际的应用部署中,经常需要为各种应用/中间件配置各种参数,如数据库地址、用户名、密码等,而且大多数生产环境中的应用程序配置较为复杂,可能是多个Con...

前端最常用的25个正则表达式,代码效率提高 80%

在日常开发中,正则表达式是非常有用的,正则表达式在每个语言中都是可以使用的,他就跟JSON一样,是通用的。在日常开发中,了解一些常用的正则表达式,能大大提高你的工作效率,例如字符串的匹配表单项的格式校...

游戏《重返德军总部》秘籍代码大全完全版简要分享

重返德军总部这款游戏当中为玩家们带来了很多非常经典熟悉的秘籍作弊码,玩家们可以通过在游戏当中使用这些秘籍作弊码更好的体验到游戏当中的精彩内容,感兴趣的小伙伴就和小编在下面一起来看看吧。重返德军总部秘籍...

32个手写JS,巩固你的JS基础(面试高频)

01.数组扁平化数组扁平化是指将一个多维数组变为一个一维数组constarr=[1,[2,[3,[4,5]]],6];//=>[1,2,3,4,5,6]复制代码...

golang常用数据结构之map详细讲解

概述map是常见的一种数据结构,大部分编程语言都有,用于存储一系列无序的键值对,map也被称为字典或关联数组,顾名思义,键相当于索引,通过键与值形成映射关系,达到快速查找数据的目的。声明和初始化var...

MapStruct 常用的重要注解和方法(mapstruct详解)

MapStruct是一个Java代码生成器,用于简化Java对象之间的映射操作。它通过注解和方法来定义映射规则。以下是MapStruct中常用的重要注解和方法:注解1.@Mapper:用于标记一个接...

Java对象中非空属性一键转Map,让你的代码飞起来

哈喽,大家好,我是木头左!引言在日常开发中,经常会遇到需要将一个Java对象中的非空属性提取出来,放到一个Map中的情况。这样的做法有很多好处,比如方便进行属性的查找、修改等操作,同时也能够提升代码的...

在Kubernetes中使用ConfigMap(kubectl set env)

在《为Kubernetes安装Dashboard》中,我们已经使用VirtualBox安装了CentOS7.9,并在其上安装了Docker20.10.11、Kubernetes1.23.3和ku...