丝袜人妻一区二区三区_少妇福利无码视频_亚洲理论片在线观看_一级毛片国产A级片

678改動(dòng)日志看這里!三個(gè)技巧,教你將Docker鏡像體積減小90%|優(yōu)化調(diào)優(yōu)

概述

創(chuàng)建Docker容器時(shí),傳輸和分發(fā)卷較小的鏡像速度更快,因此必須找到獲得盡可能小的鏡像的方法。

但RUN語(yǔ)句總是會(huì)創(chuàng)建一個(gè)新層,而且在生成鏡像之前還需要使用很多中間文件,在這種情況下,該如何獲得體積更小的鏡像呢?

你可能已經(jīng)注意到了,大多數(shù)Dockerfiles都使用了一些奇怪的技巧:

FROM ubuntu RUN apt-get update && apt-get install vim

為什么使用&&?而不是使用兩個(gè)RUN語(yǔ)句代替呢?比如:

FROM ubuntu RUN apt-get update RUN apt-get install vim

從Docker 1.10開(kāi)始,COPY、ADD和RUN語(yǔ)句會(huì)向鏡像中添加新層。前面的示例創(chuàng)建了兩個(gè)層而不是一個(gè)。

鏡像的層就像Git的提交(commit)一樣。

Docker的層用于保存鏡像的上一版本和當(dāng)前版本之間的差異。就像Git的提交一樣,如果你與其他存儲(chǔ)庫(kù)或鏡像共享它們,就會(huì)很方便。

實(shí)際上,當(dāng)你向注冊(cè)表請(qǐng)求鏡像時(shí),只是下載你尚未擁有的層。這是一種非常高效地共享鏡像的方式。

但額外的層并不是沒(méi)有代價(jià)的。

層仍然會(huì)占用空間,你擁有的層越多,最終的鏡像就越大。Git存儲(chǔ)庫(kù)在這方面也是類似的,存儲(chǔ)庫(kù)的大小隨著層數(shù)的增加而增加,因?yàn)镚it必須保存提交之間的所有變更。

過(guò)去,將多個(gè)RUN語(yǔ)句組合在一行命令中或許是一種很好的做法,就像上面的第一個(gè)例子那樣,但在現(xiàn)在看來(lái),這樣做并不妥。


1. 通過(guò)Docker多階段構(gòu)建將多個(gè)層壓縮為一個(gè)

當(dāng)Git存儲(chǔ)庫(kù)變大時(shí),你可以選擇將歷史提交記錄壓縮為單個(gè)提交。

事實(shí)證明,在Docker中也可以使用多階段構(gòu)建達(dá)到類似的目的。

在這個(gè)示例中,你將構(gòu)建一個(gè)Node.js容器。

從index.js開(kāi)始:

const express = require('express') const app = express() a('/', (req, res) => res.send('Hello World!')) a(3000, () => { con(`Example app listening on port 3000!`) })

和:

{ "name": "hello-world", "version": "1.0.0", "main": "index.js", "dependencies": { "express": "^4.16.2" }, "scripts": { "start": "node index.js" } }

你可以使用下面的Dockerfile來(lái)打包這個(gè)應(yīng)用程序:

FROM node:8 EXPOSE 3000 WORKDIR /app COPY index.js ./ RUN npm install CMD ["npm", "start"]

然后開(kāi)始構(gòu)建鏡像:

$ docker build -t node-vanilla .

然后用以下方法驗(yàn)證它是否可以正常運(yùn)行:

$ docker run -p 3000:3000 -ti --rm --init node-vanilla

你應(yīng)該能訪問(wèn)http://localhost:3000,并收到“Hello World!”。

Dockerfile中使用了一個(gè)COPY語(yǔ)句和一個(gè)RUN語(yǔ)句,所以按照預(yù)期,新鏡像應(yīng)該比基礎(chǔ)鏡像多出至少兩個(gè)層:

