現(xiàn)在,.NET開發(fā)人員可以無障礙地使用如Docker這樣的Linux容器,那么讓我們來嘗試如何以正確的方式配置一個容器。
可能,文章的標(biāo)題改成“Linux容器開發(fā)人員的演變”會更好。由于.NET可在Linux(以及Windows和macOS)上運(yùn)行,所以整個世界的Linux容器和微服務(wù)已經(jīng)開放給了.NET開發(fā)人員。
有著大量的開發(fā)人員,長期的運(yùn)行記錄和優(yōu)異性能指標(biāo)的.NET,現(xiàn)在給以Windows為中心的開發(fā)人員提供了一個使用Linux容器的機(jī)會。
雖然在Linux容器中嘗試運(yùn)行.NET代碼是誘人的,同時也會產(chǎn)生一些細(xì)微差別,但是這樣做是不會錯的。你可以很容易地將一些.NET代碼推送到鏡像中。
畢,一切都發(fā)生的這么快,一定都很好。 對不對?
事實(shí)并非如此。讓.NET代碼運(yùn)行在Linux容器中并不是一件簡單的事情,但請記住:“先讓它工作,然后讓它工作得很快。”
在下面的例子中,上文說的“很快”指的是構(gòu)建鏡像所需的時間,啟動鏡像所需的時間和鏡像內(nèi)部代碼的性能。本文將首先討論鏡像的構(gòu)建時間和啟動時間,接著會將一個簡單的.NET程序運(yùn)行在基于容器的應(yīng)用上,然后觀察鏡像大小的變化,終縮短鏡像的構(gòu)建和加載時間。此外,代碼優(yōu)化是本文的另一個主題。
考慮一個非常簡單的微服務(wù)示例,它只給出一個“Hello world”類型的HTTP響應(yīng)。也就是說,當(dāng)在瀏覽器中填寫URL,你就會得到一個包括主機(jī)名的Web頁面。
我們可從這個代碼庫中(https://github.com/donschenck/dotnet_docker_msa)下載源碼,并制作個Dockerfile(Dockerfile.attempt1),接著使用以下命令構(gòu)建鏡像:
然后在容器中運(yùn)行鏡像:
將瀏覽器的URL指向主機(jī)的IP地址,情況如下:
次構(gòu)建鏡像,一共耗時95秒。其中,下載紅帽企業(yè)Linux(簡稱RHEL)鏡像與安裝.NET SDK,這些文件一共490MB。終,鏡像大小為659MB。
一般而言,鏡像的后續(xù)構(gòu)建將更快,因?yàn)镈ocker化的鏡像已經(jīng)在主機(jī)上可用。改變源碼后,我們再次運(yùn)行構(gòu)建。這一次構(gòu)建鏡像,大約耗時50秒,得到了相同大小的鏡像,也是659MB。
鏡像的大小很重要。因?yàn)殓R像使用操作系統(tǒng)的存儲空間,雖然空間便宜,但它仍然是有限的商品。當(dāng)定期使用容器時,我們很容易忽略過時的鏡像,然而它仍然在占用磁盤。如果你不注意的話,磁盤空間將很快用盡。
如何使鏡像盡可能的小?
使用命令dotnet restore --no-cache可以消除任何緩存,這樣鏡像的大小下降到608.6MB,減少了50.6 MB,同比縮小超過7%。
應(yīng)用是在容器中運(yùn)行鏡像時構(gòu)建.NET程序的。這耗時大約1.6秒——雖然時間不長,但卻是在浪費(fèi)時間。
在恢復(fù)之前插入的dotnet build命令,并在構(gòu)建鏡像之前構(gòu)建應(yīng)用,這樣的話容器將會更快地啟動。這個結(jié)果可在Dockerfile.attempt3中實(shí)現(xiàn)。
與此同時,鏡像大小卻增加到610.2MB,而我們還得運(yùn)行dotnet build,雖然現(xiàn)在花這個時間,但卻可在每次啟動容器時受益。
因?yàn)槿萜魇且粋€運(yùn)行時環(huán)境,那我們?yōu)槭裁床皇褂胐otnet publish命令發(fā)布代碼,然后把代碼放入鏡像呢?如果這樣做的話,我們就沒必要在鏡像中安裝.NET程序了。畢,我們需要的是一個可在任何地方獨(dú)立運(yùn)行的應(yīng)用。
使用dotnet發(fā)布代碼,會減少鏡像大小和縮短容器啟動時間。更改project.json文件,注釋掉下圖中紅框的內(nèi)容,這告訴編譯器此文件為一個平臺構(gòu)建。您可以在下圖中看到它:
接下來,我們使用dotnet publish -c Release -r rheh.7.2-x64發(fā)布代碼,這會把所有的編譯文件和運(yùn)行時文件,放入一個文件夾,我們把此文件夾復(fù)制到鏡像中。
因?yàn)槲覀儾辉傩枰惭b.NET程序,只要一個包含RHEL文件的基礎(chǔ)鏡像即可,這樣就減少了鏡像的大小。這是Dockerfile的第四次迭代——Dockerfile.attempt4:
請注意,yum install命令將安裝一些.NET需要的依賴文件,然后運(yùn)行docker build命令,終生成一個694.6MB的鏡像。
多次運(yùn)行yum install命令,前一次操作將為后一次構(gòu)建緩存。如果在每個yum install命令之后,我們立即清除緩存,效果將會很好。下面是Dockerfile的第五次迭代———Dockerfile.attempt5:
基于Dockerfile.attempt5構(gòu)建的鏡像,其大小減少到293.7MB,這比次構(gòu)建縮小了55%。
對Dockerfile做后更改,我們需要堆疊yum install命令,具體內(nèi)容如下所示:
終得到的鏡像大小為257.5MB,這比次構(gòu)建縮小了60%。
下面是各個Dockerfile構(gòu)建的鏡像大小對比圖:
在探索新技術(shù)與新模式時,我們不能將早期的結(jié)果與優(yōu)做法相混淆。雖然早期的成功會給我們帶來興奮和鼓勵,但它也可能使我們喪失進(jìn)步的動力。勤奮,然后不斷嘗試,并且始終接受改進(jìn)的建議,會幫助我們走的更遠(yuǎn)。
本站文章版權(quán)歸原作者及原出處所有 。內(nèi)容為作者個人觀點(diǎn), 并不代表本站贊同其觀點(diǎn)和對其真實(shí)性負(fù)責(zé),本站只提供參考并不構(gòu)成任何投資及應(yīng)用建議。本站是一個個人學(xué)習(xí)交流的平臺,網(wǎng)站上部分文章為轉(zhuǎn)載,并不用于任何商業(yè)目的,我們已經(jīng)盡可能的對作者和來源進(jìn)行了通告,但是能力有限或疏忽,造成漏登,請及時聯(lián)系我們,我們將根據(jù)著作權(quán)人的要求,立即更正或者刪除有關(guān)內(nèi)容。本站擁有對此聲明的最終解釋權(quán)。