1. 程式人生 > >學習Docker(2017-10-1)

學習Docker(2017-10-1)

繼續學習 Docker 相關知識,上節學習瞭如何列出映象,以及映象的理解,關於 commit 生成定製的映象,最後對 commit 生成映象的缺點分析。 今天從 Dockerfile 定製映象開始學習,並完成筆記。

使用 Dockerfile 定製映象

>

Dockerfile
Dockerfile 是一個文字檔案,其中包含一條條指令(Instrution),每一條指令構建一層,因此每條指令的內容,就是描述該層的應當如何構建。

Dockerfile 的使用

在一個資料夾中建立一個 Dockerfile 的文字,其中寫入兩條命令

FROM ngix
RUN echo '<h1>
Hello,Docker!</h1>' > /usr/share/ngix/html/index.html

FROM 指定基礎映象

回顧我們上節課的 nginx 映象,就是一個基礎映象,在此基礎做出定製。基礎映象是必須指定的。而 FROM 就是指定基礎映象,每個 Dockerfile 中 FROM 是必備的,而且必須是第一條指令。

知識:在 Docker Hub 上有非常多的高質量的官方映象
1. 可以直接拿來使用的 伺服器映象:
nginx、redis、mongo、mysql、httpd、php、tomcat 等
2. 方便開發、構建、執行各種 語言應用的映象:


node、openjdk、python、ruby、galang 等
3. 基礎的 作業系統映象:
ubuntu、debian、centos、fedora、alpine 等
4. 特殊映象 scratch ,表示虛擬的概念,並不存在,是一個空白的映象
FROM scratch … 表示不以任何映象為基礎,接下來的命令作為映象第一層開始存在。

知識:不以任何系統為基礎,直接將可執行檔案複製進映象的做法並不罕見,比如 swarm、coreos/etcd 對於 Linux 下靜態編譯的程式來說,並不需要有作業系統提供執行時支援,所需的一切庫都已經讓映象體積更加小巧了。因此 FROM scratch 會讓映象體積更加小巧。
實用 Go 語言開發的應用用很多會使用這種方式來製作映象,這也是為什麼有人認為 Go 是特別適合容器微服務架構的語言之一。—來自《Docker 從入門到實踐》

RUN 執行命令
RUN 指令是執行命令列的命令。
RUN 指令在定製映象時是最常見的指令之一。其格式有兩種:
1. shell格式:RUN <命令> ,就像直接在命令列中輸入的命令一樣。
2. exec 格式:RUN [“可執行檔案”,”引數1”,”引數2”],這更像是函式呼叫中的格式

問題:既然 RUN 就像 shell 指令碼一樣可以執行命令,那麼我們是否就可以像 shell指令碼一樣把每個命令對應一個 RUN 呢?

之前說過, Dockerfile 中每一個指令都會建立一層, RUN 也不例外。 每一個 RUN 的行為,就和剛才我們手工建立映象的過程一樣:新建一層,然後執行這些命令,commit 這層的修改,構成新的映象。如果每條指令都是用 RUN 就建立了很多 映象,所以又出現了上一節的問題,增加了映象的臃腫程度。

Union FS 是有最大層數限制,比如 AUFS,曾經42層,限制127層

解決:僅僅使用一個 RUN 指令,並使用 && 將各個所需要的命令串聯起來。

Dockerfile 支援 Shell 類的行尾新增 \ 命令換行,以及行首 # 進行註釋格式

理解:閱讀上圖可能發現最後刪除了編譯構建所需要的軟體,清理了所以下載、展開的檔案,並清理了 apt 快取檔案,現在我們可能理解了 commit 和 Dockerfile 的區別,commit 直接生成了我們沒有處理乾淨的映象,其中包括很多自動生成的東西。利用 Dockerfile 相當一個”一鍵生成”的功能,把我們所要執行的工作,包括最後清理的工作,全部合成到一起,避免了 commit 忘記每一層構建的時候產生的檔案。

構建映象

回到我們剛才的 nginx 映象,讓我們構建這個映象

docker build -t nginx:v3 .
<!-- 格式:docker build [選項] <上下文路徑/URL/->-->

遇到的問題

問題1: 輸入命名顯示格式錯誤提示!

解決: 後來發現後面需要新增 . 點:表示當前目錄

問題2: 未找到 Dockerfile 檔案在你的目錄

解決:知道了找不到檔案,思考了一下可能檔案格式不對,書上沒說什麼格式,我的是txt格式,後來改成 無後綴的ok了

問題3: build 成功後 windows 提示 許可權問題

解決:
解決方法

驗證:
1. 啟動

2. 進入驗證

映象構建上下文 (Context)

構建映象命令後面有個.,表示當前目錄,對應命令格式,是上下文路徑
,什麼是上下文?

Docker build 工作原理
Docker 執行:
1. Docker 引擎(服務端守護程序)
2. 客戶端工具

Docker 的引擎提供了一組 REST API (Docker Remote API),使用 docker 命令的客戶端工具是通過這個 API 與引擎進行互動的。因此,雖然從表面上看我們好像是在本機執行各種 docker 功能,但實際上,一切都是使用的遠端呼叫形式在服務端完成。這種 C/S設計,讓我們輕鬆的操作遠端伺服器的 Docker 引擎。

當我們進行構建映象的時候,並非是在本地構建,而是在服務端,也就是 Docker 引擎中進行。其中使用了上下文概念。

上下文路徑的作用:當用戶執行 docker build 命令,獲取上下文路徑,會將這個路徑的內容打包上傳到 Docker 引擎,引擎展開這個包獲得構建映象所需的一切檔案

需要注意的是:我們上傳的內容不要在硬碟的根目錄,也就是 C,D 盤,這會在執行 docker build 命令後 傳送一個 幾十 GB 的檔案,這是一種錯誤的做法。正確的做法是建立一個空目錄,或者專案目錄,把需要的檔案複製一份,如果目錄下有不想構建的內容,可以用 .gitignore一樣的語法建立一個dockerignore

直接用 Git repo 進行構建

docker build 還支援從 URL 構建,比如可以直接從 Git repo 中構建:

用給定的 tar 壓縮包構建

docker build http://server/context.tar.gz

所給的 URL 不是git repo,而是 tar 壓縮包,那麼 Docker 引擎會下載這個包,自動解壓,以其作為上下文,開始構建。

從標準輸入中讀取 Dockerfile 進行構建

dockerfile -< Dockerfile

如果標準輸入傳入的是文字檔案,則將其視為 Dockerfile ,並開始構建。

這種形式讀取內容,沒有上下文,因此不可以將本地檔案 COPY 進映象之類的事情

從標準輸入中讀取上下文壓縮包進行構建

docker build -< context.tar.gz

如果發現標準輸入的檔案格式是 gzip、bzip2 以及 xz 的話,將會使其上下文壓縮包,直接將其展開,將裡面視為上下文,並開始構建。