Docker 鏡像的經常使用操做

  鏡像做爲 Docker 三大核心概念中,最重要的一個關鍵詞,它有不少操做,是您想學習容器技術不得不掌握的。本文將帶您一步一步,圖文並重,上手操做來學習它。python

目錄

  • 一 Docker 下載鏡像
    • 1.1 下載鏡像
    • 1.2 驗證
    • 1.3 下載鏡像相關細節
    • 1.4 PULL 子命令
  • 二 Docker 查看鏡像信息
    • 2.1 images 命令列出鏡像
    • 2.2 使用 tag 命令爲鏡像添加標籤
    • 2.3 使用 inspect 命令查看鏡像詳細信息
    • 2.4 使用 history 命令查看鏡像歷史
  • 三 Docker 搜索鏡像
    • 3.1 search 命令
    • 3.2 search 子命令
  • 四 Docker 刪除鏡像
    • 4.1 經過標籤刪除鏡像
    • 4.2 經過 ID 刪除鏡像
    • 4.3 刪除鏡像的限制
    • 4.4 清理鏡像
  • 五 Docker 建立鏡像
    • 5.1 基於已有的鏡像建立
    • 5.2 基於 Dockerfile 建立
  • 六 Docker 導出&加載鏡像
    • 6.1 導出鏡像
    • 6.2 加載鏡像
  • 七 Docker 上傳鏡像
    • 7.1 獲取 Docker ID
    • 7.2 建立鏡像倉庫
    • 7.3 上傳鏡像
  • 總結

一 Docker 下載鏡像

  若是咱們想要在本地運行容器,就必須保證本地存在對應的鏡像。因此,第一步,咱們須要下載鏡像。當咱們嘗試下載鏡像時,Docker 會嘗試先從默認的鏡像倉庫(默認使用 Docker Hub 公共倉庫)去下載,固然了,用戶也能夠自定義配置想要下載的鏡像倉庫。mysql

1.1 下載鏡像

  鏡像是運行容器的前提,咱們可使用 docker pull[IMAGE_NAME]:[TAG]命令來下載鏡像,其中 IMAGE_NAME 表示的是鏡像的名稱,而 TAG 是鏡像的標籤,也就是說咱們須要經過 「鏡像 + 標籤」 的方式來下載鏡像。git

  注意: 您也能夠不顯式地指定 TAG, 它會默認下載 latest 標籤,也就是下載倉庫中最新版本的鏡像。這裏並不推薦您下載 latest 標籤,由於該鏡像的內容會跟蹤鏡像的最新版本,並隨之變化,因此它是不穩定的。在生產環境中,可能會出現莫名其妙的 bug, 推薦您最好仍是顯示的指定具體的 TAG。github

舉個例子,如咱們想要下載一個 Mysql 5.7 鏡像,能夠經過命令來下載:sql

docker pull mysql:5.7

會看到控制檯輸出內容以下:docker

Docker 下載鏡像

注意: 因爲官方 DockerHub 倉庫服務器在國外,下載速度較慢,因此我將倉庫的地址更改爲了國內的 docker.io 的鏡像倉庫,因此在上圖中,鏡像前面會有 docker.io 出現。shell

當有 Downloaded 字符串輸出的時候,說明下載成功了!!ubuntu

1.2 驗證

讓咱們來驗證一下,本地是否存在 Mysql5.7 的鏡像,運行命令:bash

docker images

驗證本地鏡像是否存在

能夠看到本地的確存在該鏡像,確實是下載成功了!服務器

1.3 下載鏡像相關細節

再說說上面下載鏡像的過程:

