鏡像是 Docker 容器的基石惠赫,容器是鏡像的運行實例呢岗,有了鏡像才能啟動容器限府。
本章內(nèi)容安排如下:
首先通過研究幾個典型的鏡像,分析鏡像的內(nèi)部結(jié)構(gòu)供汛。
然后學習如何構(gòu)建自己的鏡像。
最后介紹怎樣管理和分發(fā)鏡像。
鏡像的內(nèi)部結(jié)構(gòu)
為什么我們要討論鏡像的內(nèi)部結(jié)構(gòu)怔昨?
如果只是使用鏡像雀久,當然不需要了解,直接通過docker命令下載和運行就可以了趁舀。
但如果我們想創(chuàng)建自己的鏡像赖捌,或者想理解 Docker 為什么是輕量級的,就非常有必要學習這部分知識了矮烹。
我們從一個最小的鏡像開始吧越庇。
hello-world - 最小的鏡像
hello-world 是 Docker 官方提供的一個鏡像,通常用來驗證 Docker 是否安裝成功奉狈。
我們先通過docker pull從 Docker Hub 下載它卤唉。
用docker images命令查看鏡像的信息。
hello-world 鏡像竟然還不到 2KB!
通過docker run運行仁期。
其實我們更關(guān)心 hello-world 鏡像包含哪些內(nèi)容桑驱。
Dockerfile 是鏡像的描述文件,定義了如何構(gòu)建 Docker 鏡像跛蛋。Dockerfile 的語法簡潔且可讀性強熬的,后面我們會專門討論如何編寫 Dockerfile。
hello-world 的 Dockerfile 內(nèi)容如下:
只有短短三條指令赊级。
FROM scratch
此鏡像是從白手起家押框,從 0 開始構(gòu)建。
COPY hello /
將文件“hello”復(fù)制到鏡像的根目錄理逊。
CMD ["/hello"]
容器啟動時橡伞,執(zhí)行 /hello
鏡像 hello-world 中就只有一個可執(zhí)行文件 “hello”,其功能就是打印出 “Hello from Docker ......” 等信息挡鞍。
/hello 就是文件系統(tǒng)的全部內(nèi)容骑歹,連最基本的 /bin,/usr, /lib, /dev 都沒有墨微。
hello-world 雖然是一個完整的鏡像道媚,但它并沒有什么實際用途。通常來說翘县,我們希望鏡像能提供一個基本的操作系統(tǒng)環(huán)境最域,用戶可以根據(jù)需要安裝和配置軟件。這樣的鏡像我們稱作 base 鏡像锈麸。
我們下一節(jié)討論 base 鏡像
base 鏡像有兩層含義:
不依賴其他鏡像镀脂,從 scratch 構(gòu)建。
其他鏡像可以之為基礎(chǔ)進行擴展忘伞。
所以薄翅,能稱作 base 鏡像的通常都是各種 Linux 發(fā)行版的 Docker 鏡像沙兰,比如 Ubuntu, Debian, CentOS 等。
我們以 CentOS 為例考察 base 鏡像包含哪些內(nèi)容翘魄。
下載鏡像:
docker pull centos
查看鏡像信息:
鏡像大小不到 200MB鼎天。
等一下!
一個 CentOS 才 200MB 暑竟?
平時我們安裝一個 CentOS 至少都有幾個 GB斋射,怎么可能才 200MB !
相信這是幾乎所有 Docker 初學者都會有的疑問,包括我自己但荤。下面我們來解釋這個問題罗岖。
Linux 操作系統(tǒng)由內(nèi)核空間和用戶空間組成。如下圖所示:
rootfs
內(nèi)核空間是 kernel腹躁,Linux 剛啟動時會加載 bootfs 文件系統(tǒng)桑包,之后 bootfs 會被卸載掉。
用戶空間的文件系統(tǒng)是 rootfs潜慎,包含我們熟悉的 /dev, /proc, /bin 等目錄捡多。
對于 base 鏡像來說,底層直接用 Host 的 kernel铐炫,自己只需要提供 rootfs 就行了垒手。
而對于一個精簡的 OS,rootfs 可以很小倒信,只需要包括最基本的命令科贬、工具和程序庫就可以了。相比其他 Linux 發(fā)行版鳖悠,CentOS 的 rootfs 已經(jīng)算臃腫的了榜掌,alpine 還不到 10MB。
我們平時安裝的 CentOS 除了 rootfs 還會選裝很多軟件乘综、服務(wù)憎账、圖形桌面等,需要好幾個 GB 就不足為奇了卡辰。
base 鏡像提供的是最小安裝的 Linux 發(fā)行版胞皱。
下面是 CentOS 鏡像的 Dockerfile 的內(nèi)容:
第二行 ADD 指令添加到鏡像的 tar 包就是 CentOS 7 的 rootfs。在制作鏡像時九妈,這個 tar 包會自動解壓到 / 目錄下反砌,生成 /dev, /proc, /bin 等目錄。
注:可在 Docker Hub 的鏡像描述頁面中查看 Dockerfile 萌朱。
支持運行多種 Linux OS
不同 Linux 發(fā)行版的區(qū)別主要就是 rootfs宴树。
比如 Ubuntu 14.04 使用 upstart 管理服務(wù),apt 管理軟件包晶疼;而 CentOS 7 使用 systemd 和 yum酒贬。這些都是用戶空間上的區(qū)別又憨,Linux kernel 差別不大。
所以 Docker 可以同時支持多種 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(比如我們的實驗環(huán)境),那么在 CentOS 容器中使用的實際是是 Host 4.x.x 的 kernel棵癣。
① Host kernel 為 4.4.0-31
② 啟動并進入 CentOS 容器
③ 驗證容器是 CentOS 7
④ 容器的 kernel 版本與 Host 一致
容器只能使用 Host 的 kernel辕翰,并且不能修改。
所有容器都共用 host 的 kernel狈谊,在容器中沒辦法對 kernel 升級喜命。如果容器對 kernel 版本有要求(比如應(yīng)用只能在某個 kernel 版本下運行),則不建議用容器河劝,這種場景虛擬機可能更合適壁榕。
。