实现prometheus+grafana的监控部署

直接贴部署用的文件信息了

kubectl label node xxx monitoring=true


创建命名空间
 

kubectl create ns monitoring

部署operator

kubectl apply -f operator-rbac.yml
kubectl apply -f operator-dp.yml
kubectl apply -f operator-crd.yml


 # 定义node-export

kubectl apply -f ./node-exporter/node-exporter-sa.yml
kubectl apply -f ./node-exporter/node-exporter-rbac.yml
kubectl apply -f ./node-exporter/node-exporter-svc.yml
kubectl apply -f ./node-exporter/node-exporter-ds.yml

 # 自定义配置文件,定义显示方式

kubectl apply -f ./grafana/pv-pvc-hostpath.yml
kubectl apply -f ./grafana/grafana-sa.yml
kubectl apply -f ./grafana/grafana-source.yml
kubectl apply -f ./grafana/grafana-datasources.yml
kubectl apply -f ./grafana/grafana-admin-secret.yml
kubectl apply -f ./grafana/grafana-svc.yml


 # 创建配置conifgmap
 

kubectl create configmap grafana-config --from-file=./grafana/grafana.ini --namespace=monitoring
kubectl create configmap all-grafana-dashboards --from-file=./grafana/dashboard --namespace=monitoring


kubectl apply -f ./grafana/grafana-dp.yml
kubectl apply -f ./service-discovery/kube-controller-manager-svc.yml
kubectl apply -f ./service-discovery/kube-scheduler-svc.yml

 # 自定义配置文件,定义收集和报警规则
 

kubectl apply -f ./prometheus/prometheus-secret.yml
kubectl apply -f ./prometheus/prometheus-rules.yml
kubectl apply -f ./prometheus/prometheus-rbac.yml
kubectl apply -f ./prometheus/prometheus-svc.yml

# prometheus-operator  部署成功后才能创建成功
 

kubectl apply -f ./prometheus/pv-pvc-hostpath.yaml
kubectl apply -f ./prometheus/prometheus-main.yml

 # 监控目标,lable必须是k8s-app  因为prometheus是按这个查找的。不然prometheus采集不了该

kubectl apply -f ./servicemonitor/alertmanager-sm.yml
kubectl apply -f ./servicemonitor/coredns-sm.yml
kubectl apply -f ./servicemonitor/kube-apiserver-sm.yml
kubectl apply -f ./servicemonitor/kube-controller-manager-sm.yml
kubectl apply -f ./servicemonitor/kube-scheduler-sm.yml
kubectl apply -f ./servicemonitor/kubelet-sm.yml
kubectl apply -f ./servicemonitor/kubestate-metrics-sm.yml
kubectl apply -f ./servicemonitor/node-exporter-sm.yml
kubectl apply -f ./servicemonitor/prometheus-operator-sm.yml
kubectl apply -f ./servicemonitor/prometheus-sm.yml
kubectl apply -f ./servicemonitor/pushgateway-sm.yml

# prometheus-adapter  部署

kubectl apply -f ./prometheus_adapter/metric_rule.yaml
kubectl apply -f ./prometheus_adapter/prometheus_adapter.yaml

受限于篇幅就不张贴部署脚本内容,详情请参见

GitHub - chenrui2200/prometheus_k8s_install

创建出进监控pod

node_exporterprometheus_k8s 是在 Kubernetes 环境中监控和收集指标的两个重要组件。它们之间有着密切的关系,以下是它们的详细讲解及相互关系。

Node Exporter

  • 定义: node_exporter 是 Prometheus 官方提供的一个工具,用于收集和暴露操作系统及硬件的性能指标。这些指标包括 CPU、内存、磁盘、网络等系统级别的性能数据。

  • 功能:

    • 它运行在每个节点上,监控该节点的系统资源使用情况。
    • 提供的指标格式符合 Prometheus 的要求,因此可以直接被 Prometheus 抓取。
  • 使用场景:

    • 适用于监控物理机、虚拟机或 Kubernetes 节点的基础设施健康状态。

