91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

做Docker Image的一些技巧

馬哥Linux運維 ? 來源:馬哥Linux運維 ? 作者:馬哥Linux運維 ? 2022-07-22 10:58 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

最近做了一個好玩的工具,叫xbin.io[1]。其中有一項工作是為不同的工具來構(gòu)建 Docker 鏡像,讓他們都運行在 Docker 中(實際上,是兼容 Docker image 的其他 sandbox 系統(tǒng),沒有直接用 Docker)。支持的工具越來越多,為了節(jié)省資源,Build 的 Docker image 就越小越好,文件越少,其實啟動速度也會略微快一些,也會更安全一些。

這篇文章來介紹一下做 Docker Image 的一些技巧。

在之前的博客Docker (容器) 的原理[2]中介紹過 Docker image 是如何工作的。簡單來說,就是使用 Linux 的overlayfs[3], overlay file system 可以做到,將兩個 file system merge 在一起,下層的文件系統(tǒng)只讀,上層的文件系統(tǒng)可寫。如果你讀,找到上層就讀上層的,否則的話就找到下層的給你讀。然后寫的話會寫入到上層。這樣,其實對于最終用戶來說,可以認(rèn)為只有一個 merge 之后的文件系統(tǒng),用起來和普通文件系統(tǒng)沒有什么區(qū)別。

有了這個功能,Docker 運行的時候,從最下層的文件系統(tǒng)開始,merge 兩層,得到新的 fs 然后再 merge 上一層,然后再 merge 最上一層,最后得到最終的 directory,然后用chroot[4]改變進(jìn)程的 root 目錄,啟動 container。

654c381a-05da-11ed-ba43-dac502259ad0.png

了解了原理之后,你會發(fā)現(xiàn),這種設(shè)計對于 Docker 來說非常合適:

如果 2 個 image 都是基于 Ubuntu,那么兩個 Image 可以共用 Ubuntu 的 base image,只需要存儲一份;

如果 pull 新的 image,某一層如果已經(jīng)存在,那么這一層之前的內(nèi)容其實就不需要 pull 了;

后面 build image 的技巧其實都是基于這兩點。

另外稍微提一下,Docker image其實就是一個 tar 包[5]。一般來說我們通過Dockerfile用docker built命令來構(gòu)建,但是其實也可以用其他工具構(gòu)建,只要構(gòu)建出來的image 符合 Docker 的規(guī)范[6],就可以運行。比如,之前的博文Build 一個最小的 Redis Docker Image[7]就是用 Nix 構(gòu)建出來的。

技巧1:刪除緩存

一般的包管理器,比如apt,pip等,下載包的時候,都會下載緩存,下次安裝同一個包的時候不必從網(wǎng)絡(luò)上下載,直接使用緩存即可。

但是在 Docker Image 中,我們是不需要這些緩存的。所以我們在Dockerfile中下載東西一般會使用這種命令:

RUNdnfinstall-y--setopt=tsflags=nodocs
httpdvim&&
systemctlenablehttpd&&
dnfcleanall

在包安裝好之后,去刪除緩存。

一個常見的錯誤是,有人會這么寫:

FROMfedora
RUNdnfinstall-ymariadb
RUNdnfinstall-ywordpress
RUNdnfcleanall

Dockerfile 里面的每一個RUN都會創(chuàng)建一層新的 layer,如上所說,這樣其實是創(chuàng)建了 3 層 layer,前 2 層帶來了緩存,第三層刪除了緩存。如同 git 一樣,你在一個新的 commit 里面刪除了之前的文件,其實文件還是在 git 歷史中的,最終的 docker image 其實沒有減少。

但是 Docker 有了一個新的功能,docker build --squash。squash 功能會在 Docker 完成構(gòu)建之后,將所有的 layers 壓縮成一個 layer,也就是說,最終構(gòu)建出來的 Docker image 只有一層。所以,如上在多個RUN中寫 clean 命令,其實也可以。我不太喜歡這種方式,因為前文提到的,多個 image 共享 base image 以及加速 pull 的 feature 其實就用不到了。

一些常見的包管理器刪除緩存的方法:

