【.com速译】自从.NET技术能够在Linux上运行(就像在Windows和macOS上一样),全世界的Linux容器和微服务(microservices)都发展到了.NET技术。NET是开放的。由于.NET拥有大量的开发者群体、长期成功的开发案例和令人印象深刻的性能参数,这为Linux容器在全球范围内扩展到原来以Windows为中心的开发者阵营提供了绝佳的机会。很好的机会。虽然在Linux容器中运行.NET代码似乎有些激进,并且有一些您不能错过的细微差别,但我仍然会脱口而出“Go,Pikachu!”在镜子里做要容易得多。毕竟,一切都发生得又快又恰到好处,不是吗?当然,让您的.NET代码在Linux容器中运行并非易事,正如一句古老的格言所说:“先让它工作,然后再让它工作得更快。”快,在我们这里指的是构建、启动镜像所花费的时间,以及镜像内代码的性能。本文将涵盖前两部分——构建和启动映像的时间。我们将从一个简单的.NET程序开始,以运行基于容器的应用程序,然后观察图像随着它变小而演变,从而加快构建和加载时间。至于代码优化,那就是另外一个话题了。市面上有很多书供你参考。不知从何而来,如此活跃!考虑一个非常简单的示例:微服务仅提供HTTP类型的“Helloworld”响应。也就是说,您将浏览器指向一个URL并获得一个非常简单的响应,其中包括主机名。请记住,这是一个简单的示例,我登录到Linux虚拟机(VM)并从其存储库下载了代码(请参阅https://github.com/donschenck/dotnet_docker_msa)。就像任何面临新技术的开发人员一样,在这种情况下,我希望尽快在Linux容器中启动并运行应用程序。因此,我快速构建了一个Dockerfile(请参阅存储库中的Dockerfile.attempt1)并使用以下命令构建了一个映像:dockerbuild-tattempt1-fDockerfile.attempt1。构建成功完成后,我当然很兴奋。当我能够在容器中运行图像时,我什至有点兴奋:dockerrun-d-p5000:5000--nameattempt1attempt1我将浏览器指向正确的URL,这也是我的IP虚拟机地址。看下面的截图:一些数字第一次构建这个镜像我用了95秒,因为需要下载整个490MBRedHatEnterpriseEdition(红帽企业版)安装了.NETSDKEnterpriseLinux、RHEL)图像。这也导致整个图像的大小为659MB。公平地说,后续构建会更快,因为docker格式的容器镜像现在可以在我的机器上使用。从那以后,我再次更改了它的源代码并再次运行构建过程,这次只用了大约50秒就生成了相同的659MB图像。其实图片的大小还是很重要的。虽然现在计算机上使用的存储空间相对便宜,但它仍然是一种有限的商品。特别是当您定期使用容器时,过时和遗忘的图像很容易就坐在那里占用空间。因此很容易意外地很快填满磁盘空间。那么如何才能让图片变小呢?添加到dotnetrestore命令的简单命令行选项会有所帮助。我正在使用:dotnetrestore--no-cache(参见Dockerfile.attempt2)来消除任何缓存,这将图像的大小减小到608.6MB,减少了50.6MB,节省了超过7%空间。但我对此并不满意,必须有更多的方法来做到这一点。在构建图像之前构建应用程序我意识到每次在容器中运行图像时,应用程序都会构建.NET应用程序。虽然这1.6秒显然不是很大一部分时间,但我仍然认为这有点浪费。我通过在dotnet和retore之间插入命令build来构建应用程序,并首先构建容器映像,这将使容器启动得更快。此结果显示在Dockerfile.attempt3中。当然,这是以消耗存储空间为代价的,图片大小已经涨到了610.2MB。不过无论如何dotnetbuild都要运行,我们现在还不如多花点时间,以后每次启动容器的时候都会受益匪浅。DotnetPublishing接下来,我们的关注点转移到一个问题上:既然容器是一个运行环境,为什么不在将代码推送到镜像之前使用dotnetpublish命令发布代码呢?如果我这样做,我就不需要在我的容器中预安装.NET。毕竟,发布是允许您构建可以在任何地方运行的单个(或“独立”)应用程序的东西。这就是dotnetpublish的真正意义所在!就图像大小和启动时间而言,这将是一个巨大的胜利。我修改了project.json文件以支持发布。同时,我删除了(实际上是注释掉了)告诉编译器构建平台的命令行。您可以在下面的屏幕截图中看到它:接下来,我使用发布命令发布了代码:dotnetpublish-cRelease-rrheh.7.2-x64。这会将所有已编译的部分(包括运行时所需的一切)放入一个文件夹中,我可以将该文件夹复制到图像中。当然,它可能会更好:因为我不需要预装.NET,所以我可以使用没有.NET的基本版本的RHEL。而之所以这样做,是因为此举肯定会节省更多的空间。为了将部件推送到映像中,我使用了以下Dockerfile(请参阅repo中的Dockerfile.attempt4):注意:两个yuminstall命令将安装一些东西,使.NET能够在RHEL先决条件上运行。目前没有办法解决这个问题。但是,这毕竟不是什么大不了的事。我运行了dockerbuild,生成的图像大小为694.6MB!这到底是怎么回事?谁还需要缓存?事实证明,这两个yuminstall指令还为以后的yuminstall命令构建了缓存。所以如果我能在每个命令后立即清除缓存会好得多。以下是我的第五次迭代Dockerfile,请参考Dockerfile.attempt5:我们将运行dockerbuild并比较这个Dockerfile生成的镜像文件的大小。可以看到这次只有293.7MB,比第一次尝试的结果少了55%以上。这里应该有鼓。积累是命令而不是文件Dockerfile中体现的cup,我最后修改的是yuminstall命令的积累,如下:可以看到,生成的镜像大小为257.5MB,相比于我第一次尝试,结果不到60%。最后,让我以下图的形式和大家一起回顾一下我这次提到的各种尝试:总结在我们探索新的技术和模式的时候,一定要注意不要把早期的结果等同于最好的结果。实践与努力相混淆。虽然早期的成功会带来兴奋和鼓励,但它也会阻止我们前进。我们应该勤奋,不断尝试,并始终乐于接受改进建议。【原标题】Linux容器的演进(作者:DonSchenck)原文链接:https://dzone.com/articles/the-evolution-of-a-linux-container原文译者及出处为.com]
