.NET程序在Linux容器中的演变
生活随笔
收集整理的這篇文章主要介紹了
.NET程序在Linux容器中的演变
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本文講的是.NET程序在Linux容器中的演變【編者的話】Linux容器技術已被開發人員所熟知,現在.NET程序可以跑在Docker容器中,這為以Windows中心的開發人員帶來了好處。
【上海站|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程序運行在基于容器的應用上,然后觀察鏡像大小的變化,最終縮短鏡像的構建和加載時間。此外,代碼優化是本文的另一個主題。
我們可從這個代碼庫中下載源碼,并制作第一個Dockerfile(Dockerfile.attempt1),接著使用以下命令構建鏡像:
#??docker??build??-t??attempt1???-f???Dockerfile.attempt1???.
然后在容器中運行鏡像:
#??docker??run???-d???-p???5000:5000???--name???attempt1???attempt1
將瀏覽器的URL指向主機的IP地址,情況如下:
一般而言,鏡像的后續構建將更快,因為Docker化的鏡像已經在主機上可用。改變源碼后,我們再次運行構建。這一次構建鏡像,大約耗時50秒,得到了相同大小的鏡像,也是659MB。
鏡像的大小很重要。因為鏡像使用操作系統的存儲空間,雖然空間便宜,但它仍然是有限的商品。當定期使用容器時,我們很容易忽略過時的鏡像,然而它仍然在占用磁盤。如果你不注意的話,磁盤空間將很快用盡。
如何使鏡像盡可能的小?
在恢復之前插入的dotnet build命令,并在構建鏡像之前構建應用,這樣的話容器將會更快地啟動。這個結果可在Dockerfile.attempt3中實現。
與此同時,鏡像大小卻增加到610.2MB,而我們還得運行dotnet build,雖然現在花這個時間,但卻可在每次啟動容器時受益。?
使用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的鏡像。
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%。
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)
===========================================
譯者介紹
【上海站|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容器中的演變
總結
以上是生活随笔為你收集整理的.NET程序在Linux容器中的演变的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sql语句按照汉字拼音首字母排序
- 下一篇: 「原创」马云又嗨啦,云栖音乐节与李健同台