DOCKERFILE參數注解

Dockerfile由一行行命令語句組成,并且支持以#開頭的注釋行。

一般的,Dockerfile 分為四部分:基礎鏡像信息、維護者信息、鏡像操作指令和容器啟動時執行指令。

Dockerfile的指令是忽略大小寫的,建議使用大寫,使用 # 作為注釋,每一行只支持一條指令,每條指令可以攜帶多個參數。

Dockerfile的指令根據作用可以分為兩種:構建指令和設置指令。

? 構建指令用于構建image,其指定的操作不會在運行image的容器上執行;
? 設置指令用于設置image的屬性,其指定的操作將在運行image的容器中執行。

可以在目錄下創建.dockerignore文件,讓Docker忽略路徑下的文件和目錄。

DockerFile的每一個指令都會新構建一層。

UnionFS是有最大層數限制的,比如AUFS,曾經是最大不能超過42層,現在是最大不能超過127層。所以,對于一些編譯、軟件的安裝、更新等操作,無需分成好幾層來操作,這樣會使得鏡像非常臃腫,擁有非常多的層,不僅僅增加了構建部署的時間,也很容易出錯!!

指令描述格式
from

構建指令。

指定基礎鏡像,它是最重要的一個且必須為dokefile文件開篇的第一個非注釋行,用于為鏡像文件構建過程中指定基礎鏡像,后續的指令運行于此基準鏡像所提供的運行環境

默認,docke會在本機尋找指定的鏡像,找不到的時候則從docke hub registery拉取所需鏡像,如果會找不到,則報錯返回報錯信息

如果在同一個Dockerfile中創建多個鏡像時,可以使用多個 FROM 指令。

DockerFile還存在一個特殊的鏡像srcatch,這個鏡像是一個虛擬的概念,并不實際存在,它表示一個空白的鏡像。

如果你以scratch作為基礎鏡像,意味著你將不使用任何鏡像為基礎,接下來你所寫的指令將作為第一層開始存在。不以任何系統為基礎,直接將可執行文件復制進鏡像的做法并不罕見。如swarmcoreos/etcd。對Linux下靜態編譯的程序來說,并不需要其他操作提供其運行時支持,所需的一切庫都在可執行文件里了,因此使用scratch作為基礎,可以使鏡像的體積更加小巧

from? <repository>[:<tag>]或者

from <repository>@<digest>

repository為基礎鏡像名稱? ?tag為鏡像標簽為可選項,省略時為latest該image的最后修改的版本

MAINTAINER

構建指令

用于為docke提供作者信息,無順序限制

用于將image的制作者相關的信息寫入到image中。當我們對該image執行docker inspect命令時,輸出中有相應的字段記錄該信息。

此命令已經過時,可以使用LABEL maintainer=xxx 來替代,定義多個LABEL時,可以使用 【\】反劃線來跨行

copy

用于從docker主機復制文件至創建的新鏡像文件,但不會自動解壓,不能從【 遠端URL 】 復制。

目標路徑是容器內的絕對路徑,也可以是工作目錄下的相對路徑,工作目錄可以使用WORKDIR指令進行指定。

使用COPY指令會將源路徑的文件的所有元數據都拷貝,比如讀、寫、指定全選、時間變更等。

<源路徑> 可以是多個,甚至可以是通配符,其通配符規則要滿足 Go 的 filepath.Match 規則

目標路徑不需要事先創建,如果目錄不存在會在復制文件前先行創建缺失目錄

在使用該指令的時候還可以加上 --chown=<user>:<group> 選項來改變文件的所屬用戶及所屬組。

文件復制準則:

1 COPY [--chown=<user>:<group>] <源路徑>... <目標路徑>
2 COPY [--chown=<user>:<group>] ["<源路徑1>",... "<目標路徑>"]
add

構建指令

ADD指令和COPY的格式和性質基本一致,只不過是在COPY的基礎上增加了一些功能。

如果是一個目錄,那么會將該目錄下的所有文件添加到container中,不包括目錄;

如果<src>是文件且<dest>中不使用斜杠結束,則會將<dest>視為文件,<src>的內容會寫入<dest>;

如果<src>是文件且<dest>中使用斜杠結束,則會<src>文件拷貝到<dest>目錄下。

