.NET程序在Linux容器中的演变
【上海站|3天烧脑式微服务架构训练营】培训内容包括:DevOps、微服务、Spring Cloud、Eureka、Ribbon、Feign、Hystrix、Zuul、Spring Cloud Config、Spring Cloud Sleuth等。
本文将首先讨论镜像的构建时间和启动时间,接着会将一个简单的.NET程序运行在基于容器的应用上,然后观察镜像大小的变化,最终缩短镜像的构建和加载时间。此外,代码优化是本文的另一个主题。
现在,.NET开发人员可以无障碍地使用如Docker这样的Linux容器,那么让我们来尝试如何以正确的方式配置一个容器。
可能,文章的标题改成“Linux容器开发人员的演变”会更好。由于.NET可在Linux(以及Windows和macOS)上运行,所以整个世界的Linux容器和微服务已经开放给了.NET开发人员。
有着大量的开发人员,长期的运行记录和优异性能指标的.NET,现在给以Windows为中心的开发人员提供了一个使用Linux容器的机会。
虽然在Linux容器中尝试运行.NET代码是诱人的,同时也会产生一些细微差别,但是这样做是不会错的。你可以很容易地将一些.NET代码推送到镜像中。
毕竟,一切都发生的这么快,一定都很好。 对不对?
事实并非如此。让.NET代码运行在Linux容器中并不是一件简单的事情,但请记住:“先让它工作,然后让它工作得很快。”
在下面的例子中,上文说的“很快”指的是构建镜像所需的时间,启动镜像所需的时间和镜像内部代码的性能。本文将首先讨论镜像的构建时间和启动时间,接着会将一个简单的.NET程序运行在基于容器的应用上,然后观察镜像大小的变化,最终缩短镜像的构建和加载时间。此外,代码优化是本文的另一个主题。
短暂的停留
考虑一个非常简单的微服务示例,它只给出一个“Hello world”类型的HTTP响应。也就是说,当在浏览器中填写URL,你就会得到一个包括主机名的Web页面。我们可从这个 代码库 中下载源码,并制作第一个Dockerfile(Dockerfile.attempt1),接着使用以下命令构建镜像:
# docker build -t attempt1 -f Dockerfile.attempt1 .
然后在容器中运行镜像:
# docker run -d -p 5000:5000 --name attempt1 attempt1
将浏览器的URL指向主机的IP地址,情况如下:
数字
第一次构建镜像,一共耗时95秒。其中,下载红帽企业Linux(简称RHEL)镜像与安装.NET SDK,这些文件一共490MB。最终,镜像大小为659MB。一般而言,镜像的后续构建将更快,因为Docker化的镜像已经在主机上可用。改变源码后,我们再次运行构建。这一次构建镜像,大约耗时50秒,得到了相同大小的镜像,也是659MB。
镜像的大小很重要。因为镜像使用操作系统的存储空间,虽然空间便宜,但它仍然是有限的商品。当定期使用容器时,我们很容易忽略过时的镜像,然而它仍然在占用磁盘。如果你不注意的话,磁盘空间将很快用尽。
如何使镜像尽可能的小?
移除镜像不需要的部分
使用命令dotnet restore --no-cache
可以消除任何缓存,这样镜像的大小下降到608.6MB,减少了50.6 MB,同比缩小超过7%。 在构建镜像之前构建应用
应用是在容器中运行镜像时构建.NET程序的。这耗时大约1.6秒——虽然时间不长,但却是在浪费时间。在恢复之前插入的
dotnet build
命令,并在构建镜像之前构建应用,这样的话容器将会更快地启动。这个结果可在Dockerfile.attempt3中实现。 与此同时,镜像大小却增加到610.2MB,而我们还得运行
dotnet build
,虽然现在花这个时间,但却可在每次启动容器时受益。 运行Dotnet Publish命令
因为容器是一个运行时环境,那我们为什么不使用dotnet publish
命令发布代码,然后把代码放入镜像呢?如果这样做的话,我们就没必要在镜像中安装.NET程序了。毕竟,我们需要的是一个可在任何地方独立运行的应用。 使用dotnet发布代码,会减少镜像大小和缩短容器启动时间。更改project.json文件,注释掉下图中红框的内容,这告诉编译器此文件为一个平台构建。您可以在下图中看到它:
接下来,我们使用
dotnet publish -c Release -r rheh.7.2-x64
发布代码,这会把所有的编译文件和运行时文件,放入一个文件夹,我们把此文件夹复制到镜像中。 因为我们不再需要安装.NET程序,只要一个包含RHEL文件的基础镜像即可,这样就减少了镜像的大小。这是Dockerfile的第四次迭代——Dockerfile.attempt4:
FROM registry.access.redhat.com/rhel7 RUN yum install -y libunwind RUN yum install -y libicu ADD bin/Release/netcoreapp1.0/rhel.7.2-x64/publish/. /opt/app-root/src/ WORKDIR /opt/app-root/src/ EXPOSE 5000 CMD ["/bin/bash", "-c", "/opt/app-root/src/dotnet_docker_msa"]
请注意,
yum install
命令将安装一些.NET需要的依赖文件,然后运行 docker build
命令,最终生成一个694.6MB的镜像。 谁需要缓存?
多次运行yum install
命令,前一次操作将为后一次构建缓存。如果在每个 yum install
命令之后,我们立即清除缓存,效果将会很好。下面是Dockerfile的第五次迭代———Dockerfile.attempt5: FROM registry.access.redhat.com/rhel7 RUN yum install -y libunwind && yum clean all RUN yum install -y libicu && yum clean all ADD bin/Release/netcoreapp1.0/rhel.7.2-x64/publish/. /opt/app-root/src/ WORKDIR /opt/app-root/src/ EXPOSE 5000 CMD ["/bin/bash", "-c", "/opt/app-root/src/dotnet_docker_msa"]
基于Dockerfile.attempt5构建的镜像,其大小减少到293.7MB,这比第一次构建缩小了55%。
堆叠命令
对Dockerfile做最后更改,我们需要堆叠yum install
命令,具体内容如下所示: FROM registry.access.redhat.com/rhel7 `RUN yum install -y libunwind libicu && yum clean all `ADD bin/Release/netcoreapp1.0/rhel.7.2-x64/publish/. /opt/app-root/src/ `WORKDIR /opt/app-root/src/ `EXPOSE 5000 `CMD ["/bin/bash", "-c", "/opt/app-root/src/dotnet_docker_msa"]
最终得到的镜像大小为257.5MB,这比第一次构建缩小了60%。
下面是各个Dockerfile构建的镜像大小对比图:
总结
在探索新技术与新模式时,我们不能将早期的结果与最优做法相混淆。虽然早期的成功会给我们带来兴奋和鼓励,但它也可能使我们丧失进步的动力。勤奋,然后不断尝试,并且始终接受改进的建议,会帮助我们走的更远。原文链接:The Evolution of a Linux Container(译者:Jack)
===========================================
译者介绍
Jack,开源软件爱好者,研究方向是云计算PaaS平台与深度学习,现积极活跃于Docker,Kubernetes,Tensorflow社区。
原文发布时间为:2017-03-17
本文作者:Jack
本文来自云栖社区合作伙伴Dockerone.io,了解相关信息可以关注Dockerone.io。
原文标题:.NET程序在Linux容器中的演变

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
基于Nginx和Consul构建高可用及自动发现的Docker服务架构
本文讲的是基于Nginx和Consul构建高可用及自动发现的Docker服务架构【编者的话】本文对于Docker和Consul Template以及Nginx如何结合使用做了较为详细的介绍。 【上海站|3天烧脑式微服务架构训练营】培训内容包括:DevOps、微服务、Spring Cloud、Eureka、Ribbon、Feign、Hystrix、Zuul、Spring Cloud Config、Spring Cloud Sleuth等。 导读 如果你在大量接触或使用微服务的话,你可能会碰到一个问题:当你创建的服务数量越来越多时,这些服务之间的通信便越难管理,而且维护代价会越来越高。 针对这个问题,Consul给出了一份完美的答卷。 Consul是一套开源的分布式服务发现和配置管理系统,支持多数据中心分布式高可用。Consul是HashiCorp(Vagrant的创建者)开发的一个服务发现与配置项目,用Go语言开发,基于 Mozilla Public License 2.0 的协议开源。 另外,架构里的另一个重要的角色则是Docker。Docker技术的不断成熟,孵化出了大量优秀的相关技...
- 下一篇
微服务和软件交付的4个原则
本文讲的是微服务和软件交付的4个原则【编者的话】本文介绍了使用微服务架构时需要考虑的问题和遵循的四个原则,对于从传统架构向微服务架构转型起到了很好的指导作用。 【上海站|3天烧脑式微服务架构训练营】培训内容包括:DevOps、微服务、Spring Cloud、Eureka、Ribbon、Feign、Hystrix、Zuul、Spring Cloud Config、Spring Cloud Sleuth等。 微服务是一个杰出的架构,因为这种架构便于对软件系统进行管理。但实际情形是,有很多遗留的应用并没有采用微服务架构,也必须纳入统一的管理范畴。任何一个企业组织,尤其是大型组织机构,都不会使用单一的软件架构。 企业拥抱微服务架构的热情正在持续升温,但就像对待任何技术行业的趋势都应该客观冷静一样,对待微服务架构也是如此。虽然目前微服务架构大行其道,但不应该因为这种趋势而盲目地对应用进行优化和改造。除非是一个创业公司,否则很可能在短时间内就要面临混合架构带来的各种问题。 微服务最大的优势在于, 不需要在同一个周期里面对系统的若干部分进行升级改造。整个系统不需要部署在一起,各个服务可以单独进行部...
相关文章
文章评论
共有0条评论来说两句吧...