色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
电子发烧友
开通电子发烧友VIP会员 尊享10大特权
海量资料免费下载
精品直播免费看
优质内容免费畅学
课程9折专享价
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

4個超實用的Docker鏡像構建技巧

dyquk4xk2p3d ? 來源:良許Linux ? 2023-02-13 11:24 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群


	

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

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

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

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

910be89c-ab48-11ed-bfe3-dac502259ad0.png

了解了原理之后,你會發現,這種設計對于 Docker 來說非常合適:

  1. 如果 2 個 image 都是基于 Ubuntu,那么兩個 Image 可以共用 Ubuntu 的 base image,只需要存儲一份;
  2. 如果 pull 新的 image,某一層如果已經存在,那么這一層之前的內容其實就不需要 pull 了;

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

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

技巧1:刪除緩存

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

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

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

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

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

FROMfedora
RUNdnfinstall-ymariadb
RUNdnfinstall-ywordpress
RUNdnfcleanall

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

但是 Docker 有了一個新的功能,docker build --squash。squash 功能會在 Docker 完成構建之后,將所有的 layers 壓縮成一個 layer,也就是說,最終構建出來的 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 看到的會是兩行內容,很不友好,容易出錯。

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

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

技巧2:改動不頻繁的內容往前放

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

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

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

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 應用代碼。

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:構建和運行 Image 分離

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

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

比如,這是安裝一個 golang 應用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 復制到 alpine, 最終的產物只有 10M 左右。這種方法特別適合一些靜態編譯的編程語言,比如 golang 和 rust.

技巧4:檢查構建產物

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

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

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

9152c0c8-ab48-11ed-bfe3-dac502259ad0.png

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

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

審核編輯 :李倩


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 進程
    +關注

    關注

    0

    文章

    207

    瀏覽量

    14275
  • 鏡像
    +關注

    關注

    0

    文章

    178

    瀏覽量

    11237
  • Docker
    +關注

    關注

    0

    文章

    515

    瀏覽量

    12940

原文標題:4 個超實用的 Docker 鏡像構建技巧

