自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

原理:Docker如何使耗時(shí)運(yùn)行的構(gòu)建腳本更容易

云計(jì)算
Docker采用的叫做AUFS的聯(lián)合文件系統(tǒng)。本文作者從長(zhǎng)時(shí)運(yùn)行構(gòu)建腳本的耗時(shí)長(zhǎng)、對(duì)早期構(gòu)建庫(kù)的嚴(yán)重依賴等問(wèn)題入手,介紹作者本人是如何使用Docker實(shí)現(xiàn)GHC7.8.3 ARM交叉編譯器的構(gòu)建腳本,來(lái)讓這些耗時(shí)運(yùn)行的構(gòu)建腳本更加容易。

我想我已經(jīng)找到了一個(gè)相當(dāng)引人注目的docker使用案例。但在此之前,如果你還是認(rèn)為這又是一個(gè)人云亦云docker美德的博客帖子的話,我想明確指出,這個(gè)帖子確實(shí)是關(guān)于把文件系統(tǒng)作為持久性數(shù)據(jù)結(jié)構(gòu)的贊美帖。

因此,這篇文章的見(jiàn)解同樣適用于其他的 copy-on-write文件系統(tǒng),如BTRFS和ZFS。

問(wèn)題

讓我們從這個(gè)我試圖解決的問(wèn)題開(kāi)始。我開(kāi)發(fā)了包括了眾多的步驟的長(zhǎng)時(shí)運(yùn)行的構(gòu)建腳本。

花費(fèi)1-2個(gè)小時(shí)運(yùn)行。

它從互聯(lián)網(wǎng)下載了很多相當(dāng)大的文件。(超過(guò)300M)。

后期嚴(yán)重依賴早期構(gòu)建的庫(kù)。

但最顯著的特點(diǎn)是,它需要花很長(zhǎng)的時(shí)間來(lái)運(yùn)行。

文件系統(tǒng)是固有狀態(tài)

我們通常是以一種狀態(tài)的方式與文件系統(tǒng)進(jìn)行交互的。我們可以添加,刪除或移動(dòng)文件。我們可以改變文件的權(quán)限或者它的訪問(wèn)時(shí)間。

隔離下的大部分操作都可以撤銷(xiāo)。例如你可以移動(dòng)文件到其其他的地方后,將文件恢復(fù)到原來(lái)的位置。通常我們不會(huì)做的是采取一個(gè)快照,并恢復(fù)到那個(gè)狀態(tài)。這篇文章建議更多地利用這一特性對(duì)開(kāi)發(fā)長(zhǎng)時(shí)運(yùn)行腳本有巨大好處。

使用聯(lián)合文件系統(tǒng)的快照

Docker采用的是所謂的聯(lián)合文件系統(tǒng)叫做AUFS。聯(lián)合文件系統(tǒng)實(shí)現(xiàn)了被稱為聯(lián)合掛載的文件系統(tǒng)。顧名思義,這意味著文件和獨(dú)立的文件系統(tǒng)的目錄被分層于互相形成的單個(gè)連貫文件系統(tǒng)之上。

這是以分層方式完成的。如果一個(gè)文件出現(xiàn)在兩個(gè)文件系統(tǒng),后來(lái)添加的文件將會(huì)呈現(xiàn) (該文件其他版本是存在于層級(jí)中的,不改變,只是看不到的)。

Docker稱呼在聯(lián)合掛載文件系統(tǒng)里的每個(gè)文件系統(tǒng)為layers(層)。使用這種技術(shù)的結(jié)果是,它的副作用可以實(shí)現(xiàn)快照。每個(gè)快照對(duì)于所有層是一個(gè)簡(jiǎn)單的聯(lián)合掛載文件系統(tǒng)掛載到某個(gè)層次結(jié)構(gòu)中。

生成腳本的快照

