解决 Prometheus 不能获取 Kubernetes 集群上 Windows 节点的 Metrics

背景

接上一篇 快速搭建 Windows Kubernetes , 我们发现原来在 Windows Kubernetes 会有一些与在 Linux 上使用不一样的体验,俗称坑,例如 hostAliases。对于我们希望真的把 Windows 放入生产,感觉除了基本的 Pod、Volume、Service 、Log 以外,我们还需要监控。一般来讲我们会用 Prometheus 来做监控,然后通过 Grafana 来展示,但是 Prometheus 的 Node Exporter 是为 *nix 设计的,所以在 Windows 上我们的自己想办法了。在 Prometheus Node Exporter 里推荐使用 WMI exporter ,感兴趣的童鞋可以去试试,本文主要还是想从一个原始的角度去分析处理,来理解怎么去写一个 Prometheus 的采集程序。

前提

  • 一套 Windows Kuberentes
  • 一个 Prometheus 环境

步骤

  • 首先得找到 Kubelet 在 Windows 上暴露出来得数据格式, 因为 cadivsor 并不支持 Windows, 社区有位同志写了一个相对简单的实现来支持; 他这个的实现还是保持 Linux 上的一样,是从 <Node_IP>:10255/stats/summary上 expose metrics, metrics-server 与 kubectl top的数据也是来源于此,大致如下:
{
  "node": {
   "nodeName": "35598k8s9001",
   "startTime": "2018-08-26T07:25:08Z",
   "cpu": {
    "time": "2018-09-10T01:44:52Z",
    "usageCoreNanoSeconds": 8532520000000
   },
   "memory": {
    "time": "2018-09-10T01:44:52Z",
    "availableBytes": 14297423872,
    "usageBytes": 1978798080,
    "workingSetBytes": 734490624,
    "rssBytes": 0,
    "pageFaults": 0,
    "majorPageFaults": 0
   },
   "fs": {
    "time": "2018-09-10T01:44:52Z",
    "availableBytes": 15829303296,
    "capacityBytes": 32212250624,
    "usedBytes": 16382947328
   },
   "runtime": {
    "imageFs": {
     "time": "2018-09-10T01:44:53Z",
     "availableBytes": 15829303296,
     "capacityBytes": 32212250624,
     "usedBytes": 16382947328,
     "inodesUsed": 0
    }
   }
  },
  "pods": [
   {
    "podRef": {
     "name": "stdlogserverwin-5fbcc5648d-ztqsq",
     "namespace": "default",
     "uid": "f461a0b4-ab36-11e8-93c4-0017fa0362de"
    },
    "startTime": "2018-08-29T02:55:15Z",
    "containers": [
     {
      "name": "stdlogserverwin",
      "startTime": "2018-08-29T02:56:24Z",
      "cpu": {
       "time": "2018-09-10T01:44:54Z",
       "usageCoreNanoSeconds": 749578125000
      },
      "memory": {
       "time": "2018-09-10T01:44:54Z",
       "workingSetBytes": 83255296
      },
      "rootfs": {
       "time": "2018-09-10T01:44:54Z",
       "availableBytes": 15829303296,
       "capacityBytes": 32212250624,
       "usedBytes": 0
      },
      "logs": {
       "time": "2018-09-10T01:44:53Z",
       "availableBytes": 15829303296,
       "capacityBytes": 32212250624,
       "usedBytes": 16382947328,
       "inodesUsed": 0
      },
      "userDefinedMetrics": null
     }
    ],
    "cpu": {
     "time": "2018-08-29T02:56:24Z",
     "usageNanoCores": 0,
     "usageCoreNanoSeconds": 749578125000
    },
    "memory": {
     "time": "2018-09-10T01:44:54Z",
     "availableBytes": 0,
     "usageBytes": 0,
     "workingSetBytes": 83255296,
     "rssBytes": 0,
     "pageFaults": 0,
     "majorPageFaults": 0
    },
    "volume": [
     {
      "time": "2018-08-29T02:55:16Z",
      "availableBytes": 17378648064,
      "capacityBytes": 32212250624,
      "usedBytes": 14833602560,
      "inodesFree": 0,
      "inodes": 0,
      "inodesUsed": 0,
      "name": "default-token-wv5fc"
     }
    ],
    "ephemeral-storage": {
     "time": "2018-09-10T01:44:54Z",
     "availableBytes": 15829303296,
     "capacityBytes": 32212250624,
     "usedBytes": 16382947328
    }
   }
  ]
}
  • 从上面可以看到,它包含了本机和 pod 的一些 metrics, 相对 cadvisor 能提供的少了一些,但是基本监控是没问题的。接下来我们需要写一个小程序把数据转换成 Prometheus 能解析的数据。接下来用 python 写个小栗子, 先声明下我们要 expose 的 stats 对象
