教你创建一个带诊断工具的.NET镜像
作者:InCerry 发布时间:2021-09-28 03:11:11
现阶段的问题
现在是云原生和容器化时代,.NET Core对于云原生来说有非常好的兼容和亲和性,dotnet社区以及微软为.NET Core提供了非常方便的镜像容器化方案。所以现在大多数的dotnet程序都是部署在各种容器化环境中,比如我们常见的Docker。
微软官方为.NET提供的许多Docker镜像,让我们可以很方便的创建容器化的.NET应用。如下所示就是部分官方提供的不同操作系统的镜像。
其它更详细的内容大家可以点击后面的网址查看:https://hub.docker.com/_/microsoft-dotnet-runtime/
使用VS新建一个项目,微软官方给出的多段构建Dockerfile如下所示:
# 使用aspnet runtime镜像作为基础镜像
FROM mcr.microsoft.com/dotnet/aspnet:6.0-focal AS base
WORKDIR /app
EXPOSE 80
# 使用sdk镜像进行编译
FROM mcr.microsoft.com/dotnet/sdk:6.0-focal AS build
WORKDIR /src
COPY ["WebApplication1/WebApplication1.csproj", "WebApplication1/"]
RUN dotnet restore "WebApplication1/WebApplication1.csproj"
COPY . .
WORKDIR "/src/WebApplication1"
RUN dotnet build "WebApplication1.csproj" -c Release -o /app/build
# 使用build镜像发布
FROM build AS publish
RUN dotnet publish "WebApplication1.csproj" -c Release -o /app/publish
# 拷贝编译结果到base镜像,完成镜像打包
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WebApplication1.dll"]
现在看起来一切都很美好,但是假设我们遇到某一些线上CPU 100%、内存占用率很高或者程序突然停止响应等问题我们需要使用dotnet-trace
、dotnet-dump
等工具时就会发现使用不了。
而且在没有安装.NET SDK的情况下,我们也无法安装dotnet tool。
解决方案
1.直接使用命令安装dotnet sdk,然后再安装dotnet tool,微软在官网给出的非常方便的安装方案,但是这不是我们想要的,毕竟每次还得下载多麻烦。
2.构建最终镜像使用sdk
镜像,这样的话我们就可以直接安装好这些工具,这也不是我们想要的,因为sdk
镜像太大了,不利于我们分发和下载(自建机房的钞能力除外)。
3.就是我们今天提到的方案,我们可以利用Docker多段构建,使用sdk
镜像安装好dotnet tool以后,直接COPY到我们runtime的镜像,然后在runtime的镜像中使用。
# 使用aspnet runtime镜像作为基础镜像
FROM mcr.microsoft.com/dotnet/aspnet:6.0-focal AS base
WORKDIR /app
EXPOSE 80
# 使用sdk镜像进行编译
FROM mcr.microsoft.com/dotnet/sdk:6.0-focal AS build
WORKDIR /src
COPY ["WebApplication1/WebApplication1.csproj", "WebApplication1/"]
RUN dotnet restore "WebApplication1/WebApplication1.csproj"
COPY . .
WORKDIR "/src/WebApplication1"
RUN dotnet build "WebApplication1.csproj" -c Release -o /app/build
# !!! 在build镜像安装dotnet tools
RUN dotnet tool install -g dotnet-dump \
&& dotnet tool install -g dotnet-trace
# 使用build镜像发布
FROM build AS publish
RUN dotnet publish "WebApplication1.csproj" -c Release -o /app/publish
# 拷贝编译结果到base镜像,完成镜像打包
FROM base AS final
WORKDIR /app
# !!! 从build镜像中把dotnet工具COPY出来 并设置为PATH
COPY --from=build /root/.dotnet/tools /root/.dotnet/tools
ENV PATH="$PATH:/root/.dotnet/tools"
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WebApplication1.dll"]
其中关键就是这两步,在build中使用dotnet tool来安装好所需要的工具,然后复制到runtime镜像中。
...
# !!! 在build镜像安装dotnet tools
RUN dotnet tool install -g dotnet-dump \
&& dotnet tool install -g dotnet-trace
...
# !!! 从build镜像中把dotnet工具COPY出来 并设置为PATH
COPY --from=build /root/.dotnet/tools /root/.dotnet/tools
ENV PATH="$PATH:/root/.dotnet/tools"
当然我们可以打包一个包含好工具的runtime,供后面使用,就不用每次都安装tool了。我个人比较喜欢使用Ubuntu作为基础镜像,大家也可以用Alpine之类的基础镜像来进一步缩小体积。
# 使用sdk镜像进行编译
FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS build
# !!! 在build镜像安装dotnet tools
RUN dotnet tool install -g dotnet-dump \
&& dotnet tool install -g dotnet-trace
# 使用aspnet runtime镜像作为基础镜像
FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine AS base
WORKDIR /app
# !!! 从build镜像中把dotnet工具COPY出来 并设置为PATH
COPY --from=build /root/.dotnet/tools /root/.dotnet/tools
ENV PATH="$PATH:/root/.dotnet/tools"
最终镜像也很小,当然我们可以使用单文件发布和Native AOT让镜像它变得更小,那就是后话了,不在本文中介绍。
常用的工具
因为公司是自建机房,所以对于存储和网络带宽都比较宽裕,我们一般会在生产环境运行的镜像中安装下面这些工具。
RUN dotnet tool install -g dotnet-dump \
&& dotnet tool install -g dotnet-trace \
&& dotnet tool install -g dotnet-counters \
&& dotnet tool install -g dotnet-sos \
&& dotnet tool install -g dotnet-gcdump \
&& dotnet tool install -g dotnet-monitor \
&& dotnet tool install -g dotnet-symbol \
&& dotnet tool install -g JetBrains.dotTrace.GlobalTools
在遇到线上问题的时候,排查起来非常方便,对于一些内存泄漏和CPU满的问题,配合dotTrace很容易就能定位到问题所在。
来源:https://www.cnblogs.com/InCerry/p/how-to-build-dotnet-image-with-trace-tool.html


