成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

程序員筆記——如何編寫(xiě)優(yōu)雅的Dockerfile

曹金海 / 1252人閱讀

摘要:導(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í)踐,感謝在此專題上不斷實(shí)踐的部分項(xiàng)目及人員的支持。

一、Docker容器 1.1 容器的特點(diǎn)

我們都知道容器就是一個(gè)標(biāo)準(zhǔn)的軟件單元,它有以下特點(diǎn):

隨處運(yùn)行:容器可以將代碼與配置文件和相關(guān)依賴庫(kù)進(jìn)行打包,從而確保在任何環(huán)境下的運(yùn)行都是一致的。

高資源利用率:容器提供進(jìn)程級(jí)的隔離,因此可以更加精細(xì)地設(shè)置CPU和內(nèi)存的使用率,進(jìn)而更好地利用服務(wù)器的計(jì)算資源。

快速擴(kuò)展:每個(gè)容器都可作為多帶帶的進(jìn)程予以運(yùn)行,并且可以共享底層操作系統(tǒng)的系統(tǒng)資源,這樣一來(lái)可以加快容器的啟動(dòng)和停止效率。

1.2 Docker容器

目前市面上的主流容器引擎有Docker、Rocket/rkt、OpenVZ/Odin等等,而獨(dú)霸一方的容器引擎就是使用最多的Docker容器引擎。

Docker容器是與系統(tǒng)其他部分隔離開(kāi)的一系列進(jìn)程,運(yùn)行這些進(jìn)程所需的所有文件都由另一個(gè)鏡像提供,從開(kāi)發(fā)到測(cè)試再到生產(chǎn)的整個(gè)過(guò)程中,Linux 容器都具有可移植性和一致性。相對(duì)于依賴重復(fù)傳統(tǒng)測(cè)試環(huán)境的開(kāi)發(fā)渠道,容器的運(yùn)行速度要快得多,并且支持在多種主流云平臺(tái)(PaaS)和本地系統(tǒng)上部署。Docker容器很好地解決了“開(kāi)發(fā)環(huán)境能正常跑,一上線就各種崩”的尷尬。

Docker容器的特點(diǎn):

輕量:容器是進(jìn)程級(jí)的資源隔離,而虛擬機(jī)是操作系統(tǒng)級(jí)的資源隔離,所以Docker容器相對(duì)于虛擬機(jī)來(lái)說(shuō)可以節(jié)省更多的資源開(kāi)銷,因?yàn)镈ocker容器不再需要GuestOS這一層操作系統(tǒng)了。

快速:容器的啟動(dòng)和創(chuàng)建無(wú)需啟動(dòng)GuestOS,可以實(shí)現(xiàn)秒級(jí)甚至毫秒級(jí)的啟動(dòng)。

可移植性:Docker容器技術(shù)是將應(yīng)用及所依賴的庫(kù)和運(yùn)行時(shí)的環(huán)境技術(shù)改造包成容器鏡像,可以在不同的平臺(tái)運(yùn)行。

自動(dòng)化:容器生態(tài)中的容器編排工作(如:Kubernetes)可幫助我們實(shí)現(xiàn)容器的自動(dòng)化管理。

二、Dockerfile

Dockerfile是用來(lái)描述文件的構(gòu)成的文本文檔,其中包含了用戶可以在使用行調(diào)用以組合Image的所有命令,用戶還可以使用Docker build實(shí)現(xiàn)連續(xù)執(zhí)行多個(gè)命令指今行的自動(dòng)構(gòu)建。

通過(guò)編寫(xiě)Dockerfile生磁鏡像,可以為開(kāi)發(fā)、測(cè)試團(tuán)隊(duì)提供基本一致的環(huán)境,從而提升開(kāi)發(fā)、測(cè)試團(tuán)隊(duì)的效率,不用再為環(huán)境不統(tǒng)一而發(fā)愁,同時(shí)運(yùn)維也能更加方便地管理我們的鏡像。

Dockerfile的語(yǔ)法非常簡(jiǎn)單,常用的只有11個(gè):

2.1 編寫(xiě)優(yōu)雅地Dockerfile

編寫(xiě)優(yōu)雅的Dockerfile主要需要注意以下幾點(diǎn):

Dockerfile文件不宜過(guò)長(zhǎng),層級(jí)越多最終制作出來(lái)的鏡像也就越大。

構(gòu)建出來(lái)的鏡像不要包含不需要的內(nèi)容,如日志、安裝臨時(shí)文件等。

