第三節 使用Docker映象

僅有的限量版寶藏男孩兒發表於2020-11-25

映象是Docker三大核心概念中最為重要的,自Docker誕生之日起“映象”就是相關社群最為熱門的關鍵詞。

 

Docker執行容器前需要本地存在對應的映象,如果映象沒儲存在本地,Docker會嘗試先從預設映象倉庫下載(預設使用Docker Hub公共註冊伺服器的倉庫),使用者也可以通過配置,使用自定義的映象倉庫。接下來將介紹更多關於Docker images的內容,包括:

  • 使用和管理本地主機上的images。
  • 建立一個基礎的images。
  • 上傳images到Dokcer Hub(公共images倉庫)。
  • 列出本地主機上已經存在的images。

 

1、搜尋映象

使用Docker search命令可以搜尋遠端倉庫中共享的映象,預設搜尋官方倉庫中的映象。用法為docker search關鍵字,支援的引數主要包括:

--automated=true | false:僅顯示自動建立的映象,預設為否;

--no-trunc=true | false:輸出資訊不截斷顯示,預設為否;

-s,--stars=X:指定僅顯示評價為指定星級以上的映象,預設為0,即輸出所有映象。

例如,搜尋所有自動建立的評價為1+的帶Nginx關鍵字的映象,預設的輸出結果將按照星級評價進行排序,如下所示:

[root@localhost ~]# docker search --automated -s 3 nginx

NAME:映象名稱

DESCRIPTION:描述

STARS:星級,代表受歡迎程度

OFFICIAL:是否官方建立

AUTOMATED:是否自動建立

 

2、獲取映象

映象是執行容器的前提,官方的Docker Hub網站已經提供了數十萬個映象供大家開放下載。

可以使用docker pull命令直接從Docker Hub映象源來下載映象。該命令的格式為docker pull NAME[:TAG]。其中,NAME是映象倉庫的名稱(用來區分映象),TAG是映象標籤(往往用來表示版本資訊)。通常情況下,描述一個映象需要包括“名稱+標籤”資訊。

例如:

[root@localhost ~]# docker pull ubuntu:14.04

對於Docker映象來說,如果不顯示指定TAG,則預設會選擇latest標籤,這會下載倉庫中最新版本的映象。

下面的例子將從Docker Hub的Ubuntu倉庫下載一個最新的Ubuntu作業系統的映象。

[root@localhost ~]# docker pull ubuntu

從下載過程中可以看出,映象檔案一般由若干層(layer)組成,bae382666908這樣的串是層的唯一id(實際上完整的id包括256位元,由64個十六進位制字元組成)。使用docker pull命令下載時會獲取並輸出映象的各層資訊。當不同的映象包括相同的層時,本地僅儲存層的一份內容,減小了需要的儲存空間。

嚴格地講,映象的倉庫名稱中還應該新增倉庫地址(即registry,註冊伺服器)作為字首,只是我們預設使用的是Docker Hub服務,該字首可以忽略。

例如,docker pull ubuntu:14.04命令相當於docker pull registry.hub.docker.com/ubuntu:14.04命令,即從預設的註冊伺服器Docker Hub Registry中的ubuntu倉庫來下載標記為14.04的映象。如果從非官方的倉庫下載,則需要在倉庫名稱前指定完整的倉庫地址。例如從網易蜂巢的映象源來下載ubuntu:14.04映象,可以使用如下命令,此時下載的映象名稱為hub.c.163.com/public/ubuntu:14.04

[root@localhost ~]# docker pull hub.c.163.com/public/ubuntu:14.04

3、檢視映象資訊

使用images命令列出映象

使用docker images命令可以列出本地主機上已有映象的基本資訊。

[root@localhost ~]# docker images

在列出的資訊中心,可以看到以下幾個欄位資訊。

來自哪個倉庫:比如ubuntu倉庫用來儲存ubuntu系列的基礎映象;

映象的標籤資訊:比如14.04、latest用來標註不同版本資訊。標籤只是標記,並不能表示映象內容;TAG資訊用來標記來自同一個倉庫的不同映象。例如ubuntu倉庫中有多個映象,通過TAG資訊來區分發行版本。

映象的ID(唯一標識映象):如果映象ID相同,說明實際上指向同一個映象;在使用映象ID的時候,一般可以使用該ID前的若干個字元組成的可區分串來替代完整ID。

建立時間:說明映象最後的更新時間

映象大小:優秀的映象往往體積都較小。映象大小資訊只是表示該映象的邏輯體積大小,實際上由於相同的映象層本地只會儲存一份,物理上佔用的儲存空間會小於各映象的邏輯體積之和。

 