文章出處:【微信號:良許Linux,微信公眾號:良許Linux】歡迎添加關注!文章轉載請注明出處。

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

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    怎么構建docker鏡像倉庫軟件

    Docker Registry】用docker registry 鏡像搭建私有測試倉庫
    發表于 08-13 11:03

    采用CentOS7的JDK Docker鏡像構建

    基于CentOS7構建JDK Docker鏡像
    發表于 04-02 11:25

    構建ARM64版本nacos docker鏡像

    在適配過程中有大量合作伙伴用到nacos且采用容器化部署,dockerhub未提供官方鏡像,因此需要在鯤鵬服務器自定義構建構建前提:Docker已部署
    發表于 06-16 14:29

    介紹一款非常方便的java領域docker鏡像構建工具

    中上述內容配置了一結果鏡像名稱imageName,也就是最終構建成的docker鏡像地址,包含容器倉庫地址/
    發表于 07-19 17:41

    應用Docker完成構建微服務開發任務

    什么是Docker? 它的核心就是:Docker是一允許你創建鏡像(這包含了很多步驟,就像在虛擬機的模板一樣)并且讓這個鏡像的實例運行在容
    發表于 09-30 16:45 ?0次下載
    應用<b class='flag-5'>Docker</b>完成<b class='flag-5'>構建</b>一<b class='flag-5'>個</b>微服務開發任務

    Docker:微容器的優勢與構建教程

    說到Docker,可能大家都不陌生了,我們可以用Docker技術將應用以及所有的依賴項打包到一鏡像中,然后把這個鏡像部署到容器中運行。這里
    發表于 10-10 11:32 ?0次下載

    淺析Docker鏡像本地存儲機制及容器啟動原理

    Docker 鏡像不是一單一的文件,而是有多層構成。我們可通過 docker images 獲取本地的鏡像列表及對應的元信息, 接著可通過
    發表于 10-19 14:17 ?2658次閱讀

    Docker鏡像的詳細講解

    本文是對 Docker 鏡像的詳細講解,講解了如何安裝 Docker、配置 Docker 鏡像加速以及操作
    的頭像 發表于 08-02 10:00 ?2508次閱讀

    docker 搜索鏡像,docker查看鏡像詳細信息(docker下載鏡像命令)

    Docker Hub是集中管理的Docker鏡像注冊中心。通過Docker 用戶可以在注冊中心搜索、下載和使用CLI命令行工具中的鏡像。以下
    的頭像 發表于 07-19 09:46 ?2256次閱讀

    Dockerfile定義Docker鏡像構建過程

    了解Dockerfile Dockerfile 是一文本文件,用于定義 Docker 鏡像構建過程。它以指令的形式描述了如何構建
    的頭像 發表于 09-30 10:22 ?2909次閱讀

    構建docker鏡像應該遵循哪些原則

    構建 Docker 鏡像時,應遵循以下原則: 單一職責:每個鏡像應只包含一應用或服務,避免將多個應用或服務放在同一
    的頭像 發表于 11-23 09:41 ?1379次閱讀

    如何使用dockerfile創建鏡像

    Docker是一開源的平臺,用于快速構建、打包、部署應用程序的容器化工具。而Dockerfile是一文本文件,包含了一組可自動化構建
    的頭像 發表于 11-23 09:52 ?1097次閱讀

    手動構建Docker鏡像的方法

    不推薦使用docker commit命令,而應該使用更靈活、更強大的dockerfile來構建docker鏡像
    的頭像 發表于 08-05 15:30 ?898次閱讀
    手動<b class='flag-5'>構建</b><b class='flag-5'>Docker</b><b class='flag-5'>鏡像</b>的方法

    Docker-鏡像的分層-busybox鏡像制作

    docker hub里面查看busybox的Dockerfile, 知識點4:bootfs 和 rootfs? 知識點5:為什么Docker鏡像要采用這種分層結構? 如果多個容器共享一
    的頭像 發表于 01-15 10:44 ?595次閱讀
    <b class='flag-5'>Docker</b>-<b class='flag-5'>鏡像</b>的分層-busybox<b class='flag-5'>鏡像</b>制作

    基于Docker鏡像逆向生成Dockerfile

    在本文中, 我們將通過理解Docker鏡像如何存儲數據, 以及如何使用工具查看鏡像方方面面的信息來逆向工程一Docker
    的頭像 發表于 03-10 09:45 ?585次閱讀
    基于<b class='flag-5'>Docker</b><b class='flag-5'>鏡像</b>逆向生成Dockerfile
    主站蜘蛛池模板: 青柠高清在线观看完整版 | 亚洲成年人在线观看 | 51无码人妻精品1国产 | 亚洲三级黄色片 | 成人免费视频在线看 | 国产精品你懂得 | 国产精品亚洲精品久久国语 | 亚洲精品福利一区二区在线观看 | 日本wwwhdsex69| 亚洲免费在线观看 | 亚洲一日韩欧美中文字幕在线 | 少妇的肉体AA片免费 | 樱花动漫成人隐藏入口 | 男人和女人全黄一级毛片 | 免费三级播放器 | 亚洲国产免费观看视频 | 小草高清视频免费直播 | 亚洲人成电影网站 | 最近中文字幕在线看免费完整版 | 色综合伊人色综合网站下载 | 亚洲乱码中文字幕久久孕妇黑人 | 日韩免费一级毛片 | 男女车车的车车网站W98免费 | qvod理论电影| 国产在线一区二区AV视频 | 午夜福利电影网站鲁片大全 | 久久精品热99看 | 俄罗斯9一14 young处 | 亚洲AV香蕉一区区二区三区蜜桃 | 日韩精品一区VR观看 | 国产精片久久久久久婷婷 | 乱淫67194 | 亲爱的妈妈6韩国电影免费观看 | 大学生宿舍飞机china free | 4480yy午夜私人影院 | 亚洲黄色三级视频 | 曰本老头同性xxxxx | 亚洲精品一二三区区别在哪 | 视频一区二区中文字幕 | 久久re视频这里精品一本到99 | 嗯啊不要老师 |

    電子發燒友

    中國電子工程師最喜歡的網站

    • 2931785位工程師會員交流學習
    • 獲取您個性化的科技前沿技術信息
    • 參加活動獲取豐厚的禮品