盡量使用運(yùn)行時(shí)的基礎(chǔ)鏡像,不需要將構(gòu)建時(shí)的過(guò)程也放到運(yùn)行時(shí)的Dockerfile里。

只要記住以上三點(diǎn)就能寫(xiě)出不錯(cuò)的Dockerfile。

為了方便大家了解,我們用兩個(gè)Dockerfile實(shí)例進(jìn)行簡(jiǎn)單的對(duì)比:

FROM ubuntu:16.04
RUN apt-get update
RUN apt-get install -y apt-utils libjpeg-dev      
python-pip
RUN pip install --upgrade pip
RUN easy_install -U setuptools
RUN apt-get clean
FROM ubuntu:16.04
RUN apt-get update && apt-get install -y apt-utils 
  libjpeg-dev python-pip 
           && pip install --upgrade pip 
      && easy_install -U setuptools 
    && apt-get clean

我們看第一個(gè)Dockerfile,乍一看條理清晰,結(jié)構(gòu)合理,似乎還不錯(cuò)。再看第二個(gè)Dockerfile,緊湊,不易閱讀,為什么要這么寫(xiě)?

第一個(gè)Dockerfile的好處是:當(dāng)正在執(zhí)行的過(guò)程某一層出錯(cuò),對(duì)其進(jìn)行修正后再次Build,前面已經(jīng)執(zhí)行完成的層不會(huì)再次執(zhí)行。這樣能大大減少下次Build的時(shí)間,而它的問(wèn)題就是會(huì)因?qū)蛹?jí)變多了而使鏡像占用的空間也變大。

第二個(gè)Dockerfile把所有的組件全部在一層解決,這樣做能一定程度上減少鏡像的占用空間,但在制作基礎(chǔ)鏡像的時(shí)候若其中某個(gè)組編譯出錯(cuò),修正后再次Build就相當(dāng)于重頭再來(lái)了,前面編譯好的組件在一個(gè)層里,得全部都重新編譯一遍,比較消耗時(shí)間。

從下表可以看出兩個(gè)Dockerfile所編譯出來(lái)的鏡像大小:

$ docker images | grep ubuntu      
REPOSITORY      TAG     IMAGE ID    CREATED     SIZE                                                                                                                                   
ubuntu                   16.04       9361ce633ff1  1 days ago 422MB
ubuntu                   16.04-1   3f5b979df1a9  1 days ago  412MB

呃…. 好像并沒(méi)有特別的效果,但若Dockerfile非常長(zhǎng)的話可以考慮減少層次,因?yàn)镈ockerfile最高只能有127層。

三、使用多階構(gòu)建

Docker在升級(jí)到Docker 17.05之后就能支持多階構(gòu)建了,為了使鏡像更加小巧,我們采用多階構(gòu)建的方式來(lái)打包鏡像。在多階構(gòu)建出現(xiàn)之前我們通常使用一個(gè)Dockerfile或多個(gè)Dockerfile來(lái)構(gòu)建鏡像。

3.1單文件構(gòu)建

在多階構(gòu)建出來(lái)之前使用單個(gè)文件進(jìn)行構(gòu)建,單文件就是將所有的構(gòu)建過(guò)程(包括項(xiàng)目的依賴、編譯、測(cè)試、打包過(guò)程)全部包含在一個(gè)Dockerfile中之下:

FROM golang:1.11.4-alpine3.8 AS build-env
ENV GO111MODULE=off
ENV GO15VENDOREXPERIMENT=1
ENV BUILDPATH=github.com/lattecake/hello
RUN mkdir -p /go/src/${BUILDPATH}
COPY ./ /go/src/${BUILDPATH}
RUN cd /go/src/${BUILDPATH} && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go install –v

CMD [/go/bin/hello]

這種的做法會(huì)帶來(lái)一些問(wèn)題:

Dockerfile文件會(huì)特別長(zhǎng),當(dāng)需要的東西越來(lái)越多的時(shí)候可維護(hù)性指數(shù)級(jí)將會(huì)下降;

鏡像層次過(guò)多,鏡像的體積會(huì)逐步增大,部署也會(huì)變得越來(lái)越慢;

代碼存在泄漏風(fēng)險(xiǎn)。

以Golang為例,它運(yùn)行時(shí)不依賴任何環(huán)境,只需要有一個(gè)編譯環(huán)境,那這個(gè)編譯環(huán)境在實(shí)際運(yùn)行時(shí)是沒(méi)有任務(wù)作用的,編譯完成后,那些源碼和編譯器已經(jīng)沒(méi)有任務(wù)用處了也就沒(méi)必要留在鏡像里。