目標路徑為一個URL時,會將其自動下載到目標路徑下,但是其權限被自動設置成了600,如果這并不是你想要的權限,那么你還需要額外增加一層RUN命令進行更改,另外,如果下載的是一個壓縮包,同樣你還需要額外增加一層RUN命令進行解壓縮。所以,在這種情況下,你還不如指定只用一層RUN,使用curl或者wget工具進行下載,并更改權限,然后進行解壓縮,最后清理無用文件!

當你的源路徑為壓縮文件并且不想讓Docker引擎將其自動解壓縮,這個時候就不可以使用ADD命令,你可以使用COPY命令進行完成

run

構建指令。

每條?RUN?指令將在當前鏡像基礎上執行指定命令,并提交為新的鏡像。當命令較長時可以使用?\?來換行

RUN可以運行任何被基礎image支持的命令。如基礎image選擇了ubuntu,那么軟件管理部分只能使用ubuntu的命令

shell格式RUN <command>?或

exec格式RUN ["executable", "param1", "param2"]

前者將在 shell 終端中運行命令,即?/bin/sh -c;后者則使用?exec?執行。指定使用其它終端可以通過第二種方式實現,例如?RUN ["/bin/bash", "-c", "echo hello"]

volume

設置指令

用于構建鏡像時定義匿名卷。

容器存儲層應該保持無狀態化,容器運行時應盡量保持容器內不發生任何寫入操作,對于需要保存動態數據的應用,其數據文件應該將其保存在數據卷中。

容器匿名卷目錄指定可以通過docker run命令中指定-v參數來進行覆蓋。

如果掛載點目錄下此前存在文件,docker run命令會在卷掛載完成之后將此前的所有文件復制到新掛載的卷中

運行通過該Dockerfile生成image的容器,/tmp/data目錄中的數據在容器關閉后,里面的數據還存在。

例如另一個容器也有持久化數據的需求,且想使用上面容器共享的/tmp/data目錄,那么可以運行下面的命令啟動一個容器:

docker run -t -i -rm?-volumes-from container1 image2bash

其中:container1為第一個容器的ID,image2為第二個容器運行image的名字。

  • VOLUME <路徑>
  • VOLUME [“<路徑1>”, “<路徑2>”, …]
expose

設置指令

EXPOSE指令是聲明運行時容器服務端口,這只是一個聲明,在運行時并不會因為這個聲明應用就會開啟這個端口的服務。

在Dockerfile中這樣聲明有兩個好處:一個是幫助鏡像使用者更好的理解這個鏡像服務的守護端口,另一個作用則是在運行時使用隨機端口映射時,也就是docker run -p命令時,會自動隨機映射EXPOSE端口。

要將EXPOSE和在運行時使用-p <宿主>:<容器端口>區分開來,-p是映射宿主端口和容器端口,換句話說,就是將容器的對應端口服務公開給外界訪問,而EXPOSE僅僅是聲明端口使用什么端口而已,并不會自動在宿主進行端口映射

EXPOSE指令可以一次設置多個端口號,相應的運行容器的時候,可以配套的多次使用-p選項。

EXPOSE 端口號

EXPOSE 端口號/協議

默認協議為TCP

env

設置指令

指定環境變量,它可以被其后的add、copy等調用

可以通過docker inspect查看這個環境變量,也可以通過在docker run --env?key=value時設置或修改環境變量

如果你要設置多個環境變量,為了美觀,你可以使用\來進行換行。多個環境變量的隔開,使用空格進行隔開的,如果某個環境變量的值是由一組英文單詞構成,那么你可以將其使用""進行圈起來

值得注意的是,如果你想通過CMD或者ENTRYPOINT指令的exec格式來打印環境

CMD ["echo", $MODE]

CMD ["echo", "$MODE"]

上面這樣都是不能正確輸出環境變量的值的,你可以改成exec格式來執行shell命令,如下

CMD ["sh", "-c", "echo $MODE"]

調用格式$name或者${name}

wokrdir

設置指令

使用WORKDIR指令來制定工作目錄(或者稱為當前目錄),以后各層操作的當前目錄就是為指定的目錄,如果該目錄不存在,WORKDIR會自動幫你創建目錄

WORKDIR指令可以通過docker run命令中的-w參數來進行覆蓋

user

設置指令

指令用于將會用以什么樣的用戶去運行默認為root

可以指定用戶名或者UID,組名或者GID,或者兩者的結合

USER指令可以在docker run命令中的-u參數進行覆蓋

后續的?RUN?也會使用指定用戶。

