[雲原生]Docker - 鏡像


參考:

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鏡像實現原理,后面專門寫一篇博客來研究。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM