主頁 > 軟體工程 > 再學dockerfile

再學dockerfile

2020-09-10 14:11:12 軟體工程

前言

docker的系統學習可以看我這篇博文:https://www.cnblogs.com/zisefeizhu/p/11298818.html 有非常詳細的講解
容器現在都是用kubernetes來編排了, 存盤、網路、都歸Kubernetes層面管理了,所以對于docker的主要掌握點也就剩dockerfile了,這也是docker的重點,

簡介

Dockerfile是一個文本檔案,里面包含一條條指令,每一條指令就是一層鏡像,
Dockerfile 一般分為四部分:基礎鏡像資訊、維護者資訊、鏡像操作指令和容器啟動時執行指令,’#’ 為 Dockerfile 中的注釋,
Docker以從上到下的順序運行Dockerfile的指令,為了指定基本鏡像,第一條指令必須是FROM,一個宣告以字符開頭則被視為注釋,
Dockerfile中所用的所有檔案一定要和Dockerfile檔案在同一級父目錄下,可以為Dockerfile父目錄的子目錄,
Dockerfile中相對路徑默認都是Dockerfile所在的目錄,
Dockerfile中一定要惜字如金,能寫到一行的指令,一定要寫到一行,原因是分層構建,聯合掛載這個特性,Dockerfile中每一條指令被視為一層,
Dockerfile中指明大寫(約定俗成)

dockerfile 圖解

dockerfile詳解

FROM

指定基礎鏡像,并且必須是第一條非注釋指令,

如果不以任何鏡像為基礎,那么寫法為:FROM scratch,

同時意味著接下來所寫的指令將作為鏡像的第一層開始

語法:

FROM <image>
FROM <image>:<tag>
FROM <image>:<digest> 
三種寫法,其中<tag>和<digest> 是可選項,如果沒有選擇,那么默認值為latest
在一個 Dockerfile 檔案中創建多個鏡像時,FROM 可以多次出現,只需在每個新命令 FROM 之前,記錄提交上次的鏡像 ID,

LABEL

功能是為鏡像指定標簽

語法:

LABEL <key>=<value> <key>=<value> <key>=<value> ...
 一個Dockerfile種可以有多個LABEL,不建議這么寫,最好是寫成一行,如太長需要換行的話則使用\符號
LABEL會繼承基礎鏡像中的LABEL,如遇到key相同,則值覆寫

ENV

設定環境變數

語法:

 ENV <key> <value>
 ENV <key>=<value> ...
 兩者的區別就是第一種是一次設定一個,第二種是一次設定多個

ADD

一個復制命令,把檔案復制到鏡像中
如果把虛擬機與容器想象成兩臺linux服務器的話,那么這個命令就類似于scp,只是scp需要加用戶名和密碼的權限驗證,而ADD不用

語法:

ADD <src>... <dest>
ADD ["<src>",... "<dest>"]
路徑的填寫可以是容器內的絕對路徑,也可以是相對于作業目錄的相對路徑,推薦寫成絕對路徑
可以是一個本地檔案或者是一個本地壓縮檔案,還可以是一個url
如果把寫成一個url,那么ADD就類似于wget命令
src為一個目錄的時候,會自動把目錄下的檔案復制過去,目錄本身不會復制
如果src為多個檔案,dest一定要是一個目錄
如果 docker 發現檔案內容被改變,則接下來的指令都不會再使用快取,關于復制檔案時需要處理的/,基本跟正常的 copy 一致

COPY

看這個名字就知道,又是一個復制命令

語法:

COPY <src>... <dest>
COPY ["<src>",... "<dest>"]
與ADD的區別:
	COPY的只能是本地檔案,其他用法一致

RUN
功能為運行指定的命令
語法:

RUN <command>
RUN ["executable", "param1", "param2"]
第一種后邊直接跟shell命令
	在linux作業系統上默認 /bin -c
	在windows作業系統上默認 cmd /S /C
第二種是類似于函式呼叫,
	可將executable理解成為可執行檔案,后面就是兩個引數,