Prometheus K8s

  • 定义: prometheus_k8s 是一个 Prometheus 实例,专门用于在 Kubernetes 集群中监控 Kubernetes 资源及其运行的应用。

  • 功能:

    • 通过 Kubernetes 的 API,自动发现集群中的服务和容器,并抓取它们暴露的指标。
    • 可以监控 Kubernetes 组件(如 kube-apiserver、kube-scheduler、kube-controller-manager)及各个应用程序的性能。
  • 使用场景:

    • 适用于监控整个 Kubernetes 集群的健康状况和性能。

二者的关系

  1. 数据来源:

    • node_exporter 收集每个节点的系统性能指标,然后 Prometheus 可以抓取这些指标。
    • prometheus_k8s 则从 Kubernetes 中的其他组件和应用程序收集指标。
  2. 监控层次:

    • node_exporter 主要关注底层硬件和操作系统级别的监控。
    • prometheus_k8s 关注 Kubernetes 资源和应用的监控,包括 Pods、服务和其它 Kubernetes 对象。
  3. 集成:

    • 在 Kubernetes 环境中,通常会在每个节点上运行 node_exporter,并配置 prometheus_k8s 来定期抓取 node_exporter 的指标,这样就能实现对节点性能的全面监控。

node_exporterprometheus_k8s 是相辅相成的。node_exporter 提供了基础设施级别的监控,而 prometheus_k8s 则补充了 Kubernetes 资源和应用的监控。结合使用这两个组件,能够实现对整个系统的全面监控,帮助运维人员及时发现和解决问题。

查看前端展示

python实现prometheus客户端

import json, datetime, time
import requests
import pysnooper


