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

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取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

    文章

    203

    瀏覽量

    13960
  • 鏡像
    +關注

    關注

    0

    文章

    164

    瀏覽量

    10707
  • Docker
    +關注

    關注

    0

    文章

    457

    瀏覽量

    11846

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

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

收藏 人收藏

    評論

    相關推薦

    怎么構建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 ?2528次閱讀

    Docker—簡介與鏡像用法

    阿里云官方鏡像站: ??https://developer.aliyun.com/mirror/?utm_content=g_1000303593?? ? 一、容器簡介 Docker是管理容器的引擎
    發表于 11-25 16:28 ?515次閱讀
    <b class='flag-5'>Docker</b>—簡介與<b class='flag-5'>鏡像</b>用法

    Docker鏡像的詳細講解

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

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

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

    Dockerfile定義Docker鏡像構建過程

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

    如何在Windows系統上設置Docker鏡像

    在使用 Docker 進行鏡像下載和構建時,由于眾所周知的原因,國內用戶可能會遇到下載速度慢或者無法連接的問題。為了解決這個問題,我們可以使用國內的鏡像源來加速下載速度。本文將介紹如何
    的頭像 發表于 10-24 16:55 ?5962次閱讀

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

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

    如何使用dockerfile創建鏡像

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

    手動構建Docker鏡像的方法

    不推薦使用docker commit命令,而應該使用更靈活、更強大的dockerfile來構建docker鏡像
    的頭像 發表于 08-05 15:30 ?516次閱讀
    手動<b class='flag-5'>構建</b><b class='flag-5'>Docker</b><b class='flag-5'>鏡像</b>的方法
    主站蜘蛛池模板: 无限资源在线观看高清| 九九热在线视频| 五月丁香啪啪.| 国产精品爆乳尤物99精品| 熟妇的味道HD中文字幕 | 黄色毛片a| 色偷偷影院| 换脸国产AV一区二区三区| 最新 国产 精品 精品 视频| 国产永不无码精品AV永久| 三级aa久久| 国产AV天堂亚洲AV麻豆| 妻中蜜在线播放| avv天堂| 亚洲精品视频免费看| 国产欧美一区二区精品久久久| 日本视频久久| 朝鲜女人性猛交| 十8禁用B站在线看漫画| 亚洲精品视频久久| 久久久久国产一级毛片高清片| 正在播放一区二区| 欧美.亚洲.日韩.天堂| 俄罗斯兽交XXXXX在线| 婷婷综合亚洲爱久久| 国产中文字幕乱码一区| 在镜头里被CAO翻了H| 免费网站在线观看国产v片| japonensis护士| 她也色在线视频站| 精品九九视频| 37大但人文艺术A级都市天气 | 国产免费午夜| 亚洲一区在线播放| 蜜臀AV色欲A片无码一区| 趁老师睡着吃她的奶水| 午夜剧场1000| 久久久无码AV精品亚洲A片软件| 99久久99久久久精品齐齐鬼色| 日韩视频在线观看| 国产亚洲精品久久孕妇呦呦你懂|