成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

Dockerfile多階段構(gòu)建原理和使用場(chǎng)景

fireflow / 3376人閱讀

摘要:版本以后,新增了多階段構(gòu)建。所謂多階段構(gòu)建,實(shí)際上是允許一個(gè)中出現(xiàn)多個(gè)指令。因?yàn)槎鄠€(gè)指令會(huì)造成多根,則是無(wú)法實(shí)現(xiàn)的。會(huì)使用一個(gè)完全干凈的文件系統(tǒng),不包含任何文件??梢允沟米詈笊傻溺R像最小化,其中只包含了程序。

Docker 17.05版本以后,新增了Dockerfile多階段構(gòu)建。所謂多階段構(gòu)建,實(shí)際上是允許一個(gè)Dockerfile 中出現(xiàn)多個(gè) FROM 指令。這樣做有什么意義呢?

老版本Docker中為什么不支持多個(gè) FROM 指令

在17.05版本之前的Docker,只允許Dockerfile中出現(xiàn)一個(gè)FROM指令,這得從鏡像的本質(zhì)說(shuō)起。

《Docker概念簡(jiǎn)介》 中我們提到,你可以簡(jiǎn)單理解Docker的鏡像是一個(gè)壓縮文件,其中包含了你需要的程序和一個(gè)文件系統(tǒng)。其實(shí)這樣說(shuō)是不嚴(yán)謹(jǐn)?shù)?,Docker鏡像并非只是一個(gè)文件,而是由一堆文件組成,最主要的文件是 層。

Dockerfile 中,大多數(shù)指令會(huì)生成一個(gè)層,比如下方的兩個(gè)例子:

# 示例一,foo 鏡像的Dockerfile
# 基礎(chǔ)鏡像中已經(jīng)存在若干個(gè)層了
FROM ubuntu:16.04