class Prometheus():

    def __init__(self, host=''):
        #  '/api/v1/query_range'    查看范围数据
        #  '/api/v1/query'    瞬时数据查询
        self.host = host
        self.query_path = 'http://%s/api/v1/query' % self.host
        self.query_range_path = 'http://%s/api/v1/query_range' % self.host

    # @pysnooper.snoop()
    def get_istio_service_metric(self, namespace):
        service_metric = {
            "qps": {},
            "gpu": {},
            "memory": {},
            "cpu": {}
        }
        # qps请求
        mem_expr = 'sum by (destination_workload,response_code) (irate(istio_requests_total{destination_service_namespace="%s"}[1m]))' % (namespace,)
        # print(mem_expr)
        params = {
            'query': mem_expr,
            'start': int(time.time())-300,
            'end': int(time.time()),
            'step': "1m",  # 运行小于1分钟的,将不会被采集到
            # 'timeout':"30s"
        }
        print(params)

        try:
            res = requests.get(url=self.query_range_path, params=params)
            metrics = json.loads(res.content.decode('utf8', 'ignore'))
            if metrics['status'] == 'success':
                metrics = metrics['data']['result']
                if metrics:
                    for service in metrics:
                        service_name = service['metric']['destination_workload']
                        if service_name not in service_metric['qps']:
                            service_metric['qps'][service_name] = {}
                        service_metric["qps"][service_name] = service['values']

        except Exception as e:
            print(e)

        # 内存
        mem_expr = 'sum by (pod) (container_memory_working_set_bytes{job="kubelet", image!="",container_name!="POD",namespace="%s"})' % (namespace,)
        # print(mem_expr)
        params = {
            'query': mem_expr,
            'start': int(time.time()) - 300,
            'end': int(time.time()),
            'step': "1m",  # 运行小于1分钟的,将不会被采集到
            # 'timeout':"30s"
        }
        print(params)

        try:
            res = requests.get(url=self.query_range_path, params=params)
            metrics = json.loads(res.content.decode('utf8', 'ignore'))
            if metrics['status'] == 'success':
                metrics = metrics['data']['result']
                if metrics:
                    for pod in metrics:
                        pod_name = pod['metric']['pod']
                        if pod_name not in service_metric['memory']:
                            service_metric[pod_name] = {}
                        service_metric['memory'][pod_name] = pod['values']

        except Exception as e:
            print(e)

        # cpu获取
        cpu_expr = "sum by (pod) (rate(container_cpu_usage_seconds_total{namespace='%s',container!='POD'}[1m]))" % (namespace)

        params = {
            'query': cpu_expr,
            'start': int(time.time()) - 300,
            'end': int(time.time()),
            'step': "1m",  # 运行小于1分钟的,将不会被采集到
            # 'timeout':"30s"
        }
        print(params)
        try:

            res = requests.get(url=self.query_range_path, params=params)
            metrics = json.loads(res.content.decode('utf8', 'ignore'))
            if metrics['status'] == 'success':
                metrics = metrics['data']['result']
                if metrics:
                    for pod in metrics:
                        pod_name = pod['metric']['pod']
                        if pod_name not in service_metric['cpu']:
                            service_metric[pod_name] = {}
                        service_metric['cpu'][pod_name] = pod['values']

        except Exception as e:
            print(e)

        gpu_expr = "avg by (pod) (DCGM_FI_DEV_GPU_UTIL{namespace='%s'})" % (namespace)

        params = {
            'query': gpu_expr,
            'start': (datetime.datetime.now() - datetime.timedelta(days=1) - datetime.timedelta(hours=8)).strftime('%Y-%m-%dT%H:%M:%S.000Z'),
            'end': datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%S.000Z'),
            'step': "1m",  # 运行小于1分钟的,将不会被采集到
            # 'timeout':"30s"
        }
        print(params)
        try:

            res = requests.get(url=self.query_range_path, params=params)
            metrics = json.loads(res.content.decode('utf8', 'ignore'))
            if metrics['status'] == 'success':
                metrics = metrics['data']['result']
                if metrics:
                    # print(metrics)
                    for pod in metrics:
                        pod_name = pod['metric']['pod']
                        if pod_name not in service_metric['gpu']:
                            service_metric['gpu'][pod_name] = {}
                        service_metric['gpu'][pod_name] = pod['values']

        except Exception as e:
            print(e)

        return service_metric



    # 获取当前pod利用率
    # @pysnooper.snoop()
    def get_resource_metric(self):
        max_cpu = 0
        max_mem = 0
        ave_gpu = 0
        pod_metric = {}
        # 这个pod  30分钟内的最大值
        mem_expr = "sum by (pod) (container_memory_working_set_bytes{container!='POD', container!=''})"
        # print(mem_expr)
        params = {
            'query': mem_expr,
            'start': int(time.time()) - 300,
            'end': int(time.time()),
            'step': "1m",  # 运行小于1分钟的,将不会被采集到
            # 'timeout':"30s"
        }
        print(params)

        try:
            res = requests.get(url=self.query_range_path, params=params)
            metrics = json.loads(res.content.decode('utf8', 'ignore'))
            if metrics['status'] == 'success':
                metrics = metrics['data']['result']
                if metrics:
                    for pod in metrics:
                        if pod['metric']:
                            pod_name = pod['metric']['pod']
                            values = max([float(x[1]) for x in pod['values']])
                            if pod_name not in pod_metric:
                                pod_metric[pod_name] = {}
                            pod_metric[pod_name]['memory'] = round(values / 1024 / 1024 / 1024, 2)

        except Exception as e:
            print(e)

        cpu_expr = "sum by (pod) (rate(container_cpu_usage_seconds_total{container!='POD'}[1m]))"

        params = {
            'query': cpu_expr,
            'start': int(time.time()) - 300,
            'end': int(time.time()),
            'step': "1m",  # 运行小于1分钟的,将不会被采集到
            # 'timeout':"30s"
        }
        print(params)
        try:

            res = requests.get(url=self.query_range_path, params=params)
            metrics = json.loads(res.content.decode('utf8', 'ignore'))
            if metrics['status'] == 'success':
                metrics = metrics['data']['result']
                if metrics:
                    for pod in metrics:
                        if pod['metric']:
                            pod_name = pod['metric']['pod']
                            values = [float(x[1]) for x in pod['values']]
                            # values = round(sum(values) / len(values), 2)
                            values = round(max(values), 2)
                            if pod_name not in pod_metric:
                                pod_metric[pod_name] = {}
                            pod_metric[pod_name]['cpu'] = values

        except Exception as e:
            print(e)

        gpu_expr = "avg by (pod) (DCGM_FI_DEV_GPU_UTIL)"

        params = {
            'query': gpu_expr,
            'start': int(time.time()) - 300,
            'end': int(time.time()),
            'step': "1m",  # 运行小于1分钟的,将不会被采集到
            # 'timeout':"30s"
        }
        print(params)
        try:

            res = requests.get(url=self.query_range_path, params=params)
            metrics = json.loads(res.content.decode('utf8', 'ignore'))
            if metrics['status'] == 'success':
                metrics = metrics['data']['result']
                if metrics:
                    # print(metrics)
                    for pod in metrics:
                        if pod['metric']:
                            pod_name = pod['metric']['pod']
                            values = [float(x[1]) for x in pod['values']]
                            # values = round(sum(values)/len(values),2)
                            values = round(max(values), 2)
                            if pod_name not in pod_metric:
                                pod_metric[pod_name] = {}
                            pod_metric[pod_name]['gpu'] = values / 100

        except Exception as e:
            print(e)

        return pod_metric

    # @pysnooper.snoop()
    def get_namespace_resource_metric(self, namespace):
        max_cpu = 0
        max_mem = 0
        ave_gpu = 0
        pod_metric = {}
        # 这个pod  30分钟内的最大值
        mem_expr = "sum by (pod) (container_memory_working_set_bytes{namespace='%s',container!='POD', container!=''})" % (namespace,)
        # print(mem_expr)
        params = {
            'query': mem_expr,
            'start': int(time.time()) - 60*60*24,
            'end': int(time.time()),
            'step': "1m",  # 运行小于1分钟的,将不会被采集到
            # 'timeout':"30s"
        }
        print(params)

        try:
            res = requests.get(url=self.query_range_path, params=params)
            metrics = json.loads(res.content.decode('utf8', 'ignore'))
            if metrics['status'] == 'success':
                metrics = metrics['data']['result']
                if metrics:
                    for pod in metrics:
                        pod_name = pod['metric']['pod']
                        values = max([float(x[1]) for x in pod['values']])
                        if pod_name not in pod_metric:
                            pod_metric[pod_name] = {}
                        pod_metric[pod_name]['memory'] = round(values / 1024 / 1024 / 1024, 2)

        except Exception as e:
            print(e)

        cpu_expr = "sum by (pod) (rate(container_cpu_usage_seconds_total{namespace='%s',container!='POD'}[1m]))" % (namespace)

        params = {
            'query': cpu_expr,
            'start': int(time.time()) - 60*60*24,
            'end': int(time.time()),
            'step': "1m",  # 运行小于1分钟的,将不会被采集到
            # 'timeout':"30s"
        }
        print(params)
        try:

            res = requests.get(url=self.query_range_path, params=params)
            metrics = json.loads(res.content.decode('utf8', 'ignore'))
            if metrics['status'] == 'success':
                metrics = metrics['data']['result']
                if metrics:
                    for pod in metrics:
                        pod_name = pod['metric']['pod']
                        values = [float(x[1]) for x in pod['values']]
                        # values = round(sum(values) / len(values), 2)
                        values = round(max(values), 2)
                        if pod_name not in pod_metric:
                            pod_metric[pod_name] = {}
                        pod_metric[pod_name]['cpu'] = values

        except Exception as e:
            print(e)

        gpu_expr = "avg by (pod) (DCGM_FI_DEV_GPU_UTIL{namespace='%s'})" % (namespace)

        params = {
            'query': gpu_expr,
            'start': int(time.time()) - 60*60*24,
            'end': int(time.time()),
            'step': "1m",  # 运行小于1分钟的,将不会被采集到
            # 'timeout':"30s"
        }
        print(params)
        try:

            res = requests.get(url=self.query_range_path, params=params)
            metrics = json.loads(res.content.decode('utf8', 'ignore'))
            if metrics['status'] == 'success':
                metrics = metrics['data']['result']
                if metrics:
                    # print(metrics)
                    for pod in metrics:
                        pod_name = pod['metric']['pod']
                        values = [float(x[1]) for x in pod['values']]
                        # values = round(sum(values)/len(values),2)
                        values = round(max(values), 2)
                        if pod_name not in pod_metric:
                            pod_metric[pod_name] = {}
                        pod_metric[pod_name]['gpu'] = values / 100

        except Exception as e:
            print(e)

        return pod_metric

        # @pysnooper.snoop()

    def get_pod_resource_metric(self, pod_name, namespace):
        max_cpu = 0
        max_mem = 0
        ave_gpu = 0

        # 这个pod  30分钟内的最大值
        mem_expr = "sum by (pod) (container_memory_working_set_bytes{namespace='%s', pod=~'%s.*',container!='POD', container!=''})"%(namespace,pod_name)
        # print(mem_expr)
        params = {
            'query': mem_expr,
            'start': int(time.time()) - 60*60*24,
            'end': int(time.time()),
            'step': "1m",  # 运行小于1分钟的,将不会被采集到
            # 'timeout':"30s"
        }
        print(params)

        try:
            res = requests.get(url=self.query_range_path, params=params)
            metrics = json.loads(res.content.decode('utf8', 'ignore'))
            if metrics['status'] == 'success':
                metrics = metrics['data']['result']
                if metrics:
                    metrics = metrics[0]['values']
                    for metric in metrics:
                        if int(metric[1]) > max_mem:
                            max_mem = int(metric[1]) / 1024 / 1024 / 1024

        except Exception as e:
            print(e)

        cpu_expr = "sum by (pod) (rate(container_cpu_usage_seconds_total{namespace='%s',pod=~'%s.*',container!='POD'}[1m]))" % (namespace, pod_name)

        params = {
            'query': cpu_expr,
            'start': int(time.time()) - 60*60*24,
            'end': int(time.time()),
            'step': "1m",  # 运行小于1分钟的,将不会被采集到
            # 'timeout':"30s"
        }
        print(params)
        try:

            res = requests.get(url=self.query_range_path, params=params)
            metrics = json.loads(res.content.decode('utf8', 'ignore'))
            if metrics['status'] == 'success':
                metrics = metrics['data']['result']
                if metrics:
                    metrics = metrics[0]['values']
                    for metric in metrics:
                        if float(metric[1]) > max_cpu:
                            max_cpu = float(metric[1])
        except Exception as e:
            print(e)

        gpu_expr = "avg by (pod) (DCGM_FI_DEV_GPU_UTIL{namespace='%s',pod=~'%s.*'})" % (namespace, pod_name)

        params = {
            'query': gpu_expr,
            'start': int(time.time()) - 60*60*24,
            'end': int(time.time()),
            'step': "1m",  # 运行小于1分钟的,将不会被采集到
            # 'timeout':"30s"
        }
        print(params)
        try:
            res = requests.get(url=self.query_range_path, params=params)
            metrics = json.loads(res.content.decode('utf8', 'ignore'))
            if metrics['status'] == 'success':
                metrics = metrics['data']['result']
                if metrics:
                    metrics = metrics[0]['values']
                    all_util = [float(metric[1]) for metric in metrics]
                    ave_gpu = sum(all_util) / len(all_util) / 100
        except Exception as e:
            print(e)

        return {"cpu": round(max_cpu, 2), "memory": round(max_mem, 2), 'gpu': round(ave_gpu, 2)}

    # todo 获取机器的负载补充完整
    # @pysnooper.snoop()
    def get_machine_metric(self):
        # 这个pod  30分钟内的最大值
        metrics = {
            "pod_num": "sum(kubelet_running_pod_count)by (node)",
            "request_memory": "",
            "request_cpu": "",
            "request_gpu": "",
            "used_memory": "",
            "used_cpu": "",
            "used_gpu": "",
        }
        back = {}
        for metric_name in metrics:
            # print(mem_expr)
            params = {
                'query': metrics[metric_name],
                'timeout': "30s"
            }
            print(params)
            back[metric_name] = {}

            try:
                res = requests.get(url=self.query_path, params=params)
                metrics = json.loads(res.content.decode('utf8', 'ignore'))
                if metrics['status'] == 'success':
                    metrics = metrics['data']['result']
                    if metrics:
                        for metric in metrics:
                            node = metric['metric']['node']
                            if ':' in node:
                                node = node[:node.index(':')]
                            value = metric['value'][1]
                            back[metric_name][node] = int(value)


            except Exception as e:
                print(e)

        return back