快 照使開(kāi)發(fā)一個(gè)長(zhǎng)時(shí)運(yùn)行的構(gòu)建腳本成為夢(mèng)想??偟南敕ㄊ牵纸獯竽_本為更小的腳本(我喜歡稱之為scriptlets)并且單獨(dú)地運(yùn)行每一個(gè),每一個(gè)運(yùn)行后 快照其文件系統(tǒng)。 (Docker會(huì)自動(dòng)執(zhí)行此操作。)如果你發(fā)現(xiàn)一個(gè)scriptlet運(yùn)行失敗,簡(jiǎn)單的可以回到最后的快照(仍處于原始狀態(tài)?。?,然后再試一次。

一旦你完成你的構(gòu)建腳本,你可以保證,腳本正常工作,現(xiàn)在可以分配給其他主機(jī)。

相對(duì)于如果你沒(méi)有使用快照會(huì)發(fā)生什么。除了在我們中間那些有和尚般的耐心的人,當(dāng)它在1個(gè)半小時(shí)后失敗了,沒(méi)有人會(huì)去從頭開(kāi)始運(yùn)行他們的構(gòu)建腳本。當(dāng)然,我們會(huì)盡最大努力把系統(tǒng)恢復(fù)到失敗前的狀態(tài)。例如我們可以刪除一個(gè)目錄或運(yùn)行 make clean。

但是,我們可能沒(méi)有真正地理解我們正在構(gòu)建的組件。它可能復(fù)雜的Makefile:把文件放到文件系統(tǒng)中我們不知道的地方。唯一真正確定的途徑是恢復(fù)到快照。

使用快照構(gòu)建腳本的docker

在 本節(jié)中,我將介紹我是如何使用Docker實(shí)現(xiàn)GHC7.8.3 ARM交叉編譯器的構(gòu)建腳本。對(duì)于這個(gè)任務(wù)Docker相當(dāng)不錯(cuò)的,但并不是完美的。我做了一些事情,可能看起來(lái)浪費(fèi)的或不雅的,但都是必要的,以保持開(kāi) 發(fā)腳本的總時(shí)間到最低限度。構(gòu)建腳本可以在這里找到。

用Dockerfile構(gòu)建

Docker 讀取一個(gè)名為Dockerfile來(lái)構(gòu)建鏡像。Dockerfile包含一些命令詞匯來(lái)具體指定哪些行動(dòng)應(yīng)該被執(zhí)行。一個(gè)完整的參考可以在這里找到。其中 在我的腳本主要用了WORKDIR,ADD和RUN。ADD命令非常有用因?yàn)樗梢宰屇阍谶\(yùn)行之前將外部文件添加到當(dāng)前Docker鏡像中然后轉(zhuǎn)換成鏡像 的文件系統(tǒng)。你可以在這里看到很多scriptlets構(gòu)成的構(gòu)建腳本。

#p#

設(shè)計(jì)

1.在RUN之前ADD scriptlets

如 果你太早ADD所有的scriptlets在Dockerfile,您可能會(huì)遇到以下問(wèn)題:你的腳本失敗,你回去修改scriptlet并再次運(yùn)行 docker build .。但是你發(fā)現(xiàn),Docker開(kāi)始在首次加入scriptlets的地方構(gòu)建!這會(huì)浪費(fèi)了大量的時(shí)間和違背了使用快照的目的。

出 現(xiàn)這種情況的原因是因?yàn)镈ocker如何追蹤它的中間鏡像(快照)。當(dāng)Docker通過(guò)Dockerfile構(gòu)建鏡像時(shí)它會(huì)與中間鏡像比較當(dāng)前命令是否一 致。然而,在ADD命令的情況下被裝進(jìn)鏡像的文件里的內(nèi)容也會(huì)被檢查。這是有道理的。如果文件已改變就現(xiàn)有的中間鏡像那么Docker將別無(wú)選擇,只能從 從這點(diǎn)開(kāi)始建立一個(gè)新的鏡像。只是沒(méi)有辦法可以知道這些變化不會(huì)影響到構(gòu)建。這是必須要保守的即使他們沒(méi)有。

此外,使用RUN命令 要注意,每次運(yùn)行時(shí)它將導(dǎo)致文件系統(tǒng)有不同的更改。在這種情況下,Docker會(huì)發(fā)現(xiàn)中間鏡像并使用它,但是這將是錯(cuò)誤的。RUN命令每次運(yùn)行時(shí)必須造成 文件系統(tǒng)相同的改變。舉個(gè)例子,我確保在我的scriptlets我總是下載了一個(gè)已知版本的文件與一個(gè)特定MD5校驗(yàn)。

對(duì)Docker 構(gòu)建緩存更詳細(xì)的解釋可以在這里找到。

2.不要使用ENV命令來(lái)設(shè)置環(huán)境變量。使用scriptlet。

它似乎看起來(lái)很有誘惑力:使用ENV命令來(lái)設(shè)置所有構(gòu)建腳本需要的環(huán)境變量。但是,它不支持變量替換的方式,例如 ENV BASE=$HOME/base 將設(shè)置BASE的值為$HOME/base著很可能不是你想要的。

相反,我用ADD命令添加一個(gè)名為set-env.sh文件。此文件被包含在每個(gè)后續(xù)的scriptlet中:

  1. THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" source $THIS_DIR/set-env-1.sh