為了方便在後續工作中使用特定映象,還可以使用docker tag命令來為本地映象任意新增新的標籤。例如新增一個新的mynginx:latest映象標籤:

[root@localhost ~]# docker tag nginx:latest mynginx:latest

[root@localhost ~]# docker images

可以看到mynginx和nginx的映象ID是一致的,他們實際上指向同一個映象檔案,只是別名不同而已。docker tag命令新增的標籤實際上起到了類似連結的作用。

使用inspect命令檢視詳細資訊

使用docker inspect命令可以獲取該映象的詳細資訊,包括製作者,適應架構,各層的數字摘要等:

[root@localhost ~]# docker inspect nginx

[

{

"Id": "sha256:f35646e83998b844c3f067e5a2cff84cdf0967627031aeda3042d78996b68d35",

"RepoTags": [

"mynginx:latest",

"nginx:latest"

],

"RepoDigests": [

"nginx@sha256:ed7f815851b5299f616220a63edac69a4cc200e7f536a56e421988da82e44ed8"

],

"Parent": "",

"Comment": "",

"Created": "2020-10-13T08:39:44.146921461Z",

"Container": "30fd95c5c49c51e06f02efdb7f6cf22adc04ac7e88eb0ccd0ec3e3f40adae506",

"ContainerConfig": {

"Hostname": "30fd95c5c49c",

"Domainname": "",

"User": "",

"AttachStdin": false,

"AttachStdout": false,

"AttachStderr": false,

"ExposedPorts": {

"80/tcp": {}

},

"Tty": false,

"OpenStdin": false,

"StdinOnce": false,

"Env": [

"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",

"NGINX_VERSION=1.19.3",

"NJS_VERSION=0.4.4",

"PKG_RELEASE=1~buster"

],

"Cmd": [

"/bin/sh",

"-c",

"#(nop) ",

"CMD [\"nginx\" \"-g\" \"daemon off;\"]"

],

"ArgsEscaped": true,

"Image": "sha256:f85f5bff1b6ddc8f428f8528f19c24e9c2284fec8ce02dbc1899b971f4b525cf",

"Volumes": null,

"WorkingDir": "",

"Entrypoint": [

"/docker-entrypoint.sh"

],

"OnBuild": null,

"Labels": {

"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"

},

"StopSignal": "SIGTERM"

},

"DockerVersion": "18.09.7",

"Author": "",

"Config": {

"Hostname": "",

"Domainname": "",

"User": "",

"AttachStdin": false,

"AttachStdout": false,

"AttachStderr": false,

"ExposedPorts": {

"80/tcp": {}

},

"Tty": false,

"OpenStdin": false,

"StdinOnce": false,

"Env": [

"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",

"NGINX_VERSION=1.19.3",

"NJS_VERSION=0.4.4",

"PKG_RELEASE=1~buster"

],

"Cmd": [

"nginx",

"-g",

"daemon off;"

],

"ArgsEscaped": true,

"Image": "sha256:f85f5bff1b6ddc8f428f8528f19c24e9c2284fec8ce02dbc1899b971f4b525cf",

"Volumes": null,

"WorkingDir": "",

"Entrypoint": [

"/docker-entrypoint.sh"

],

"OnBuild": null,

"Labels": {

"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"

},

"StopSignal": "SIGTERM"

},

"Architecture": "amd64",

"Os": "linux",

"Size": 132861270,

"VirtualSize": 132861270,

"GraphDriver": {

"Data": {

"LowerDir": "/var/lib/docker/overlay2/c9e69a8a754aeabf58ca0d84d490f109fdeb40640a9c5b9fe56c010e935bb07e/diff:/var/lib/docker/overlay2/1a5cff3a19d90b819a1894a935f8ea4b657bd0e02d874fd784c37338d348e0b0/diff:/var/lib/docker/overlay2/97367e7ed5ed260b924724c37f24a180c36ea7598d1d12c21d128298fd233738/diff:/var/lib/docker/overlay2/26b59294b44042ec0252d88fa513b8950d2094f095887010dff5ba2e47762d8a/diff",

"MergedDir": "/var/lib/docker/overlay2/4cf3b9944fdccfc1a04dce3a50d96536b497e0bf05eb57f6c1dbac40d4cdde87/merged",

"UpperDir": "/var/lib/docker/overlay2/4cf3b9944fdccfc1a04dce3a50d96536b497e0bf05eb57f6c1dbac40d4cdde87/diff",

"WorkDir": "/var/lib/docker/overlay2/4cf3b9944fdccfc1a04dce3a50d96536b497e0bf05eb57f6c1dbac40d4cdde87/work"

},

"Name": "overlay2"

},

"RootFS": {

"Type": "layers",

"Layers": [

"sha256:d0fe97fa8b8cefdffcef1d62b65aba51a6c87b6679628a2b50fc6a7a579f764c",

"sha256:f14cffae5c1add412127e0704008bb8e730773c0945345c9ea61b7e6eabea8e5",

"sha256:280ddd108a0a0ef53ed20d6715facc1cdd9497ef05cad03c3e5b73521a588511",

"sha256:fe08d9d9f18556ca241f00b6efd6c7b25767463084e14c05da9e535c0782409c",

"sha256:cdd1d8ebeb066bd40f9be824201afe18f0d4fe93b8462353921f0277c09e1289"

]

},

"Metadata": {

"LastTagTime": "2020-10-18T22:51:56.843614041+08:00"

}

}

]

 