Prometheus 查询语法使用一种类似于函数式编程的表达方式,允许用户从时间序列数据库中提取和聚合数据。你提供的查询语句 cpu_expr 是一个典型的 Prometheus 查询,下面是对其各个部分的详细讲解:

  1. 函数 sum:是一个聚合函数,用于对一组时间序列进行求和。它可以用于计算所有匹配指标的总和。

  2. by (pod)这是一个分组操作,表示将结果按 pod 标签进行分组。这样,查询结果将显示每个 pod 的 CPU 使用量总和。

  3. rate(container_cpu_usage_seconds_total{...}[1m]):

    rate 是一个用于计算时间序列速率的函数。在这里,它计算 container_cpu_usage_seconds_total 指标在过去 1 分钟内的变化率。container_cpu_usage_seconds_total 是一个计数器类型的指标,表示容器 CPU 使用时间的总和。{namespace='%s',container!='POD'} 是一个标签选择器,用于过滤指标。它选择特定命名空间下的所有容器,但排除了名为 POD 的容器。
  • 整体而言,这个查询的目的是计算指定命名空间下,所有非 POD 容器的 CPU 使用率,并按每个 pod 进行分组。通过使用 rate 函数,它可以提供 CPU 使用的实时速率,而不是总使用时间,这样更能反映容器的当前状态。

    def echart(self, filters=None):
        
        prometheus = Prometheus(conf.get('PROMETHEUS', 'prometheus-k8s.monitoring:9090'))
        # 获取 prometheus-k8s 地址
        pod_resource_metric = prometheus.get_resource_metric()
        print('pod_resource_metric', pod_resource_metric)

        all_resource = {
            "mem_all": sum([int(global_cluster_load[cluster_name]['mem_all']) for cluster_name in global_cluster_load]),
            "cpu_all": sum([int(global_cluster_load[cluster_name]['cpu_all']) for cluster_name in global_cluster_load]),
            "gpu_all": sum([int(global_cluster_load[cluster_name]['gpu_all']) for cluster_name in global_cluster_load]),
        }
        all_resource_req = {
            "mem_req": sum([int(global_cluster_load[cluster_name]['mem_req']) for cluster_name in global_cluster_load]),
            "cpu_req": sum([int(global_cluster_load[cluster_name]['cpu_req']) for cluster_name in global_cluster_load]),
            "gpu_req": sum([int(global_cluster_load[cluster_name]['gpu_req']) for cluster_name in global_cluster_load]),
        }
        all_resource_used = {
            "mem_used": sum([pod_resource_metric[x].get('memory', 0) for x in pod_resource_metric]),
            "cpu_used": sum([pod_resource_metric[x].get('cpu', 0) for x in pod_resource_metric]),
            "gpu_used": sum([pod_resource_metric[x].get('gpu', 0) for x in pod_resource_metric]),
        }

        option = {
            "title": [
                {
                    "subtext": __('集群信息'),
                    "MEM_NAME": __('内存请求占有率'),
                    "MEM_VALUE": int(100 * all_resource_req['mem_req'] / (0.001 + all_resource['mem_all'])),
                    "CPU_NAME": __('CPU占用率'),
                    "CPU_VALUE": int(all_resource['cpu_all']),
                    'GPU_NAME': __('GPU总量(卡)'),
                    'GPU_VALUE': int(all_resource['gpu_all']),
                    'MEM_MAX': int(all_resource['mem_all'] * 2),
                    'CPU_MAX': int(all_resource['cpu_all'] * 2),
                    'GPU_MAX': int(all_resource['gpu_all'] * 2)
                },
                {
                    "subtext": __('资源占用率'),
                    "MEM_NAME": __('内存占用率'),
                    "MEM_VALUE": int(100 * all_resource_req['mem_req'] / (0.001 + all_resource['mem_all'])),
                    "CPU_NAME": __('CPU占用率'),
                    "CPU_VALUE": int(100 * all_resource_req['cpu_req'] / (0.001 + all_resource['cpu_all'])),
                    "GPU_NAME": __('GPU占用率'),
                    "GPU_VALUE": int(100 * all_resource_req['gpu_req'] / (0.001 + all_resource['gpu_all']))

                },
                {
                    "subtext": __('资源利用率'),
                    'MEM_NAME': __('内存利用率'),
                    'MEM_VALUE': str(min(100,
                                         int(100 *
                                             all_resource_used[
                                                 'mem_used'] / (
                                                     0.001 +
                                                     all_resource[
                                                         'mem_all'])))),
                    'CPU_NAME': __('CPU利用率'),
                    'CPU_VALUE': str(min(100, int(100 *
                                                  all_resource_used[
                                                      'cpu_used'] / (
                                                          0.001 +
                                                          all_resource[
                                                              'cpu_all'])))),
                    'GPU_NAME': __('GPU利用率'),
                    'GPU_VALUE': str(min(100, int(100 *
                                                  all_resource_used[
                                                      'gpu_used'] / (
                                                          0.001 +
                                                          all_resource[
                                                              'gpu_all']))))
                }
            ]
        }

        return option

