Docker鏡像細節

前言

只有光頭才能變強。html

文本已收錄至個人GitHub倉庫,歡迎Star:https://github.com/ZhongFuCheng3y/3ygit

Docker

回顧前面:github

前面兩篇已經講解了爲何須要Docker這項技術,以及解釋了Docker的基本概念/術語,使用Docker成功運行Tomcat~docker

在上篇也一樣留下一個問題:咱們知道Tomcat運行起來須要Java的支持,那麼咱們在DockerHub拉取下來的Tomcat鏡像是否是也有Java環境呢?shell

因此,這篇主要來說講Docker鏡像相關的知識點!json

1、簡單瞭解Dockerfile

Dockerfile是用來構建Docker鏡像的文件,是由一系列命令和參數構成的腳本centos

簡單來講:Dockerfile是鏡像的源碼tomcat

上一篇咱們pull了一份Tomcat的鏡像,咱們也能夠去看看它的Dockerfile長的什麼樣:bash

搜索,拉下去就有得看Dockerfile了

咱們隨便點進去一個看一下:網絡

Dockerfile

咱們在Dockerfile的第一行就能夠發現FROM openjdk:8-jre,因此能夠肯定的是:在DockerHub拉取下來的Tomcat鏡像必定有Java環境

在這裏咱們先不說如何閱讀/編寫Dockerfile文件,先了解到Dockerfile是鏡像的源碼便可

簡單來講:經過Dockerfile文件能夠知道咱們拉取下來的鏡像到底是怎麼構建的。

2、解除鏡像的疑惑

咱們知道Docker Hub有不少經常使用的鏡像,好比說Centos。咱們去pull一個下來看看Docker中的Centos長啥樣:

從Hub中pull一個Centos

咱們能夠發現的是:TomcatSIZE居然比Centos還要大!但按咱們常規的想法,Centos的鏡像多是3或4GB(如今200M),Tomcat的鏡像可能就200M(如今400M)。這是爲何呢??

若是咱們在pull的時候觀察得比較仔細的話,能夠發現pull會拉下不少鏡像:

pull到不少層鏡像

徹底pull下來的以後,咱們若是使用docker images只能查看到最終的鏡像:

只能看到最終咱們拉下來的鏡像

若是咱們使用docker images -a命令的話,能夠把中間層鏡像都查出來:

  • 理想效果:(在鏡像列表裏邊除了tomcat和centos應該還夾雜着名爲<none>的鏡像)
  • 遺憾的是:博主一直沒測出效果來,也就是個人鏡像列表裏沒有<none>的鏡像(懷疑是版本的問題,個人版本是Docker版本是18.09.1,Centos的版本是CentOS Linux release 7.3.1611 。若是知道具體緣由的不妨在評論區下告訴我)

理想效果

Emmm,咱們可使用history命令來看看,能夠發現Tomcat包含不少個鏡像層

使用history命令能夠發現Tomcat包含不少個鏡像層

還能夠發現一點:Dockerfile有多少條命令,那就有多少個鏡像層(不信你數數)

說了那麼多,就想讓你們知道:咱們拉取下來的鏡像其實是由不少中間層鏡像組成的。

再結合咱們上一篇Docker入門爲何能夠這麼簡單?,在解決Tomcat啓動時一直卡住問題時,可以發現的是,咱們可使用cd, ls等基礎命令,但沒法使用vi命令(須要我本身去下載)。

咱們能夠推斷出,pull下來的鏡像由不少層鏡像組成【這些鏡像都是精簡過的(甚至連vi命令都不支持)】

  • 由於Tomcat鏡像要的基礎環境比Centos鏡像要多,因此Tomcat鏡像的SIZECentos要大

3、Docker鏡像的特色

關於Docker鏡像,有如下特色:

  • Dockerfile生成
  • 呈現層級結構
  • 每層鏡像包含:鏡像文件以及鏡像json元數據信息

Docker鏡像示意圖