返回的是一個JSON格式的訊息,如果我們只要其中一項內容時,可以使用引數-f來指定,例如,獲取映象的Architecture:

[root@localhost ~]# docker inspect -f {{".Architecture"}} nginx

amd64

使用history命令檢視映象歷史

既然映象檔案由多個層組成,那麼怎麼知道各個層的內容具體是什麼呢?這時候可以使用history子命令,該命令將列出各層的建立資訊。

[root@localhost ~]# docker history nginx

 

4、刪除映象

使用標籤刪除映象,使用docker rmi命令可以刪除映象,命令格式為docker rmi IMAGE [IMAGE...],其中IMAGE可以為標籤或ID。

例如,要刪除mynginx:latest映象,可以使用如下命令:

[root@localhost ~]# docker rmi mynginx:latest

 

使用映象ID刪除映象:

[root@localhost ~]# docker rmi f35646e83998

 

當使用docker rmi命令,並且後面跟上映象ID(也可以是能進行區分的部分ID串字首)時,會先嚐試刪除所有指向該映象的標籤,然後刪除該映象檔案本身。

注意,當有該映象建立的容器存在時,映象檔案預設是無法被刪除的。如果要想強行刪除映象,可以使用-f引數。注意,通常並不推薦使用-f引數來強制刪除一個存在容器依賴的映象。正確的做法是,先刪除依賴該映象的所有容器,再來刪除映象。

 

5、建立映象

建立映象的方法主要有三種:基於已有映象的容器建立、基於本地模板匯入、基於Dockerfile建立。

1)基於已有映象的容器建立

該方法主要是使用docker commit命令。命令格式為docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]],主要選項包括:

-a,--author="":作者資訊;

-c,--change=[]:提交的時候執行Dockerfile指令,包括CMD | ENTRYPOINT | EVN | EXPOSE | LABEL | ONBUILD | USER | VOLUME | WORKDIR等;

-m,--message="":提交訊息;

-p,--pause=true:提交時暫停容器執行。

 

下面將演示如何使用該命令建立一個新映象。首先,啟動一個映象,並在其中進行修改操作,例如建立一個test檔案,之後退出。

[root@localhost ~]# docker run -it ubuntu:14.04 /bin/bash

root@34a82035447e:/# touch test

root@34a82035447e:/# exit

記住容器ID為34a82035447e。

此時該容器跟原ubuntu:14.04映象相比,已經發生了改變,可以使用docker commit命令來提交為一個新的映象。提交時可以使用ID或名稱來指定容器:

[root@localhost ~]# docker commit -m "Added a new file" -a "Docker Newbee" 34a82035447e test:0.1

sha256:0424732335ec49ce12f69e32004c646599a8f7147988ff8661595ff92e4fe689

順利的話,會返回新建立的映象的ID資訊,例如:

0424732335ec49ce12f69e32004c646599a8f7147988ff8661595ff92e4fe689

此時檢視本地映象列表,會發現新建立的映象已經存在了:

[root@localhost ~]# docker images

我們可以在做一個mariadb的資料庫映象,先啟動一個centos容器

[root@localhost ~]# docker run -it centos:7 /bin/bash

[root@3c6b6b860c0c /]# yum -y install mariadb-server //在容器裡面安裝mariadb-server軟體包

當結束後,我們使用exit退出,現在我們的容器已經被我們改變了。

使用docker commit命令來提交相應的副本。

[root@localhost ~]# docker commit -m "add mariadb server" -a "docker zhang" 3c6b6b860c0c mariadb:1.0

sha256:d91c6a086478f57ead2de59f33ed773551a343d732f353d787a4b2f325940b6c

[root@localhost ~]# docker images

 

2)基於本地模板匯入

使用者也可以直接從一個作業系統模板檔案匯入一個映象,主要使用docker import命令,命令格式為docker import [OPTIONS] file | URL | -[REPOSITORY[:TAG]]。