附一个用上面代码实现的运维表盘界面

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Qt 支持打包成安卓

1. 打开维护Qt,双击MaintenanceTool.exe 2.登陆进去,默认是添加或移除组件,点击下一步, 勾选Android, 点击下一步 3.更新安装中 4.进度100%,完成安装,重启。 5.打开 Qt Creator,编辑-》Preferences... 6.进…

self-supervised learning(BERT和GPT)

1芝麻街与NLP模型 我們接下來要講的主題呢叫做Self-Supervised Learning,在講self-supervised learning之前呢,就不能不介紹一下芝麻街,為什麼呢因為不知道為什麼self-supervised learning的模型都是以芝麻街的人物命名。 因為Bert是一個非常…

maven下载依赖报错Blocked mirror for repositories

原因&#xff1a;Maven版本过高 解决办法 setting文件添加 或者降低maven版本 <mirrors><mirror><id>maven-default-http-blocker</id><mirrorOf>external:dummy:*</mirrorOf><name>Pseudo repository to mirror external reposit…

表格切割效果,“两个”表格实现列对应、变化一致

如何让两个表格的部分列对应且缩放一致 先看效果 使用一个原生table的即可实现 “两个”表格的视觉效果让“两个”表格的对应列缩放保持一致 废话不多说&#xff0c;直接上代码 html: <html><div><table><caption class"table-name">表格…

