Docker 鏡像

(一)下載實例

在這裏插入圖片描述

(二)鏡像基本操作

在這裏插入圖片描述
備註:
相同名稱的鏡像可以存在多個,即需要不同的tags版本

(三)使用 Dockerfile 定製鏡像
(1)介紹

鏡像的定製實際上就是定製每一層所添加的配置、文件。如果我們可以把每一層修改、安裝、構建、操作的命令都寫入一個腳本,用這個腳本來構建、定製鏡像,那麼之前提及的無法重複的問題、鏡像構建透明性的問題、體積的問題就都會解決。這個腳本就是 Dockerfile。

Dockerfile 是一個文本文件,其內包含了一條條的指令(Instruction),每一條指令構建一層,因此每一條指令的內容,就是描述該層應當如何構建。

注意:Docker是存在[沙箱機制]的,即每個啓動的鏡像是互不干擾的,所以我們在修改容器鏡像的時候是要確定修改哪一個.
此外,每次執行run命令都是在新建一個容器對象,類似於類被new了一個對象,所以此時操作的可能不是我們想要操作的那個對象,當某個容器啓動的時候我們想要操作我們需要進入該容器對象內,而不是重新run啓動一個,應該exec

(2)自定義鏡像

1:自定義鏡像Dockerfile腳本必須有FROM命令
2:自定義鏡像必須繼承於一個基礎鏡像,即FROM

需求:自定義一個tomcat鏡像,首頁訪問顯示Hello World
流程:
1:首先你要清楚tomcat的目錄結構和需要修改的部分
2:本次就修改index.jsp

FROM tomcat
RUN echo "Hello World" > /usr/local/tomcat/webapps/ROOT/index.html

3:構建鏡像

docker build -t nginx:v3 .

4:啓動Docker的Tomcat

docker run -p 8080:8080 myshop
(3)具體操作步驟
--在虛擬機服務器中進入目錄:(默認都在這個目錄下創建)
cd   /usr/local
--創建tomcat目錄
mkdir  tomcat
--創建Dockerfile 文件
touch Dockerfile
--編輯Dockerfile文件
vim  Dockerfile
-- 輸入如下內容,注意不能使用多個RUN,需要使用WORKDIR,詳解參考((四)Dockerfile相關命令)https://www.funtl.com/zh/docs-docker/Docker-Dockerfile-%E6%8C%87%E4%BB%A4%E8%AF%A6%E8%A7%A3.html#workdir-指定工作目錄

FROM tomcat
RUN  cd   /usr/local/tomcat/webapps/ \
     &&   mkdir ROOT   \
     &&  cd  ROOT    \
     &&  touch  index.html  \
     &&  echo "Hello World" > index.html
--構建鏡像 , 點是告訴程序在當前目錄下尋找Dockerfile文件,
myshop 是自定義的鏡像名稱
docker build -t myshop .

在這裏插入圖片描述
從圖片我們看到構建了對應的鏡像,而且是構建了兩層

-- 查看鏡像
docker  imges

在這裏插入圖片描述

--啓動鏡像bash(docker run -it --rm tomcat:標籤 bash)
docker run -it --rm tomcat bash
此時可去對應的目錄下查看,如果錯誤,根據實際情況檢查

測試:docker run -p 8080:8080 myshop  啓動Docker的Tomcat
(4)Dockerfile相關命令

FROM

FROM指定一個基礎鏡像, 一般情況下一個可用的 Dockerfile一定是 FROM 爲第一個指令。至於image則可以是任何合理存在的image鏡像。 FROM 一定是首個非註釋指令 Dockerfile. FROM 可以在一個 Dockerfile 中出現多次,以便於創建混合的images。 如果沒有指定 tag ,latest 將會被指定爲要使用的基礎鏡像版本。

MAINTAINER

這裏是用於指定鏡像製作者的信息 RUN RUN命令將在當前image中執行任意合法命令並提交執行結果。命令執行提交後,就會自動執行Dockerfile中的下一個指令。 層級 RUN 指令和生成提交是符合Docker核心理念的做法。它允許像版本控制那樣,在任意一個點,對image 鏡像進行定製化構建。 RUN 指令緩存不會在下個命令執行時自動失效。比如 RUN apt-get dist-upgrade -y 的緩存就可能被用於下一個指令. --no-cache 標誌可以被用於強制取消緩存使用。

ENV

ENV指令可以用於爲docker容器設置環境變量 ENV設置的環境變量,可以使用 docker inspect命令來查看。同時還可以使用docker run --env =來修改環境變量。

USER USER

用來切換運行屬主身份的。Docker 默認是使用 root,但若不需要,建議切換使用者身分,畢竟 root 權限太大了,使用上有安全的風險。

WORKDIR

WORKDIR 用來切換工作目錄的。Docker 默認的工作目錄是/,只有 RUN 能執行 cd 命令切換目錄,而且還只作用在當下下的 RUN,也就是說每一個 RUN 都是獨立進行的。如果想讓其他指令在指定的目錄下執行,就得靠 WORKDIR。WORKDIR 動作的目錄改變是持久的,不用每個指令前都使用一次 WORKDIR。

COPY

COPY 將文件從路徑 複製添加到容器內部路徑 。 必須是想對於源文件夾的一個文件或目錄,也可以是一個遠程的url, 是目標容器中的絕對路徑。 所有的新文件和文件夾都會創建UID 和 GID 。事實上如果 是一個遠程文件URL,那麼目標文件的權限將會是600。

ADD

ADD 將文件從路徑 複製添加到容器內部路徑 。 必須是想對於源文件夾的一個文件或目錄,也可以是一個遠程的url。 是目標容器中的絕對路徑。 所有的新文件和文件夾都會創建UID 和 GID。事實上如果 是一個遠程文件URL,那麼目標文件的權限將會是600。