class Node:
    def __init__(self, name, cpu, memory):
        self.name = name
        self.cpu = cpu
        self.memory = memory

class Pod:
    def __init__(self, name, namespace,cpu, memory):
        self.name = name
        self.namespace = namespace
        self.cpu = cpu
        self.memory = memory

class Stats:
    def __init__(self, node, pods):
        self.node = node
        self.pods = pods
  • 使用 Prometheus 的 python-client 来写一个 polling 的程序,去转换 kubelet stats 数据。
from urllib.request import urlopen
from stats import Node
from stats import Pod
from stats import Stats
import json
import asyncio
import prometheus_client as prom
import logging
import random

def getMetrics(url):
    #获取数据集
    response = urlopen(url)
    string = response.read().decode(‘utf-8‘)
    json_obj = json.loads(string)
    #用之前定义好的 stats 的对象来做 mapping
    node = Node(‘‘,‘‘,‘‘)
    node.name = json_obj[‘node‘][‘nodeName‘]
    node.cpu = json_obj[‘node‘][‘cpu‘][‘usageCoreNanoSeconds‘]
    node.memory = json_obj[‘node‘][‘memory‘][‘usageBytes‘]

    pods_array = json_obj[‘pods‘]

    pods_list = []

    for item in pods_array:
        pod = Pod(‘‘,‘‘,‘‘,‘‘)
        pod.name = item[‘podRef‘][‘name‘]
        pod.namespace = item[‘podRef‘][‘namespace‘]
        pod.cpu = item[‘cpu‘][‘usageCoreNanoSeconds‘]
        pod.memory = item[‘memory‘][‘workingSetBytes‘]
        pods_list.append(pod)

    stats = Stats(‘‘,‘‘)
    stats.node = node
    stats.pods = pods_list
    return stats

#写个简单的日志输出格式
format = "%(asctime)s - %(levelname)s [%(name)s] %(threadName)s %(message)s"
logging.basicConfig(level=logging.INFO, format=format)
#声明我们需要导出的 metrics 及对应的  label 供未来查询使用
g1 = prom.Gauge(‘node_cpu_usageCoreNanoSeconds‘, ‘CPU useage of the node‘, labelnames=[‘node_name‘])
g2 = prom.Gauge(‘node_mem_usageBytes‘, ‘Memory useage of the node‘, labelnames=[‘node_name‘])
g3 = prom.Gauge(‘pod_cpu_usageCoreNanoSeconds‘, ‘Memory useage of the node‘, labelnames=[‘pod_name‘,‘pod_namespace‘])
g4 = prom.Gauge(‘pod_mem_usageBytes‘, ‘Memory useage of the node‘, labelnames=[‘pod_name‘,‘pod_namespace‘])

async def expose_stats(url):
    while True:
        stats = getMetrics(url)
        #以打印 node 本身的监控信息为例
        logging.info("nodename: {} value {}".format(stats.node.name, stats.node.cpu))
        # 为当前要 poll 的 metrics 赋值
        g1.labels(node_name=stats.node.name).set(stats.node.cpu)
        g2.labels(node_name=stats.node.name).set(stats.node.memory)
        pods_array = stats.pods
        for item in pods_array:
            g3.labels(pod_name=item.name,pod_namespace=item.namespace).set(item.memory)
            g4.labels(pod_name=item.name,pod_namespace=item.namespace).set(item.cpu)
        await asyncio.sleep(1)
if __name__ == ‘__main__‘:
    loop = asyncio.get_event_loop()
    # 启动一个 http server 来做 polling
    prom.start_http_server(8000)
    t0_value = 50
    #可以在每一台 Windows 机器上都启动一个这样的程序,也可以远程部署脚本来做 exposing
    url = ‘http://localhost:10255/stats/summary‘
    tasks = [loop.create_task(expose_stats(url))]
    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass
    finally:
        loop.close()
  • 写完以后就可以启动这个程序了,访问他的 8000 端口就能看到相关的数据

  • 接下来需要在 prometheus 里加入配置,增加一个收集对象,如下例:
- job_name: python_app
  scrape_interval: 15s
  scrape_timeout: 10s
  metrics_path: /
  scheme: http
  static_configs:
  - targets:
    - localhost:8000
  • 这样在 Prometheus 的页面上能查询到相关的信息了

提问??

  • kubelet 返回的usageNanoCoresusageCoreNanoSeconds 怎么换算成我们通常理解的 CPU 使用百分比

Ref:

原文地址:https://www.cnblogs.com/bigdaddyblog/p/9719878.html

时间: 2024-10-08 12:21:45

解决 Prometheus 不能获取 Kubernetes 集群上 Windows 节点的 Metrics的相关文章