模拟信号采集显示器+GPS同步信号发生器制作全过程(焊接、问题、代码、电路)

1、制作最小系统板 在制作最小系统板的时候&#xff0c;要用USB转TTL给板子供电&#xff0c;留了一个电源输入的四个接口&#xff0c;同时又用排针引出来VCC和GND用于后续其他外设的电源供应&#xff0c;电源配有电源指示灯和保护电容&#xff0c; 当时在焊接的时候把接口处的…

设计模式(二)工厂模式详解

设计模式&#xff08;二&#xff09;工厂模式详解 简单工厂模式指由一个工厂对象来创建实例,适用于工厂类负责创建对象较少的情况。例子&#xff1a;Spring 中的 BeanFactory 使用简单工厂模式&#xff0c;产生 Bean 对象。 工厂模式简介 定义&#xff1a;工厂模式是一种创建…

机房巡检机器人有哪些功能和作用

随着数据量的爆炸式增长和业务的不断拓展&#xff0c;数据中心面临诸多挑战。一方面&#xff0c;设备数量庞大且复杂&#xff0c;数据中心内服务器、存储设备、网络设备等遍布&#xff0c;这些设备需时刻保持良好运行状态&#xff0c;因为任何一个环节出现问题都可能带来严重后…

java项目之电影评论网站(springboot)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的电影评论网站。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 电影评论网站的主要使用者管…