當服務不需要管理員權限時,可以通過該命令指定運行用戶。并且可以在之前創建所需要的用戶,例如:RUN groupadd -r postgres && useradd -r -g postgres postgres。要臨時獲取管理員權限可以使用?gosu,而不推薦?sudo

healthcheck

告訴Docker該如何判斷容器的狀態是否正常,這是1.12引入的新指令

在沒有HEALTHCHECK指令之前,Docker引擎只可以通過容器內主進程是否退出來判斷容器狀態是否異常。很多情況下這沒有問題,但是如果程序進入了死鎖狀態,或者死循環狀態,應用進程并不退出,但是該容器已經無法繼續提供服務了。在1.12之前,Docker引擎不會檢測到容器的這種狀態,從而不會重新調度,導致可能容器已經無法提供服務了卻仍然還在接收用戶的請求。

HEALTHCHECK指令只可以出現一次,如果有多個HEALTHCHECK指令,那么只有最后一個才會生效

HEALTHCHECK [options] CMD <命令>:檢查容器健康狀態的命令

HEALTHCHECK NONE:如果基礎鏡像有健康檢查指令,這一行將會屏蔽掉其健康檢查指令

HEALTHECHECK支持下列選項:

? ? ?–interval=<間隔>:兩次檢查的時間間隔,默認為30s

? ? ?–timeout=<時長>:健康檢查命令運行超時時間,如果超過這個時間,本次健康檢查將會判定? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 為失敗,默認為30s

? ? ? –retries=<次數>:當連續失敗指定次數之后,則將容器狀態視為unhealthy,默認為3次

onbuildONBUILD是一個特殊的指令,它后面跟著的是其他指令,比如COPYRUN等,而這些命令在當前鏡像被構建時,并不會被執行。只有以當前鏡像為基礎鏡像去構建下一級鏡像時,才會被執行ONBUILD <其他指令>
shell

指定Dockerfile中 【 shell form 】命令的默認shell。

Linux中默認shell為 【 “/bin/sh”, “-c”】

arg

構建參數ARGENV指令一樣,都是設置環境變量。與之不同的是,ARG設置的環境變量只是在鏡像構建時所設置的,在將來容器運行時是不會存在這些環境變量的。但是不要因此就用ARG來保存密碼之類的信息,因為通過docker history還是能夠看得到的。ARG指令與ENV指令的使用類似

ARG構建參數可以通過docker run命令中的--build-arg參數來進行覆蓋

cmd

設置指令。

Docker不是虛擬機,容器就是進程。既然是進程,那么在啟動容器的時候,就需要指定運行的程序及參數。CMD就是指定默認的容器主進程的啟動命令的

每個 Dockerfile 只能有一條?CMD?命令。如果指定了多條命令,只有最后一條會被執行。

如果用戶啟動容器時候指定了運行的命令,則會覆蓋掉?CMD?指定的命令

這里邊包括參數的一定要用雙引號,就是",不能是單引號。千萬不能寫成單引號。

原因是參數傳遞后,docker解析的是一個JSON array

一些命令在加上sh -c之后,有可能會發生意想不到的錯誤,因此在Dockerfile中使用RUN指令時,更加推薦使用exec格式!最后需要牢記,使用docker run命令指定要執行的命令可以覆蓋RUN指令,如果我們的docker run中指定了我們將要執行的命令,并且在Dockerfile中也指定了CMD命令

exec格式CMD ["executable","param1","param2"]?

使用?exec?執行,推薦方式;

shell格式CMD command param1 param2?在?/bin/sh?中執行,提供給需要交互的應用。

CMD ["param1","param2"]?提供給?ENTRYPOINT?的默認參數,如果CMD指令使用上面的形式,那么Dockerfile中必須要有配套的ENTRYPOINT

entrypoint

設置指令

指定容器運行程序及參數

配置容器啟動后執行的命令,并且不可被?docker run?提供的參數覆蓋。

每個 Dockerfile 中只能有一個?ENTRYPOINT,當指定多個時,只有最后一個起效

ENTRYPOINT也更加推薦使用exec格式,ENTRYPOINTdocker run命令中同樣也可以進行指定,只不過比CMD指令來的繁瑣一些,需要指定--entrypoint參數。同樣,在docker run命令中指定了--entrypoint參數的話,會覆蓋Dockerfile中ENTRYPOINT上的指令。

該指令的使用分為兩種情況,一種是獨自使用,另一種和CMD指令配合使用。