# RUN指令會(huì)增加一層,在這一層中,安裝了 git 軟件
RUN apt-get update 
  && apt-get install -y --no-install-recommends git 
  && apt-get clean 
  && rm -rf /var/lib/apt/lists/*
# 示例二,bar 鏡像的Dockerfile
FROM foo

# RUN指令會(huì)增加一層,在這一層中,安裝了 nginx
RUN apt-get update 
  && apt-get install -y --no-install-recommends nginx 
  && apt-get clean 
  && rm -rf /var/lib/apt/lists/*

假設(shè)基礎(chǔ)鏡像ubuntu:16.04已經(jīng)存在5層,使用第一個(gè)Dockerfile打包成鏡像 foo,則foo有6層,又使用第二個(gè)Dockerfile打包成鏡像bar,則bar中有7層。

如果ubuntu:16.04 等其他鏡像不算,如果系統(tǒng)中只存在 foo 和 bar 兩個(gè)鏡像,那么系統(tǒng)中一共保存了多少層呢?

是7層,并非13層,這是因?yàn)?,foo和bar共享了6層。層的共享機(jī)制可以節(jié)約大量的磁盤(pán)空間和傳輸帶寬,比如你本地已經(jīng)有了foo鏡像,又從鏡像倉(cāng)庫(kù)中拉取bar鏡像時(shí),只拉取本地所沒(méi)有的最后一層就可以了,不需要把整個(gè)bar鏡像連根拉一遍。但是層共享是怎樣實(shí)現(xiàn)的呢?

原來(lái),Docker鏡像的每一層只記錄文件變更,在容器啟動(dòng)時(shí),Docker會(huì)將鏡像的各個(gè)層進(jìn)行計(jì)算,最后生成一個(gè)文件系統(tǒng),這個(gè)被稱(chēng)為 聯(lián)合掛載。對(duì)此感興趣的話可以進(jìn)入了解一下 AUFS。

Docker的各個(gè)層是有相關(guān)性的,在聯(lián)合掛載的過(guò)程中,系統(tǒng)需要知道在什么樣的基礎(chǔ)上再增加新的文件。那么這就要求一個(gè)Docker鏡像只能有一個(gè)起始層,只能有一個(gè)根。所以,Dockerfile中,就只允許一個(gè)FROM指令。因?yàn)槎鄠€(gè)FROM 指令會(huì)造成多根,則是無(wú)法實(shí)現(xiàn)的。但為什么 Docker 17.05 版本以后允許 Dockerfile支持多個(gè) FROM 指令了呢,莫非已經(jīng)支持了多根?

多個(gè) FROM 指令的意義

多個(gè) FROM 指令并不是為了生成多根的層關(guān)系,最后生成的鏡像,仍以最后一條 FROM 為準(zhǔn),之前的 FROM 會(huì)被拋棄,那么之前的FROM 又有什么意義呢?

每一條 FROM 指令都是一個(gè)構(gòu)建階段,多條 FROM 就是多階段構(gòu)建,雖然最后生成的鏡像只能是最后一個(gè)階段的結(jié)果,但是,能夠?qū)⑶爸秒A段中的文件拷貝到后邊的階段中,這就是多階段構(gòu)建的最大意義。

最大的使用場(chǎng)景是將編譯環(huán)境和運(yùn)行環(huán)境分離,比如,之前我們需要構(gòu)建一個(gè)Go語(yǔ)言程序,那么就需要用到go命令等編譯環(huán)境,我們的Dockerfile可能是這樣的:

# Go語(yǔ)言環(huán)境基礎(chǔ)鏡像
FROM golang:1.10.3

# 將源碼拷貝到鏡像中
COPY server.go /build/

# 指定工作目錄
WORKDIR /build

# 編譯鏡像時(shí),運(yùn)行 go build 編譯生成 server 程序
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GOARM=6 go build -ldflags "-w -s" -o server

# 指定容器運(yùn)行時(shí)入口程序 server
ENTRYPOINT ["/build/server"]

基礎(chǔ)鏡像golang:1.10.3是非常龐大的,因?yàn)槠渲邪怂械腉o語(yǔ)言編譯工具和庫(kù),而運(yùn)行時(shí)候我們僅僅需要編譯后的server程序就行了,不需要編譯時(shí)的編譯工具,最后生成的大體積鏡像就是一種浪費(fèi)。

使用脈沖云的解決辦法是將程序編譯和鏡像打包分開(kāi),使用脈沖云的編譯構(gòu)建服務(wù),選擇增加構(gòu)Go語(yǔ)言構(gòu)建工具,然后在構(gòu)建步驟中編譯。

最后將編譯接口拷貝到鏡像中就行了,那么Dockerfile的基礎(chǔ)鏡像并不需要包含Go編譯環(huán)境:

# 不需要Go語(yǔ)言編譯環(huán)境
FROM scratch

# 將編譯結(jié)果拷貝到容器中
COPY server /server

# 指定容器運(yùn)行時(shí)入口程序 server
ENTRYPOINT ["/server"]
提示:scratch 是內(nèi)置關(guān)鍵詞,并不是一個(gè)真實(shí)存在的鏡像。 FROM scratch 會(huì)使用一個(gè)完全干凈的文件系統(tǒng),不包含任何文件。 因?yàn)镚o語(yǔ)言編譯后不需要運(yùn)行時(shí),也就不需要安裝任何的運(yùn)行庫(kù)。FROM scratch可以使得最后生成的鏡像最小化,其中只包含了 server 程序。

在 Docker 17.05版本以后,就有了新的解決方案,直接一個(gè)Dockerfile就可以解決:

# 編譯階段
FROM golang:1.10.3

COPY server.go /build/

WORKDIR /build

RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GOARM=6 go build -ldflags "-w -s" -o server

# 運(yùn)行階段
 FROM scratch

# 從編譯階段的中拷貝編譯結(jié)果到當(dāng)前鏡像中
COPY --from=0 /build/server /

ENTRYPOINT ["/server"]

這個(gè) Dockerfile 的玄妙之處就在于 COPY 指令的--from=0 參數(shù),從前邊的階段中拷貝文件到當(dāng)前階段中,多個(gè)FROM語(yǔ)句時(shí),0代表第一個(gè)階段。除了使用數(shù)字,我們還可以給階段命名,比如:

# 編譯階段 命名為 builder
FROM golang:1.10.3 as builder

# ... 省略

# 運(yùn)行階段
FROM scratch

# 從編譯階段的中拷貝編譯結(jié)果到當(dāng)前鏡像中
COPY --from=builder /build/server /

更為強(qiáng)大的是,COPY --from 不但可以從前置階段中拷貝,還可以直接從一個(gè)已經(jīng)存在的鏡像中拷貝。比如,

   FROM ubuntu:16.04
    
   COPY --from=quay.io/coreos/etcd:v3.3.9 /usr/local/bin/etcd /usr/local/bin/

我們直接將etcd鏡像中的程序拷貝到了我們的鏡像中,這樣,在生成我們的程序鏡像時(shí),就不需要源碼編譯etcd了,直接將官方編譯好的程序文件拿過(guò)來(lái)就行了。

有些程序要么沒(méi)有apt源,要么apt源中的版本太老,要么干脆只提供源碼需要自己編譯,使用這些程序時(shí),我們可以方便地使用已經(jīng)存在的Docker鏡像作為我們的基礎(chǔ)鏡像。但是我們的軟件有時(shí)候可能需要依賴多個(gè)這種文件,我們并不能同時(shí)將 nginx 和 etcd 的鏡像同時(shí)作為我們的基礎(chǔ)鏡像(不支持多根),這種情況下,使用 COPY --from 就非常方便實(shí)用了。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/97016.html

相關(guān)文章

  • 容器化-Docker介紹

    摘要:容器作為一類(lèi)操作系統(tǒng)層面的虛擬化技術(shù),其目標(biāo)是在單一主機(jī)交付多套隔離性環(huán)境,容器共享同一套主機(jī)操作系統(tǒng)內(nèi)核。與其它容器平臺(tái)不同,引入了一整套與容器管理相關(guān)的生態(tài)系統(tǒng)。每個(gè)容器都是相互隔離的保證安全的平臺(tái)。 導(dǎo)讀:本文章對(duì)Docker技術(shù)進(jìn)行了介紹,闡述了Docker的技術(shù)發(fā)展歷程、容器與虛擬機(jī)的差異、Docker原理、特點(diǎn)、Docker三組件和Docker帶來(lái)的影響,為我們進(jìn)一步理解D...

    李增田 評(píng)論0 收藏0
  • 程序員筆記——如何編寫(xiě)優(yōu)雅的Dockerfile

    摘要:導(dǎo)讀要從容器化開(kāi)始,而容器又需要從開(kāi)始,本文將介紹如何寫(xiě)出一個(gè)優(yōu)雅的文件。只要記住以上三點(diǎn)就能寫(xiě)出不錯(cuò)的。執(zhí)行完成項(xiàng)目的構(gòu)建。 導(dǎo)讀 Kubernetes要從容器化開(kāi)始,而容器又需要從Dockerfile開(kāi)始,本文將介紹如何寫(xiě)出一個(gè)優(yōu)雅的Dockerfile文件。 文章主要內(nèi)容包括: Docker容器 Dockerfile 使用多階構(gòu)建 感謝公司提供大量機(jī)器資源及時(shí)間讓我們可以實(shí)踐...

    曹金海 評(píng)論0 收藏0
  • 最小化 Java 鏡像的常用技巧

    摘要:本文將介紹精簡(jiǎn)容器鏡像的必要性并以基于的應(yīng)用為例描述最小化容器鏡像的常用技巧。經(jīng)過(guò)這一優(yōu)化,最終鏡像的大小為。 背景 隨著容器技術(shù)的普及,越來(lái)越多的應(yīng)用被容器化。人們使用容器的頻率越來(lái)越高,但常常忽略一個(gè)基本但又非常重要的問(wèn)題 - 容器鏡像的體積。本文將介紹精簡(jiǎn)容器鏡像的必要性并以基于 spring boot 的 java 應(yīng)用為例描述最小化容器鏡像的常用技巧。 精簡(jiǎn)容器鏡像的必要性 ...

    MudOnTire 評(píng)論0 收藏0
  • docker進(jìn)階,nginx部署的幾個(gè)重要點(diǎn)詳解以及開(kāi)發(fā)流程---持續(xù)更新

    摘要:無(wú)論這個(gè)連接是外部主動(dòng)建立的,還是內(nèi)部建立的。協(xié)議有表示層數(shù)據(jù)的表示安全壓縮。在整個(gè)發(fā)展過(guò)程中的所有思想和著重點(diǎn)都以一種稱(chēng)為的文檔格式存在。 部署基礎(chǔ)知識(shí)url:協(xié)議://網(wǎng)站地址:端口(/)路徑地址?參數(shù)eg: http://www.baidu.com:80/abc/dd/ www.baidu.com找服務(wù)器 80端口:找服務(wù)器上提供服務(wù)的應(yīng)用 nginx uri:/ab...

    KunMinX 評(píng)論0 收藏0
  • docker進(jìn)階,nginx部署的幾個(gè)重要點(diǎn)詳解以及開(kāi)發(fā)流程---持續(xù)更新

    摘要:無(wú)論這個(gè)連接是外部主動(dòng)建立的,還是內(nèi)部建立的。協(xié)議有表示層數(shù)據(jù)的表示安全壓縮。在整個(gè)發(fā)展過(guò)程中的所有思想和著重點(diǎn)都以一種稱(chēng)為的文檔格式存在。 部署基礎(chǔ)知識(shí)url:協(xié)議://網(wǎng)站地址:端口(/)路徑地址?參數(shù)eg: http://www.baidu.com:80/abc/dd/ www.baidu.com找服務(wù)器 80端口:找服務(wù)器上提供服務(wù)的應(yīng)用 nginx uri:/ab...

    ytwman 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<