前情概要

随着容器和云技术的发展, 大量的应用运行在云上的容器中, 它们的好处是毋庸置疑的, 例如极大的提高了我们的研发部署速度, 快速的扩缩容等等, 但是也存在一些小小的问题, 例如难以调试.

基于VM的部署我们可以通过安全的方式登录到主机上做一些你想做的事情, 但是云上的容器那就是不太方便了(目前AWS的ECS已经有类似docker exec的方式直接进入容器中了, 其他的云未作了解).

但是就算能进入容器也不意味着调试就好做了, 通常来说使用的镜像都是经过优化和精简的(如果要调式可能需要安装大量的组件).

所以, 接下来介绍一下使用dotnet-monitor 来内存转储(memory dump)运行在容器中的 dotnet 程序.

需要提前知晓的一些知识点

什么是 dotnet-monitor?

Announcing dotnet monitor in .NET 6 官方博客的原文:

Running a .NET application in diverse environments can make collecting diagnostics artifacts (e.g., logs, traces, process dumps) challenging. dotnet monitor is a tool that provides an unified way to collect these diagnostic artifacts regardless of whether running you’re running on your desktop machine or in a kubernetes cluster.

There are two different mechanisms for collection of these diagnostic artifacts:

An HTTP API for on demand collection of artifacts. You can call these API endpoints when you already know your application is experiencing an issue and you are interested in gathering more information.
Triggers for rule-based configuration for always-on collection of artifacts. You may configure rules to collect diagnostic artifacts when a desired condition is met, for example, collect a process dump when you have sustained high CPU.

google翻译:

在不同的环境中运行 .NET 应用程序会使收集诊断工件(例如,日志、跟踪、进程转储)具有挑战性。dotnet monitor是一个工具,它提供了一种统一的方式来收集这些诊断工件,无论您是在台式机上运行还是在 kubernetes 集群中运行。

收集这些诊断工件有两种不同的机制:

用于按需收集工件的HTTP API 。当您已经知道您的应用程序遇到问题并且您有兴趣收集更多信息时,您可以调用这些 API 端点。

基于规则的配置触发器,用于始终在线收集工件。您可以配置规则以在满足所需条件时收集诊断工件,例如,当您持续使用高 CPU 时收集进程转储。

dotnet-monitor工作在什么位置?

借用官方博客中的一张图说明一下dotnet-monitor工作在什么地方

dotnet-monitor是如何能对我们的目标程序进行操作的?

dotnet-monitor 可以连接到dotnet运行时公开的一个诊断端口(diagnostic port)(3.0新提供的新功能), 并通过自定义协议(ipc protocol)与运行时交互,

更多调试知识和工具例如ETW, eventpipe, lldb, dotnet-trace, dotent-counters 等可以查看 dotnet diagnostics.

目标应用程序容器准备

首先, 我们得让我们被调试的目标程序公开这个诊断端口, 因为默认情况下这个诊断端口只能由运行这个程序的用户或者root用户来访问, 显然sidecar 模式启动的dotnet-monitor是不可能和目标程序用的是同一个用户的.

未作特别声明的话, 后文给出的实验都是基于AWS FargateLinux 配置.

#添加环境变量
DOTNET_DiagnosticPorts=/my_diagnostic_volume/diag.sock,suspend,connect

/my_diagnostic_volume/diag.sockUnix Domain Socket 文件路径, my_diagnostic_volume 是挂载的一个volume.

suspend 意思是让运行时等待dotnet-monitor 连接进来之后在执行托管代码.

connect 接受dotnet-monitor连接, 详细解释看这里diagnostic ports

上述配置的完整语法结构是 address[,(listen|connect)][,(suspend|nosuspend)]

详情请查看文档configure additional diagnostic ports

如果我们的需要dump内存文件, 可能会遇到WriteDumpAsync failed - HRESULT: 0x00000000 issues 1783这样的错误, 是因为权限问题.

比如我在AWS Fargate中遇到的就是 /dump API 返回400错误 Write dump failed - HRESULT: 0x00000000, 目标程序输出日志 ptrace(ATTACH, 1) FAILED Operation not permitted.

解决这个需要吧SYS_PTRACE权限给到目标程序. AWS Fargate 是编辑任务定义的json文件增加这一部分, docker 启动是通过增加--cap-add=SYS_PTRACE 参数.

