建立docker映象的方法
承接上篇的docker簡介,實際上,映象(image)其實就是容器(container)的模板,容器都是通過映象建立的,所以映象中包含啟動容器所需要的所有檔案系統結構和內容。簡單來講,映象是一個特殊的檔案系統,它提供了容器執行時所需的程式、軟體庫、資源、配置等靜態資料。即映象是隻讀的,其不包含任何動態資料,映象在被構建後,其內容也不會再被改變。
關於docker映象的操作常用的主要包括:拉取、查詢、重新命名、刪除、構建,下面我們將對這些操作逐一進行講解。
(1)拉取映象
docker拉取映象的方法格式如下:
docker pull [Registry]/[Repository]/[Image]:[Tag]
- Registry 為註冊伺服器,Docker 預設會從 http://docker.io 拉取映象,如果你有自己私有的映象倉庫,可以把 Registry 替換為自己的註冊伺服器。
- Repository 為映象倉庫,通常把一組相關聯的映象歸為一個映象倉庫,library為 Docker 預設的映象倉庫。
- Image 為映象名稱。
- Tag 為映象的標籤,如果你不指定拉取映象的標籤,預設為latest。
例如,我們需要獲取一個 busybox 映象,可以執行以下命令:
$ docker pull busyboxUsing default tag: latestlatest: Pulling from library/busybox61c5ed1cbdf8: Pull complete8lacjeddcbf59: Pull completeDigest: sha256:4f47c01fa91355af2865ac10fef5bf6ec9c7f42ad2321377c21e844427972977Status: Downloaded newer image for busybox:latestdocker.io/library/busybox:latest
這裡我們可以注意到幾個問題:首先就是我們pull直接使用的是 【docker pull Image】這樣的格式,沒有新增Registry、Repository和Tag。那麼也就是說本次拉取我們是從預設伺服器【http://docker.io】和預設倉庫【library】拉取的。而且,在沒有指定tag標籤的情況下會預設使用latest【Using default tag: latest】
*注意,特別不建議在生產環境使用預設的 latest 映象標籤,因為獲取這樣的映象會跟蹤隨著最新版本的變化而變化,比如今天剛剛拉取的映象版本是1.0的,突然版本更新到2.0 了,此時伺服器上的該映象也會自動更新為2.0,然而在生產環境中穩定低錯誤才是關鍵,所以不推薦使用預設標籤 latest
其次我們可以看到映象是“多層儲存結構“,所以下載其實是一層層下載而並不是單一的檔案。在下載過程中,每一層都會有一個12位的索引 ID 做標識,形如【61c5ed1cbdf8:Pull complete】。下載完成後,最終會有一個 sha256 的識別號 Digest 俗稱摘要來確保下載的一致性。
(2)檢視映象
Docker 映象檢視使用docker images或者docker image ls命令。
使用docker images命令列出本地所有的映象。
$ docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEnginx latest 4bb46517cac3 9 days ago 133MBnginx 1.15 53f3fd8007f7 15 months ago 109MBbusybox latest 018c9d7b792b 3 weeks ago 1.22MB
如果我們想要查詢指定的映象,可以使用docker image ls命令來查詢。
$ docker image ls busyboxREPOSITORY TAG IMAGE ID CREATED SIZEbusybox latest 018c9d7b792b 3 weeks ago 1.22MB
當然你也可以使用docker images命令列出所有映象,然後使用grep命令進行過濾:
$ docker images |grep busyboxbusybox latest 018c9d7b792b 3 weeks ago 1.22MB
在上面拉取映象時我們提到過,我們拉取映象時沒有指定伺服器和倉庫。所以我們注意到我們的映象名就是簡單的【busybox】。而如果我們拉取的時候指定了伺服器和倉庫的話,那麼我們通過【docker images】看到的結果就不一樣了:
$ docker pull registry.hepantec.com/private_repo/busybox:1.2.2
$ docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEnginx latest 4bb46517cac3 9 days ago 133MBnginx 1.15 53f3fd8007f7 15 months ago 109MBregistry.hepantec.com/private_repo/busybox 1.2.2 018c9d7b792b 3 weeks ago 1.22MB
(3)映象重新命名
有時候會因為任務需要特定的映象做統一管理,就可以用 docker tag 命令為本地任意映象新增新的標籤,即所謂的映象重新命名。
$ docker tag busybox:latest mybusybox:latest
所以映象重新命名可以實現:自定義映象名稱或者推送映象到其他映象倉庫。docker tag的命令格式為【docker tag SOURCE_IMAGE TARGET_IMAGE】。值得注意的是打了新的TAG雖然會多了一條記錄,但是從IMAGE ID 可以得知他們是同一個映象。
執行完docker tag命令後,使用查詢映象命令檢視映象列表。可以看到,映象列表中多了一個mybusybox的映象。busybox和mybusybox這兩個映象的 IMAGE ID 是完全一樣的。實際上它們指向了同一個映象檔案,只是別名不同而已。
docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEbusybox latest 018c9d7b792b 3 weeks ago 1.22MBmybusybox latest 018c9d7b792b 3 weeks ago 1.22MB
而形如【
registry.hepantec.com/private_repo/busybox】這樣的image實際上也是可以通過打tag的方法然後直接推送到其他倉庫的,示例如下:
$ docker tag registry.test.com/myrepo/busybox:1.2 registry.online.com/myrepo/busybox:1.0$ docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEregistry.test.com/myrepo/busybox:1.2 latest 018c9d7b792b 3 weeks ago 1.22MBregistry.online.com/myrepo/busybox:1.0 latest 018c9d7b792b 3 weeks ago 1.22MB$ docker push registry.online.com/myrepo/busybox:1.0
(4)刪除映象
我們可以使用docker rmi或者docker image rm命令刪除映象。
例:刪除mybusybox映象
$ docker rmi mybusybox$ docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEbusybox latest 018c9d7b792b 3 weeks ago 1.22MB
此處需要注意的是,如果這個image已經構建了容器,會刪除失敗。此時需要先將容器移除映象才能刪除成功。關於容器的具體使用方法將在下一篇文章中詳解。
(5)構建映象
構建映象主要有兩種方式:
- docker commit命令從執行中的容器提交為映象;
- docker build命令從 Dockerfile 構建映象。
Docker commit命令
首先介紹下如何從執行中的容器提交為映象。我依舊使用 busybox 映象舉例,使用以下命令建立一個名為 busybox 的容器並進入 busybox 容器。
# 建立容器$ docker run -itd busybox# 通過docker ps可以看到剛剛建立的容器,然後進入容器$ docker exec -it 容器id /binn/bash
執行完上面的命令後,當前視窗會啟動一個 busybox 容器並且進入容器中。在容器中,執行以下命令建立一個檔案並寫入內容:
touch hello.txt && echo "I love Docker. " > hello.txt
此時在容器的根目錄下,已經建立了一個 hello.txt 檔案,並寫入了 "I love Docker. "。下面,我們新開啟另一個命令列視窗,執行以下命令提交映象:
$ docker commit busybox busybox:hellosha256:cbc6406aaef080d1dd3087d4ea1e6c6c9915ee0ee0f5dd9e0a90b03e2215e81c
然後使用上面講到的docker image ls命令檢視映象:
$ docker image ls busyboxREPOSITORY TAG IMAGE ID CREATED SIZEbusybox hello cbc6406aaef0l 2 minutes ago 1.22MBbusybox latest 018c9d7b792b 4 weeks ago 1.22MB
此時我們可以看到主機上新生成了 busybox:hello 這個映象。
Docker build命令
最常用的映象構建方式:Dockerfile。Dockerfile 是一個包含了使用者所有構建命令的文字。通過docker build命令可以從 Dockerfile 生成映象。
使用 Dockerfile 構建映象具有以下特性:
- Dockerfile 的每一行命令都會生成一個獨立的映象層,並且擁有唯一的 ID;
- Dockerfile 的命令是完全透明的,通過檢視 Dockerfile 的內容,就可以知道映象是如何一步步構建的;
- Dockerfile 是純文字的,方便跟隨程式碼一起存放在程式碼倉庫並做版本管理。
先學習下 Dockerfile 常用的指令。
Dockerfile 指令 指令簡介
- FROM Dockerfile 除了註釋第一行必須是 FROM ,FROM 後面跟映象名稱,代表我們要基於哪個基礎映象構建我們的容器。( 預設會先從本地去查詢映象)
- RUN RUN 後面跟一個具體的命令,類似於 Linux 命令列執行命令。
- ADD 拷貝本機檔案或者遠端檔案到映象內
- COPY 拷貝本機檔案到映象內
- USER 指定容器啟動的使用者
- ENTRYPOINT 容器的啟動命令
- CMD CMD 為 ENTRYPOINT 指令提供預設引數,也可以單獨使用 CMD 指定容器啟動引數
- ENV 指定容器執行時的環境變數,格式為 key=value
- ARG 定義外部變數,構建映象時可以使用 build-arg = 的格式傳遞引數用於構建
- EXPOSE 指定容器監聽的埠,格式為 [port]/tcp 或者 [port]/udp
- WORKDIR 為 Dockerfile 中跟在其後的所有 RUN、CMD、ENTRYPOINT、COPY 和 ADD 命令設定工作目錄。
先分析下如下Dockerfile檔案中的含義:
FROM centos:7COPY nginx.repo /etc/yum.repos.d/nginx.repoRUN yum install -y nginxEXPOSE 80ENV HOST=mynginxCMD ["nginx","-g","daemon off;"]
- 第一行表示我要基於 centos:7 這個映象來構建自定義映象。這裡需要注意,每個 Dockerfile 的第一行除了註釋都必須以 FROM 開頭。
- 第二行表示拷貝本地檔案 nginx.repo 檔案到容器內的 /etc/yum.repos.d 目錄下。這裡拷貝 nginx.repo 檔案是為了新增 nginx 的安裝源。
- 第三行表示在容器內執行yum install -y nginx命令,安裝 nginx 服務到容器內,執行完第三行命令,容器內的 nginx 已經安裝完成。
- 第四行宣告容器內業務(nginx)使用 80 埠對外提供服務。
- 第五行定義容器啟動時的環境變數 HOST=mynginx,容器啟動後可以獲取到環境變數 HOST 的值為 mynginx。
- 第六行定義容器的啟動命令,命令格式為 json 陣列。這裡設定了容器的啟動命令為 nginx ,並且新增了 nginx 的啟動引數 -g 'daemon off;' ,使得 nginx 以前臺的方式啟動。
上面這個 Dockerfile 的例子基本涵蓋了常用的映象構建指令。目錄中配置好Dockerfile之後,就可以進行映象構建了。命令形如:
$ docker build -t IMAGE_NAME ./image_dir
上面命令就是基於image_dir目錄進行映象構建的方法,Dockerfile檔案就在image_dir這個目錄中,如果不在就會構建失敗。
限於篇幅原因關於docker映象的探討本篇就先到這裡,後續將繼續更新,敬請期待……