使用 dotnet-monitor 在 Kubernetes 中收集 .NET metrics

使用 dotnet-monitor 在 Kubernetes 中收集 .NET metrics

Intro

dotnet-monitor 是微软推出的一个帮助我们诊断和监控 .NET 应用程序的工具,在 Kubernetes 中我们可以让 dotnet-monitor 作为 sidecar 运行,无侵入地监控 .NET 应用,今天我们就来介绍一下如果在 Kubernetes 中使用吧

GetStarted

作为 sidecar 运行的时候,我们只需要修改应用的 deployment 对应的 yaml 文件即可,下面是一个示例:

apiVersion: apps/v1
kind: Deployment
metadata:name: sparktodo-apilabels:app: sparktodo-api
spec:replicas: 1revisionHistoryLimit: 0selector:matchLabels:app: sparktodo-apiminReadySeconds: 0strategy:type: RollingUpdaterollingUpdate:maxUnavailable: 1maxSurge: 1template:metadata:annotations:prometheus.io/scrape: "true"prometheus.io/port: "52323"labels:app: sparktodo-apispec:containers:- name: sparktodo-apiimage: weihanli/sparktodo-api:latestimagePullPolicy: Alwaysresources:requests:memory: "64Mi"cpu: "20m"limits:memory: "128Mi"cpu: "50m"env:- name: DOTNET_DiagnosticPortsvalue: /diag/portports:- name: httpcontainerPort: 80protocol: TCPlivenessProbe:httpGet:path: /healthport: 80initialDelaySeconds: 60periodSeconds: 30readinessProbe:httpGet:path: /healthport: 80initialDelaySeconds: 60periodSeconds: 30volumeMounts:- mountPath: /diagname: diagvol- mountPath: /dumpsname: dumpsvol- name: monitorimage: mcr.microsoft.com/dotnet/monitorargs: [ "--no-auth" ]imagePullPolicy: Alwaysports:- containerPort: 52323env:- name: DOTNETMONITOR_DiagnosticPort__ConnectionModevalue: Listen- name: DOTNETMONITOR_DiagnosticPort__EndpointNamevalue: /diag/port- name: DOTNETMONITOR_Storage__DumpTempFoldervalue: /dumps- name: DOTNETMONITOR_Urlsvalue: "http://+:52323"volumeMounts:- mountPath: /diagname: diagvol- mountPath: /dumpsname: dumpsvolresources:requests:cpu: 20mmemory: 32Milimits:cpu: 50mmemory: 256Mivolumes:- name: diagvolemptyDir: {}- name: dumpsvolemptyDir: {}

为了方便对比,下面是一个变更对比

template:metadata:
+      annotations:
+        prometheus.io/scrape: "true"
+        prometheus.io/port: "52323"labels:app: sparktodo-apispec:containers:- name: sparktodo-apiimage: weihanli/sparktodo-api:latestimagePullPolicy: Alwaysresources:requests:memory: "64Mi"cpu: "20m"limits:memory: "128Mi"cpu: "50m"
+          env:
+          - name: DOTNET_DiagnosticPorts
+            value: /diag/portports:- name: httpcontainerPort: 80protocol: TCPlivenessProbe:httpGet:path: /healthport: 80initialDelaySeconds: 60periodSeconds: 30readinessProbe:httpGet:path: /healthport: 80initialDelaySeconds: 60periodSeconds: 30
+          volumeMounts:
+          - mountPath: /diag
+            name: diagvol
+          - mountPath: /dumps
+            name: dumpsvol
+        - name: monitor
+          image: mcr.microsoft.com/dotnet/monitor
+          args: [ "--no-auth" ]
+          imagePullPolicy: Always
+          ports:
+            - containerPort: 52323
+          env:
+          - name: DOTNETMONITOR_DiagnosticPort__ConnectionMode
+            value: Listen
+          - name: DOTNETMONITOR_DiagnosticPort__EndpointName
+            value: /diag/port
+          - name: DOTNETMONITOR_Storage__DumpTempFolder
+            value: /dumps
+          - name: DOTNETMONITOR_Urls
+            value: "http://+:52323"
+          volumeMounts:
+          - mountPath: /diag
+            name: diagvol
+          - mountPath: /dumps
+            name: dumpsvol
+          resources:
+            requests:
+              cpu: 20m
+              memory: 32Mi
+            limits:
+              cpu: 50m
+              memory: 256Mi
+      volumes:
+      - name: diagvol
+        emptyDir: {}
+      - name: dumpsvol
+        emptyDir: {}

