[雲原生]Docker - 映象

SkyBiuBiu發表於2021-12-09

參考:

Docker映象

在之前的介紹中,我們知道映象是Docker的三大元件之一。

Docker執行容器前需要本地存在對應的映象,如果映象不存在本地,Docker會從映象倉庫下載(預設是Docker Hub公共註冊伺服器中的倉庫)。

本文將介紹關於映象的內容,包括:

  • 從倉庫獲取映象
  • 管理本地主機上的映象
  • 介紹映象實現的基本原理

獲取映象

可以使用docker pull命令來從倉庫獲取所需要的映象。

舉例:從Docker Hub倉庫下載一個Ubuntu作業系統的映象。

[root@localhost /]# docker pull ubuntu:latest

latest: Pulling from library/ubuntu
7b1a6ab2e44d: Pull complete 
Digest: sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest

下載過程中,會輸出獲取映象的每一層的資訊。

該命令等價於docker pull registry.hub.docker.com/ubuntu:latest命令,即從註冊伺服器registry.hub.docker.com中的ubuntu倉庫來下載latest的映象。

有時候官方倉庫註冊伺服器下載比較慢,可以從其他倉庫中下載。以阿里雲映象加速為例,配置流程:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://<個人的地址號>.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

*注意:容器映象服務 (aliyun.com),登陸阿里雲賬號,可檢視自己的映象加速器地址。

image-20211208200311196

配置完之後可以通過docker info檢視

image-20211208201623732

列出本地映象

使用docker images顯示本地已有的映象。

[root@localhost /]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
ubuntu        latest    ba6acccedd29   7 weeks ago    72.8MB
ubuntu        test    	ba6acccedd29   7 weeks ago    72.8MB
hello-world   latest    feb5d9fea6a5   2 months ago   13.3kB

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

  • REPOSITORY:來源於哪個倉庫,比如ubuntu
  • TAG:映象的標籤,比如latest
  • IMAGE ID:映象ID(唯一)
  • CREATED:建立時間
  • SIZE:映象大小

其中映象的IMAGE ID唯一標識了映象,上面ubuntu:latestubuntu:test具有相同的映象IMAGE ID,說明它們實際上是同一映象。

TAG資訊用來標記來自同一個倉庫的不同映象。例如ubuntu倉庫中有多個映象,通過TAG資訊來區分發行版本,例如10.0412.0414.04等,而latest標識最新的版本。

下面的命令指定使用映象ubuntu:latest來啟動一個容器。

sudo docker run -it ubuntu:latest /bin/bash

如果不指定具體的標記,則預設使用latest標記資訊。

其中-it的含義:

選項 簡寫 說明
-detach -d 在後臺執行容器,並且列印容器ID。
-interactive -i 即使沒有連線,也要保持標準輸入保持開啟狀態,一般與-t連用。
-tty -t 分配一個偽tty,一般與-i連用。

建立映象

建立映象有很多方法,使用者可以從Docker Hub獲取已有映象並更新,也可以利用本地檔案系統建立一個。

方法一:修改已有映象

通過修改原有的映象,來定製建立映象,以上面的ubuntu映象為例子。

  1. 啟動映象,寫入一些檔案或者更新軟體。
[root@localhost /]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
ubuntu        latest    ba6acccedd29   7 weeks ago    72.8MB
hello-world   latest    feb5d9fea6a5   2 months ago   13.3kB
[root@localhost /]# 
[root@localhost /]# docker run -it ubuntu:latest /bin/bash
root@ad84bf1eb7d8:/# 
root@ad84bf1eb7d8:/# cd ~
root@ad84bf1eb7d8:~# echo "Modify test" >> test.txt
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES
ad84bf1eb7d8   ba6acccedd29   "/bin/bash"   27 seconds ago   Up 26 seconds    
  1. 提交映象更改(將容器轉為映象)
