​要在容器中运行.net应用程序,你需要在容器镜像中安装.net Framework或.net Core 运行时。这不是你需要自己管理的东西,因为微软提供的Docker镜像已经安装了运行时,你可以使用它们作为基础镜像来打包你自己的应用程序。

. net镜像有几种变体,涵盖了不同的版本和不同的运行时。本文将指导你为应用程序选择正确的镜像。

使用基础镜像

你的应用需要运行一堆先决条件,比如操作系统和语言运行时。通常,平台所有者会打包一个安装了所有预请求的镜像,并将其发布到Docker Hub上——你会看到Go, Node.js, Java等都是官方镜像。

微软对.net应用程序也做了同样的事情,所以你可以使用它们的一个镜像作为基础镜像。它们定期更新,所以你可以通过使用最新的微软镜像重建它们来修补你的镜像。

.NET应用程序的Docker镜像托管在微软自己的容器注册表mcr.microsoft.com上,但它们仍然列在Docker Hub上,所以你可以在那里找到它们:

  • .NET Core和.NET 5在Docker Hub上的镜像
  • .NET Framework在Docker Hub上的镜像

这些页面列出了许多不同的.net镜像变体,并将它们划分为SDK镜像和运行时镜像。

你可以用一个简单的Dockerfile来打包.net应用:

FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8
SHELL ["powershell"] COPY app.msi /
RUN Start-Process msiexec.exe -ArgumentList '/i', 'C:\app.msi', '/quiet', '/norestart' -NoNewWindow -Wait

这是一种进入Docker的简单方法,获取一个现有的部署包(在本例中是一个MSI安装程序),并使用在容器中运行的PowerShell命令安装它。

这个例子使用了ASP.NET 4.8的基本镜像,所以你从这个Dockerfile构建的镜像:

  • 拥有IIS, . net Framework 4.8和ASP.NET已经配置。

  • 从MSI部署你的应用程序,希望是一个ASP.NET应用程序。

  • 需要有一个现有的进程来创建MSI。

这是一个简单的方法,但它有问题,因为Dockerfile是打包格式,它应该包含部署的所有细节,但所有的安装步骤都隐藏在MSI中。

相反,你可以使用Docker从源代码编译应用程序,这是SDK镜像的来源。这些SDK镜像有你的应用程序的所有构建工具:MSBuild和NuGet或dotnet CLI。你可以在一个多阶段Docker构建中使用它们,其中阶段1从源代码编译,阶段2从阶段1构建:

# the build stage uses the SDK image:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as builder
COPY src /src
RUN dotnet publish -c Release -o /out app.csproj # the final app uses the runtime image:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
COPY --from=builder /out/ .
ENTRYPOINT ["dotnet", "app.dll"]

这种方法更好,因为:

  • 整个构建是可移植的,你只需要Docker和源代码来构建和运行应用程序,你不需要在你的机器上安装任何.net sdk或运行时。

  • 你的Dockerfile是部署脚本,每一步都很清晰,并且它在没有额外的部署工作。

  • 你的最终镜像有它需要的所有运行时要求。

仍然有很多.net Docker镜像的变体,所以下一个任务是找出哪些可以用于不同的应用程序。

.NET Framework应用程序的Docker镜像

. net Framework应用程序是最简单的,因为它们只运行在Windows上,而且它们需要完整的Windows Server核心功能集。

你可以在任何你想要容器化的. net Framework应用中使用它们——你可以在Docker、Docker Swarm和Kubernetes中使用Windows容器来运行它们。

目前所有的. net Framework Docker镜像都使用mcr.microsoft.com/windows/servercore:lts2019作为基础镜像——这是Windows Server Core 2019的最新长期支持版本。

然后.net镜像以层次结构的形式从基本的Windows镜像中扩展出来:

.NET Core应用的Docker镜像

. net Core有点复杂,因为它是一个跨平台框架,有不同的镜像可供Windows和Linux容器使用。你将优先使用Linux,因为它们更精简,而且不需要为主机支付操作系统许可证。

Linux的变体源自Debian,它们使用类似于.net Framework镜像的分层构建方法和相同的命名标准:

