2019-04-23-docker基本知識(shí)(鏡像)

鏡像是 Docker 容器的基石,容器是鏡像的運(yùn)行實(shí)例,有了鏡像才能啟動(dòng)容器。

本章內(nèi)容安排如下:

首先通過研究幾個(gè)典型的鏡像,分析鏡像的內(nèi)部結(jié)構(gòu)。

然后學(xué)習(xí)如何構(gòu)建自己的鏡像。

最后介紹怎樣管理和分發(fā)鏡像。

鏡像的內(nèi)部結(jié)構(gòu)

為什么我們要討論鏡像的內(nèi)部結(jié)構(gòu)?

如果只是使用鏡像,當(dāng)然不需要了解,直接通過docker命令下載和運(yùn)行就可以了。

但如果我們想創(chuàng)建自己的鏡像,或者想理解 Docker 為什么是輕量級(jí)的,就非常有必要學(xué)習(xí)這部分知識(shí)了。

我們從一個(gè)最小的鏡像開始吧。

hello-world - 最小的鏡像

hello-world 是 Docker 官方提供的一個(gè)鏡像,通常用來驗(yàn)證 Docker 是否安裝成功。

我們先通過docker pull從 Docker Hub 下載它。

用docker images命令查看鏡像的信息。

hello-world 鏡像竟然還不到 2KB!

通過docker run運(yùn)行。

其實(shí)我們更關(guān)心 hello-world 鏡像包含哪些內(nèi)容。

Dockerfile 是鏡像的描述文件,定義了如何構(gòu)建 Docker 鏡像。Dockerfile 的語法簡潔且可讀性強(qiáng),后面我們會(huì)專門討論如何編寫 Dockerfile。

hello-world 的 Dockerfile 內(nèi)容如下:

只有短短三條指令。

FROM scratch

此鏡像是從白手起家,從 0 開始構(gòu)建。

COPY hello /

將文件“hello”復(fù)制到鏡像的根目錄。

CMD ["/hello"]

容器啟動(dòng)時(shí),執(zhí)行 /hello

鏡像 hello-world 中就只有一個(gè)可執(zhí)行文件 “hello”,其功能就是打印出 “Hello from Docker ......” 等信息。

/hello 就是文件系統(tǒng)的全部內(nèi)容,連最基本的 /bin,/usr, /lib, /dev 都沒有。

hello-world 雖然是一個(gè)完整的鏡像,但它并沒有什么實(shí)際用途。通常來說,我們希望鏡像能提供一個(gè)基本的操作系統(tǒng)環(huán)境,用戶可以根據(jù)需要安裝和配置軟件。這樣的鏡像我們稱作 base 鏡像。

我們下一節(jié)討論 base 鏡像

base 鏡像有兩層含義:

不依賴其他鏡像,從 scratch 構(gòu)建。

其他鏡像可以之為基礎(chǔ)進(jìn)行擴(kuò)展。

所以,能稱作 base 鏡像的通常都是各種 Linux 發(fā)行版的 Docker 鏡像,比如 Ubuntu, Debian, CentOS 等。

我們以 CentOS 為例考察 base 鏡像包含哪些內(nèi)容。

下載鏡像:

docker pull centos

查看鏡像信息:

鏡像大小不到 200MB。

等一下!

一個(gè) CentOS 才 200MB ?

平時(shí)我們安裝一個(gè) CentOS 至少都有幾個(gè) GB,怎么可能才 200MB !

相信這是幾乎所有 Docker 初學(xué)者都會(huì)有的疑問,包括我自己。下面我們來解釋這個(gè)問題。

Linux 操作系統(tǒng)由內(nèi)核空間和用戶空間組成。如下圖所示:

rootfs

內(nèi)核空間是 kernel,Linux 剛啟動(dòng)時(shí)會(huì)加載 bootfs 文件系統(tǒng),之后 bootfs 會(huì)被卸載掉。

用戶空間的文件系統(tǒng)是 rootfs,包含我們熟悉的 /dev, /proc, /bin 等目錄。

對(duì)于 base 鏡像來說,底層直接用 Host 的 kernel,自己只需要提供 rootfs 就行了。

而對(duì)于一個(gè)精簡的 OS,rootfs 可以很小,只需要包括最基本的命令、工具和程序庫就可以了。相比其他 Linux 發(fā)行版,CentOS 的 rootfs 已經(jīng)算臃腫的了,alpine 還不到 10MB。

我們平時(shí)安裝的 CentOS 除了 rootfs 還會(huì)選裝很多軟件、服務(wù)、圖形桌面等,需要好幾個(gè) GB 就不足為奇了。

base 鏡像提供的是最小安裝的 Linux 發(fā)行版。

下面是 CentOS 鏡像的 Dockerfile 的內(nèi)容:

第二行 ADD 指令添加到鏡像的 tar 包就是 CentOS 7 的 rootfs。在制作鏡像時(shí),這個(gè) tar 包會(huì)自動(dòng)解壓到 / 目錄下,生成 /dev, /proc, /bin 等目錄。

注:可在 Docker Hub 的鏡像描述頁面中查看 Dockerfile 。

支持運(yùn)行多種 Linux OS

不同 Linux 發(fā)行版的區(qū)別主要就是 rootfs。

比如 Ubuntu 14.04 使用 upstart 管理服務(wù),apt 管理軟件包;而 CentOS 7 使用 systemd 和 yum。這些都是用戶空間上的區(qū)別,Linux kernel 差別不大。

所以 Docker 可以同時(shí)支持多種 Linux 鏡像,模擬出多種操作系統(tǒng)環(huán)境。

上圖 Debian 和 BusyBox(一種嵌入式 Linux)上層提供各自的 rootfs,底層共用 Docker Host 的 kernel。

這里需要說明的是:

base 鏡像只是在用戶空間與發(fā)行版一致,kernel 版本與發(fā)行版是不同的。

例如 CentOS 7 使用 3.x.x 的 kernel,如果 Docker Host 是 Ubuntu 16.04(比如我們的實(shí)驗(yàn)環(huán)境),那么在 CentOS 容器中使用的實(shí)際是是 Host 4.x.x 的 kernel。

① Host kernel 為 4.4.0-31

② 啟動(dòng)并進(jìn)入 CentOS 容器

③ 驗(yàn)證容器是 CentOS 7

④ 容器的 kernel 版本與 Host 一致

容器只能使用 Host 的 kernel,并且不能修改。

所有容器都共用 host 的 kernel,在容器中沒辦法對(duì) kernel 升級(jí)。如果容器對(duì) kernel 版本有要求(比如應(yīng)用只能在某個(gè) kernel 版本下運(yùn)行),則不建議用容器,這種場(chǎng)景虛擬機(jī)可能更合適。

。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容