Docker 鏡像下載

  經過下載過程,能夠看到,一個鏡像通常是由多個層( layer) 組成,相似 f7e2b70d04ae這樣的串表示層的惟一 ID(實際上完整的 ID 包括了 256 個 bit, 64 個十六進制字符組成)。

  您可能會想,若是多個不一樣的鏡像中,同時包含了同一個層( layer),這樣重複下載,豈不是致使了存儲空間的浪費麼?

  實際上,Docker 並不會這麼傻會去下載重複的層( layer),Docker 在下載以前,會去檢測本地是否會有一樣 ID 的層,若是本地已經存在了,就直接使用本地的就行了。

  另外一個問題,不一樣倉庫中,可能也會存在鏡像重名的狀況發生, 這種狀況咋辦?

  嚴格意義上,咱們在使用 docker pull 命令時,還須要在鏡像前面指定倉庫地址( Registry), 若是不指定,則 Docker 會使用您默認配置的倉庫地址。例如上面,因爲我配置的是國內 docker.io 的倉庫地址,我在 pull 的時候,docker 會默認爲我加上 docker.io/library 的前綴。

  如:當我執行 docker pull mysql:5.7 命令時,實際上至關於 docker pull docker.io/mysql:5.7,若是您未自定義配置倉庫,則默認在下載的時候,會在鏡像前面加上 DockerHub 的地址。

  Docker 經過前綴地址的不一樣,來保證不一樣倉庫中,重名鏡像的惟一性。

1.4 PULL 子命令

命令行中輸入:

docker pull --help

會獲得以下信息:

[root@iZbp1j8y1bab0djl9gdp33Z ~]# docker pull --help
Usage:  docker pull [OPTIONS] NAME[:TAG|@DIGEST]
Pull an image or a repository from a registry
Options:  -a, --all-tags                Download all tagged images in the repository      --disable-content-trust   Skip image verification (default true)      --help                    Print usage

咱們能夠看到主要支持的子命令有:

  1. -a,--all-tags=true|false: 是否獲取倉庫中全部鏡像,默認爲否;
  2. --disable-content-trust: 跳過鏡像內容的校驗,默認爲 true;

二 Docker 查看鏡像信息

2.1 images 命令列出鏡像

經過使用以下兩個命令,列出本機已有的鏡像:

docker images

或:

docker image ls

以下圖所示:

Docker 查看鏡像信息

對上述紅色標註的字段作一下解釋:

  • REPOSITORY: 來自於哪一個倉庫;
  • TAG: 鏡像的標籤信息,好比 5.七、latest 表示不一樣的版本信息;
  • IMAGE ID: 鏡像的 ID, 若是您看到兩個 ID 徹底相同,那麼實際上,它們指向的是同一個鏡像,只是標籤名稱不一樣罷了;
  • CREATED: 鏡像最後的更新時間;
  • SIZE: 鏡像的大小,優秀的鏡像通常體積都比較小,這也是我更傾向於使用輕量級的 alpine 版本的緣由;

注意:圖中的鏡像大小信息只是邏輯上的大小信息,由於一個鏡像是由多個鏡像層( layer)組成的,而相同的鏡像層本地只會存儲一份,因此,真實狀況下,佔用的物理存儲空間大小,可能會小於邏輯大小。

2.2 使用 tag 命令爲鏡像添加標籤

一般狀況下,爲了方便在後續工做中,快速地找到某個鏡像,咱們可使用 docker tag 命令,爲本地鏡像添加一個新的標籤。以下圖所示:

Docker tag 添加標籤

爲 docker.io/mysql 鏡像,添加新的鏡像標籤 allen_mysql:5.7。而後使用 docker images 命令,查看本地鏡像:

Docker tag 添加標籤

  能夠看到,本地多了一個 allen_mysql:5.7 的鏡像。細心的你必定還會發現, allen_mysql:5.7 和 docker.io/mysql:5.7的鏡像 ID 是如出一轍的,說明它們是同一個鏡像,只是別名不一樣而已。

docker tag 命令功能更像是, 爲指定鏡像添加快捷方式同樣。

2.3 使用 inspect 命令查看鏡像詳細信息

經過 docker inspect 命令,咱們能夠獲取鏡像的詳細信息,其中,包括建立者,各層的數字摘要等。

docker inspect docker.io/mysql:5.7

Docker inspect 查看鏡像詳細信息

docker inspect 返回的是 JSON 格式的信息,若是您想獲取其中指定的一項內容,能夠經過 -f 來指定,如獲取鏡像大小:

docker inspect -f {{".Size"}} docker.io/mysql:5.7

