微容器 更小的,更輕便的Docker容器

2021-09-23 00:09:26 字數 3159 閱讀 1925

本文講的是微容器:更小的,更輕便的docker容器

【編者的話】本文介紹了微容器的概念和好處,並用一些例子介紹了如何構建微映象,從scratch到alpine linux,並推薦了一些已有的基礎微映象,方便為幾乎所有主流語言的應用構建微映象。本文也指出了構建微映象的基本原理:將構建時依賴和執行時依賴分開,構建時所用的映象包含所有構建所用的工具,它可以比較大,但執行時的基礎映象應該僅包含執行時依賴。使用微容器,

no going back!

docker

使你能把你的應用和應用的依賴打包到乙個良好的自包含映象中。然後你可以用該那個映象來在容器中執行你的應用。問題是,你通常也打包了一些你可能不需要比你需要的更多的東西,最終座椅最重你得到了乙個巨大的映象和巨大的容器。大多數開始使用docker的人會使用docker的

官方倉庫

作為他們的語言的選擇,但是不幸的是,如果你使用官方映象,你會得到乙個巨大的映象,而本來你可以得到乙個小映象的。你並不需要和這些官方映象中一起的許多複雜的東西。例如,如果你使用

官方的node映象

構建乙個你的應用的node的映象,它至少有643mb大,因為這是

官方node映象的大小

。我構建了乙個簡單的

hello world node 應用

,在官方node映象上構建,它的大小是644mb。

這太大了!我的應用加上依賴也不超過1mb,node.js的執行時大概20mb,那是什麼佔據了剩下的620mb?我們應該能做得更好。

乙個微容器僅包含os庫和執行應用所需要的語言依賴以及應用本身。其他都不需要。

與其包含所有,不如僅包含最基本的,在需要的時候新增依賴。

以上面的node應用為例,使用乙個小的基礎映象,然後安裝核心的部分,即node.js和它的依賴,它只有29mb,小了22倍(見下圖)!

如果你想,現在試試執行這兩個映象,docker run –rm -p 8080:8080 treeder/tiny-node:fat然後docker run –rm -p 8080:8080 treeder/tiny-node:latest。完全一樣的應用,而大小大不相同。

有許多使用微容器的好處:

這些好處和

unikernels

的好處類似,沒有任何缺點。

所有docker映象的基礎映象是

scratch

映象。它本質上什麼都沒有。聽起來它好像沒什麼無用,但是你可以用它

建立你的應用的最小可能映象

,如果你把你的應用編譯為乙個沒有依賴的靜態二進位制檔案,像go或c那樣。例如,我的

treeder/static-go 映象

包含了乙個go的web應用,則整個映象(包括我的應用)是5mb。

這是關於如何得到盡可能小的映象:scratch映象+你的應用的二進位制檔案。

然而並不是所有人都是用go,所以你可能有更多的依賴,並且你需要比scratch映象要多一些的東西。關於

alpine linux

,我不會枯燥地告訴你關於它的細節,但是他們的廣告語說出了全部:「alpine linux是乙個面向安全的,輕量的linux發行版,基於musl libc和busybox。」 你可以在

這裡得到詳細說明,但是我們這篇文章最關心的是「輕量」的部分。基礎的alpine映象只有5mb。

現在我們有乙個非常好的os作為乙個基礎映象,它有乙個

很好的包管理系統

來新增我們的依賴。對於我們的簡單的node應用而言,我們只需要node自己,所以我們可以只新增node包。我們的dockerfile看起來像這樣:

from alpine

run apk update && apk upgrade

run apk add nodejs

簡單而整潔。現在我們只在映象中有node和node的依賴。

現在為了新增我們的**到映象中,只需要在我們的dockerfile中新增幾行:

from alpine

run apk update && apk upgrade

run apk add nodejs

entrypoint [ "node", "server.js" ]

你可以獲得示例**並且在

這裡檢視完整的構建指導。

同樣的規則適用於所有其他的語言。

幸運的是,我們已經構建了乙個適用所有主要語言的基礎映象,你可以在這裡找到它們:

。它們有一些優化來使它們盡可能的小,並且我們會定期更新,使用基礎映象使得它們比起你自己來更好。通過使用iron.io的基礎映象,上面node應用的dockerfile變成這樣:

from iron/node

entrypoint [ "node", "server.js" ]

另外,對於每一種其他語言,我們構建了兩個版本的這種映象,乙個用於構建,另乙個用於執行。用於構建的映象有所有的構建工具在其中,所以可能比執行時要更大。

例如,為了構建node的依賴,你要像這樣使用iron/node:dev

然後在你的dockerfile中使用iron/node然後執行它:

上述方法同樣適用於其他語言,但是你需要使用它們自己的build/vendor/run的指令。

如果你想要乙個語言的不同版本,你可以改變tag,例如你可以使用iron/node:4.1或者iron/node:0.12。你可以在docker hub上找到每個語言的所有的版本tag。例如node的tag在這裡:

。你可以在

iron-io/dockers

的專案裡找到所有其他docker hub tags的鏈結。

這可能沒那麼幸運了,但是我們有一些例子可以讓大多數主流語言使用上面的基礎映象:

。你可以看看那個專案中的每個語言的readme,它會指引你如何構建你的依賴,測試你的**,構建乙個小的docker映象和測試映象。

讀完本文之後,你應該可以為你的應用建立只包含執行應用所需要的東西的docker映象。容器本質是乙個映象的例項,所以一旦你開始用你的映象來執行容器,你就進入了微容器的世界。沒有(理由)回頭。

剛使用了你的「小映象」技術在我的乙個golang專案上,很棒!感謝這篇偉大的文章。竟然令人震驚地減小到5mb。 —— harlow ward @ clearbit
原文發布時間為:2016-02-20

清理映象 構建更小的容器映象的技巧

linux 容器已經成為乙個熱門話題,保證容器映象較小被認為是乙個好習慣。本文提供了有關如何構建較小 fedora 容器映象的一些技巧。muayyad alsadi 作者 linux 容器已經成為乙個熱門話題,保證容器映象較小被認為是乙個好習慣。本文提供了有關如何構建較小 fedora 容器映象的一...

docker的容器除錯

docker的除錯和虛擬機器操作 1 如何給給docker新增加速器 a 執行一下命令 mkdir etc docker echo etc docker daemon.json 重啟docker systemctl restart docker 或者 etc init.d docker restar...

docker容器的互通

在這裡跟大家說一下我們今天要做的事情 1 在docker中在建立多個容器 2 進入剛建立好的容器內,然後測試該容器是否與剛建好的其它容器能夠相互ping通 3 自定義乙個網路,再把剛剛建立好的容器放進該網路在進行測試。好了開始幹活吧!首先我這裡是拉取了乙個busybox映象 在此之前我已經拉取好了 ...