如果你沒(méi)有在第一時(shí)間獲取set-env.sh會(huì)怎么樣呢?自從它很早就被加入Dockerfile并不意味著修改它將會(huì)使隨后的快照無(wú)效?

是的,這將導(dǎo)致一些不雅。在開(kāi)發(fā)腳本時(shí),我發(fā)現(xiàn),我已經(jīng)錯(cuò)過(guò)了在set-env.sh添加一個(gè)有用的環(huán)境變量。解決方案是創(chuàng)建一個(gè)新的文件set-env-1.sh包含:

  1. THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" source $THIS_DIR/set-env.sh 
  2.  
  3. if ! [ -e "$CONFIG_SUB_SRC/config.sub" ] ; then 
  4.  
  5. CONFIG_SUB_SRC=${CONFIG_SUB_SRC:-$NCURSES_SRC} 
  6.  
  7. fi 

然后,在所有后續(xù)的scriptlets文件中包含了此文件?,F(xiàn)在,我已經(jīng)完成了構(gòu)建腳本,我可以回去解決這個(gè)問(wèn)題了,但是,在某種意義上,它會(huì)破壞最初的目標(biāo)。我將不得不從頭開(kāi)始運(yùn)行構(gòu)建腳本看看這種變化是否能成功。

缺點(diǎn)

一個(gè)主要缺點(diǎn)是這種方法是,所構(gòu)建的鏡像尺寸是大于它實(shí)際需求的尺寸。在我的情況下尤其如此,因?yàn)槲以谧詈髣h除了大量文件的。然而,這些文件都仍然存在于聯(lián)合掛載文件系統(tǒng)的底層文件系統(tǒng)內(nèi),所以整個(gè)鏡像是大于它實(shí)際需要的大小至少多余的是刪除文件的大小。

然而,有一個(gè)變通。我沒(méi)有公布此鏡像到Docker Hub Registry。相反,我:

  • 使用docker export導(dǎo)出內(nèi)容到tar文件。
  • 創(chuàng)建一個(gè)新的Dockerfile簡(jiǎn)單地添加了這個(gè)tar文件的內(nèi)容。

來(lái)產(chǎn)生尺寸盡可能小的鏡像。

結(jié)論

這種方法的優(yōu)點(diǎn)是雙重的:

  • 它使開(kāi)發(fā)時(shí)間降至最低。不再做那些已經(jīng)構(gòu)建成功的子組件。你可以專注于那些失敗的組件。
  • 這是偉大對(duì)于維護(hù)構(gòu)建腳本。有一個(gè)機(jī)會(huì) 古怪的RUN命令在一段時(shí)間(即使它不應(yīng)該)會(huì)改變其行為。構(gòu)建可能會(huì)失敗,但至少你不必再回到開(kāi)頭,一旦你解決了Dockerfile

此外,正如我前面提到的Docker不僅使寫(xiě)這些構(gòu)建腳本更加容易。有了合適的工具同樣可以在任何提供快照的文件系統(tǒng)實(shí)現(xiàn)。

構(gòu)建快樂(lè)!

文章出自:http://dockerone.com/article/100

責(zé)任編輯:Ophira 來(lái)源: dockerone
相關(guān)推薦

2021-06-29 15:52:03

PythonPOST

2018-02-25 12:19:02

2020-02-11 12:35:19

Kubernetes容器

2019-09-23 10:59:31

機(jī)器學(xué)習(xí)算法編程

2019-09-23 11:17:46

機(jī)器學(xué)習(xí)數(shù)據(jù)技術(shù)

2019-11-15 09:26:36

OAuthWeb系統(tǒng)

2019-07-09 10:57:04

云計(jì)算無(wú)服務(wù)器計(jì)算開(kāi)發(fā)

2023-02-28 14:50:02

人工智能首席信息官

2023-03-13 14:26:00

人工智能首席信息官疫情

2017-11-14 08:27:32

云中數(shù)據(jù)存儲(chǔ)

2017-02-06 11:55:40

DockerJava Web環(huán)境

2021-01-14 10:48:05

技術(shù)RPCRS

2022-06-17 09:47:04

Linux命令

2019-08-05 09:39:05

2024-04-11 11:37:25

人工智能機(jī)器學(xué)習(xí)自動(dòng)化流程

2021-06-07 17:10:07

區(qū)塊鏈出入口控制物聯(lián)網(wǎng)

2022-07-26 07:14:52

Docker宿主命令

2015-11-06 14:41:30

微軟Windows 10

2016-01-28 13:33:07

2010-02-06 14:59:37

Android程序
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)