要直接匯入一個映象,可以使用OpenVZ提供的模板來建立,或者用其他已匯出的映象模板來建立。OpengVZ模板的下載地址為http://download.openvz.org/template/precreated/

例如,下載了fedora-23-x86_64.tar.gz的模板壓縮包,之後使用以下命令匯入:

[root@localhost ~]# wget https://download.openvz.org/template/precreated/fedora-23-x86_64.tar.gz //先下載映象到本地

 

[root@localhost ~]# cat fedora-23-x86_64.tar.gz.2 | docker import - fedora:23

sha256:01aa44e07add28bf6389cc43f22c2252bfe86cfb3f6e1f854217e0311b158cc4

然後檢視新匯入的映象,會發現它已經在本地存在了:

[root@localhost ~]# docker images

 

6、儲存和載入映象

使用者可以使用docker save和docker load命令來儲存和載入映象。

1)存出映象

如果要匯出映象到本地檔案,可以使用docker save命令。例如,匯出本地的ubuntu:14.04映象為ubuntu_14.04.tar,可以如下所示:

[root@localhost ~]# docker save -o ubuntu_14.04.tar ubuntu:14.04

[root@localhost ~]# ls -lh ubuntu_14.04.tar

-rw-------. 1 root root 197M 10月 19 00:42 ubuntu_14.04.tar

之後,使用者就可以複製ubuntu_14.04.tar檔案將該映象分享給他人使用了。

 

2)載入映象

可以使用docker load將匯出的tar檔案在匯入到本地映象庫,例如從檔案ubuntu_14.04.tar匯入映象到本地映象列表,如下所示:

[root@localhost ~]# docker load --input ubuntu_14.04.tar

或者

[root@localhost ~]# docker load < ubuntu_14.04.tar

這將匯入映象及其相關原資料資訊(包括標籤等)。匯入成功後,可以使用docker images 命令進行檢視。

 

7、上傳映象

使用者可以通過docker push命令,把自己建立的映象上傳到倉庫中來共享,預設上傳到Docker Hub官方倉庫(需要登入),官網地址:https://hub.docker.com。

命令格式:

docker push NAME[:TAG] | [REGISTRY_HOST[:REGISTRY_PORT]/] NAME[:TAG]

 

1)首先申請一個docker hub賬號:

 

2)註冊成功後,登入到docker hub點選一下按鈕:create ——> create repository,取個名字,這裡我們最終建立的倉庫名稱:1851***3999/kube-apiserver-adm64,這個1851***3999是賬號, kube-apiserver-adm64是其中一個倉庫名。如下圖所示:

輸入賬號名和倉庫名,點選下面create,就可以建立公有倉庫了。

 

3)為存在於本地的映象打標籤,命令如下:

docker tag <existing-image> <hub-user>/<repo-name> [:<tag>]

這裡的tag不指定就是latest

具體樣例如下:

[root@localhost ~]# docker tag fedora:23 1851***3999/kube-apiserver-adm64:v1.5.5

1851***3999/kube-apiserver-adm64:v1.5.5解釋:

1851***3999是上面的賬戶名

kube-apiserver-adm64是上面的倉庫名稱

v1.5.5是tag版本。

 

4)在本地登入docker hub賬號,命令如下:

[root@localhost ~]# docker login

Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.

Username: 1851***3999 //docker hub的賬號

Password: //docker hub的密碼

WARNING! Your password will be stored unencrypted in /root/.docker/config.json.

Login Succeeded

 

5)push映象,命令如下:

docker push <hub-user>/<repo-name>:<tag>

具體樣例如下:

[root@localhost ~]# docker push 18511453999/kube-apiserver-adm64:v1.5.5

The push refers to repository [docker.io/18511453999/kube-apiserver-adm64]

8f3620fb53e1: Pushing [===================> ] 267.5MB/695.9MB

 

6)可以有以下兩種方式進行驗證

A、網址方式。登入到docker hub網站,檢視一下剛才建立的倉庫名稱。如圖:

 

B、命令方式。

通過命令拉取一下映象看看是否成功。命令如下:

docker pull <hub-user>/<repo-name>:<tag>

具體樣例如下:

[root@localhost ~]# docker pull 1851***3999/kube-apiserver-adm64:v1.5.5

v1.5.5: Pulling from 1851***3999/kube-apiserver-adm64

Digest: sha256:2a91b295d75e47184260591453aad85f409e0176d0150e9aa80f635ccd22afcf

Status: Image is up to date for 18511453999/kube-apiserver-adm64:v1.5.5

docker.io/1851***3999/kube-apiserver-adm64:v1.5.5

相關文章