{
"linuxParameters": {
"capabilities": {
"add": [
"SYS_PTRACE"
]
}
}
}

最后, 配置目标程序容器依赖dotnet-monitor容器, 这样可以先让dotnet-monitor容器启动后, 在启动目标程序容器.

到此, 目标程序容器的配置就完成了, 接下来配置dotnet-monitor

dotnet-monitor容器准备

  • 增加 Docker image 作为目标容器的sidecar 容器.
  • 暴露端口52323 #dotnet-monitor映射端口.
  • 增加容器启动命令参数 --no-auth # 简单粗暴的让所有的API都不要鉴权.
  • 添加环境变量
    • DOTNETMONITOR_DiagnosticPort__ConnectionMode=Listen # 必须的.
    • DOTNETMONITOR_DiagnosticPort__EndpointName=/my_diagnostic_volume/diag.sock # 目标容器配置的DOTNET_DiagnosticPorts中的address.
    • DOTNETMONITOR_Storage__DumpTempFolder=/my_diagnostic_volume/dump_files # dump内存是用的目录.
    • DOTNETMONITOR_Urls=http://+:52323 # dotnet-monitor要提供服务在什么端口上. dotnet-monitor默认用的就是52323.

详细的文档解释看这里

至此, 所有的配置就都完成了.

使用dotnet-monitor 来dump目标容器的内存文件

Get 请求 /dump endpoint 即可下载内存转储文件.

wget ip:52323/dump -O my_target_application_memory_dump.dmp
| Route            | Description                                                        | Version Introduced |
| ---------------- | ------------------------------------------------------------------ | ------------------ |
| /processes | Gets detailed information about discoverable processes. | 6.0 |
| /dump | Captures managed dumps of processes without using a debugger. | 6.0 |
| /gcdump | Captures GC dumps of processes. | 6.0 |
| /trace | Captures traces of processes without using a profiler. | 6.0 |
| /metrics | Captures metrics of a process in the Prometheus exposition format. | 6.0 |
| /livemetrics | Captures live metrics of a process. | 6.0 |
| /stacks | [Experimental] Gets the current callstacks of all .NET threads. | 7.0 |
| /logs | Captures logs of processes. | 6.0 |
| /info | Gets info about dotnet monitor. | 6.0 |
| /operations | Gets egress operation status or cancels operations. | 6.0 |
| /collectionrules | Gets the current state of collection rules. | 6.3 |

所有可用的API以及解释, 请看这里API's

在之后的问内存文件的分析可以使用dotnet-dump程序.

更多高级用法请查看, 例如可以配置内存每增加100Mb就触发dump内存文件.

相关链接

https://learn.microsoft.com/zh-cn/dotnet/core/diagnostics/dotnet-monitor

https://learn.microsoft.com/zh-cn/dotnet/core/diagnostics/dotnet-dump

https://learn.microsoft.com/zh-cn/dotnet/core/diagnostics/diagnostic-port

https://github.com/dotnet/dotnet-monitor/blob/main/README.md

https://devblogs.microsoft.com/dotnet/announcing-dotnet-monitor-in-net-6/