这些镜像的名字需要再次使用mcr.microsoft.com/前缀,现在aspnet: 3.1是aspnet别名:3.1.11,但下个月3.1相同的标签将被用于一个更新的版本。

  • dotnet/core/runtime:3.1包含.net core runtime,所以你可以使用控制台应用;
  • dotnet/core/sdk:3.1已经安装了sdk,所以你可以在构建阶段使用它来编译.net core应用程序;
  • dotnet /core/ aspnet: 3.1 ASP.NET Core 3.1已安装,所以你可以使用它来运行web应用程序。

.NET Core 3.1将支持到2022年12月;2.1也是一个LTS版本,支持到2021年8月,并且有用于2.1运行时的镜像,使用相同的镜像名称和标签:2.1。你可以在dotnet/dotnet-docker中找到GitHub上的所有Dockerfiles和一些示例应用程序。

还有一些.net core镜像的Alpine Linux版本,它们更小更精简。如果你正在构建运行在Linux上的镜像,而你对跨平台运行在Windows上不感兴趣,这些是最好的-但有些依赖不能在Alpine正常工作(Sqlite是其中之一),所以你需要测试你的应用:

  • dotnet /core/runtime:3.1-alpine
  • dotnet /core/ sdk: 3.1-alpine
  • dotnet /core/ aspnet: 3.1-alpine

如果你想用相同的源代码和dockerfile构建Linux和Windows的镜像,坚持使用通用的:3.1——这些是多架构的镜像,所以有针对Linux、Windows、Intel和Arm 64的版本。

Windows版本都是基于Nano服务器的:

注意,它们有相同的镜像名称-多架构的镜像Docker会拉出正确的版本来匹配你使用的操作系统和CPU。你可以通过查看清单来检查所有可用的版本:

docker manifest inspect mcr.microsoft.com/dotnet/core/runtime:3.1

你将在响应中看到JSON,其中包括所有版本的详细信息——以下是删减后的版本:

"manifests": [
{
"digest": "sha256:6c67be...",
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"digest": "sha256:d50e61...",
"platform": {
"architecture": "arm64",
"os": "linux",
"variant": "v8"
}
},
{
"digest": "sha256:3eb5f6...",
"platform": {
"architecture": "amd64",
"os": "windows",
"os.version": "10.0.17763.1697"
}
},
{
"digest": "sha256:4d53d2d...",
"platform": {
"architecture": "amd64",
"os": "windows",
"os.version": "10.0.18363.1316"
}
}
]

你可以在这里看到镜像标签dotnet/core/runtime:3.1有用于Intel上的Linux、Arm上的Linux和Intel上的多个Windows版本的镜像版本。

只要你保持你的dockerfile是通用的——并且在运行指令中不包含特定于操作系统的命令——你就可以基于微软的镜像构建你自己的多架构 . net Core应用。

前进吧-.net 5的Docker镜像

.NET 5是.net Core的新版本,在MCR上有一些常见版本的Docker镜像:

  • dotnet /runtime:5.0
  • dotnet / sdk: 5.0
  • dotnet / aspnet: 5.0

将.net Core应用迁移到.net 5应该是一个简单的改变,但是请记住5不是一个LTS版本——你需要等待.net 6,它是LTS的。

欢迎关注我的公众号,如果你有喜欢的外文技术文章,可以通过公众号留言推荐给我。

原文链接:https://blog.sixeyed.com/understanding-microsofts-docker-images-for-net-apps/

