原文:https://blogs.msdn.microsoft.com/dotnet/2018/06/13/using-net-and-docker-together-dockercon-2018-update/

去年我写了一篇关于共同使用 .NET 和 Docker 的文章。随着本周 DockerCon 2018 的开始,似乎是一个更新的好时机。从上一篇文章以来,我们启用了一系列的 .NET Core.NET Framework 向导和示例的 Docker 工作流,用于开发,CI/CD 和 生产。我们也提供了更多的 Windows 和 Linux 的镜像。如果你最近没有关注 Docker 和 .NET,现在是一个好时机。

在和 .NET 开发者对话中 Docker 和容器越来越多的被提到。它已经成为许多人部署服务端应用程序的方式。由于一致性和轻量级的主要优点代替了虚拟机。在 DockerCon 的主题中,有多个 .NET 演示了如何应用 Docker 到现代应用和传统架构的旧应用中。它使得通过微软和 Docker 的工具封装 .NET 应用更容易。

关于 .NET 容器镜像的信息请看与.NET容器映像保持同步.

尝试 Docker

我们维护了 .NET Core 和 .NET Framework 的示例仓库。只需命令行中的几个命令,就可以用这些示例镜像测试 Docker

最简单的(支持大多数操作系统)是 .NET Core 控制台应用示例。你只需要输入以下命令:

docker run --rm microsoft/dotnet-samples

你也可尝试其他的示例,都是控制台和 ASP.NET 应用:

如何使用 Docker

Docker 是灵活的,使你能够以多种不同的方式使用它。当采用 Docker 时主要有三种主要的方案需要考虑:

  • 构建源代码
  • 测试二进制文件
  • 在生产环境运行应用程序/服务

你可以采用 Docker 来处理所有这些角色或者一个子集。从我们所看到的,大多数开发者从生产场景开始,然后在他们发现有用的基础架构采用更多的 Docker。这种处理是有意义的,选择使用 Docker 通常用它来运行应用程序为中心。

在 .NET 团队,我们在构建和测试代码时已经大量的使用 Docker。高保真和即时启动计算环境的价值非常高,例如,当你可以可以在几秒钟内启动完全正确的环境时,无需在 Debian 上推迟产品调查。

以下部分显示了针对这三种方案的 .NET Core 和 .NET Framework 混合的示例。

使用二进制文件构建容器镜像

在生产环境中运行 Docker 的主要需求是容器化应用程序。在现有的构建基础结构中创建镜像最简单的方式是复制构建文件到镜像里。这个模型的主要价值是环境之间的一致性,比如 staging 环境和生产环境。

以下 Dockerfile 将当前目录中的构建资产复制到基于 Docker Hub 上的.NET Core 运行时镜像的新镜像。

FROM microsoft/dotnet:2.1-runtime
WORKDIR /app
COPY . .
ENTRYPOINT ["dotnet","app.dll"]

以下命令通过上边的 Dockerfile 创建了一个 app 的镜像,假设命令在 Dockerfile 和 app.dll 所在的目录运行:

docker build --pull -t app .

以下命令基于 app 镜像创建了一个运行的容器:

docker run --rm app

注意:--rm 参数在容器结束后移除该容器。保持容器只有在你想调查为什么他们表现某一(不希望的)方式时。

使用源文件构建容器镜像

Docker 使为应用程序构建源文件并在一个步骤中生成容器镜像变得容易。这也被称为多级构建。在容器内构建源文件的价值如下:

  • 在构建和运行/生产环境之间的一致性。
  • 由于 Docker 层缓存,对于增量构建的速度比你自己的构建系统更快。
  • Docker 不依赖于外部功能构建(如果你在 Docker 内构从源文件构建)。

下边的 Dockerfile 基于 Docker Hub 上的 .NET Framework SDK 镜像从当前目录复制源文件到新的镜像。Dockerfile 命令使用 NuGet 和 MSBuild 来构建源代码。将基于 .NET Framework 运行时镜像的二进制文件在构建阶段复制到一个新镜像。构建阶段镜像被丢弃。所选的镜像名称仅用于从最后阶段生成的镜像。