$ docker history node-vanilla IMAGE CREATED BY SIZE 075d229d3f48 /bin/sh -c #(nop) CMD ["npm" "start"] 0B bc8c3cc813ae /bin/sh -c npm install 2.91MB bac31afb6f42 /bin/sh -c #(nop) COPY multi:3071ddd474429e1… 364B 500a9fbef90e /bin/sh -c #(nop) WORKDIR /app 0B 78b28027dfbf /bin/sh -c #(nop) EXPOSE 3000 0B b87c2ad8344d /bin/sh -c #(nop) CMD ["node"] 0B <missing> /bin/sh -c set -ex && for key in 6A010… 4.17MB <missing> /bin/sh -c #(nop) ENV YARN_VERSION=1.3.2 0B <missing> /bin/sh -c ARCH= && dpkgArch="$(dpkg --print… 56.9MB <missing> /bin/sh -c #(nop) ENV NODE_VERSION=8.9.4 0B <missing> /bin/sh -c set -ex && for key in 94AE3… 129kB <missing> /bin/sh -c groupadd --gid 1000 node && use… 335kB <missing> /bin/sh -c set -ex; apt-get update; apt-ge… 324MB <missing> /bin/sh -c apt-get update && apt-get install… 123MB <missing> /bin/sh -c set -ex; if ! command -v gpg > /… 0B <missing> /bin/sh -c apt-get update && apt-get install… 44.6MB <missing> /bin/sh -c #(nop) CMD ["bash"] 0B <missing> /bin/sh -c #(nop) ADD file:1dd78a123212328bd… 123MB

但實(shí)際上,生成的鏡像多了五個(gè)新層:每一個(gè)層對(duì)應(yīng)Dockerfile里的一個(gè)語(yǔ)句。

現(xiàn)在,讓我們來(lái)試試Docker的多階段構(gòu)建。

你可以繼續(xù)使用與上面相同的Dockerfile,只是現(xiàn)在要調(diào)用兩次:

FROM node:8 as build WORKDIR /app COPY index.js ./ RUN npm install FROM node:8 COPY --from=build /app / EXPOSE 3000 CMD ["index.js"]

Dockerfile的第一部分創(chuàng)建了三個(gè)層,然后這些層被合并并復(fù)制到第二個(gè)階段。在第二階段,鏡像頂部又添加了額外的兩個(gè)層,所以總共是三個(gè)層。

現(xiàn)在來(lái)驗(yàn)證一下。首先,構(gòu)建容器:

$ docker build -t node-multi-stage .

查看鏡像的歷史:

$ docker history node-multi-stage IMAGE CREATED BY SIZE 331b81a245b1 /bin/sh -c #(nop) CMD ["index.js"] 0B bdfc932314af /bin/sh -c #(nop) EXPOSE 3000 0B f8992f6c62a6 /bin/sh -c #(nop) COPY dir:e2b57dff89be62f77… 1.62MB b87c2ad8344d /bin/sh -c #(nop) CMD ["node"] 0B <missing> /bin/sh -c set -ex && for key in 6A010… 4.17MB <missing> /bin/sh -c #(nop) ENV YARN_VERSION=1.3.2 0B <missing> /bin/sh -c ARCH= && dpkgArch="$(dpkg --print… 56.9MB <missing> /bin/sh -c #(nop) ENV NODE_VERSION=8.9.4 0B <missing> /bin/sh -c set -ex && for key in 94AE3… 129kB <missing> /bin/sh -c groupadd --gid 1000 node && use… 335kB <missing> /bin/sh -c set -ex; apt-get update; apt-ge… 324MB <missing> /bin/sh -c apt-get update && apt-get install… 123MB <missing> /bin/sh -c set -ex; if ! command -v gpg > /… 0B <missing> /bin/sh -c apt-get update && apt-get install… 44.6MB <missing> /bin/sh -c #(nop) CMD ["bash"] 0B <missing> /bin/sh -c #(nop) ADD file:1dd78a123212328bd… 123MB

文件大小是否已發(fā)生改變?

$ docker images | grep node- node-multi-stage 331b81a245b1 678MB node-vanilla 075d229d3f48 679MB

最后一個(gè)鏡像(node-multi-stage)更小一些。