圖像來源:http://open.daocloud.io/allen-tan-docker-xi-lie-zhi-shen-ke-li-jie-docker-jing-xiang-da-xiao/

3.1鏡像呈現層級結構

聯合文件系統(UnionFS)是實現Docker鏡像的技術基礎。在Docker中通常使用是AUFS(Another Union File System或Advanced Multilayered Unification File System)【具體仍是得看宿主機用的什麼系統】。

在搜索中文資料的時候,經常會發現有相似的解釋:

「AUFS是一種 Union FS, 簡單來講就是「支持將不一樣目錄掛載到同一個虛擬文件系統下的文件系統」, AUFS支持爲每個成員目錄設定只讀(Rreadonly)、讀寫(Readwrite)和寫(Whiteout-able)權限。Union FS 能夠將一個Readonly的Branch和一個Writeable的Branch聯合在一塊兒掛載在同一個文件系統下」。

看得我一頭霧水....後來去官方文檔介紹AUFS:

AUFS is a union filesystem, which means that it layers multiple directories on a single Linux host and presents them as a single directory. These directories are called branches in AUFS terminology, and layers in Docker terminology

說白了,仍是能夠理解成:Docker的鏡像的基礎是聯合文件系統,它支持將文件系統中的修改信息做爲一次提交,並層層疊加,外界看到的是最外層的鏡像。(好比外界只看到Tomcat鏡像,而中間疊加了不少層鏡像)

(這裏只是拿AUFS說明,Docker實際上支持不少存儲驅動,好比還有devicemapper,overlay2(Ubuntu的14.04.4或更高版本,16.04或更高版本), overlay,zfs

3.1.1鏡像繼承(共享)

Docker鏡像能夠經過分層來進行繼承

例如,hello-world的Dockerfile鏡像FROM scratch鏡像,scratch在Docker中是一個基礎鏡像

FROM scratch
COPY hello /
CMD ["/hello"]

Centos的Dockerfile鏡像也是FROM scratch鏡像:

FROM scratch
ADD centos-7-docker.tar.xz /

LABEL org.label-schema.schema-version="1.0" \
    org.label-schema.name="CentOS Base Image" \
    org.label-schema.vendor="CentOS" \
    org.label-schema.license="GPLv2" \
    org.label-schema.build-date="20181205"

CMD ["/bin/bash"]

那麼Centos鏡像和hello-world共享同一個基礎鏡像層scratch,提升了存儲效率

再說個例子,好比咱們有一個Centos鏡像,這個鏡像大小是202M。而後,咱們基於Centos鏡像手動往裏邊添加一個Tomcat(假設這個Tomcat的大小是300M),生成一個鏡像,總大小就是502M了。

若是僅僅是單純的累加這兩個鏡像的大小:202M+502M=704M,可是因爲鏡像複用的存在,實際佔用的磁盤空間大小是:202M+300M=502M

AUFS uses the Copy-on-Write (CoW) strategy to maximize storage efficiency and minimize overhead。

若是想要了解COW,不妨閱讀我以前寫過的文章:

3.2json文件

Docker每一層鏡像的json文件,都扮演着一個很是重要的角色,其主要的做用以下:

  • 記錄 Docker 鏡像中與容器動態信息相關的內容
  • 記錄父子 Docker 鏡像之間真實的差別關係
  • 彌補 Docker 鏡像內容的完整性與動態內容的缺失

Docker鏡像的json文件能夠認爲是鏡像的元數據信息

最後

今天簡單地聊了一下Docker鏡像的一些細節,但沒去深刻了解,想要繼續深刻的同窗還得經過官方文檔等途徑去學習哈。

參考資料:

樂於輸出乾貨的Java技術公衆號:Java3y。公衆號內有200多篇原創技術文章、海量視頻資源、精美腦圖,不妨來關注一下!

帥的人都關注了

以爲個人文章寫得不錯,不妨點一下

相關文章
相關標籤/搜索