与没有使用 dotnet-monitor 之前相比,主要的变化有这几个方面:

  • 增加了一个 dotnet-monitor 的容器

  • 增加了 volume 和 DiagnosticPorts 配置以支持 .NET 应用和 dotnet-monitor 的通信

  • 增加了 Prometheus 的配置以让 Prometheus 从 dotnet-monitor 拉取 metrics

实际效果:

metrics 示例:

b3f00241cbcc14422fed41020b27a58a.png

cf916b80b9150e2c1f504c4d4984e66c.png

144df4028ffe88c1d4381f45e15bde63.png

dotnet-monitor 默认会收集很多信息,包括了 CPU、内存、GC、线程池等等信息,可以帮助我们更好的了解 .NET 应用的运行状况,通过 Prometheus 收集到数据之后,我们可以进一步通过 Grafana 来做更好的 UI 展示以及可以根据指定的指标来做监控报警(做了几个小示例,数据仅供参考)

275a7cba1ca9c57828103a6904543ab7.png

b2760e22bba479202e5c827082d4044b.png

e14ad394185642eef30dd7499497ddb5.png

Sample 2

默认地,dotnet-monitor 会监控三个来源的数据,可以认为就是 dotnet-counters 中的三个 Provider,

分别是 System.Runtime/Microsoft.AspNetCore.Hosting/Grpc.AspNetCore.Server

我们也可以自定义 dotnet-monitor 的配置来禁用默认的 provider 或者添加更多新的 provider,我们可以提供两种类型的配置,一种是环境变量形式的配置,配置分隔符使用 __ 来表示,比如

Metrics__IncludeDefaultProviders: true

也可以使用 Json 文件配置(推荐):

{"Metrics": {"IncludeDefaultProviders": true}
}

更加推荐使用 JSON 方式,因为更加直观,而且更便于维护

这两种方式配置方式配置文件的路径是不一样的,对于第一种配置配置文件放在 /etc/dotnet-monitor 中,而对于 Json 方式的配置则可以更加灵活的自定义,可以使用 XDG_CONFIG_HOME 来定义配置根目录,如果配置为 /etc 则配置文件对应的路径则是 /etc/dotnet-monitor/settings.json,下面是一个使用自定义配置的示例,无论哪种方式配置都可以通过 ConfigMap 来定义,挂载到容器的指定路径

apiVersion: apps/v1
kind: Deployment
metadata:name: reservation-servernamespace: defaultlabels:app: reservation-server
spec:replicas: 1revisionHistoryLimit: 2selector:matchLabels:app: reservation-serverminReadySeconds: 0strategy:type: RollingUpdaterollingUpdate:maxUnavailable: 1maxSurge: 1template:metadata:labels:app: reservation-serverspec:containers:        - name: reservation-serverimage: openreservation/reservation-server:latestimagePullPolicy: Alwaysresources:requests:cpu: 30mmemory: 32Milimits:cpu: 80mmemory: 256MireadinessProbe:httpGet:path: /healthport: 80initialDelaySeconds: 60periodSeconds: 30livenessProbe:httpGet:path: /healthport: 80initialDelaySeconds: 60periodSeconds: 30ports:- containerPort: 80env:- name: DOTNET_DiagnosticPortsvalue: /diag/portvolumeMounts:- name: settingsmountPath: /app/appsettings.Production.jsonsubPath: appsettings- mountPath: /diagname: diagvol- mountPath: /dumpsname: dumpsvol- mountPath: /tmpname: tmpvol- name: dotnet-monitorimage: mcr.microsoft.com/dotnet/monitorargs: [ "--no-auth" ]imagePullPolicy: Alwaysports:- containerPort: 52323env:- name: DOTNETMONITOR_DiagnosticPort__ConnectionModevalue: Listen- name: DOTNETMONITOR_DiagnosticPort__EndpointNamevalue: /diag/port- name: DOTNETMONITOR_Storage__DumpTempFoldervalue: /dumps- name: DOTNETMONITOR_Urlsvalue: "http://+:52323"- name: XDG_CONFIG_HOMEvalue: "/etc"volumeMounts:- mountPath: /diagname: diagvol- mountPath: /dumpsname: dumpsvol- mountPath: /tmpname: tmpvol- name: monitor-configsmountPath: /etc/dotnet-monitor/settings.jsonsubPath: defaultresources:requests:cpu: 30mmemory: 32Milimits:cpu: 50mmemory: 256Mivolumes:- name: settingsconfigMap:name: reservation-configs- name: monitor-configsconfigMap:name: dotnet-monitor-configs- name: diagvolemptyDir: {}- name: dumpsvolemptyDir: {}- name: tmpvolemptyDir: {}

