構建 Docker 映象的 N 個小技巧,運維工程師看過來
構建映象的幾個小技巧
構建上下文
執行 docker build 命令時,當前的工作目錄被稱為構建上下文。預設情況下,Dockerfile 就位於該路徑下。也可以透過 -f 引數來指定 dockerfile ,但 docker 客戶端會將當前工作目錄下的所有檔案傳送到 docker 守護程式進行構建。
所以來說,當執行 docker build 進行構建映象時,當前目錄一定要 乾淨 ,切記不要在家裡錄下建立一個 Dockerfile 緊接著 docker build 一把梭 。
正確做法是為專案建立一個資料夾,把構建映象時所需要的資源放在這個資料夾下。比如這樣:
也可以透過 .dockerignore 檔案來忽略不需要的檔案傳送到 docker 守護程式
基礎映象
使用體積較小的基礎映象,比如 alpine 或者 debian:buster-slim,像 openjdk 可以選用 openjdk:xxx-slim,由於 openjdk 是基於 debian 的基礎映象構建的,所以向 debian 基礎映象一樣,後面帶個 slim 就是基於 debian:xxx-slim 映象構建的。
不過需要注意的是,alpine 的 c 庫是 musl libc ,而不是正統的 glibc,另外對於一些依賴 glibc 的大型專案,像 openjdk 、tomcat、rabbitmq 等都不建議使用 alpine 基礎映象,因為 musl libc 可能會導致 JVM 一些奇怪的問題。這也是為什麼 tomcat 官方沒有給出基礎映象是 alpine 的 Dockerfile 的原因。
國內軟體源
使用預設的軟體源安裝構建時所需的依賴,對於絕大多數基礎映象來說,可以透過修改軟體源的方式更換為國內的軟體源映象站。目前國內穩定可靠的映象站主要有,華為雲、阿里雲、騰訊雲、163 等。
對於 alpine 基礎映象修改軟體源
debian 基礎映象修改預設原件原始碼
Ubuntu 基礎映象修改預設原件原始碼
對於 CentOS ???
你確定要用 220MB 大小的基礎映象?
建議這些命令就放在 RUN 指令的第一條,update 以下軟體源,之後再 install 相應的依賴。
時區設定
由於絕大多數基礎映象都是預設採用 UTC 的時區,與北京時間相差 8 個小時,這將會導致容器內的時間與北京時間不一致,因而會對一些應用造成一些影響,還會影響容器內日誌和監控的資料。
因此對於東八區的使用者,最好在構建映象的時候設定一下容器內的時區,以免以後因為時區遇到一些 bug。
可以透過環境變數設定容器內的時區。在啟動的時候可以透過設定環境變數 -e TZ=Asia/Shanghai 來設定容器內的時區。
alpine
但對於 alpine 基礎映象無法透過 TZ 環境變數的方式設定時區,需要安裝 tzdata 來配置時區。
對於 alpine 基礎映象,可以在 RUN 指令後面追加上以下命令
透過 tzdate 設定時區
debian
透過啟動時設定環境變數指定時區
也可以再構建映象的時候複製時區檔案設定容器內時區
ubuntu
透過啟動時設定環境變數指定時區,發射失敗 ,只能透過時區檔案來設定時區了。
在這裡有個命令執行的小技巧,透過脫字元 ^ 來替換上一條命令中的 debian 為 ubuntu 然後執行相同的命令。
透過時區檔案來設定時區
儘量使用 URL 新增原始碼
如果不採用分階段構建,對於一些需要在容器內進行編譯的專案,最好透過 git 或者 wegt 的方式將原始碼打入到映象內,而非採用 ADD 或者 COPY ,因為原始碼編譯完成之後,原始碼就不需要可以刪掉了,而透過 ADD 或者 COPY 新增進去的原始碼已經用在下一層映象中了,是刪不掉滴啦。
也就是說 git & wget source 然後 build,最後 rm -rf source/ 這三部放在一條 RUN 指令中,這樣就能避免原始碼新增到映象中而增大映象體積啦。
下面以 FastDFS 的 Dockerfile 為例:
專案官方的 Dockerfile
經過本人最佳化後的 Dockerfile
構建之後的對比
使用專案預設的 Dockerfile 進行構建的話,映象大小接近 500MB,而經過一些的最佳化,將所有的 RUN 指令合併為一條,最終構建出來的映象大小為 30MB。
使用虛擬編譯環境
對於只在編譯過程中使用到的依賴,我們可以將這些依賴安裝在虛擬環境中,編譯完成之後可以一併刪除這些依賴,比如 alpine 中可以使用 apk add --no-cache --virtual .build-deps,後面加上需要安裝的相關依賴。
構建完成之後可以使用 apk del .build-deps 命令,一併將這些編譯依賴全部刪除。
需要注意的是,.build-deps 後面接的是編譯時以來的軟體包,並不是所有的編譯依賴都可以刪除,不要把執行時的依賴包接在後面,最好單獨 add 一下。
最小化層數
docker 在 1.10 以後,只有 RUN、COPY 和 ADD 指令會建立層,其他指令會建立臨時的中間映象,但是不會直接增加構建的映象大小了。
前文提到了建議使用 git 或者 wget 的方式來將檔案打入到映象當中,但如果我們必須要使用 COPY 或者 ADD 指令呢?
還是拿 FastDFS 為例:
多個檔案需要新增到容器中不同的路徑,每個檔案使用一條 ADD 指令的話就會增加一層映象,這樣戲曲就多了 12 層映象 。
其實大可不必,我們可以將這些檔案全部打包為一個檔案為 src.tar.gz 然後透過 ADD 的方式把檔案新增到當中去,然後在 RUN 指令後使用 mv 命令把檔案移動到指定的位置。這樣僅僅一條 ADD 和 RUN 指令取代掉了 12 個 ADD 指令。
其他最小化層數無非就是把構建專案的整個步驟弄成一條 RUN 指令,不過多條命令合併可以使用 && 或者 ; 這兩者都可以,不過據我在 docker hub 上的所見所聞,使用 ; 的居多,尤其是官方的 Dockerfile。
來自 “ https://blog.k8s.li/dockerfile-tips.html ”, 原文作者:reimu;原文連結:https://blog.k8s.li/dockerfile-tips.html,如有侵權,請聯絡管理員刪除。
相關文章
- 構建 Docker 映象的 N 個小技巧Docker
- 構建Docker幾個小技巧Docker
- docker構建映象Docker
- docker 構建自己的映象Docker
- Docker 構建 kubectl 映象Docker
- Docker映象構建(五)Docker
- Docker映象構建原理解析(不裝docker也能構建映象)Docker
- 安全運維小技巧運維
- 用dockerfile構建docker映象Docker
- Docker 映象構建之 DockerfileDocker
- docker之手動構建新的映象Docker
- Docker 構建PHP 映象環境DockerPHP
- Docker 分階段構建映象Docker
- Docker 映象分階段構建Docker
- Docker構建多平臺映象Docker
- Docker 構建多平臺映象Docker
- 怎樣去構建一個優質的Docker容器映象Docker
- 不用安裝docker也能構建docker映象Docker
- 三個技巧幫助Docker映象瘦身Docker
- 使用maven外掛構建docker映象MavenDocker
- 《前端運維》三、Docker--1映象與容器前端運維Docker
- Docker容器學習梳理 - Dockerfile構建映象Docker
- Docker容器 關於映象構建的安全問題Docker
- 讓“懶惰” Linux 運維工程師事半功倍的 10 個關鍵技巧!Linux運維工程師
- 推薦給“懶惰” Linux 運維工程師的 10 個關鍵技巧,瞬間提升運維效率!Linux運維工程師
- 構建API的7個技巧API
- 使用構建好的 Docker 映象來搭建 Laravel Sail 開發環境,解決 Laravel Sail 映象構建失敗的問題DockerLaravelAI開發環境
- Docker從零構建php-nginx-alpine映象DockerPHPNginx
- 構建Docker Image的五個建議Docker
- SpringBoot 構建 Docker 映象的最佳 3 種方式Spring BootDocker
- 構建 Go 應用 docker 映象的十八種姿勢GoDocker
- 從0開始構建一個瀚高資料庫Docker映象資料庫Docker
- Docker映象的構成__docker commitDockerMIT
- apisix閘道器-構建docker映象構建及外掛化開發APIDocker
- 使用 Docker 開發 - 使用多階段構建映象Docker
- 使用Docker buildx 為 .NET 構建多平臺映象DockerUI
- 使用docker構建jenkins映象並執行容器DockerJenkins
- 源設定導致Docker映象構建失敗Docker