猜你喜欢
- 本文实例讲述了C# Socket网络编程技巧。分享给大家供大家参考。具体分析如下:客户端要连接服务器:首先要知道服务器的IP地址。而服务器里
- 定义Builder模式是一步步创建一个复杂对象的创建型模式,它允许用户在不知道内部构建细节的情况下,可以更精细的控制对象的构建过程。该模式是
- 在常见场景下:返回数据建议使用map,不建议使用实体对象 /** * 1. 名字包含雨并且年龄小于40  
- java 中编写 GUI 有两中工具包,分别为 AWT、Swing。Swing 是 AWT 的拓展,Swing 具有比 AWT 丰富的组件和
- 最近 * 丝的公司想要为以前的那个网页产品加上一个过滤的功能,废话不多说,直接看筛选的界面是啥样的吧:可以看出,我们的Message分为Crit
- 本文研究的主要是Java回调函数与观察者模式的实现,具体介绍和实现代码如下。观察者模式(有时又被称为发布(publish )-订阅(Subs
- 本文主要探讨以下几个问题:嵌套滑动设计目的嵌套滑动的实现嵌套滑动与事件分发机制嵌套滑动设计目的不知道大家有没有注意过淘宝APP首页的二级联动
- c++智能指针介绍由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete,比如流程太复杂,最终导致没有
- java 引用类型的数据传递的是内存地址java中引用类型的数据,传递的是内存地址,像类,数组,接口,String等等都是引用类型!看下面的
- 需求在前面的文章里使用.NET 6开发TodoList应用之领域实体创建原理和思路,我们留了一个坑还没有填上,就是在数据库保存的时
- 不说废话了,进入我们今天的主题吧。先贴上前面内容的地址:Android手势ImageView三部曲(一)Android手势ImageView
- 首先需要建立两个库进行测试,我这里使用的是master_test和slave_test两个库,两张库都有一张同样的表(偷懒,喜喜),表结构表
- 下面对Java反射的基础知识进行说明和总结:首先定义一个MyBase类,其中有私有字段,也有公有字段。同时也有公有方法和私有方法。MyBas
- 1、前言当提及如何终止一个线程时,部分读者通常立马想到的方法肯定是stop(),但是stop()方法并不被推荐使用(很多规范中是禁止使用的)
- ClasspathResource路径问题前言在项目中工程以springboot jar形式发布,跟之前容器比少了一个解压目录,这个过程中出
- 注意我这里用的是官方最稳定的版本3.7.1,版本之间有个别命令是有差距的!1.zkCli.sh客户端zkCli.sh可以理解成客户端,也可以
- 对于ApplicationListener使用Spring的应该也熟悉,因为这就是我们平时学习的观察者模式的实际代表。Spring基于Jav
- 我们在编程的时候,有时会使用多线程来解决问题,比如你的程序需要在后台处理一大堆数据,但还要使用户界面处于可操作状态;或者你的程序需要访问一些
- 最大单词长度乘积给你一个字符串数组 words ,找出并返回 length(words[i]) * length(words[j]
- 本文实例讲述了C#远程获取图片文件流的方法。分享给大家供大家参考,具体如下:protected void Page_Load(object