RUN 指令創建的中間鏡像會被快取,并會在下次構建中使用,如果不想使用這些快取鏡像,可以在構建時指定 --no-cache 引數,如:docker build --no-cache,

CMD
功能為容器啟動時要運行的命令

語法:

CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2
第三種比較好理解了,就時shell這種執行方式和寫法
第一種和第二種其實都是可執行檔案加上引數的形式
舉例說明兩種寫法:
CMD [ "sh", "-c", "echo $HOME" 
CMD [ "echo", "$HOME" ]
這里邊包括引數的一定要用雙引號,就是",不能是單引號,千萬不能寫成單引號,
原因是引數傳遞后,docker決議的是一個JSON array

RUN&&CMD

RUN是構件容器時就運行的命令以及提交運行結果
CMD是容器啟動時執行的命令,在構件時并不運行,構件時僅僅指定了這個命令到底是做什么的

WORKDIR

設定作業目錄,對RUN,CMD,ENTRYPOINT,COPY,ADD生效,如果不存在則會創建,也可以設定多次,

語法:

WORKDIR /path/to/workdir
WORKDIR也可以決議環境變數
ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
pwd的執行結果是/path/$DIRNAME

VOLUME

實作掛載功能,可以將宿主機目錄掛載到容器中

可用專用的檔案存盤當作Docker容器的資料存盤部分

語法:

VOLUME ["/data"]
使用場景為需要持久化存盤資料時.
容器使用的是AUFS,這種檔案系統不能持久化資料,當容器關閉后,所有的更改都會丟失,
所以當資料需要持久化時用這個命令,
	VOLUME ["/var/log/"]
	VOLUME /var/log
	VOLUME /var/log /var/db
卷可以容器間共享和重用
容器并不一定要和其它容器共享卷
修改卷后會立即生效
對卷的修改不會對鏡像產生影響
卷會一直存在,直到沒有任何容器在使用它
VOLUME 讓我們可以將源代碼、資料或其它內容添加到鏡像中,而又不并提交到鏡像中,并使我們可以多個容器間共享這些內容,

USER

設定啟動容器的用戶,可以是用戶名或UID

語法:

USER daemo
USER UID
如果設定了容器以daemon用戶去運行,那么RUN, CMD 和 ENTRYPOINT 都會以這個用戶去運行,
使用這個命令一定要確認容器中擁有這個用戶,并且擁有足夠權限,

ENTRYPOINT

啟動時的默認命令

語法:

ENTRYPOINT ["executable", "param1", "param2"]  
ENTRYPOINT command param1 param2
第一種就是可執行檔案加引數
第二種就是寫shell

ENTRYPOINT&&CMD

相同點:
	只能寫一條,如果寫了多條,那么只有最后一條生效
	容器啟動時才運行,運行時機相同
不同點:
	ENTRYPOINT不會被運行的command覆寫,而CMD則會被覆寫
如果我們在Dockerfile種同時寫了ENTRYPOINT和CMD,并且CMD指令不是一個完整的可執行命令,那么CMD指定的內容將會作為ENTRYPOINT的引數,
FROM ubuntu
ENTRYPOINT ["netstat", "-ln"]
CMD ["-tup"]
如果在Dockerfile種同時寫了ENTRYPOINT和CMD,并且CMD是一個完整的指令,那么它們兩個會互相覆寫,誰在最后誰生效
FROM ubuntu
ENTRYPOINT ["netstat", "-ln"]
CMD ls -l
那么將執行ls -l ,netstat -ln不會執行,

ARG

設定變數命令,ARG命令定義了一個變數,在docker build創建鏡像的時候,使用 --build-arg =來指定引數

語法:

ARG <name>[=<default value>]
如果用戶在build鏡像時指定了一個引數沒有定義在Dockerfile中,那么將有一個Warning
[Warning] One or more build-args [foo] were not consumed.
可以定義一個或多個引數
	FROM busybox
	ARG user1
	ARG buildno
可以給引數一個默認值
	FROM busybox
	ARG user1=someuser
	ARG buildno=1
如果給了ARG定義的引數默認值,那么當build鏡像時沒有指定引數值,將會使用這個默認值

HEALTHCHECK

容器健康狀況檢查命令

語法:

HEALTHCHECK [OPTIONS] CMD command
HEALTHCHECK NONE
第一個的功能是在容器內部運行一個命令來檢查容器的健康狀況
第二個的功能是在基礎鏡像中取消健康檢查命令
[OPTIONS]的選項支持以下三中選項:
–interval=DURATION 兩次檢查默認的時間間隔為30秒
–timeout=DURATION 健康檢查命令運行超時時長,默認30秒
–retries=N 當連續失敗指定次數后,則容器被認為是不健康的,狀態為unhealthy,默認次數是3
注意:
HEALTHCHECK命令只能出現一次,如果出現了多次,只有最后一個生效,
CMD后邊的命令的回傳值決定了本次健康檢查是否成功,具體的回傳值如下:
0: success - 表示容器是健康的
1: unhealthy - 表示容器已經不能作業了
2: reserved - 保留值
例:
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/8080 || exit 1
健康檢查命令是:curl -f http://localhost/8080 || exit 1
兩次檢查的間隔時間是5秒
命令超時時間為3秒

ONBUILD

用于在dockerfile中定義一個觸發器,只對當前鏡像的子鏡像生效

語法:

ONBUILD [INSTRUCTION]
dockerfile用于build鏡像檔案,此鏡像檔案亦可作為base image被另一個dockerfile用作FROM指令引數,并以之構建新的鏡像,在后面的dockerfile中的FROM指令在build程序中被執行時,將會觸發創建其baseimage的dockerfile檔案中的ONBUILD指令定義的觸發器,
比如當前鏡像為A,在Dockerfile種添加:
	ONBUILD RUN ls -l
這個 ls -l 命令不會在A鏡像構建或啟動的時候執行
此時有一個鏡像B是基于A鏡像構建的,那么這個ls -l 命令會在B鏡像構建的時候被執行,		

EXPOSE

功能為暴漏容器運行時的監聽埠給外部
語法:

EXPOSE <port>/<tcp/udp>
但是EXPOSE并不會使容器訪問主機的埠
EXPOSE 指令并不會讓容器監聽 host 的埠,如果需要,需要在 docker run 時使用 `-p`、`-P` 引數來發布容器埠到 host 的某個埠上,

STOPSIGNAL

STOPSIGNAL命令是的作用是當容器停止時給系統發送什么樣的指令,默認是15

語法:

STOPSIGNAL signal

Dockerfile中使用變數的方式

$varname
${varname}
${varname:-default value}
${varname:+default value}
第一種和第二種相同
第三種表示當變數不存在使用-號后面的值
第四種表示當變數存在時使用+號后面的值

原則及建議

容器輕量化,從鏡像中產生的容器應該盡量輕量化,能在足夠短的時間內停止、銷毀、重新生成并替換原來的容器,
使用 .gitignore,在大部分情況下,Dockerfile 會和構建所需的檔案放在同一個目錄中,為了提高構建的性能,應該使用 .gitignore 來過濾掉不需要的檔案和目錄,
為了減少鏡像的大小,減少依賴,僅安裝需要的軟體包,
一個容器只做一件事,解耦復雜的應用,分成多個容器,而不是所有東西都放在一個容器內運行,如一個 Python Web 應用,可能需要 Server、DB、Cache、MQ、Log 等幾個容器,一個更加極端的說法:One process per container,
減少鏡像的圖層,不要多個 Label、ENV 等標簽,
對續行的引數按照字母表排序,特別是使用apt-get install -y安裝包的時候,
使用構建快取,如果不想使用快取,可以在構建的時候使用引數--no-cache=true來強制重新生成中間鏡像,

實戰

我的一篇docker實戰博文

https://blog.csdn.net/zisefeizhu/article/details/90729970

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/2422.html

標籤:其他

上一篇:專案微管理39 - 懲罰

下一篇:Jenkins容器無法執行docker命令

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more