當獨自使用時,如果你還使用了CMD命令且CMD是一個完整的可執行的命令,那么CMD指令和ENTRYPOINT會互相覆蓋,只有最后一個CMD或者ENTRYPOINT有效。

CMDecho?“Hello, World!”?

ENTRYPOINT?ls?-l?

另一種用法和CMD指令配合使用來指定ENTRYPOINT的默認參數,這時CMD指令不是一個完整的可執行命令,僅僅是參數部分;

ENTRYPOINT指令只能使用JSON方式指定執行命令,而不能指定參數。

CMD ["-l"]?

ENTRYPOINT ["/usr/bin/ls"]?

exec格式ENTRYPOINT ["executable", "param1", "param2"]

shell格式ENTRYPOINT command param1 param2(shell中執行)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/535452.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/535452.shtml
英文地址,請注明出處:http://en.pswp.cn/news/535452.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Zookeeper:分布式過程協同技術

Zookeeper 是一個高性能的分布式一致系統&#xff0c;在分布式系統中有著廣泛的應用。基于它&#xff0c;可以實現諸如“分布式同步”、“配置管理”、“命名空間管理”等眾多功能&#xff0c;是分布式系統中常見的基礎系統。Zookeeper 主要用來解決分布式集群中應用系統的一致…

面試題2021-2-24

給某CentOs6慮擬機添加了新的數據盤&#xff0c;設備名為/de/sdd.寫命令格式化滿加的效的并掛載到指定目錄/opt fdisk -l mkfs.ext4 /de/sdd mount /de/sdd /opt 如何查看與RabbtMQ服務器之間的establish狀態連接數&#xff1f;netstat -an |grep ESTABLISHED |grep tcp |wc -l…

Zookeeper:在三種模式下的部署

zookeeper 安裝模式有三種&#xff1a;單機模式&#xff1a;單機單 server&#xff1b;集群模式&#xff1a;多機多 server&#xff0c;形成集群&#xff1b;偽集群模式&#xff1a;單機多 server&#xff0c;形成偽集群。 ~ 本篇內容包括&#xff1a;Zookeeper 官網下載、Zook…

Linux namespace概述

操作系統通過虛擬內存技術&#xff0c;使得每個用戶進程都認為自己擁有所有的物理內存&#xff0c;這是操作系統對內存的虛擬化。操作系統通過分時調度系統&#xff0c;每個進程都能被【公平地】調度執行&#xff0c;即每個進程都能獲取到CPU&#xff0c;使得每個進程都認為自己…

Zookeeper:Zookeeper的主從選舉機制

ZAB 協議&#xff0c;全稱 Zookeeper Atomic Broadcast&#xff08;Zookeeper 原子廣播協議&#xff09;&#xff0c;是為分布式協調服務 ZooKeeper 專門設計的一種支持崩潰恢復的一致性協議。基于該協議&#xff0c;ZooKeeper 實現了一種主從模式的系統架構來保持集群中各個副…

Linux namespace之:uts namespace

理解uts namespace uts(UNIX Time-Sharing System) namespace可隔離hostname和NIS Domain name資源&#xff0c;使得一個宿主機可擁有多個主機名或Domain Name。換句話說&#xff0c;可讓不同namespace中的進程看到不同的主機名。 例如&#xff0c;使用unshare命令(較新版本L…

Zookeeper:事件監聽和通知機制

Zookeeper 允許客戶端向服務端的某個 Znode 注冊一個 Watcher 監聽&#xff0c;當服務端的一些指定事件觸發了這個 Watcher&#xff0c;服務端會向指定客戶端發送一個事件通知來實現分布式的通知功能&#xff0c;然后客戶端根據 Watcher 通知狀態和事件類型做出業務上的改變。 …

Linux namespace之:mount namespace

理解mount namespace 用戶通常使用mount命令來掛載普通文件系統&#xff0c;但實際上mount能掛載的東西非常多&#xff0c;甚至連現在功能完善的Linux系統&#xff0c;其內核的正常運行也都依賴于掛載功能&#xff0c;比如掛載根文件系統/。其實所有的掛載功能和掛載信息都由內…

Linux namespace之:network namespace

理解network namespace network namespace用來隔離網絡環境&#xff0c;「在network namespace中&#xff0c;網絡設備、端口、套接字、網絡協議棧、路由表、防火墻規則等都是獨立的」。 因network namespace中具有獨立的網絡協議棧&#xff0c;因此每個network namespace中都…

Kubernetes 的原理