如何在 Ubuntu 24.04 上安装多PHP版本 (从8.3到5.6) ?

PHP 代表超文本预处理器&#xff0c;它仍然是网络的基石&#xff0c;为互联网上很大一部分网站和网络应用程序提供动力。大多数顶级网站和博客工具仍然使用 PHP&#xff0c;如 WordPress, Facebook, Wikipedia 等。如果你在 Ubuntu 24.04 上为 web 开发&#xff0c;安装 PHP 可…

算法的学习笔记—数组中只出现一次的数字(牛客JZ56)

&#x1f600;前言 在数组中寻找只出现一次的两个数字是一道经典的问题&#xff0c;通常可以通过位运算来有效解决。本文将详细介绍这一问题的解法&#xff0c;深入解析其背后的思路。 &#x1f3e0;个人主页&#xff1a;尘觉主页 文章目录 &#x1f970;数组中只出现一次的数字…

rtsp的2种收流模式

rtsp协商成功以后就是rtp收流&#xff0c;又分为两种模式:rtp over rtsp(tcp)和rtp over udp。 1.rtsp over rtsp 这个现在一般都叫TCP&#xff0c;它的特点是rtsp服务端和客户端是共用一个tcp链接&#xff0c;也就是说rtsp协议报文、rtp包、rtcp数据都是通过这一个链接来交互…

