如何创建一个带诊断工具的.NET镜像
现阶段的问题
现在是云原生和容器化时代,.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很容易就能定位到问题所在。
总结
本文编写的初衷是因为在群里有很多小伙伴遇到生产环境性能问题的时候,.NET的runtime镜像中没有带一些工具,安装和使用起来很麻烦,所以分享一些我们公司内部一些技巧,希望能帮到大家。
相关文章
- 最流行的 .NET 反编译工具合集
- 一系列令人敬畏的.NET核心库,工具,框架和软件[通俗易懂]
- 【愚公系列】2022年11月 .NET CORE工具案例-.NET Core执行JavaScript
- .Net CLR R2R获取RuntimeFunctions索引
- .net 温故知新:【8】.NET 中的配置从xml转向json
- VB.NET 图片在图片框内缩放及移动
- [接上篇]在Window10/11的Linux子系统Docker上部署VB.NET Asp.Net Core WebAPI应用
- 【愚公系列】2022年12月 .NET CORE工具案例-性能监控工具WatchDog的使用
- 【愚公系列】2023年01月 .NET CORE工具案例-DeveloperSharp的使用(数据库)
- 【愚公系列】2023年01月 .NET CORE工具案例-RedLock.net实现分布式锁
- 【愚公系列】2023年02月 .NET CORE工具案例-对象映射Master的使用
- 【愚公系列】2023年02月 .NET CORE工具案例-Lib.Harmony之AOP拦截
- 如何使用nginx作为docker容器中ASP.NET应用的反向代理
- 企业用户选择 Java 多于.NET的几个原因详解编程语言
- .NET 工具生成引擎概述详解编程语言
- 数据库使用.NET连接MySQL数据库(net连接mysql)
- .net让Oracle与ASP.NET实现无缝连接(oracleasp)
- .net安装 Linux 上的 ASP.NET 环境(linux安装asp)
- .NET Core支持FreeBSD
- 使用Net与Redis的完美结合(netredis)
- Net与Oracle构建连接的数据价值(.net 链oracle)
- NET备份MySQL提升数据安全性(.net 备份mysql)
- 基于NET的MySQL数据库开发实践(.net中使用mysql)
- asp.net半角全角转化工具
- asp.net(c#)做一个网页数据采集工具
- asp.net下遍历页面中所有的指定控件的代码
- asp.net使用Response.Filter过滤非法词汇
- IE性能分析工具(asp.net环境)
- asp.net网站开发中用jquery实现滚动浏览器滚动条加载数据(类似于腾讯微博)
- 基于ASP.NET的lucene.net全文搜索实现步骤
- .Net中导出数据到Excel(asp.net和winform程序中)
- ADO.NET无连接模式的详细介绍
- C#和asp.net中链接数据库中参数的几种传递方法实例代码
- asp.net操作ini文件示例
- ASP.NET取得所有颜色值示例
- .NET中StringBuilder用法实例分析