VOOZH about

URL: https://read01.com/kza2QQ.html

⇱ 微容器:更小的,更輕便的 Docker 容器 - 壹讀


Sunday, Apr 12, 2026

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

2016/02/29 來源:開發者頭條

【編者的話】本文介紹了微容器的概念和好處,並用一些例子介紹了如何構建微鏡像,從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。完全一樣的應用,而大小大不相同。

為什麼微容器很棒?有許多使用微容器的好處:

  • 大小 —— 微容器很小。像上面展示的,沒有改變任何代碼,鏡像大小減少了22倍。
  • 快速/簡單的發布 —— 因為鏡像非常小,可以更快地從 Docker registry(例如Docker Hub)下載鏡像,因而可以更快地發布到不同的機器。
  • 提高安全性 —— 更少的代碼和程序在容器中意味著更小的攻擊面。基礎OS就更安全(詳見下文)。
這些好處和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

WORKDIR /app

ADD . /app

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

你可以獲得示例代碼並且在這裡查看完整的構建指導。

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

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

它們有一些優化來使它們儘可能的小,並且我們會定期更新,使用基礎鏡像使得它們比起你自己來更好。通過使用Iron.io的基礎鏡像,上面Node應用的Dockerfile變成這樣:

FROM iron/node

WORKDIR /app

ADD . /app

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

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

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

docker run --rm -v "$PWD":/app -w /app iron/node:dev npm install

然後在你的Dockerfile中使用iron/node然後運行它:

docker run --rm -it -p 8080:8080 -v "$PWD":/app -w /app iron/node node server.js

上述方法同樣適用於其他語言,但是你需要使用它們自己的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
原文連結:Microcontainers – Tiny, Portable Docker Containers(翻譯:陳光 審校:高婧雅)
您可能感興趣
免責聲明:本文內容來源于開發者頭條,文章觀點不代表壹讀立場,如若侵犯到您的權益,或涉不實謠言,敬請向我們提出檢舉
最新文章 / 服務條款 / 私隱保護 / DMCA / 聯絡我們

壹讀/READ01.COM