Docker inspect 查看鏡像詳細信息

2.4 使用 history 命令查看鏡像歷史

前面的小節中,咱們知道了,一個鏡像是由多個層(layer)組成的,那麼,咱們要如何知道各個層的具體內容呢?

經過 docker history 命令,能夠列出各個層(layer)的建立信息,如咱們查看 docker.io/mysql:5.7 的各層信息:

docker history docker.io/mysql:5.7

Docker history 各層信息

能夠看到,上面過長的信息,爲了方便展現,後面都省略了,若是您想要看具體信息,能夠經過添加 --no-trunc 選項,以下面命令:

docker history --no-trunc docker.io/mysql:5.7

三 Docker 搜索鏡像

3.1 search 命令

您能夠經過下面命令進行搜索:

docker search [option] keyword

好比,您想搜索倉庫中 mysql 相關的鏡像,能夠輸入以下命令:

docker search mysql

Docker 搜索鏡像

3.2 search 子命令

命令行輸入 docker search--help, 輸出以下:

Usage:  docker search [OPTIONS] TERM
Search the Docker Hub for images
Options:  -f, --filter filter   Filter output based on conditions provided      --help            Print usage      --limit int       Max number of search results (default 25)      --no-index        Don't truncate output      --no-trunc        Don't truncate output

能夠看到 search 支持的子命令有:

  • -f,--filter filter: 過濾輸出的內容;
  • --limitint:指定搜索內容展現個數;
  • --no-index: 不截斷輸出內容;
  • --no-trunc:不截斷輸出內容;

舉個列子,好比咱們想搜索官方提供的 mysql 鏡像,命令以下:

docker search --filter=is-offical=true mysql

Docker 搜索官方鏡像

再好比,咱們想搜索 Stars 數超過 100 的 mysql 鏡像:

docker search --filter=stars=100 mysql

Docker 搜索鏡像

四 Docker 刪除鏡像

4.1 經過標籤刪除鏡像

經過以下兩個均可以刪除鏡像:

docker rmi [image]

或者:

docker image rm [image]

支持的子命令以下:

  • -f,-force: 強制刪除鏡像,即使有容器引用該鏡像;
  • -no-prune: 不要刪除未帶標籤的父鏡像;

Docker 查看鏡像信息Docker 查看鏡像信息

例如,咱們想刪除上章節建立的 allen_mysql:5.7 鏡像,命令以下:

docker rmi allen_mysql:5.7

Docker 刪除鏡像

  從上面章節中,咱們知道 allen_mysql:5.7 和 docker.io/mysql:5.7 實際上指向的是同一個鏡像,那麼,您能夠能會有疑問,我刪除了 allen_mysql:5.7, 會不會將 docker.io/mysql:5.7 鏡像也給刪除了?

  實際上,當同一個鏡像擁有多個標籤時,執行 docker rmi 命令,只是會刪除了該鏡像衆多標籤中,您指定的標籤而已,並不會影響原始的那個鏡像文件。

  不信的話,咱們能夠執行 docker images 命令,來看下 docker.io/mysql:5.7 鏡像還在不在:

Docker 查看鏡像信息

能夠看到, docker.io/mysql:5.7 鏡像依然存在!

那麼,若是某個鏡像不存在多個標籤,當且僅當只有一個標籤時,執行刪除命令時,您就要當心了,這會完全刪除鏡像。

例如,這個時候,咱們再執行 docker rmi docker.io/mysql:5.7 命令:

Docker 刪除鏡像

從上圖能夠看到,咱們已經刪除了 docker.io/mysql:5.7 鏡像的全部文件層。該鏡像在本地已不復存在了!

4.2 經過 ID 刪除鏡像

除了經過標籤名稱來刪除鏡像,咱們還能夠經過制定鏡像 ID, 來刪除鏡像,如:

docker rmi ee7cbd482336

一旦制定了經過 ID 來刪除鏡像,它會先嚐試刪除全部指向該鏡像的標籤,而後在刪除鏡像自己。

4.3 刪除鏡像的限制

刪除鏡像很簡單,但也不是咱們什麼時候何地都能刪除的,它存在一些限制條件。