在Kubernetes集群上部署和管理JFrog Artifactory

JFrog Artifactory是一个artifacts仓库管理平台,它支持所有的主流打包格式.构建工具和持续集成(CI)服务器.它将所有二进制内容保存在一个单一位置并提供一个接口,这使得用户在整个应用程序开发和交付过程中,能更易于上传.查找和使用二进制文件. 在本文中我们将介绍如何使用Rancher在Kubernetes集群上部署和管理JFrog Artifactory.在看完本文后,你将会系统地了解JFrog Artifactory OSS的安装设置,并且能够按照同样的步骤在任何Kuber

Rancher2.x 一键式部署 Prometheus + Grafana 监控 Kubernetes 集群

目录 1.Prometheus & Grafana 介绍 2.环境.软件准备 3.Rancher 2.x 应用商店 4.一键式部署 Prometheus 5.验证 Prometheus + Grafana 1.Prometheus & Grafana 介绍 Prometheus 是一套开源的系统监控.报警.时间序列数据库的组合,Prometheus 基本原理是通过 Http 协议周期性抓取被监控组件的状态,而通过 Exporter Http 接口输出这些被监控的组件信息,而且已经有很多 E

从认证到调度,K8s 集群上运行的小程序到底经历了什么?

作者 | 声东? 阿里云售后技术专家 导读:不知道大家有没有意识到一个现实:大部分时候,我们已经不像以前一样,通过命令行,或者可视窗口来使用一个系统了. 前言 现在我们上微博.或者网购,操作的其实不是眼前这台设备,而是一个又一个集群.通常,这样的集群拥有成百上千个节点,每个节点是一台物理机或虚拟机.集群一般远离用户,坐落在数据中心.为了让这些节点互相协作,对外提供一致且高效的服务,集群需要操作系统.Kubernetes 就是这样的操作系统. 比较 Kubernetes 和单机操作系统,Kuber

基于Python+Django的Kubernetes集群管理平台

原文出自[听云技术博客]:http://blog.tingyun.com/web/article/detail/1345 时至今日,接触kubernetes也有一段时间了,而我们的大部分业务也已经稳定地运行在不同规模的kubernetes集群上,不得不说,无论是从应用部署.迭代,还是从资源调度管理等方面都有其难以言喻的优势,但是随着业务的不断增长,以及服务的多元化,容器的体量与管理的难度也随之增长. 浅述Kubernetes集群日常管理维护中的一些痛点: 1.较为庞大的集群规模及容器数量维护管理

实战4节点Centos7.3 安装Kubernetes集群

Kubernetes集群安装部署 Kubernetes集群组件: -Master节点 - etcd 一个高可用的K/V键值对存储和服务发现系统 - kube-apiserver 提供kubernetes集群的API调用 - kube-controller-manager 确保集群服务 - kube-scheduler 调度容器,分配到Node -Minion节点 - flannel 实现夸主机的容器网络的通信 - kubelet 在Node节点上按照配置文件中定义的容器规格启动容器 - kube

Longhorn:实现Kubernetes集群的持久化存储

Longhorn项目是Rancher Labs推出的开源的基于云和容器部署的分布式块存储新方式.Longhorn遵循微服务的原则,利用容器将小型独立组件构建为分布式块存储,并使用容器编排来协调这些组件,形成弹性分布式系统. 自2017年4月Longhorn项目发布以来,人们对在Kubernetes集群上运行Longhorn存储就产生了极大的兴趣.近日,Longhorn v0.2版本发布了,它可支持任何Kubernetes集群的持久化存储实现! Why Longhorn 如今,基于云和容器的部署规

安装部署Kubernetes集群实战

kubernetes概述: Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的一种机制.Kubernetes是Google 2014年创建管理的,是Google 10多年大规模容器管理技术Borg的开源版本. 通过kubernetes可以实现的功能: 快速部署应用 快速扩展应用 无缝对接新的应用功能 节省资源,优化硬件资源的使用 我们的目

【prometheus】kubernetes集群性能监控

手动安装方案——阿里云解决方案(部署失败): https://www.jianshu.com/p/1c7ddf18e8b2 手动安装方案—— (部署成功,但是只有CPU内存等的监控信息,没有GPU的监控信息): https://github.com/camilb/prometheus-kubernetes/tree/master helm安装方案——GPU-Monitoring-tools解决方案(部署成功): 参考:http://fly-luck.github.io/2018/12/10/gp

Centos7上安装Kubernetes集群部署docker

一.安装前准备 1.操作系统详情 需要三台主机,都最小化安装 centos7.3,并update到最新 cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core)  角色主机名IP Master      master192.168.1.14 node1    slave-1192.168.1.15 node2slave-2192.168.1.16 2.在每台主机上关闭firewalld改用iptables 输入以下命令,关闭fire