上边的第二部分是 Docker 闪光的地方。Docker 中的每一个命令创建 Docker 镜像中的不同的层。如果 Docker 发现给定层的输入没有改变,那么后续 Docker 的构建不会重新构建该层。第二部分复制了 msbuild 资产,比如项目文件,然后运行 nuget 恢复。如果 msbuild 资产没有改变,则跳过执行恢复。这样最终节省了大量时间。它也解释了为什么 Dockerfile 编写的方式。

接下来的命令使用上边的 Dockerfile 创建了一个 aspnetapp 的新镜像,假设该命令是从 Dockerfile 和 源文件所在的目录运行的:

docker build --pull -t aspnetapp .

例如,如果 Docker Hub 上存在  --pull 参数会拉取新的 microsoft/dotnet-framework 镜像,这个参数会花费更长的时间(如果没有新的镜像存在)在每次 docker 构建,但要保持最新环境。从长远来看,最新的方法是非常有用的,因为它使你的环境于没有缓存镜像的环境保持同步。

下边的命令创建了一个基于 aspnetapp 镜像的容器:

docker run --rm -it -p 8000:80 aspnetapp

-p 参数把主机端口映射到 Docker 客户端端口。

更多用 Docker 构建源代码的信息请参考下面的示例:

用 Docker 测试二进制文件

测试场景展示了 Docker 的价值,因为当测试环境和目标环境保持高度一致时测试具有更多价值。假设你的应用支持多个操作系统或操作系统版本。你可以在他们每一个的 Docker 中测试你的应用。它很容易做到并且非常有价值。

到目前为止,在本篇文章中你看到有运行命令的 Dockerfile ,它描述了需要用 Docker 构建执行的逻辑以及用 Docker 运行的最终结果。通过 Docker 构建运行测试作为早期反馈是有用的,主要是通过打印到控制台/终端的通过/失败结果。这种模型可以很好的用于测试,但是有两个原因规模不大:

  • 如果测试存在固有的错误有错误,则 docker 构建会失败。
  • docker 构建不允许 volume 安装,这是手机测试日志所必须的。

使用 docker 运行测试时一个很好的选择,因为它不受这两个挑战的任何一个的影响。使用 docker 构建测试很有用,假如测试失败你也想让你的构建失败。本文档中的说明展示了如何使用 docker 运行测试。

下面的 Dockerfile 在正常使用中与上面看到的 .NET Framework 类似。然后,这其中包含了一些技巧来实现测试。包括一个通常非常接近 no-op testrunner 阶段,但这对测试非常有用。

为了测试,创建一个 testrunner 阶段镜像,这将包括所有内容构建成一点。结果镜像是基于 .NET Core SDK 镜像的,包括所有 .NET Core 测试基础设施。这个 Dockerfile 的诀窍在于 testrunner 阶段提供了一个替代的 ENTRYPOINT,调用 dotnet 测试来启动测试。如果你一直通过运行 Dockerfile (不针对特定的阶段),那么第一个 ENTRYPOINT 会被最后一个替换,这是应用程序的 ENTRYPOINT。

下面的命令创建一个 dotnetapp:test 的新镜像,使用上面的 Dockerfile 只限构建和包括 testrunner 阶段,假设命令是从 Dockerfile 和 源文件目录运行的:

docker build --pull --target testrunner -t dotnetapp:test .

为了在本地机器上手机测试日志,需要使用 volume安装。简而言之,你可以将你机器上的目录作为统一目录导入容器中。 Volume 安装是一种获取容器内或从容器输出很好的方法。

下面的命令基于 dotnetapp:test 创建了一个容器。volume 将 C:\app\TestResults 本地目录安装到应用中的 /app/tests/TestResults。本地目录必须已经存在,并且 C 盘必须共享给 Docker。

docker run --rm -v C:\app\TestResults:/app/tests/TestResults dotnetapp:test

运行命令后,你应该在 C:\app\TestResults 文件中看到 .trx 文件。

用 Docker 运行 .NET Core 单元测试 显示了如何在容器中进行更详细的测试。包括 Windows,macOS 和 Linux。还包括本节中描述的管理测试工作流的脚本