VOLUME

創建一個可以從本地主機或其他容器掛載的掛載點,一般用來存放數據庫和需要保持的數據等。

EXPOSE

EXPOSE 指令指定在docker允許時指定的端口進行轉發。

CMD

Dockerfile.中只能有一個CMD指令。 如果你指定了多個,那麼最後個CMD指令是生效的。 CMD指令的主要作用是提供默認的執行容器。這些默認值可以包括可執行文件,也可以省略可執行文件。 當你使用shell或exec格式時, CMD 會自動執行這個命令。

ONBUILD

ONBUILD 的作用就是讓指令延遲執行,延遲到下一個使用 FROM 的 Dockerfile 在建立 image 時執行,只限延遲一次。 ONBUILD 的使用情景是在建立鏡像時取得最新的源碼 (搭配 RUN) 與限定系統框架。

ARG

ARG是Docker1.9 版本才新加入的指令。 ARG 定義的變量只在建立 image 時有效,建立完成後變量就失效消失 LABEL 定義一個 image 標籤 Owner,並賦值,其值爲變量 Name 的值。(LABEL Owner=$Name )

ENTRYPOINT

ENTRYPOINT是指定 Docker image 運行成 instance (也就是 Docker container) 時,要執行的命令或者文件。

(5)鏡像構建上下文(Context)

如果注意,會看到 docker build 命令最後有一個 .。. 表示當前目錄,而 Dockerfile 就在當前目錄,因此不少初學者以爲這個路徑是在指定 Dockerfile 所在路徑,這麼理解其實是不準確的。如果對應上面的命令格式,你可能會發現,這是在指定上下文路徑。那麼什麼是上下文呢?

首先我們要理解 docker build 的工作原理。Docker 在運行時分爲 Docker 引擎(也就是服務端守護進程)和客戶端工具。Docker 的引擎提供了一組 REST API,被稱爲 Docker Remote API,而如 docker 命令這樣的客戶端工具,則是通過這組 API 與 Docker 引擎交互,從而完成各種功能。因此,雖然表面上我們好像是在本機執行各種 docker 功能,但實際上,一切都是使用的遠程調用形式在服務端(Docker 引擎)完成。也因爲這種 C/S 設計,讓我們操作遠程服務器的 Docker 引擎變得輕而易舉。

當我們進行鏡像構建的時候,並非所有定製都會通過 RUN 指令完成,經常會需要將一些本地文件複製進鏡像,比如通過 COPY 指令、ADD 指令等。而 docker build 命令構建鏡像,其實並非在本地構建,而是在服務端,也就是 Docker 引擎中構建的。那麼在這種客戶端/服務端的架構中,如何才能讓服務端獲得本地文件呢?

這就引入了上下文的概念。當構建的時候,用戶會指定構建鏡像上下文的路徑,docker build 命令得知這個路徑後,會將路徑下的所有內容打包,然後上傳給 Docker 引擎。這樣 Docker 引擎收到這個上下文包後,展開就會獲得構建鏡像所需的一切文件

在這裏插入圖片描述
如果在 Dockerfile 中這麼寫:

COPY ./package.json /app/

這並不是要複製執行 docker build 命令所在的目錄下的 package.json,也不是複製 Dockerfile 所在目錄下的 package.json,而是複製 上下文(context) 目錄下的 package.json。

因此,COPY 這類指令中的源文件的路徑都是相對路徑。這也是初學者經常會問的爲什麼 COPY …/package.json /app 或者 COPY /opt/xxxx /app 無法工作的原因,因爲這些路徑已經超出了上下文的範圍,Docker 引擎無法獲得這些位置的文件。如果真的需要那些文件,應該將它們複製到上下文目錄中去。

現在就可以理解剛纔的命令 docker build -t nginx:v3 . 中的這個 .,實際上是在指定上下文的目錄,docker build 命令會將該目錄下的內容打包交給 Docker 引擎以幫助構建鏡像。

如果觀察 docker build 輸出,我們其實已經看到了這個發送上下文的過程:

$ docker build -t nginx:v3 .
Sending build context to Docker daemon 2.048 kB
...

理解構建上下文對於鏡像構建是很重要的,避免犯一些不應該的錯誤。比如有些初學者在發現 COPY /opt/xxxx /app 不工作後,於是乾脆將 Dockerfile 放到了硬盤根目錄去構建,結果發現 docker build 執行後,在發送一個幾十 GB 的東西,極爲緩慢而且很容易構建失敗。那是因爲這種做法是在讓 docker build 打包整個硬盤,這顯然是使用錯誤。

一般來說,應該會將 Dockerfile 置於一個空目錄下,或者項目根目錄下。如果該目錄下沒有所需文件,那麼應該把所需文件複製一份過來。如果目錄下有些東西確實不希望構建時傳給 Docker 引擎,那麼可以用 .gitignore 一樣的語法寫一個 .dockerignore,該文件是用於剔除不需要作爲上下文傳遞給 Docker 引擎的。

那麼爲什麼會有人誤以爲 . 是指定 Dockerfile 所在目錄呢?這是因爲在默認情況下,如果不額外指定 Dockerfile 的話,會將上下文目錄下的名爲 Dockerfile 的文件作爲 Dockerfile。

這只是默認行爲,實際上 Dockerfile 的文件名並不要求必須爲 Dockerfile,而且並不要求必須位於上下文目錄中,比如可以用 -f …/Dockerfile.php 參數指定某個文件作爲 Dockerfile。

當然,一般大家習慣性的會使用默認的文件名 Dockerfile,以及會將其置於鏡像構建上下文目錄中

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章