你已經(jīng)將鏡像的體積減小了,即使它已經(jīng)是一個(gè)很小的應(yīng)用程序。

但整個(gè)鏡像仍然很大!

有什么辦法可以讓它變得更小嗎?


2. 用distroless去除容器中所有不必要的東西

這個(gè)鏡像包含了Node.js以及yarn、npm、bash和其他的二進(jìn)制文件。因?yàn)樗彩腔赨buntu的,所以你等于擁有了一個(gè)完整的操作系統(tǒng),其中包括所有的小型二進(jìn)制文件和實(shí)用程序。

但在運(yùn)行容器時(shí)是不需要這些東西的,你需要的只是Node.js。

Docker容器應(yīng)該只包含一個(gè)進(jìn)程以及用于運(yùn)行這個(gè)進(jìn)程所需的最少的文件,你不需要整個(gè)操作系統(tǒng)。

實(shí)際上,你可以刪除Node.js之外的所有內(nèi)容。

但要怎么做?

所幸的是,谷歌為我們提供了distroless。

以下是distroless存儲(chǔ)庫(kù)的描述:

“distroless”鏡像只包含應(yīng)用程序及其運(yùn)行時(shí)依賴項(xiàng),不包含程序包管理器、shell以及在標(biāo)準(zhǔn)Linux發(fā)行版中可以找到的任何其他程序。

這正是你所需要的!

你可以對(duì)Dockerfile進(jìn)行調(diào)整,以利用新的基礎(chǔ)鏡像,如下所示:

FROM node:8 as build WORKDIR /app COPY index.js ./ RUN npm install FROM gcr.io/distroless/nodejs COPY --from=build /app / EXPOSE 3000 CMD ["index.js"]

你可以像往常一樣編譯鏡像:

$ docker build -t node-distroless .

這個(gè)鏡像應(yīng)該能正常運(yùn)行。要驗(yàn)證它,可以像這樣運(yùn)行容器:

$ docker run -p 3000:3000 -ti --rm --init node-distroless

現(xiàn)在可以訪問(wèn)http://localhost:3000頁(yè)面。

不包含其他額外二進(jìn)制文件的鏡像是不是小多了?

$ docker images | grep node-distroless node-distroless 7b4db3b7f1e5 76.7MB

只有76.7MB!

比之前的鏡像小了600MB!

但在使用distroless時(shí)有一些事項(xiàng)需要注意。

當(dāng)容器在運(yùn)行時(shí),如果你想要檢查它,可以使用以下命令attach到正在運(yùn)行的容器上:

$ docker exec -ti <insert_docker_id> bash

attach到正在運(yùn)行的容器并運(yùn)行bash命令就像是建立了一個(gè)SSH會(huì)話一樣。

但distroless版本是原始操作系統(tǒng)的精簡(jiǎn)版,沒(méi)有了額外的二進(jìn)制文件,所以容器里沒(méi)有shell!

在沒(méi)有shell的情況下,如何attach到正在運(yùn)行的容器呢?

答案是,你做不到。這既是個(gè)壞消息,也是個(gè)好消息。

之所以說(shuō)是壞消息,因?yàn)槟阒荒茉谌萜髦袌?zhí)行二進(jìn)制文件。你可以運(yùn)行的唯一的二進(jìn)制文件是Node.js:

$ docker exec -ti <insert_docker_id> node

說(shuō)它是個(gè)好消息,是因?yàn)槿绻粽呃媚愕膽?yīng)用程序獲得對(duì)容器的訪問(wèn)權(quán)限將無(wú)法像訪問(wèn)shell那樣造成太多破壞。換句話說(shuō),更少的二進(jìn)制文件意味著更小的體積和更高的安全性,不過(guò)這是以痛苦的調(diào)試為代價(jià)的。

或許你不應(yīng)在生產(chǎn)環(huán)境中attach和調(diào)試容器,而應(yīng)該使用日志和監(jiān)控。

但如果你確實(shí)需要調(diào)試,又想保持小體積該怎么辦?


3. 小體積的Alpine基礎(chǔ)鏡像

你可以使用Alpine基礎(chǔ)鏡像替換distroless基礎(chǔ)鏡像。