yum yum clean all
dnf dnf clean all
rvm rvm cleanup all
gem gem cleanup
cpan rm -rf ~/.cpan/{build,sources}/*
pip rm -rf ~/.cache/pip/*
apt-get apt-get clean

另外,上面這個命令其實還有一個缺點。因為我們在同一個RUN中寫多行,不容易看出這個dnf到底安裝了什么。而且,第一行和最后一行不一樣,如果修改,diff 看到的會是兩行內(nèi)容,很不友好,容易出錯。

可以寫成這種形式,比較清晰。

RUNtrue
&&dnfinstall-y--setopt=tsflags=nodocs
httpdvim
&&systemctlenablehttpd
&&dnfcleanall
&&true

技巧2:改動不頻繁的內(nèi)容往前放

通過前文介紹過的原理,可以知道,對于一個 Docker image 有 ABCD 四層,B 修改了,那么 BCD 會改變。

根據(jù)這個原理,我們在構(gòu)建的時候可以將系統(tǒng)依賴往前寫,因為像apt,dnf這些安裝的東西,是很少修改的。然后寫應(yīng)用的庫依賴,比如pip install,最后 copy 應(yīng)用。

比如下面這個 Dockerfile,就會在每次代碼改變的時候都重新 Build 大部分 layers,即使只改了一個網(wǎng)頁的標(biāo)題。

FROMpython:3.7-buster

#copysource
RUNmkdir-p/opt/app
COPYmyapp/opt/app/myapp/
WORKDIR/opt/app

#installdependenciesnginx
RUNapt-getupdate&&apt-getinstallnginx
RUNpipinstall-rrequirements.txt
RUNchown-Rwww-data:www-data/opt/app

#startserver
EXPOSE8020
STOPSIGNALSIGTERM
CMD["/opt/app/start-server.sh"]

我們可以改成,先安裝 Nginx,再單獨 copyrequirements.txt,然后安裝pip依賴,最后 copy 應(yīng)用代碼。

FROMpython:3.7-buster

#installdependenciesnginx
RUNapt-getupdate&&apt-getinstallnginx
COPYmyapp/requirements.txt/opt/app/myapp/requirements.txt
RUNpipinstall-rrequirements.txt

#copysource
RUNmkdir-p/opt/app
COPYmyapp/opt/app/myapp/
WORKDIR/opt/app

RUNchown-Rwww-data:www-data/opt/app

#startserver
EXPOSE8020
STOPSIGNALSIGTERM
CMD["/opt/app/start-server.sh"]

技巧3:構(gòu)建和運行 Image 分離

我們在編譯應(yīng)用的時候需要很多構(gòu)建工具,比如 gcc, golang 等。但是在運行的時候不需要。在構(gòu)建完成之后,去刪除那些構(gòu)建工具是很麻煩的。

我們可以這樣:使用一個 Docker 作為 builder,安裝所有的構(gòu)建依賴,進(jìn)行構(gòu)建,構(gòu)建完成后,重新選擇一個 Base image,然后將構(gòu)建的產(chǎn)物復(fù)制到新的 base image,這樣,最終的 image 只含有運行需要的東西。

比如,這是安裝一個 golang 應(yīng)用pup的代碼:

FROMgolangasbuild
ENVCGO_ENABLED0
RUNgoinstallgithub.com/ericchiang/pup@latest

FROMalpine:3.15.4asrun
COPY--from=build/go/bin/pup/usr/local/bin/pup

我們使用golang這個 1G 多大的 image 來安裝,安裝完成之后將 binary 復(fù)制到 alpine, 最終的產(chǎn)物只有 10M 左右。這種方法特別適合一些靜態(tài)編譯的編程語言,比如 golang 和 rust.

技巧4:檢查構(gòu)建產(chǎn)物

這是最有用的一個技巧了。

dive 是一個 TUI,命令行的交互式 App,它可以讓你看到 docker 每一層里面都有什么。

dive ubuntu:latest命令可以看到 ubuntu image 里面都有什么文件。內(nèi)容會顯示為兩側(cè),左邊顯示每一層的信息,右邊顯示當(dāng)前層(會包含之前的所有層)的文件內(nèi)容,本層新添加的文件會用黃色來顯示。通過tab鍵可以切換左右的操作。

656e6296-05da-11ed-ba43-dac502259ad0.png

一個非常有用的功能是,按下ctrl+U可以只顯示當(dāng)前層相比于前一層增加的內(nèi)容,這樣,就可以看到增加的文件是否是預(yù)期的了。

按ctrl+Space可以折疊起來所有的目錄,然后交互式地打開他們查看,就像是 Docker 中的ncdu。

審核編輯:彭靜

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 鏡像
    +關(guān)注

    關(guān)注

    0

    文章

    180

    瀏覽量

    11646
  • root
    +關(guān)注

    關(guān)注

    1

    文章

    86

    瀏覽量

    22099
  • Docker
    +關(guān)注

    關(guān)注

    0

    文章

    532

    瀏覽量

    14246

原文標(biāo)題:4 個超實用的 Docker 鏡像構(gòu)建技巧

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    在并聯(lián)使用MOS存在一些問題,要怎樣才能避免這些問題?

    在并聯(lián)使用MOS存在一些問題,那我們要怎樣才能避免這些問題? 首先,器件的致性定要好。 在功率MOSFET多管并聯(lián)時,器件內(nèi)部參數(shù)的微小差異就會引起并聯(lián)各支路電流的不平衡而導(dǎo)致單
    發(fā)表于 12-10 08:19

    【HZ-T536開發(fā)板免費體驗】Docker 環(huán)境安裝及應(yīng)用

    、檢查 Docker 安裝狀態(tài) 板子提示“command not found”或無版本信息,說明 Docker 未安裝,如有需要請自行安裝 二、Docker 環(huán)境安裝 首先更新系統(tǒng)
    發(fā)表于 09-01 17:59

    Docker容器安全攻防實戰(zhàn)案例

    在云原生時代,Docker已成為現(xiàn)代應(yīng)用部署的基石。然而,容器化帶來便利的同時,也引入了新的安全挑戰(zhàn)。作為名在生產(chǎn)環(huán)境中管理過數(shù)千個容器的運維工程師,我將通過真實的攻防實戰(zhàn)案例,帶你深入了解Docker安全的每
    的頭像 發(fā)表于 08-05 09:52 ?1338次閱讀

    docker無法啟用怎么解決?

    mengxing@mengxing-virtual-machine:/etc/docker$ sudo systemctl daemon-reload
    發(fā)表于 06-23 07:17

    Docker Volume管理命令大全

    Docker Volume管理命令大全
    的頭像 發(fā)表于 05-28 17:14 ?894次閱讀

    如何使用Docker部署大模型

    隨著深度學(xué)習(xí)和大模型的快速發(fā)展,如何高效地部署這些模型成為了個重要的挑戰(zhàn)。Docker 作為種輕量級的容器化技術(shù),能夠?qū)⒛P图捌湟蕾嚟h(huán)境打包成個可移植的容器,極大地簡化了部署流程
    的頭像 發(fā)表于 05-24 16:39 ?1113次閱讀

    Debian和Ubuntu哪個好一些?

    兼容性對比Debian和Ubuntu哪個好一些,并為您揭示如何通過RAKsmart服務(wù)器釋放Linux系統(tǒng)的最大潛能。
    的頭像 發(fā)表于 05-07 10:58 ?1140次閱讀

    在FX2LP USB上配置GPIF中斷時遇到一些問題,求解決

    你好,我在 FX2LP USB 上配置 GPIF 中斷時遇到一些問題。 我啟用了 INT4 中斷并從 GPIF 中選擇了源 INT4,然后啟用了 GPIF 完成中斷,但我看不到中斷 4 工作。 我該如何呢?
    發(fā)表于 05-06 08:00

    Docker Compose的常用命令

    大家好,今天給大家分享Docker Compose的常用命令,以及docker-compose文件的屬性。Docker Compose 是個用于定義和運行多容器
    的頭像 發(fā)表于 04-30 13:40 ?1198次閱讀

    如何添加一些網(wǎng)絡(luò)上的庫到mpy固件的說明或手冊教程?

    下有沒有關(guān)于如何添加一些網(wǎng)絡(luò)上的庫到mpy固件的說明或手冊教程? 問題2: 關(guān)于mpy的image庫在哪里能了解學(xué)習(xí)內(nèi)部代碼,只了解一些python,想知道怎么從c轉(zhuǎn)換成mpy能調(diào)用的,自己寫的c也能轉(zhuǎn)成py調(diào)用
    發(fā)表于 04-29 08:16

    Docker常用命令大全

    Docker種開源的應(yīng)用容器引擎,廣泛應(yīng)用于開發(fā)、部署和運行分布式應(yīng)用。掌握 Docker 常用命令對于開發(fā)人員和運維人員來說非常重要。本文將為大家整理常用的Docker 命令,
    的頭像 發(fā)表于 04-22 12:47 ?864次閱讀

    基于RV1126開發(fā)板的板卡Docker環(huán)境部署方法

    自動化腳本可以創(chuàng)建Image。 ? ? ? ?Dockerfile:中文名叫鏡像描述文件,是個包含用于組合鏡像目錄的文本文檔,也可以叫“腳本”。用戶通過docker build命令,讀取
    的頭像 發(fā)表于 04-16 10:04 ?650次閱讀
    基于RV1126開發(fā)板的板卡<b class='flag-5'>Docker</b>環(huán)境部署方法

    【技術(shù)案例】Android in Docker

    Docker介紹Docker個開源的容器化平臺,用于打包、分發(fā)和運行應(yīng)用程序。它通過將應(yīng)用及其所有依賴打包到獨立的容器中,確保應(yīng)用在不同環(huán)境中致運行。
    的頭像 發(fā)表于 04-02 16:33 ?1757次閱讀
    【技術(shù)案例】Android in <b class='flag-5'>Docker</b>

    樹莓派在自動化控制項目中的一些潛在應(yīng)用

    自動化控制項目中的一些潛在應(yīng)用。之前,我們已經(jīng)為Arduino平臺探討了相同的話題。我們確定Arduino是個出色的教育工具,但由于一些限制,它無法在工業(yè)環(huán)境中完全
    的頭像 發(fā)表于 03-25 09:45 ?620次閱讀
    樹莓派在自動化控制項目中的<b class='flag-5'>一些</b>潛在應(yīng)用

    基于Docker鏡像逆向生成Dockerfile

    在本文中, 我們將通過理解Docker鏡像如何存儲數(shù)據(jù), 以及如何使用工具查看鏡像方方面面的信息來逆向工程Docker鏡像; 以及如何使用Python的Docker API來構(gòu)建
    的頭像 發(fā)表于 03-10 09:45 ?1549次閱讀
    基于<b class='flag-5'>Docker</b>鏡像逆向生成Dockerfile