合约门合同全生命周期管理系统:企业合同管理的数字化转型之道

合约门合同全生命周期管理系统&#xff1a;企业合同管理的数字化转型之道 1. 引言 在现代企业中&#xff0c;合同管理已经不再是简单的文件存储和审批流程&#xff0c;而是企业合规性、风险管理和业务流程的关键环节之一。随着企业规模的扩大和合同数量的增加&#xff0c;传统…

第二单元历年真题整理

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 参考答案 1. A 2. A 3. A 4. D 5. D 6. D 解析&#xff1a; 栈和队列是两个不一样的结构&#xff0c;不能放在一起表示 7. B 8. C 解析&#xff1a; S --> A0 | B1 --> (S1 | 1) 0 | (S0 | 0)1 --> S10 | 10 | S…

51单片机快速入门之 模拟 I2C 用精准中断来控制

51单片机快速入门之 模拟 I2C 用精准中断来控制 首先复习一下51单片机快速入门之定时器和计数器(含中断基础) 再看看之前的I2C操作 51单片机快速入门之 IIC I2C通信 定时器/计数器是51单片机中用于实现精确延时的硬件资源。通过配置定时器的初始值和工作模式&#xff0c;可以…

Unable to open nested entry ‘********.jar‘ 问题解决

今天把现网版本的task的jar拖回来然后用7-zip打开拖了一个jar进去替换mysql-connector-java-5.1.47.jar 为 mysql-connector-java-5.1.27.jar 启动微服务的时候就报错下面的 Exception in thread "main" java.lang.IllegalStateException: Failed to get nested ar…

《Python游戏编程入门》注-第2章2

《Python游戏编程入门》的“2.2.5 绘制线条”中提到了通过pygame库绘制线条的方法。 1 相关函数介绍 通过pygame.draw模块中的line()函数来绘制线条&#xff0c;该函数的格式如下所示。 line(surface, color, start_pos, end_pos, width1) -> Rect 其中&#xff0c;第一…

开源限流组件分析(二):uber-go/ratelimit

文章目录 本系列漏桶限流算法uber的漏桶算法使用mutex版本数据结构获取令牌松弛量 atomic版本数据结构获取令牌测试漏桶的松弛量 总结 本系列 开源限流组件分析&#xff08;一&#xff09;&#xff1a;juju/ratelimit开源限流组件分析&#xff08;二&#xff09;&#xff1a;u…

部署前后端分离若依项目--CentOS7宝塔版

准备&#xff1a; CentOS7服务器一台 通过网盘分享的文件&#xff1a;CentOS 7 h 链接: https://pan.baidu.com/s/17DF8eRSSDuj9VeqselGa_Q 提取码: s7x4 大家有需要可以下载这个&#xff0c;密码61 若依前端编译后文件 通过网盘分享的文件&#xff1a;ruoyi-admin.jar 链…

生信软件39 - GATK最佳实践流程重构,提高17倍分析速度的LUSH流程

1. LUSH流程简介 基因组测序通常用于分子诊断、分期和预后&#xff0c;而大量测序数据在分析时间方面提出了挑战。 对于从FASTQ到VCF的整个流程&#xff0c;LUSH流程在非GVCF和GVCF模式下都大大降低了运行时间&#xff0c;30 X WGS数据耗时不到2 h&#xff0c;从BAM到VCF约需…

【计网】UDP Echo Server与Client实战:从零开始构建简单通信回显程序

目录 前言&#xff1a; 1.实现udpserver类 1.1.创建udp socket 套接字 --- 必须要做的 socket&#xff08;&#xff09;讲解 代码实现&#xff1a;​编辑 代码讲解&#xff1a; 1.2.填充sockaddr_in结构 代码实现&#xff1a; 代码解析&#xff1a; 1.3.bind sockfd和…