对于 dotnet-monitor 的配置可以放在一个 ConfigMap 中,通过挂载的方式挂载到 dotnet-monitor 容器中,dotnet-monitor 配置 ConfigMap 示例如下:

apiVersion: v1
kind: ConfigMap
metadata:name: dotnet-monitor-configsnamespace: default
data:default: |{"urls": "http://*:52323","Metrics": {"IncludeDefaultProviders": true,"Providers": [{"ProviderName": "System.Net.Http"},{"ProviderName": "Microsoft.EntityFrameworkCore"},{"ProviderName": "Microsoft.Data.SqlClient.EventSource"}]}}

这里另外配置了 Metrics 来源

  • System.Net.Http 提供 HttpClient 相关的 EventCounters 数据

  • Microsoft.EntityFrameworkCore 提供 EF Core 相关的 EventCounters 数据

如果我们自己应用程序中有自己封装的一些 Event counters 数据也是可以收集的

3dc837eb75df22f95fe6ba502dab41d1.png

Connection Mode

细心的小伙伴们可能会发现我们前面示例中在 dotnet-monitor 容器中都配置了一个环境变量 DOTNETMONITOR_DiagnosticPort__ConnectionMode Listen

上面两个示例中都是使用 Listen 模式,但是 Listen 模式是 .NET 5 之后才支持的,对于 .NET Core 3.x 的应用应该使用 Connect 模式(踩了坑的==

下面是一个 Connect 模式的 deployment 示例,也是第一个示例改成的 Connect 模式

apiVersion: apps/v1
kind: Deployment
metadata:name: sparktodo-apilabels:app: sparktodo-api
spec:replicas: 1revisionHistoryLimit: 0selector:matchLabels:app: sparktodo-apiminReadySeconds: 0strategy:type: RollingUpdaterollingUpdate:maxUnavailable: 1maxSurge: 1template:metadata:annotations:prometheus.io/scrape: "true"prometheus.io/port: "52323"labels:app: sparktodo-apispec:containers:- name: sparktodo-apiimage: weihanli/sparktodo-api:latestimagePullPolicy: Alwaysresources:requests:memory: "64Mi"cpu: "20m"limits:memory: "128Mi"cpu: "50m"ports:- name: httpcontainerPort: 80protocol: TCPlivenessProbe:httpGet:path: /healthport: 80initialDelaySeconds: 60periodSeconds: 30readinessProbe:httpGet:path: /healthport: 80initialDelaySeconds: 60periodSeconds: 30volumeMounts:- mountPath: /tmpname: tmpvol- name: monitorimage: mcr.microsoft.com/dotnet/monitorargs: [ "--no-auth" ]imagePullPolicy: Alwaysports:- containerPort: 52323env:- name: DOTNETMONITOR_DiagnosticPort__ConnectionModevalue: Connect- name: DOTNETMONITOR_Urlsvalue: "http://+:52323"volumeMounts:- mountPath: /tmpname: tmpvolresources:requests:cpu: 20mmemory: 32Milimits:cpu: 50mmemory: 256Mivolumes:- name: tmpvolemptyDir: {}

Listen 模式相比,Connect 模式更为简单一些,应用程序只需要和 dotnet-monitor 容器挂载同一个 tmp 目录即可,但是 Listen 模式功能更为强大,Listen 模式可以支持同时监听多个 .NET 容器,Connect 模式不支持,而且有一些高级的用法 CollectionRule 的配置仅仅支持 Listen 模式,可以参考:https://github.com/dotnet/dotnet-monitor/issues/1274,所以如果可能应当使用 Listen 模式,.NET Core 3.x 只支持 Connect 模式

Open API

dotnet-monitor 除了 metrics 之外还提供了很多的别的 API 可以参考文档 https://github.com/dotnet/dotnet-monitor/blob/main/documentation/api/README.md

RouteDescription
/processes获取捕获的进程的信息
/dump生成一个进程的托管 dump
/gcdump生成进程的 GC dump
/trace生成进程的 Trace 信息
/metrics生成进程的 metrics 信息,并以 Prometheus 的格式返回
/livemetrics捕获进程的实时 metrics 信息
/logs捕获进程日志信息(EventLog)
/info获取当前 dotnet-monitor 的信息(版本信息,基本配置)
/operations获取 egress 操作状态获取取消操作

More

使用 dotnet-monitor 之后,我们就可以更好的监控我们的应用程序,之前我们使用 prometheus-net.DotNetRuntime 这个项目来监控我们的应用程序,有了 dotnet-monitor 基本完全可以取代它了,而且不需要写一行代码,而且扩展性也比较强,只需要修改配置文件就能收集更多自己关心的数据了,功能也很强大,metrics 数据能够帮助我们了解应用程序的整体状态,但是有些问题可能还需要生成进程 dump 来分析具体原因,dotnet-monitor 也可以很方便地生成进程 dump 以及 trace 数据等等,还可以配置一些动态创建 dump,trace 的配置,比如内存持续一分钟超过 2G 创建 dump 等。

另外在部署的时候,上面为了简单没有启用授权,实际使用如果需要公网访问,授权一定要做好,现在已经默认支持授权了,可以参考文档配置,另外一种则是不要给公网访问,只在 k8s 集权内部可以访问,需要的话本地做一个 port-forward 进行操作,也是我更为推荐的使用方式。

功能很强大,一篇文章很难介绍完,大家可以了解一下,有需要的时候就可以用起来了

目前使用下来,总体感觉还是很棒的,但是发现一个问题,有时候信息收集有问题,部署了几个应用,有一个应用的 System.Runtime 相关的 metrics 数据没有收集到,其他的数据都有的,感觉很奇怪,搞了几天了不知道哪里的姿势不对,提了一个 issue,感兴趣的可以关注一下 https://github.com/dotnet/dotnet-monitor/issues/1241,有踩过坑的大佬可以帮忙看一下万分感谢

另外还有一点,上面 Prometheus 只会收集 dotnet-monitor 的数据,如果要同时收集 dotnet-monitor 的 metrics 和 应用的 metrics ,你可能需要使用 Prometheus 的 Service Monitor 的 Operator,这里不多做介绍了,可以自己了解一下

References

  • https://github.com/WeihanLi/SparkTodo/blob/master/manifests/deployment.yml

  • https://github.com/OpenReservation/ReservationServer/blob/dev/k8s/dotnet-monitor-configmap.yaml

  • https://github.com/OpenReservation/ReservationServer/blob/dev/k8s/reservation-deployment.yaml

  • https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack#kube-prometheus-stack

  • https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/crds

  • https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/troubleshooting.md

  • https://github.com/dotnet/dotnet-monitor/issues/1274

  • https://github.com/dotnet/dotnet-monitor/issues/1241

  • https://github.com/dotnet/dotnet-monitor/

  • https://github.com/dotnet/dotnet-monitor/tree/main/documentation

  • https://github.com/dotnet/dotnet-monitor/blob/main/documentation/kubernetes.md

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

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

相关文章

arcgis 分区 属性值_ArcGIS制图之Maplex自动点抽稀

制图工作中,大量密集点显示是最常遇到的问题。其特点是分布可能不均匀、数据点比较密集,容易造成空间上的重叠,影响制图美观。那么,如果美观而详细的显示制图呢?主要原理Maplex中对标注有很好的显示控制,一…

学术造假导致导师自杀,后将这段学术丑闻经历出书贩卖,一年收入上百万......

全世界只有3.14 % 的人关注了爆炸吧知识本文转自募格学术2020年2月11日,小保方晴子又被撤回了一篇研究论文。Tissue Engineering Part A撤稿给出的原因是:通过哈佛医学院正式调查后,无法确实其实验结果的准确性,尽管作者本人坚持已…

汇编语言之数据处理的2个基本问题

1、bx、si、di和bp Bx、si和di这3个寄存器我们已经学过了,现在进行一下总结,并学一下bp。 1:在8086CPU中,只有这4个寄存器可以用在[…]中来进行内存单元的寻址。比如,下面的指令都是正确 的…

nvm用标准sata ahci码_能者多劳!让NVMe固态硬盘做系统盘的同时,加速SATA数据盘...

不知不觉当中,固态硬盘已经取代机械硬盘成为主流。越来越多的玩家已经淘汰机械盘,使用NVMeSATA的固态硬盘高低搭配。既然是高低搭配,就一定会有性能差距,是否能从NVMe固态硬盘中划分出一小部分空间来给SATA固态硬盘加速&#xff0…

天了噜!定义static字段还有顺序要求?

前言前段时间,发现一个bug,代码结构类似下面的示例。你能说出这段代码的正确返回结果吗?class Program {private static int a1 a2;private static int a2 Init();private static int Init(){return 123;}static void Main(string[] args){…

汇编语言之转移指令和原理

1、引言 可以修改IP,或同时修改CS和IP的指令统称为转移指令。概括地讲,转移指令就是可以控制CPU执行内存 中某处代码的指令。 8086CPU的转移行为有以下几类: 1. 同时修改CS和IP时,称为段间转移&#…

【高德地图开发2】---配置工程

1.从网站下载开发包并解压。 3D地图包解压后得到:3D地图显示包“Android_Map_2.x.x.jar ”和文件夹“ armeabi ”(以 V2.2.0为例,含 - libamapv302.so 和 libmapv302ex.so 文件)。2D地图包解压后得到:2D地图显示包“An…

antd option宽度自适应_建议收藏:Axure手机自适应教程

hello,我又来啦,今天和大家分享用axure怎么做自适应,也就是说,我们做app端的作品时,怎么在不同的手机尺寸,显示最佳的样式。那么这期的话,我会以一个游戏的案例来展开,所以比较好玩。…

安装pip

2019独角兽企业重金招聘Python工程师标准>>> linux系统安装pip: 1.下载get-pip.py wget https://bootstrap.pypa.io/get-pip.py 2.安装pip python get-pip.py windows系统安装pip,这里使用easy_install: 1.首先在命令行切换到easy_install.exe所在的Scri…

所以,路遥工具箱到底是什么东西?

笔者的软件开发生涯是从 2008 年开始的,彼时还是 2G 时代。站长之家是笔者当时经常访问的网站,站长工具也成为当时探索网络世界时的入门工具。软件开发这些年也是浑浑噩噩的度过,鲜有建树。2020 年之前也写了一些小工具用于解决一些注入字符串…

刷1000遍奥数题,不如学会这几道逻辑题,让孩子秒懂数学,学习早开窍!

▲ 点击查看前阵子发现一个英国BBC制作的纪录片,叫《逻辑的乐趣》(The Joy Of Logic),介绍了逻辑的概念,逻辑的发展史,及其在现实生活中的应用和价值。讲解非常有意思,深入浅出,风趣…

oracle技术之顺序文件上的索引(一)

顺序文件上的索引(一)研究索引结构,我们首先来考虑最简单的一种:由一个称为数据文件的排序文件得到另一个称为索引文件的文件,而这个索引文件由键-指针对组成。在索引文件中查找键K通过指针指向数据文件中查找键为K的记…

汇编语言之标志寄存器

1、标志寄存器 CPU内部的寄存器中,有一种特殊的寄存器(对于不同的处理机,个数和结构都可能不同)具有以下3种作 用: 1. 用来存储相关指令的某些执行结果。 2. 用来为CPU执行相关指令提供行…

web网页的表单排版利器--960css

表单排版样式 960css 前言 一般web网页的表单排版,大家都习惯用table排版,自己需要根据实际需要去定义TR和TD,很多时候对于TD的高宽度、是否合并行,合并列,都要去做一些处理,这些都是比较繁琐的工作。找到一…

c语言将十进制转化为二进制算法_base64算法初探即逆向分析

算法分析虽说base64严格意义上来说并不能算是加密算法,但的确应用方面来说还算是比较广,在CTF的算法逆向中Base系列算是也比较常见的,萌新刚开始学算法,就以base64为例,对该算法进行一个简单的分析。简单来说&#xff…

新功能抢先看!Windows 11 2022 版全新 ISO 镜像来了+下载

面向 Dev 频道的 Windows 预览体验成员,微软现已发布 Windows 11 操作系统全新 ISO 镜像文件,此版本 ISO 镜像整合了自 Build 22449 至 Build 22533 的所有功能。文件名称:windows11_insiderpreview_client_x64_zh-cn_22533.iso 文件大小: 4.64 GB MD5:…

这是哪里来的小妖精!!!

1 或许小鸟依人就是怎么来的吧2 果然球体运动全靠弹。。3 小猫咪从爬猫架下来时的样子萌爆了....4 这猫也是很配合了~5 以后请不要说“有朝一日”,请说“下周五晚七点我请你吃火锅”,“三分钟后我给你打钱”,“现在我就喜欢你”。6 内容来源于…

汇编语言之常见的汇编指令

1、常见汇编指令 1. 传送指令(4个):mov、push、pop、lea。2. 转移指令(8个):call、jmp、je、jne、jb、jnb、ja、jna。3. 运算指令(7个):add、sub、mul、div、adc、sbb、c…