kubernetes 已經成為容器編排領域的王者&#xff0c;它是基于容器的集群編排引擎&#xff0c;具備擴展集群、滾動升級回滾、彈性伸縮、自動治愈、服務發現等多種特性能力。 本文將帶著大家快速了解 kubernetes &#xff0c;了解我們談論 kubernetes 都是在談論什么。 kuberne…

Zookeeper:實現“分布式鎖”的 Demo

Zookeeper 能保證數據的強一致性&#xff0c;用戶任何時候都可以相信集群中每個節點的數據都是相同的。一個用戶創建一個節點作為鎖&#xff0c;另一個用戶檢測該節點&#xff0c;如果存在&#xff0c;代表別的用戶已經鎖住&#xff0c;如果不存在&#xff0c;則可以創建一個節…

JavaIO流:案例

java.io 包下需要掌握的流有 16 個&#xff0c;本篇內容包括&#xff1a;java.io包下需要掌握的流、Java IO 案例。 文章目錄一、java.io包下需要掌握的流二、Java IO 案例1、Demo 1&#xff08;FileInputStream&#xff09;2、Demo 2&#xff08;FileInputStream&#xff09;3…

比對excel數據

#!/usr/bin/env pythonimport openpyxl from openpyxl.styles import PatternFill from openpyxl.styles import colors from openpyxl.styles import Font, Color aD:/測算單位設置/比對/吉林/tmp001.xlsx bD:/測算單位設置/比對/吉林/國網吉林電力.xlsx cD:/測算單位設置/比對…

CPU 是如何執行任務的

前言 你清楚下面這幾個問題嗎&#xff1f; 有了內存&#xff0c;為什么還需要 CPU Cache&#xff1f; CPU 是怎么讀寫數據的&#xff1f; 如何讓 CPU 能讀取數據更快一些&#xff1f; CPU 偽共享是如何發生的&#xff1f;又該如何避免&#xff1f; CPU 是如何調度任務的&a…

Ansible 的自動化運維

1、Ansible 特點 Ansible 自 2012 年發布以來&#xff0c;很快在全球流行&#xff0c;其特點如下&#xff1a; Ansible 基于 Python 開發&#xff0c;運維工程師對其二次開發相對比較容易&#xff1b; Ansible 豐富的內置模塊&#xff0c;幾乎可以滿足一切要求&#xff1b; …

Shell 信號發送與捕捉

1、Linux信號類型 信號&#xff08;Signal&#xff09;&#xff1a;信號是在軟件層次上對中斷機制的一種模擬&#xff0c;通過給一個進程發送信號&#xff0c;執行相應的處理函數。 進程可以通過三種方式來響應一個信號&#xff1a; 1&#xff09;忽略信號&#xff0c;即對信…

運維面試題總結

集群相關 簡述 ETCD 及其特點&#xff1f; etcd 是 CoreOS 團隊發起的開源項目&#xff0c;是一個管理配置信息和服務發現&#xff08;service discovery&#xff09;的項目&#xff0c;它的目標是構建一個高可用的分布式鍵值&#xff08;key-value&#xff09;數據庫&#x…

詳解設計模式:建造者模式

建造者模式&#xff08;Builder Pattern&#xff09;也叫做生成器模式&#xff0c;是 GoF 的 23 種設計模式的一種&#xff0c;它將一個復雜對象的構建與它的表示分離&#xff0c;使得同樣的構建過程可以創建不同的表示。 當我們需要實列化一個復雜的類&#xff0c;以得到不同結…

圖文并茂 VLAN 詳解,讓你看一遍就理解 VLAN

一、為什么需要VLAN 1.1、什么是VLAN? VLAN(Virtual LAN)&#xff0c;翻譯成中文是“虛擬局域網”。LAN可以是由少數幾臺家用計算機構成的網絡&#xff0c;也可以是數以百計的計算機構成的企業網絡。VLAN所指的LAN特指使用路由器分割的網絡——也就是廣播域。 在此讓我們先復習…

認識VLAN,并學會VLAN的劃分和網絡配置實例

VLAN的劃分和網絡的配置實例 1、VLAN基礎知識 VLAN&#xff08;Virtual Local Area Network&#xff09;的中文名為&#xff1a;“虛擬局域網”&#xff0c;注意和VPN&#xff08;虛擬專用網&#xff09;進行區分。 VLAN是一種將局域網設備從邏輯上劃分&#xff08;不是從物…