使用dotnet-monitor sidecar模式 dump docker运行的dotnet程序.的更多相关文章

  1. Docker 运行的 应用程序无法连接Oracle数据库的解决办法

    1. 最近公司使用docker化部署运行 app  发现一个部门的 多数据源取数的功能连接不上 oracle数据库 报错提示为: 2. 公司平台部同事给出两个解决方案: https://blog.cs ...

  2. docker运行php网站程序

    有一个之前的php网站程序需要迁移到K8S,简单调研了下. 基础镜像 官方提供了诸如php:7.1-apache的基础镜像,但是确认必要的扩展,例如gd,当然官方提供了docker-php-ext-i ...

  3. 【翻译】.NET 6 中的 dotnet monitor

    原文:Announcing dotnet monitor in .NET 6 我们在 2020 年 6 月首次推出了dotnet monitor 作为实验工具,并在去年(2020年)努力将其转变为生产 ...

  4. 分布式数据库DDM Sidecar模式负载均衡

    简介 1.分布式数据库中间件 DDM 分布式数据库中间件(Distributed Database Middleware)是解决数据库容量.性能瓶颈和分布式扩展问题的中间件服务,提供分库分表.读写分离 ...

  5. 使用dotnet-monitor分析在Kubernetes的应用程序:Sidecar模式

    dotnet-monitor可以在Kubernetes中作为Sidecar运行,Sidecar是一个容器,它与应用程序在同一个Pod中运行,利用Sidecar模式使我们可以诊断及监控应用程序. 如下图 ...

  6. 使用 Skywalking Agent,这里使用sidecar 模式挂载 agent

    文章转载自:https://bbs.huaweicloud.com/blogs/315037 方法汇总 Java 中使用 agent ,提供了以下三种方式供你选择 使用官方提供的基础镜像 将 agen ...

  7. Docker运行dotnetcore

                    windows下安装docker 参考: https://www.jianshu.com/p/502b4ac536ef https://docs.docker.com/ ...

  8. K8S 使用 SideCar 模式部署 Filebeat 收集容器日志

    对于 K8S 内的容器日志收集,业内一般有两种常用的方式: 使用 DaemonSet 在每台 Node 上部署一个日志收集容器,用于收集当前 Node 上所有容器挂载到宿主机目录下的日志 使用 Sid ...

  9. 下一代云计算模式:Docker正掀起个性化商业革命

    作者: 吴宁川  来源: ITValue  发布时间: 2015-09-20 10:41  阅读: 10008 次  推荐: 16   原文链接   [收藏] 文/ITValue 记者吴宁川 从 20 ...

随机推荐

  1. Navicat的使用与python中使用MySQL的基本方法

    Navicat的使用与python中使用MySQL的基本方法 Navicat的下载及安装 下载地址 http://www.navicat.com.cn/download/navicat-premium ...

  2. 基于SpringSecurity的@PreAuthorize实现自定义权限校验方法

    一.前言 在我们一般的web系统中必不可少的就是权限的配置,也有经典的RBAC权限模型,是基于角色的权限控制.这是目前最常被开发者使用也是相对易用.通用权限模型.当然SpringSecurity已经实 ...

  3. 前端利器躬行记(8)——VSCode插件研发

    VSCode提供了丰富的 API,可以借助编辑器扩展许多定制功能. 本次研发了一款名为 Search Method 的插件,在此记录整个研发过程. 一.准备工作 1)安装环境 首先是全局安装 yo 和 ...

  4. [网鼎杯 2020 朱雀组]phpweb-1|反序列化

    1.打开界面之后界面一直在刷新,检查源代码也未发现提示信息,但是在检查中发现了两个隐藏的属性:func和p,抓包进行查看一下,结果如下: 2.对两个参数与返回值进行分析,我们使用dat时一般是这种格式 ...

  5. ansible 003 常用模块

    常用模块 file 模块 管理被控端文件 回显为绿色则,未变更,符合要求 黄色则改变 红色则报错 因为默认值为file,那么文件不存在,报错 改为touch则创建 将state改为directory变 ...

  6. 【设计模式】Java设计模式 -工厂模式

    [设计模式]Java设计模式 -工厂模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目 ...

  7. 干货分享!JAVA诊断工具Arthas在Rainbond上实践~

    别再担心线上 Java 业务出问题怎么办了,Arthas 帮助你解决以下常见问题: 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception? 我改的代码为什么没有执行到?难道是我没 ...

  8. Redis变慢?深入浅出Redis性能诊断系列文章(三)

    (本文首发于"数据库架构师"公号,订阅"数据库架构师"公号,一起学习数据库技术,助力职业发展) 本篇为Redis性能问题诊断系列的第三篇,主要从Redis服务层 ...

  9. 【Java面试】这应该是面试官最想听到的回答,Mysql如何解决幻读问题?

    "Mysql如何解决幻读问题" 一个工作了4年小伙伴,去一个美团面试,遇到了这样一个问题. 大家好,我是Mic,一个工作了14年的Java程序员 关于这个问题,面试官想考察什么?我 ...

  10. Kubernetes 多租户:资源配额

    资源配额用于管理命名空间中对象使用的资源量,我们可以按 CPU 和内存用量或对象数量来设置配额.通过资源配额,可以确保租户不会使用超过其分配份额的集群资源. 资源配额是通过 ResourceQuota ...