當經過該鏡像建立的容器未被銷燬時,鏡像是沒法被刪除的。爲了驗證這一點,咱們來作個試驗。首先,咱們經過 docker pull alpine 命令,拉取一個最新的 alpine 鏡像, 而後啓動鏡像,讓其輸出 hello,docker!:

Docker run alpine

接下來,咱們來刪除這個鏡像試試:

Docker 刪除鏡像

能夠看到提示信息,沒法刪除該鏡像,由於有容器正在引用他!同時,這段信息還告訴咱們,除非經過添加 -f 子命令,也就是強制刪除,才能移除掉該鏡像!

docker rmi -f docker.io/alpine

可是,咱們通常不推薦這樣暴力的作法,正確的作法應該是:

  1. 先刪除引用這個鏡像的容器;
  2. 再刪除這個鏡像;

也就是,根據上圖中提示的,引用該鏡像的容器 ID ( 9d59e2278553), 執行刪除命令:

docker rm 9d59e2278553

而後,再執行刪除鏡像的命令:

docker rmi 5cb3aa00f899

Docker 刪除鏡像Docker 刪除鏡像

這個時候,就能正常刪除了!

4.4 清理鏡像

咱們在使用 Docker 一段時間後,系統通常都會殘存一些臨時的、沒有被使用的鏡像文件,能夠經過如下命令進行清理:

docker image prune

它支持的子命令有:

  • -a,--all: 刪除全部沒有用的鏡像,而不只僅是臨時文件;
  • -f,--force:強制刪除鏡像文件,無需彈出提示確認;

五 Docker 建立鏡像

此小節中,您將學習 Docker 如何建立鏡像?Docker 建立鏡像主要有三種:

  1. 基於已有的鏡像建立;
  2. 基於 Dockerfile 來建立;
  3. 基於本地模板來導入;

咱們將主要介紹經常使用的 1,2 兩種。

5.1 基於已有的鏡像建立

經過以下命令來建立:

docker container commit

支持的子命令以下:

  • -a,--author="": 做者信息;
  • -c,--change=[]: 能夠在提交的時候執行 Dockerfile 指令,如 CMD、ENTRYPOINT、ENV、EXPOSE、LABEL、ONBUILD、USER、VOLUME、WORIR 等;
  • -m,--message="": 提交信息;
  • -p,--pause=true: 提交時,暫停容器運行。

接下來,基於本地已有的 Ubuntu 鏡像,建立一個新的鏡像:

Docker 建立鏡像

首先,讓我將它運行起來,並在其中建立一個 test.txt 文件:

Docker 建立鏡像

命令以下:

docker run -it docker.io/ubuntu:latest /bin/bashroot@a0a0c8cfec3a:/# touch test.txtroot@a0a0c8cfec3a:/# exit

建立完 test.txt 文件後,須要記住標註的容器 ID: a0a0c8cfec3a, 用它來提交一個新的鏡像(PS: 你也能夠經過名稱來提交鏡像,這裏只演示經過 ID 的方式)。

執行命令:

docker container commit -m "Added test.txt file" -a "Allen" a0a0c8cfec3a test:0.1

提交成功後,會返回新建立的鏡像 ID 信息,以下圖所示:

Docker 提交新建立的鏡像

再次查看本地鏡像信息,能夠看到新建立的 test:0.1 鏡像了:

Docker 查看鏡像信息

5.2 基於 Dockerfile 建立

經過 Dockerfile 的方式來建立鏡像,是最多見的一種方式了,也是比較推薦的方式。Dockerfile 是一個文本指令文件,它描述了是如何基於一個父鏡像,來建立一個新鏡像的過程。

下面讓咱們來編寫一個簡單的 Dockerfile 文件,它描述了基於 Ubuntu 父鏡像,安裝 Python3 環境的鏡像:

FROM docker.io/ubuntu:latest
LABEL version="1.0" maintainer="Allen <weiwosuo@github>"
RUN apt-get update && \    apt-get install -y python3 && \    apt-get clean && \    rm -rf /var/lib/apt/lists/*

建立完成後,經過這個 Dockerfile 文件,來構建新的鏡像,執行命令:

docker image build -t python:3 .

注意: 命令的最後有個點,若是不加的話,會構建不成功 !

Docker 經過 Dockerfile 構建鏡像

編譯成功後,再次查看本地鏡像信息,就能夠看到新構建的 python:3 鏡像了。

Docker 查看鏡像信息

六 Docker 導出&加載鏡像

此小節中,您將學習 Docker 如何導出&加載鏡像。

一般咱們會有下面這種需求,須要將鏡像分享給別人,這個時候,咱們能夠將鏡像導出成 tar 包,別人直接經過加載這個 tar 包,快速地將鏡像引入到本地鏡像庫。

要想使用這兩個功能,主要是經過以下兩個命令:

  1. docker save
  2. docker load

6.1 導出鏡像

查看本地鏡像以下:

Docker 查看鏡像信息

例如,咱們想要將 python:3 鏡像導出來,執行命令:

docker save -o python_3.tar python:3

執行成功後,查看當前目錄:

Docker 導出文件Docker 導出文件

能夠看到 python_3.tar 鏡像文件已經生成。接下來,你能夠將它經過複製的方式,分享給別人了!

6.2 加載鏡像

別人拿到了這個 tar 包後,要如何導入到本地的鏡像庫呢?

經過執行以下命令:

docker load -i python_3.tar

或者:

docker load < python_3.tar

導入成功後,查看本地鏡像信息,你就能夠得到別人分享的鏡像了!怎麼樣,是否是很方便呢!

七 Docker 上傳鏡像

咱們將以上傳到 Docker Hub 上爲示例,演示 Docker 如何上傳鏡像。

7.1 獲取 Docker ID

想要上傳鏡像到 Docker Hub 上,首先,咱們須要註冊 Docker Hub 帳號。打開 Docker Hub 網址 https://hub.docker.com,開始註冊:

Docker Hub 註冊帳號

填寫您的 Docker ID (也就是帳號),以及密碼,Email, 點擊繼續。

接下來,Docker Hub 會發送驗證郵件,到您填寫的郵箱當中:

Docker Hub 驗證郵件

點擊驗證便可,接下來,再次返回 Docker Hub 官網,用您剛剛註冊的 Docker ID 和密碼來登陸帳號!

Docker Hub 登陸頁面

7.2 建立鏡像倉庫

登陸成功後,會出現以下頁面:

歡迎來到 Docker Hub

選擇建立一個鏡像倉庫:

建立 Python 倉庫

填寫倉庫名稱、描述信息、是否公開後,點擊建立。

倉庫鏡像展現頁倉庫鏡像展現頁

咱們看到,倉庫已經建立成功了,可是裏面尚未任何鏡像,接下來開始上傳鏡像,到此新建立的倉庫中。

7.3 上傳鏡像

進入命令行,用咱們剛剛獲取的 Docker ID 以及密碼登陸,執行命令:

docker login

命令行登陸 Docker ID命令行登陸 Docker ID

登陸成功後,咱們開始準備上傳本地的 python:3 鏡像:

python:3 鏡像

首先,咱們對其打一個新的標籤,前綴與咱們新建立的 Docker ID 、倉庫名保持一致:

docker tag python:3 weiwosuoai1991/python:3

python:3 鏡像打標籤

查看本地信息,能夠看到,標籤打成功了。接下開,開始上傳!執行命令:

docker push weiwosuoai1991/python:3

上傳 python:3 鏡像

上傳成功!去 Docker Hub 官網,新建立的倉庫的信息頁面驗證一下,是否真的成功了:

倉庫鏡像展現頁倉庫鏡像展現頁

大工告成!!!

八 總結

本文中,咱們着重學習了 Docker 中下載鏡像,、查看鏡像信息、搜索鏡像、刪除鏡像,、建立鏡像、導出&加載鏡像以及向 Docker Hub 上傳鏡像的相關操做。

 

出處:https://github.com/Snailclimb/JavaGuide/blob/master/docs/tools/Docker-Image.md

相關文章
相關標籤/搜索