在容器中开发

以上场景关注于生成或验证容器镜像。Docker 的使用可以进一步向上游发展。

Visual Studio 允许在容器中进行开发。你可以添加 Dockerfile 到一个 .NET 项目中,Windows 容器或者 Linux 容器。经验几乎是无缝的。很难说你在使用 Docker,就像你在下面的图片中看到的一样。

你还可以在命令行的容器内开发。.NET Core SDK 镜像包含了很多功能,你可以创建一个 Dockerfile 来毫不费力的使用它。事实上,你可以通过命令行运行,构建或者测试你的应用程序。

在容器中开发 ASP.NET Core 应用程序说明了如何通过 Docker 构建和重新构建 ASP.NET Core 应用程序,例如你可以在本地机器上在本地机器上从 Visual Studio Code 中编辑他们。

下面的命令行通过 dotnet 宿主一个 ASP.NET Core 应用程序守候在 macOS 或者 Linux 上。在容器中开发 ASP.NET Core 应用程序中Windows 说明是可用的。每次在本地机器上编辑和保存应用程序时,它将在容器中重新构建。我从来没有试过连续1000次这样做,但是你很可能做到。此方案依赖于 volume 安装,将本地化的源代码投影到正在运行的容器中。正如你所见,通过编写 Dockerfile 来实现 volume 安装是一个强有力的选择。

docker run --rm -it -p 8000:80 -v ~/git/aspnetapp:/app/ -w /app/aspnetapp microsoft/dotnet:2.1-sdk dotnet watch run

有关 .NET Core 控制台应用程序的类似指令请参见在容器中开发 .NET Core 应用程序

ASP.NET Core 和 HTTPS

用 HTTPS 来托管 Web 应用程序时很中亚哦的。在许多情况下,在到达 ASP.NET Core 站点前会种终止 HTTPS 请求。在 ASP.NET Core 需要直接处理 HTTPS 流量的情况并且在容器中运行你的站点时,则需要一个解决方案。

通过 HTTPS 在 Docker 中托管 ASP.NET Core 镜像描述了如何用 HTTPS 来托管我们的 ASP.NET Core 样品镜像。所描述的模型非常类似于如何用你自己的证书来托管自己的镜像。

以下命令可用于在 Windows 上使用 Linux 容器运行 dev 证书的 ASP.NET Core 示例镜像:

dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\aspnetapp.pfx -p crypticpassword
dotnet dev-certs https --trust
docker pull microsoft/dotnet-samples:aspnetapp
docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_Kestrel__Certificates__Default__Password="crypticpassword" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx -v %USERPROFILE%\.aspnet\https:/https/ microsoft/dotnet-samples:aspnetapp

在 Docker 中通过 HTTPS 指令托管 ASP.NET Core 镜像可以用在 Windows,macOS 和 Linux 上。

结尾

你可能会发现我们在一起使用 .NET 和 Docker 的方法上比我们在最初2017的主题文章中走的更远。我们远没有完成所有可以想象的容器控件,但已经为你提供了一个更完整的基础作为你采用 Docker 的使用。