上表可以看到,單文件構(gòu)建最終占用了312MB的空間。

3.2 多文件構(gòu)建

在多階構(gòu)建出來(lái)之前有沒(méi)有好的解決方案呢?有,比如采用多文件構(gòu)建或在構(gòu)建服務(wù)器上安裝編譯器,不過(guò)在構(gòu)建服務(wù)器上安裝編譯器這種方法我們就不推薦了,因?yàn)樵跇?gòu)建服務(wù)器上安裝編譯器會(huì)導(dǎo)致構(gòu)建服務(wù)器變得非常臃腫,需要適配各個(gè)語(yǔ)言多個(gè)版本、依賴,容易出錯(cuò),維護(hù)成本高。所以我們只介紹多文件構(gòu)建的方式。

多文件構(gòu)建,其實(shí)就是使用多個(gè)Dockerfile,然后通過(guò)腳本將它們進(jìn)行組合。假設(shè)有三個(gè)文件分別是:Dockerfile.run、Dockerfile.build、build.sh。

Dockerfile.run就是運(yùn)行時(shí)程序所必須需要的一些組件的Dockerfile,它包含了最精簡(jiǎn)的庫(kù);

Dockerfile.build只是用來(lái)構(gòu)建,構(gòu)建完就沒(méi)用了;

build.sh的功能就是將Dockerfile.run和Dockerfile.build進(jìn)行組成,把Dockerfile.build構(gòu)建好的東西拿出來(lái),然后再執(zhí)行Dockerfile.run,算是一個(gè)調(diào)度的角色。

Dockerfile.build

FROM golang:1.11.4-alpine3.8 AS build-env
ENV GO111MODULE=off
ENV GO15VENDOREXPERIMENT=1
ENV BUILDPATH=github.com/lattecake/hello
RUN mkdir -p /go/src/${BUILDPATH}
COPY ./ /go/src/${BUILDPATH}
RUN cd /go/src/${BUILDPATH} && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go install –v

Dockerfile.run

FROM alpine:latest
RUN apk –no-cache add ca-certificates
WORKDIR /root
ADD hello .
CMD ["./hello"]

Build.sh

#!/bin/sh
docker build -t –rm hello:build . -f Dockerfile.build
docker create –name extract hello:build
docker cp extract:/go/bin/hello ./hello
docker rm -f extract
docker build –no-cache -t –rm hello:run . -f Dockerfile.run
rm -rf ./hello

執(zhí)行build.sh完成項(xiàng)目的構(gòu)建。

從上表可以看到,多文件構(gòu)建大大減小了鏡像的占用空間,但它有三個(gè)文件需要管理,維護(hù)成本也更高一些。

3.3 多階構(gòu)建

最后我們來(lái)看看萬(wàn)眾期待的多階構(gòu)建。

完成多階段構(gòu)建我們只需要在Dockerfile中多次使用FORM聲明,每次FROM指令可以使用不同的基礎(chǔ)鏡像,并且每次FROM指令都會(huì)開(kāi)始新的構(gòu)建,我們可以選擇將一個(gè)階段的構(gòu)建結(jié)果復(fù)制到另一個(gè)階段,在最終的鏡像中只會(huì)留下最后一次構(gòu)建的結(jié)果,這樣就可以很容易地解決前面提到的問(wèn)題,并且只需要編寫(xiě)一個(gè)Dockerfile文件。這里值得注意的是:需要確保Docker的版本在17.05及以上。下面我們來(lái)說(shuō)說(shuō)具體操作。

在Dockerfile里可以使用as來(lái)為某一階段取一個(gè)別名”build-env”:

FROM golang:1.11.2-alpine3.8 AS build-env

然后從上一階段的鏡像中復(fù)制文件,也可以復(fù)制任意鏡像中的文件:

COPY –from=build-env /go/bin/hello /usr/bin/hello 

看一個(gè)簡(jiǎn)單的例子:

FROM golang:1.11.4-alpine3.8 AS build-env
 
ENV GO111MODULE=off
ENV GO15VENDOREXPERIMENT=1
ENV GITPATH=github.com/lattecake/hello
RUN mkdir -p /go/src/${GITPATH}
COPY ./ /go/src/${GITPATH}
RUN cd /go/src/${GITPATH} && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go install -v
 