Alpine Linux是:

一個(gè)基于musl libc和busybox的面向安全的輕量級(jí)Linux發(fā)行版。

換句話說(shuō),它是一個(gè)體積更小也更安全的Linux發(fā)行版。

不過(guò)你不應(yīng)該理所當(dāng)然地認(rèn)為他們聲稱的就一定是事實(shí),讓我們來(lái)看看它的鏡像是否更小。

先修改Dockerfile,讓它使用node:8-alpine:

FROM node:8 as build WORKDIR /app COPY index.js ./ RUN npm install FROM node:8-alpine COPY --from=build /app / EXPOSE 3000 CMD ["npm", "start"]

使用下面的命令構(gòu)建鏡像:

$ docker build -t node-alpine .

現(xiàn)在可以檢查一下鏡像大小:

$ docker images | grep node-alpine node-alpine aa1f85f8e724 69.7MB 69.7MB!

甚至比distrless鏡像還??!

現(xiàn)在可以attach到正在運(yùn)行的容器嗎?讓我們來(lái)試試。

讓我們先啟動(dòng)容器:

$ docker run -p 3000:3000 -ti --rm --init node-alpine Example app listening on port 3000!

你可以使用以下命令attach到運(yùn)行中的容器:

$ docker exec -ti 9d8e97e307d7 bash OCI runtime exec failed: exec failed: container_linux.go:296: starting container process caused "exec: \"bash\": executable file not found in $PATH": unknown

看來(lái)不行,但或許可以使用shell?

$ docker exec -ti 9d8e97e307d7 sh / #

成功了!現(xiàn)在可以attach到正在運(yùn)行的容器中了。

看起來(lái)很有希望,但還有一個(gè)問(wèn)題。

Alpine基礎(chǔ)鏡像是基于muslc的——C語(yǔ)言的一個(gè)替代標(biāo)準(zhǔn)庫(kù),而大多數(shù)Linux發(fā)行版如Ubuntu、Debian和CentOS都是基于glibc的。這兩個(gè)庫(kù)應(yīng)該實(shí)現(xiàn)相同的內(nèi)核接口。

但它們的目的是不一樣的:

glibc更常見(jiàn),速度也更快;

muslc使用較少的空間,并側(cè)重于安全性。

在編譯應(yīng)用程序時(shí),大部分都是針對(duì)特定的libc進(jìn)行編譯的。如果你要將它們與另一個(gè)libc一起使用,則必須重新編譯它們。

換句話說(shuō),基于Alpine基礎(chǔ)鏡像構(gòu)建容器可能會(huì)導(dǎo)致非預(yù)期的行為,因?yàn)闃?biāo)準(zhǔn)C庫(kù)是不一樣的。

你可能會(huì)注意到差異,特別是當(dāng)你處理預(yù)編譯的二進(jìn)制文件(如Node.js C++擴(kuò)展)時(shí)。

例如,PhantomJS的預(yù)構(gòu)建包就不能在Alpine上運(yùn)行。

你應(yīng)該選擇哪個(gè)基礎(chǔ)鏡像?

你應(yīng)該使用Alpine、distroless還是原始鏡像?

如果你是在生產(chǎn)環(huán)境中運(yùn)行容器,并且更關(guān)心安全性,那么可能distroless鏡像更合適。

添加到Docker鏡像的每個(gè)二進(jìn)制文件都會(huì)給整個(gè)應(yīng)用程序增加一定的風(fēng)險(xiǎn)。

只在容器中安裝一個(gè)二進(jìn)制文件可以降低總體風(fēng)險(xiǎn)。

例如,如果攻擊者能夠利用運(yùn)行在distroless上的應(yīng)用程序的漏洞,他們將無(wú)法在容器中使用shell,因?yàn)槟抢锔揪蜎](méi)有shell!

請(qǐng)注意,OWASP本身就建議盡量減少攻擊表面。

如果你只關(guān)心更小的鏡像體積,那么可以考慮基于Alpine的鏡像。