聊聊.net应用程序的Docker镜像的更多相关文章

  1. 把java(springboot)程序打包docker镜像

    前言:要在docker运行java(jar包)程序,就要把程序打包成docker镜像(以下简称镜像),可以先理解为镜像就是jar包 打包需要程序代码,java本身的打包环境(包括jdk和maven), ...

  2. 通过IDEA制作包含Java应程序的Docker镜像

    IDEA官网在IDEA中把Java App制作成Docker镜像并启动一个容器运行 在idea上使用docker作为java的开发环境[][] ubuntu+docker+docker-compose ...

  3. 【Docker】在本地打包maven程序为docker镜像报错: Connect to localhost:2375 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1]

    错误信息: [ERROR] Failed to execute goal com.spotify:docker-maven-plugin:1.0.0:build (default-cli) on pr ...

  4. 多阶段构建Golang程序Docker镜像

    Docker简介 Docker是基于Linux容器技术(LXC),使用Go语言实现的开源项目,诞生于2013年,遵循Apache2.0协议.Docker自开源后,受到广泛的关注和讨论. Docker在 ...

  5. Java SpringBoot 项目构建 Docker 镜像调优实践

    PS:已经在生产实践中验证,解决在生产环境下,网速带宽小,每次推拉镜像影响线上服务问题,按本文方式构建镜像,除了第一次拉取.推送.构建镜像慢,第二.三-次都是几百K大小传输,速度非常快,构建.打包.推 ...

  6. Docker容器技术-优化Docker镜像

    一.优化Docker镜像 1.降低部署时间 一个大的Docker应用是如何影响在新Docker宿主机上的部署时间. (1)编写Dockerfile创建一个大Docker镜像 [root@bogon ~ ...

  7. Spring Boot 创建 Docker 镜像

    随着越来越多的组织转向容器和虚拟服务器,Docker正成为软件开发工作流程中一个更重要的部分.为此,Spring Boot 2.3中最新的功能之中,提供了为Spring Boot应用程序创建 Dock ...

  8. 程序员修神之路--打通Docker镜像发布容器运行流程

    菜菜哥,我看了一下docker相关的内容,但是还是有点迷糊 还有哪不明白呢? 如果我想用docker实现所谓的云原生,我的项目该怎么发布呢? 这还是要详细介绍一下docker了 Docker 是一个开 ...

  9. springboot程序构建一个docker镜像(十一)

    准备工作 环境: linux环境或mac,不要用windows jdk 8 maven 3.0 docker 对docker一无所知的看docker教程. 创建一个springboot工程 引入web ...

随机推荐

  1. A-交叉熵的使用

    交叉熵刻画了两个概率分布之间的距离 但是神经网络的输出却不是一个概率分布 softmax回归可以把前向传播返回的结果变成一个概率分布的问题 在tf中,softmax回归参数被去掉了,只是一个额外的输出 ...

  2. java_day03

    一.this关键字的作用 昨天学了Java private 关键字 ,private关键字主要是为了 保护变量 ,感觉用着好像并不是特别方便 如果需要访问本类当中的成员变量,需要使用的格式: this ...

  3. RabbiMQ重新安装会遇到的错误-SpiritMark

    这里只做安装过程中遇到错误的介绍,不喜勿喷,如果对您有帮助右上角关注一下,是对我最大的肯定 重新安装的注意事项: 先卸载RabbitMQ,后卸载Erlang RabbitMQ卸载,选择uninstal ...

  4. .net下com调用支持x86/x64

    起因 项目涉及u3d/wpf端的渲染图形合成,采用了开源项目spout,为了便捷,采用了spout的com版本作为c#端的调用 项目调整后,细节已经捋清楚了. 但是考虑桌面应用采用anypc,根据运行 ...

  5. 恶补了 Python 装饰器的六种写法,你随便问~

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 今天给大家分享一下关于装饰器的知识点,内容非常干,全程高能,认真吸收看完,一定会对装饰器有更深的理解 ...

  6. Python求一个数字列表的元素总和

    Python求一个数字列表的元素总和.练手: 第一种方法,直接sum(list): 1 lst = list(range(1,11)) #创建一个1-10的数字列表 2 total = 0 #初始化总 ...

  7. 华为全栈AI技术干货深度解析,解锁企业AI开发“秘籍”

    摘要:针对企业AI开发应用中面临的痛点和难点,为大家带来从实践出发帮助企业构建成熟高效的AI开发流程解决方案. 在数字化转型浪潮席卷全球的今天,AI技术已经成为行业公认的升级重点,正在越来越多的领域为 ...

  8. java中文上传下载功能实现(自己测试项目)

    1.新建maven项目打war包 2.搭建springMVC框架 web.xml文件配置 <?xml version="1.0" encoding="UTF-8&q ...

  9. Docker容器技术--自定义网桥后的默认网卡名称

    新建docker虚拟网络命令 这里以172.18.0.1为例,名字为clusterdocker network create --subnet=172.18.0.0/16 cluster 当我们想新建 ...

  10. 实现连续登录X天送红包这个连续登录X天算法

    实现用户只允许登录系统1次(1天无论登录N次算一次) //timeStamp%864000计算结果为当前时间在一天当中过了多少秒 //当天0点时间戳 long time=timeStamp-timeS ...