(翻译)一起使用 .NET 和 Docker——DockerCon 2018 更新的更多相关文章

  1. Ubuntu 16.04安装docker(2018年最新)

    参考https://blog.csdn.net/bingzhongdehuoyan/article/details/79411479 http://www.cnblogs.com/lighten/p/ ...

  2. Docker Kubernetes 容器更新与回滚

    Docker Kubernetes 容器更新与回滚 环境: 系统:Centos 7.4 x64 Docker版本:18.09.0 Kubernetes版本:v1.8 管理节点:192.168.1.79 ...

  3. 使用Watchtower实现Docker容器自动更新

    前言:通常情况下我们手动更新容器的步骤比较繁琐,需要四个步骤: 1.停止容器 2.删除容器 3.检查镜像更新情况,更新镜像 4.重新启动容器 容器少还无所谓,但要是需要更新大量的容器就会工作量巨大. ...

  4. [翻译] ASP.NET Core 利用 Docker、ElasticSearch、Kibana 来记录日志

    原文: Logging with ElasticSearch, Kibana, ASP.NET Core and Docker 一步一步指导您使用 ElasticSearch, Kibana, ASP ...

  5. Ubuntu Docker 版本的更新与安装

    突然发现自己的docker 版本特别的低,目前是1.9.1 属于古董级别的了,想更新一下最新版本,这样最新的一下命令就可以被支持.研究了半天都没有更新成功,更新后的版本始终都是1.9.1 :蒙圈了,找 ...

  6. Ubuntu Docker版本的更新与安装

    突然发现自己的docker版本特别的低,目前是1.9.1属于古董级别的了,想更新一下最新版本,这样最新的一下命令就可以被支持.研究了半天都没有更新成功,更新后的版本始终都是1.9.1 :查阅了官网资料 ...

  7. Docker service update更新不成功的问题

    一.基本信息 1.Docker版本 [root@ip---- ~]# docker --version Docker version , build a872fc2f86   2.系统版本 [root ...

  8. Docker 版本的更新和安装

    涉及到网址:1.https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/#prerequisites (官网)       ...

  9. 37. docker swarm docker service 的更新

    在service 运行的情况下 进行更新 1. 创建 名为 demo 的 overlay 网络 docker network create -d overlay demo 2. 创建 python-f ...

随机推荐

  1. ReentrantLock和synchronized区别和联系?

    相同:ReentrantLock提供了synchronized类似的功能和内存语义,都是可重入锁. 不同: 1.ReentrantLock功能性方面更全面,比如时间锁等候,可中断锁等候,锁投票等,因此 ...

  2. Ubuntu Android adb调试无法识别设备 -- List of devices attached ???????????? no permissions

    在Ubuntu下做Android开发, 使用adb devices调试的时候出现在面的错误: 这个问题之前就出现过的,突然就忘了,Mark一下.在网上找了一下,基本上是一些比较麻烦的办法,但是在我的记 ...

  3. boost文件锁的使用

    boost中可以用boost::interprocess::file_lock类对文件进行加锁和解锁操作. #include <fstream> #include <iostream ...

  4. [技巧篇]10.那些年我们一起优化过的MyEclipse8.6

    这里里面是针对于四海的给位学生预留的视频,请自行下载,我希望对大家有所帮助 我这里使用了百度网盘,这里的东西还是比较多的!如果喜欢请关注我,当好胖先生的粉丝 链接:http://pan.baidu.c ...

  5. ZooKeeper分层次的法定人数(十二)

    分层次的法定人数的介绍 这个文档给出一个关于怎么使用分层次的法定人数的例子.基本思路是很简单的.首先,我们把服务端分组,然后每一组一行.下一步我们分配一个权重为每一个服务端. 下面的例子展示了怎么每组 ...

  6. Hadoop window win10 基础环境搭建(2.8.1)

    下面运行步骤除了配置文件有部分改动,其他都是参照hadoop下载解压的share/doc/index.html. hadoop下载:http://apache.opencas.org/hadoop/c ...

  7. [USACO Mar08] 牛跑步

    http://www.cogs.pro/cogs/problem/problem.php?pid=133 ★★★   输入文件:cowjog.in   输出文件:cowjog.out   简单对比时间 ...

  8. MSSQL Get Last Monday and Last Sunday

    获取上周的周一和周日 代码: --start of last week , ) --end of last week , )

  9. 【poj2182】【poj2828】树状数组/线段树经典模型:逆序查找-空位插入法

    poj2182题意:有一个1~n的排列,现在给定每个人前面有多少个人的编号比他大,求这个排列是什么.n<=8000 poj2182题解: 逆序做,可以确定二分最后一个是什么,然后删除这个数.树状 ...

  10. Python 对象模型 -- (转)

    面向对象的纯粹性 在很久很久以前,C++还被称为面向对象语言(现在一般称为多范式通用语言),人们就对C++的面向对象的纯粹性提出了质疑,主要有以下几点: 并非所有的对象都是对象(很拗口?),比如指针本 ...