[root@localhost ~]# docker commit -m="Ubuntu image commit test" -a="Skybiubiu" ad84bf1eb7d8 ubuntu2:test
sha256:5299c83968a8ef1a44308d851593f74620945ccda08a6ea516fd0ad9055dc019
[root@localhost ~]# 
[root@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
ubuntu2       test      5299c83968a8   4 seconds ago   72.8MB
ubuntu        latest    ba6acccedd29   7 weeks ago     72.8MB
hello-world   latest    feb5d9fea6a5   2 months ago    13.3kB

格式:docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

-m:提交的描述資訊

-a:指定映象作者

方法二:通過Dockerfile構建映象

使用docker commit來擴充套件一個映象比較簡單,但是不方便在一個團隊中分享。

我們可以使用docker build來建立一個新的映象。為此,首先需要建立一個Dockerfile,包含一些如何建立映象的指令。

新建一個目錄和一個Dockerfile。

cd ~
mkdir Dockerfile_dir
cd Dockerfile_dir
touch Dockerfile

Dockerfile中每一條指令都建立映象的一層(並非絕對),以構建一個Nginx映象為例子

[root@localhost Dockerfile_dir]# vim Dockerfile 
FROM nginx
MAINTAINER SkyBiuBiu
RUN echo "It 's a Nginx image,created by skybiubiu." > /usr/share/nginx/html/index.html

Dockerfile基本的語法是

  • 使用#來註釋。
  • FROM關鍵字告訴Docker使用哪個映象作為基礎。
  • 接著MAINTAINER是維護者資訊。
  • RUN開頭的指令會在建立中執行,比如安裝一個軟體包。

編寫完成的Dockerfile可以通過docker build命令來生成映象。

docker build -t="skybiubiu/nginx:v1" .

格式:

  • -t:打標籤
  • .:表示當前資料夾下

image-20211208215110959

image-20211208215201394

*注意:更多寫法,在後面Dockerfile章節補充。

方法三:從本地檔案系統匯入

通過docker import命令從本地檔案系統匯入映象。

將一個本地資料夾匯入轉化成一個映象。

上傳映象

首先,得通過docker login命令登陸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: skybiubiu
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

然後通過docker push命令上傳映象。

格式docker push 倉庫ID/映象名:Tag

[root@localhost ~]# docker push skybiubiu/nginx:v1
The push refers to repository [docker.io/skybiubiu/nginx]
42bab3f962bd: Pushed 
2bed47a66c07: Mounted from library/nginx 
82caad489ad7: Mounted from library/nginx 
d3e1dca44e82: Mounted from library/nginx 
c9fcd9c6ced8: Mounted from library/nginx 
0664b7821b60: Mounted from library/nginx 
9321ff862abb: Mounted from library/nginx 
v1: digest: sha256:57227eb210f8abbeacd1f54f3334300636968371adfbe7a9a3a94f00931444d8 size: 1777

儲存和載入映象

映象列表如下

[root@localhost ~]# docker images
REPOSITORY        TAG       IMAGE ID       CREATED        SIZE
skybiubiu/nginx   v1        c841f47ef705   3 hours ago    141MB
ubuntu2           test      5299c83968a8   3 hours ago    72.8MB
nginx             latest    f652ca386ed1   6 days ago     141MB
ubuntu            latest    ba6acccedd29   7 weeks ago    72.8MB
hello-world       latest    feb5d9fea6a5   2 months ago   13.3kB

ubuntu2:test匯出到本地,-o表示output。

[root@localhost ~]# docker save -o ubuntu2.tar ubuntu2:test

[root@localhost ~]# ls | grep ubuntu2.tar 
ubuntu2.tar

將本地ubuntu2.tar匯入為映象,-i表示input。

[root@localhost ~]# docker load -i ubuntu2.tar
Loaded image: ubuntu2:test

移除本地映象

通過docker rmi命令可以刪除映象。

通過命令刪除skybiubiu/nginx:v1的映象。

[root@localhost ~]# docker rmi skybiubiu/nginx:v1 
Untagged: skybiubiu/nginx:v1
Untagged: skybiubiu/nginx@sha256:57227eb210f8abbeacd1f54f3334300636968371adfbe7a9a3a94f00931444d8
Deleted: sha256:c841f47ef70593e223dfd75f23df2c21dbe7e75cd1a63eea9dd454bf0f6f0d99
Deleted: sha256:79ff50c01b6592d364734334d08ea63d7bd7a00646d710c8e1a4927666271544
Deleted: sha256:e94202cb0e93a88978d0bacfd032e2158fb68b4803d900868595b351a7801fb3

*注意:docker rm命令刪除的是容器

有一個刪除所有映象的小技巧,如下。

docker rmi -f $(docker images -q)

上面命令中,docker images -q輸出的是映象ID,將映象ID作為變數傳入docker rmi -f中,刪除所有映象。

映象的實現原理

Docker 映象是怎麼實現增量的修改和維護的? 每個映象都由很多層次構成,Docker 使用 Union FS 將這 些不同的層結合到一個映象中去。

通常 Union FS 有兩個用途, 一方面可以實現不借助 LVM、RAID 將多個 disk 掛到同一個目錄下,另一個更 常用的就是將一個只讀的分支和一個可寫的分支聯合在一起,Live CD 正是基於此方法可以允許在映象不 變的基礎上允許使用者在其上進行一些寫操作。 Docker 在 AUFS 上構建的容器也是利用了類似的原理。

*注意:關於Docker映象實現原理,後面專門寫一篇部落格來研究。

相關文章