FROM alpine:latest
ENV apk –no-cache add ca-certificates
COPY --from=build-env /go/bin/hello /root/hello
WORKDIR /root
CMD ["/root/hello"]

執(zhí)行docker build -t –rm hello3 .后再執(zhí)行docker images ,然后我們來(lái)看鏡像的大小:

多階構(gòu)建給我們帶來(lái)很多便利,最大的優(yōu)勢(shì)是在保證運(yùn)行鏡像足夠小的情況下還減輕了Dockerfile的維護(hù)負(fù)擔(dān),因此我們極力推薦使用多階構(gòu)建來(lái)將你的代碼打包成Docker 鏡像。

作者:王聰

內(nèi)容來(lái)源:宜信技術(shù)學(xué)院

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/27806.html

相關(guān)文章

  • PHP下如何優(yōu)雅使用Docker來(lái)構(gòu)建環(huán)境(二)

    摘要:指令這條命令是指明最后容器需要暴露哪些端口號(hào),這樣其他系統(tǒng)才能使用這個(gè)端口。但是靈活性不高,后面我在編排的時(shí)候會(huì)教大家用編排來(lái)統(tǒng)一開(kāi)發(fā)環(huán)境。更多還有更多指令大家看下官方文檔,我自己覺(jué)得上面的指令算是使用比較多的了。 前言 上一篇文章呢,我們簡(jiǎn)單的了解了Docker的基本命令,這篇文章呢,我們來(lái)了解下Dockerfile這個(gè)文件。 一個(gè)神奇的文件:Dockerfile 我不知道有多少同學(xué)...

    longshengwang 評(píng)論0 收藏0
  • PHP下如何優(yōu)雅使用Docker來(lái)構(gòu)建環(huán)境(二)

    摘要:指令這條命令是指明最后容器需要暴露哪些端口號(hào),這樣其他系統(tǒng)才能使用這個(gè)端口。但是靈活性不高,后面我在編排的時(shí)候會(huì)教大家用編排來(lái)統(tǒng)一開(kāi)發(fā)環(huán)境。更多還有更多指令大家看下官方文檔,我自己覺(jué)得上面的指令算是使用比較多的了。 前言 上一篇文章呢,我們簡(jiǎn)單的了解了Docker的基本命令,這篇文章呢,我們來(lái)了解下Dockerfile這個(gè)文件。 一個(gè)神奇的文件:Dockerfile 我不知道有多少同學(xué)...

    jollywing 評(píng)論0 收藏0
  • Dockerfile 與 Compose 環(huán)境搭建學(xué)習(xí)筆記(一)

    摘要:的主要作用是自己根據(jù)基礎(chǔ)鏡像,重新定制鏡像,而不是直接從官方倉(cāng)庫(kù)拿現(xiàn)成的使用。以接下來(lái)要構(gòu)建的環(huán)境來(lái)說(shuō)明下,下面我將要搭建一個(gè)的開(kāi)發(fā)環(huán)境,需要進(jìn)行配合。它的主要作用是持久化數(shù)據(jù),避免容器銷毀后內(nèi)部數(shù)據(jù)丟失暴露到宿主機(jī)的端口。 以前一直使用 Vagrant 作為自己的開(kāi)發(fā)環(huán)境,并且在上家公司也推行大家采用 Vagrant 作為開(kāi)發(fā)環(huán)境,保障公司使用的是同一套開(kāi)發(fā)環(huán)境。隨著docker的流...

    TZLLOG 評(píng)論0 收藏0
  • Dockerfile 與 Compose 環(huán)境搭建學(xué)習(xí)筆記(一)

    摘要:的主要作用是自己根據(jù)基礎(chǔ)鏡像,重新定制鏡像,而不是直接從官方倉(cāng)庫(kù)拿現(xiàn)成的使用。以接下來(lái)要構(gòu)建的環(huán)境來(lái)說(shuō)明下,下面我將要搭建一個(gè)的開(kāi)發(fā)環(huán)境,需要進(jìn)行配合。它的主要作用是持久化數(shù)據(jù),避免容器銷毀后內(nèi)部數(shù)據(jù)丟失暴露到宿主機(jī)的端口。 以前一直使用 Vagrant 作為自己的開(kāi)發(fā)環(huán)境,并且在上家公司也推行大家采用 Vagrant 作為開(kāi)發(fā)環(huán)境,保障公司使用的是同一套開(kāi)發(fā)環(huán)境。隨著docker的流...

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

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

0條評(píng)論

閱讀需要支付1元查看
<