Docker 詳解(三):Docker 鏡像管理基礎
1.鏡像的概念
鏡像可以理解為應用程序的集裝箱,而 Docker 用來裝卸集裝箱。
Docker 鏡像含有啟動容器所需要的文件系統及其內容,因此,其用于創建并啟動容器。
Docker 鏡像采用分層構建機制,最底層為 bootfs,其上為 rootfs。
- bootfs:用于系統引導的文件系統,包括
bootloader
和kernel
,容器啟動完成后會被卸載以節約內存資源。 - rootfs:位于 bootfs 之上,表現為 Docker 容器的根文件系統。
- 傳統模式中,系統啟動之時,內核掛載 rootfs 會首先將其掛載為 只讀 模式,完整性自檢完成后將其重新掛載為 讀寫 模式。
- Docker中,rootfs 由內核掛載為 只讀 模式,而后通過 聯合掛載 技術額外掛載一個 可寫層。
注意:當刪除容器時,這個容器自有的 可寫層 會一起被刪除。
2.Docker 鏡像層
位于下層的鏡像稱為 父鏡像(parent image
),最底層的稱為 基礎鏡像(base image
);最上層為 可讀寫層,其下的均為 只讀層。
3.Docker 存儲驅動
Docker 提供了多種存儲驅動來實現不同的方式存儲鏡像,下面是常用的幾種存儲驅動:
- AUFS
- OverlayFS
- Devicemapper
- Btrfs
- VFS
3.1 AUFS
AUFS(AnotherUnionFS)是一種 Union FS,是文件級的存儲驅動。AUFS 是一個能透明覆蓋一個或多個現有文件系統的層狀文件系統,把多層合并成文件系統的單層表示。簡單來說就是支持將不同目錄掛載到同一個虛擬文件系統下的文件系統。這種文件系統可以一層一層地疊加修改文件。無論底下有多少層都是只讀的,只有最上層的文件系統是可寫的。當需要修改一個文件時,AUFS 創建該文件的一個副本,使用 CoW 將文件從只讀層復制到可寫層進行修改,結果也保存在可寫層。在 Docker 中,底下的只讀層就是 Image,可寫層就是 Container。
3.2 OverlayFS
Overlay 是 Linux 內核 3.18 3.18 3.18 后支持的,也是一種 Union FS,和 AUFS 的多層不同的是 Overlay 只有兩層:一個 upper
文件系統和一個 lower
文件系統,分別代表 Docker 的鏡像層和容器層。當需要修改一個文件時,使用 CoW 將文件從只讀的 lower
復制到可寫的 upper
進行修改,結果也保存在 upper
層。在 Docker 中,底下的只讀層就是 Image,可寫層就是 Container。目前最新的 OverlayFS 為 Overlay2。
3.3 DeviceMapper
Device Mapper 是 Linux 內核 2.6.9 2.6.9 2.6.9 后支持的,提供的一種從邏輯設備到物理設備的映射框架機制,在該機制下,用戶可以很方便的根據自己的需要制定實現存儲資源的管理策略。AUFS 和 OverlayFS 都是文件級存儲,而 Device Mapper 是塊級存儲,所有的操作都是直接對塊進行操作,而不是文件。Device Mapper 驅動會先在塊設備上創建一個資源池,然后在資源池上創建一個帶有文件系統的基本設備,所有鏡像都是這個基本設備的快照,而容器則是鏡像的快照。所以在容器里看到文件系統是資源池上基本設備的文件系統的快照,并沒有為容器分配空間。當要寫入一個新文件時,在容器的鏡像內為其分配新的塊并寫入數據,這個叫 用時分配。當要修改已有文件時,再使用 CoW 為容器快照分配塊空間,將要修改的數據復制到在容器快照中新的塊里再進行修改。
4.Docker Registry
啟動容器時,Docker daemon 會試圖從本地獲取相關的鏡像,本地鏡像不存在時,其將從 Registry 中下載該鏡像并保存到本地。
Registry 用于保存 Docker 鏡像,包括鏡像的層次結構和元數據。用戶可以自建 Registry,亦可使用官方的 Docker Hub。
Docker Registry 的分類:
Sponsor Registry
:第三方的 Registry,供客戶和 Docker 社區使用。Mirror Registry
:第三方的 Registry,只讓客戶使用。Vendor Registry
:由發布 Docker 鏡像的供應商提供的 Registry。Private Registry
:通過設有防火墻和額外的安全層的私有實體提供的 Registry。
Docker Registry 的組成:
- Repository
- 由某特定的 Docker 鏡像的所有迭代版本組成的鏡像倉庫。
- 一個 Registry 中可以存在多個 Repository。
- Repository 可分為 頂層倉庫 和 用戶倉庫。
- 用戶倉庫名稱格式為 “用戶名/倉庫名”。
- 每個倉庫可包含多個 Tag(標簽),每個標簽對應一個鏡像。
- Index
- 維護用戶帳戶、鏡像的檢驗以及公共命名空間的信息。
- 相當于為 Registry 提供了一個完成用戶認證等功能的檢索接口。
Docker Registry 中的鏡像通常由開發人員制作,而后推送至 公共 或 私有 Registry上保存,供其他人員使用,例如部署到生產環境。
5.Docker 鏡像的制作
多數情況下,我們做鏡像是基于別人已存在的某個基礎鏡像來實現的,我們把它稱為 Base Image。比如一個純凈版的最小化的 centos
、ubuntu
或 debian
。
鏡像的生成途徑:
- Dockerfile
- 基于容器制作
- Docker Hub automated builds
5.1 基于容器制作鏡像
Create a new image from container’s changes
Usage:(通過一個容器來新建一個鏡像)
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Options | Default | Description |
---|---|---|
-a(--author) | - | Author (e.g., “John Hannibal Smith hannibal@a-team.com”) |
-c(--change list) | - | Apply Dockerfile instruction to the created image |
-m(--message string) | - | Commit message |
-p(--pause) | true | Pause container during commit |
下載 busybox
鏡像(使用 docker pull
命令)。
[root@wang ~]# docker pull busybox
[root@wang ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest b97242f89c8a 6 weeks ago 1.23MB
httpd latest 683a7aad17d3 6 weeks ago 138MB
在鏡像 busybox
中 創建并運行 一個叫 tests
的容器,并使用交互模式進行編輯。
--name
:為容器指定一個名稱。-i
:以交互模式運行容器,通常于-t
一起使用。-t
:為容器重新分配一個偽輸入終端,通常于-i
一起使用。
[root@wang ~]# docker run --name tests -it busybox
/ # ls
bin etc proc sys usr
dev home root tmp var
/ # mkdir /data
/ # echo 'hello world' > /data/index.html
/ # cat data/index.html
hello world
在創建鏡像時,我們不能關閉容器,必須使其處于運行狀態,所以我們必須要 另起一個終端,然后執行。
docker commit -p ${boolean} ${id|name}
。-p
表示在commit
時,將容器暫停,默認為true
。
[root@wang ~]# docker commit -p tests
sha256:cf9069c773f714266dceb1a676d2149c0eb3486210b16098064a7e47d144e93d
[root@wang ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> cf9069c773f7 12 seconds ago 1.23MB
busybox latest b97242f89c8a 6 weeks ago 1.23MB
httpd latest 683a7aad17d3 6 weeks ago 138MB
更改鏡像容器名稱,鏡像有名稱時為復制,沒名稱時為剪切。
[root@wang ~]# docker tag cf9069c773f7 web:v0.1
[root@wang ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
web v0.1 cf9069c773f7 2 minutes ago 1.23MB
busybox latest b97242f89c8a 6 weeks ago 1.23MB
httpd latest 683a7aad17d3 6 weeks ago 138MB
[root@wang ~]# docker tag web:v0.1 wangming111/web:v0.2
[root@wang ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
web v0.1 cf9069c773f7 5 minutes ago 1.23MB
wangming111/web v0.2 cf9069c773f7 5 minutes ago 1.23MB
busybox latest b97242f89c8a 6 weeks ago 1.23MB
httpd latest 683a7aad17d3 6 weeks ago 138MB
登入 Docker Hub 賬號
[root@wang ~]# 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: wangming111
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-storeLogin Succeeded[root@wang ~]# docker push wangming111/web:v0.2
The push refers to repository [docker.io/wangming123/web]
def2306acc5a: Retrying in 1 second
0064d0478d00: Preparing
denied: requested access to the resource is denied
上傳鏡像
[root@wang ~]# docker push wangming111/web:v0.2
The push refers to repository [docker.io/wangming111/web]
def2306acc5a: Pushed
0064d0478d00: Pushed
v0.2: digest: sha256:ce8bd8180ce19ff284885d996201f7f923232f23ff2de936e90e432aa40bfe80 size: 734
刪除鏡像
[root@wang ~]# docker rmi wangming111/web:v0.2
Untagged: wangming111/web:v0.2
Untagged: wangming111/web@sha256:ce8bd8180ce19ff284885d996201f7f923232f23ff2de936e90e432aa40bfe80
[root@wang ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
web v0.1 cf9069c773f7 38 minutes ago 1.23MB
busybox latest b97242f89c8a 6 weeks ago 1.23MB
httpd latest 683a7aad17d3 6 weeks ago 138MB
下載鏡像
[root@wang ~]# docker pull wangming111/web:v0.2
v0.2: Pulling from wangming111/web
Digest: sha256:ce8bd8180ce19ff284885d996201f7f923232f23ff2de936e90e432aa40bfe80
Status: Downloaded newer image for wangming111/web:v0.2
docker.io/wangming111/web:v0.2
[root@wang ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
web v0.1 cf9069c773f7 39 minutes ago 1.23MB
wangming111/web v0.2 cf9069c773f7 39 minutes ago 1.23MB
busybox latest b97242f89c8a 6 weeks ago 1.23MB
httpd latest 683a7aad17d3 6 weeks ago 138MB
查看下載鏡像的內容是否一致
[root@wang ~]# docker run -it wangming111/web:v0.2
/ # ls
bin dev home root tmp var
data etc proc sys usr
/ # cat data/index.html
hello world
/ #
創建 httpd
鏡像,并設置為默認進程,-a
作者信息,-c
修改默認啟動命令,/bin/httpd
為啟動進程,-f
是不讓它在后臺運行,-h
指定目錄。
docker run -it --rm
命令可以輕松快速地啟動和停止容器。由于容器是輕量級的,啟動速度非常快,可以在幾秒鐘內啟動一個新的容器。而當容器不再使用時,rm
參數也能夠快速地清除該容器,避免垃圾堆積(當用戶退出終端時,容器會被立即刪除)。docker ps
用于查看 Docker 服務器中容器狀態(運行 / 暫停 / 停止)。
[root@wang ~]# docker run -it --rm httpd
[root@wang ~]# docker commit -a 'wangming111.com' -c 'CMD ["/bin/httpd","-f","-h","/data"]' -p 8e5929feae8d wangming111/web:v0.3
sha256:e102ed55833191216045bd6425c9e7981eb361443a883af4e65b8e9fc29c41e2
[root@wang ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
wangming111/web v0.3 e102ed558331 23 seconds ago 1.23MB
web v0.1 cf9069c773f7 About an hour ago 1.23MB
wangming111/web v0.2 cf9069c773f7 About an hour ago 1.23MB
busybox latest b97242f89c8a 6 weeks ago 1.23MB
httpd latest 683a7aad17d3 6 weeks ago 138MB
[root@wang ~]# docker push wangming111/web:v0.3
The push refers to repository [docker.io/wangming111/web]
877b56cdb8c4: Pushed
def2306acc5a: Layer already exists
0064d0478d00: Layer already exists
v0.3: digest: sha256:37a806e1b51abe84477a525dbfe4cb7f702fcbb16bcb103dbdf1ed57cfcf14e8 size: 941
[root@wang ~]# docker run -it --rm wangming111/web:v0.3
[root@wang ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
08dda626edb1 wangming111/web:v0.3 "/bin/httpd -f -h /d…" 3 minutes ago Up 3 minutes stoic_elion
5.2 鏡像的導入與導出
假如有 2 2 2 臺主機,我們在主機 1 1 1 上做了一個鏡像,主機 2 2 2 想用這個鏡像怎么辦呢?
我們可以在主機 1 1 1上 push 鏡像到鏡像倉庫中,然后在主機 2 2 2 上 pull 把鏡像拉下來使用,這種方式就顯得比較麻煩,假如我只是測試用的,在一臺主機上做好鏡像后在另一臺主機上跑一下就行了,沒必要推到倉庫上然后又把它拉到本地來。
此時我們可以在已有鏡像的基礎上把鏡像打包成一個壓縮文件,然后拷貝到另一臺主機上將其導入,這就是鏡像的 導入 和 導出 功能。
鏡像導出
[root@wang ~]# docker save -o web.tar.gz wangming111/web
[root@wang ~]# ls
anaconda-ks.cfg web.tar.gz
鏡像導入
[root@wang ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
web v0.1 cf9069c773f7 3 hours ago 1.23MB
busybox latest b97242f89c8a 6 weeks ago 1.23MB
httpd latest 683a7aad17d3 6 weeks ago 138MB
[root@wang ~]# docker load -i web.tar.gz
Loaded image: wangming111/web:v0.3
Loaded image: wangming111/web:v0.2
[root@wang ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
wangming111/web v0.3 e102ed558331 About an hour ago 1.23MB
web v0.1 cf9069c773f7 3 hours ago 1.23MB
wangming111/web v0.2 cf9069c773f7 3 hours ago 1.23MB
busybox latest b97242f89c8a 6 weeks ago 1.23MB
httpd latest 683a7aad17d3 6 weeks ago 138MB