它們的體積非常小,但代價(jià)是兼容性較差。Alpine使用了略微不同的標(biāo)準(zhǔn)C庫(kù)——muslc。你可能會(huì)時(shí)不時(shí)地遇到一些兼容性問(wèn)題。

原始基礎(chǔ)鏡像非常適合用于測(cè)試和開(kāi)發(fā)。

它雖然體積很大,但提供了與Ubuntu工作站一樣的體驗(yàn)。此外,你還可以訪問(wèn)操作系統(tǒng)的所有二進(jìn)制文件。

再回顧一下各個(gè)鏡像的大?。?/p>node:8 681MB node:8 使用多階段構(gòu)建為678MB gcr.io/distroless/nodejs 76.7MB node:8-alpine 69.7MB


文章很長(zhǎng),但是很實(shí)用,玩docker必會(huì),覺(jué)得有用的話幫忙點(diǎn)贊轉(zhuǎn)發(fā)哦。

后面會(huì)分享更多關(guān)于自動(dòng)化運(yùn)維(devops)內(nèi)容,感興趣的朋友可以關(guān)注下~

1.《678改動(dòng)日志看這里!三個(gè)技巧,教你將Docker鏡像體積減小90%|優(yōu)化調(diào)優(yōu)》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識(shí),僅代表作者本人觀點(diǎn),與本網(wǎng)站無(wú)關(guān),侵刪請(qǐng)聯(lián)系頁(yè)腳下方聯(lián)系方式。

2.《678改動(dòng)日志看這里!三個(gè)技巧,教你將Docker鏡像體積減小90%|優(yōu)化調(diào)優(yōu)》僅供讀者參考,本網(wǎng)站未對(duì)該內(nèi)容進(jìn)行證實(shí),對(duì)其原創(chuàng)性、真實(shí)性、完整性、及時(shí)性不作任何保證。

3.文章轉(zhuǎn)載時(shí)請(qǐng)保留本站內(nèi)容來(lái)源地址,http://f99ss.com/gl/2078268.html

上一篇

《王者榮耀》全英雄符文搭配

下一篇

【dota270】專題DOTA2 6.84版本來(lái)襲 新增8個(gè)道具 全英雄改動(dòng)

【678改動(dòng)日志】開(kāi)賭場(chǎng)要退贓678萬(wàn)拒不執(zhí)行,名下141個(gè)ZIPPO打火機(jī)、多個(gè)大牌手表1元起拍

【678改動(dòng)日志】開(kāi)賭場(chǎng)要退贓678萬(wàn)拒不執(zhí)行,名下141個(gè)ZIPPO打火機(jī)、多個(gè)大牌手表1元起拍

678改動(dòng)日志相關(guān)介紹,錢江晚報(bào)時(shí)間記者黃偉芬 阿里拍賣中經(jīng)常出現(xiàn)1元拍賣資產(chǎn),包括11月16日浙江省瀘州市龍游縣人民法院在阿里拍賣中處置一輛車牌號(hào)為Ria A00 K7N的白色寶馬轎車。 車子估價(jià)39萬(wàn),起拍價(jià)1元,最后以...

678改動(dòng)日志看這里!開(kāi)賭場(chǎng)要退贓678萬(wàn)拒不執(zhí)行,名下141個(gè)ZIPPO打火機(jī)、多個(gè)大牌手表1元起拍

678改動(dòng)日志看這里!開(kāi)賭場(chǎng)要退贓678萬(wàn)拒不執(zhí)行,名下141個(gè)ZIPPO打火機(jī)、多個(gè)大牌手表1元起拍

678改動(dòng)日志相關(guān)介紹,錢江晚報(bào)時(shí)間記者黃偉芬 阿里拍賣中經(jīng)常出現(xiàn)1元拍賣資產(chǎn),包括11月16日浙江省瀘州市龍游縣人民法院在阿里拍賣中處置一輛車牌號(hào)為Ria A00 K7N的白色寶馬轎車。 車子估價(jià)39萬(wàn),起拍價(jià)1元,最后以...

【678改動(dòng)日志】專題e8c現(xiàn)場(chǎng)常見(jiàn)問(wèn)題分析

【678改動(dòng)日志】專題e8c現(xiàn)場(chǎng)常見(jiàn)問(wèn)題分析

678改動(dòng)日志相關(guān)介紹,主要介紹E8-C故障診斷的思路和方法。 1.E8-C簡(jiǎn)介 E8-C是中國(guó)電信定制的家庭智能終端設(shè)備,其優(yōu)點(diǎn)是通過(guò)ITMS(集成終端管理系統(tǒng))部署多種業(yè)務(wù)的遠(yuǎn)程配置,并遠(yuǎn)程管理終端。 可以向用戶提供基于...

【678改動(dòng)日志】專題大數(shù)據(jù)開(kāi)發(fā)之HBase異常問(wèn)題分析

【678改動(dòng)日志】專題大數(shù)據(jù)開(kāi)發(fā)之HBase異常問(wèn)題分析

678改動(dòng)日志相關(guān)介紹,1.問(wèn)題現(xiàn)象和原因概述 我們行Hadoop群集生產(chǎn)環(huán)境中的Hbase在7月7月和8月部分請(qǐng)求響應(yīng)速度慢,出現(xiàn)了數(shù)據(jù)不一致,通過(guò)分析,問(wèn)題的主要原因有兩個(gè)。 1)網(wǎng)卡已滿,請(qǐng)求響應(yīng)緩慢: 從群集服務(wù)器在...

678改動(dòng)日志專題之Flink 最佳實(shí)踐之使用 Canal 同步 MySQL 數(shù)據(jù)至 TiDB

678改動(dòng)日志專題之Flink 最佳實(shí)踐之使用 Canal 同步 MySQL 數(shù)據(jù)至 TiDB

678改動(dòng)日志相關(guān)介紹,一.背景介紹 本文介紹了將MySQL中的數(shù)據(jù)通過(guò)Binlog Canal導(dǎo)入Kafka,然后由Flink消耗的情況。 為了能夠快速的驗(yàn)證整套流程的功能性,所有的組件都以單機(jī)的形式部署。如果手上的物理資...

678改動(dòng)日志看這里!Flink 最佳實(shí)踐之使用 Canal 同步 MySQL 數(shù)據(jù)至 TiDB

678改動(dòng)日志看這里!Flink 最佳實(shí)踐之使用 Canal 同步 MySQL 數(shù)據(jù)至 TiDB

678改動(dòng)日志相關(guān)介紹,一. 背景介紹 本文將介紹如何將 MySQL 中的數(shù)據(jù),通過(guò) Binlog + Canal 的形式導(dǎo)入到 Kafka 中,繼而被 Flink 消費(fèi)的案例。 達(dá)到當(dāng)天最大量API KEY 超過(guò)次數(shù)限制 ...

關(guān)于678改動(dòng)日志我想說(shuō)第84章 春風(fēng)行動(dòng)

關(guān)于678改動(dòng)日志我想說(shuō)第84章 春風(fēng)行動(dòng)

678改動(dòng)日志相關(guān)介紹,“謝謝大家熱烈的掌聲,今天面對(duì)各位前輩和老師,雷倩倩的身份首先是一名學(xué)生,請(qǐng)?jiān)试S我向各位尊敬的師長(zhǎng)致敬!” 雷倩倩起立,她走到講臺(tái)中央,向在座的廣大教育工作者,深深鞠躬! “正因?yàn)槲沂紫仁且幻麑W(xué)生,所...

678改動(dòng)日志看這里!記一次 .NET 某紡織工廠 MES系統(tǒng) API 掛死分析

678改動(dòng)日志看這里!記一次 .NET 某紡織工廠 MES系統(tǒng) API 掛死分析

678改動(dòng)日志相關(guān)介紹,一、背景 1.講故事 這個(gè)月中旬,一個(gè)朋友向我求助wx的程序線程份額很高,探討了如何解決。屏幕截圖如下: 說(shuō)實(shí)話,和其他行業(yè)的程序員聊天還是很有趣的,可以交朋友,擴(kuò)大自己的圈子。朋友說(shuō),因?yàn)檫@個(gè)bug...