只有光頭才能變強。html
文本已收錄至個人GitHub倉庫,歡迎Star:https://github.com/ZhongFuCheng3y/3ygit
回顧前面:github
前面兩篇已經講解了爲何須要Docker這項技術,以及解釋了Docker的基本概念/術語,使用Docker成功運行Tomcat~docker
在上篇也一樣留下一個問題:咱們知道Tomcat運行起來須要Java的支持,那麼咱們在DockerHub拉取下來的Tomcat鏡像是否是也有Java環境呢?
shell
因此,這篇主要來說講Docker鏡像相關的知識點!json
Dockerfile是用來構建Docker鏡像的文件,是由一系列命令和參數構成的腳本。centos
簡單來講:Dockerfile是鏡像的源碼。tomcat
上一篇咱們pull
了一份Tomcat
的鏡像,咱們也能夠去看看它的Dockerfile長的什麼樣:bash
咱們隨便點進去一個看一下:網絡
咱們在Dockerfile的第一行就能夠發現FROM openjdk:8-jre
,因此能夠肯定的是:在DockerHub拉取下來的Tomcat鏡像必定有Java環境!
在這裏咱們先不說如何
閱讀/編寫
Dockerfile文件,先了解到Dockerfile是鏡像的源碼便可
簡單來講:經過Dockerfile文件能夠知道咱們拉取下來的鏡像到底是怎麼構建的。
咱們知道Docker Hub有不少經常使用的鏡像,好比說Centos
。咱們去pull
一個下來看看Docker中的Centos
長啥樣:
咱們能夠發現的是:Tomcat
的SIZE居然比Centos
還要大!但按咱們常規的想法,Centos
的鏡像多是3或4GB(如今200M),Tomcat
的鏡像可能就200M(如今400M)。這是爲何呢??
若是咱們在pull
的時候觀察得比較仔細的話,能夠發現pull
會拉下不少層鏡像:
徹底pull
下來的以後,咱們若是使用docker images
只能查看到最終的鏡像:
若是咱們使用docker images -a
命令的話,能夠把中間層鏡像都查出來:
<none>
的鏡像)<none>
的鏡像(懷疑是版本的問題,個人版本是Docker版本是18.09.1,Centos的版本是CentOS Linux release 7.3.1611 。若是知道具體緣由的不妨在評論區下告訴我)Emmm,咱們可使用history
命令來看看,能夠發現Tomcat包含不少個鏡像層
還能夠發現一點:Dockerfile有多少條命令,那就有多少個鏡像層(不信你數數)
說了那麼多,就想讓你們知道:咱們拉取下來的鏡像其實是由不少中間層鏡像組成的。
再結合咱們上一篇Docker入門爲何能夠這麼簡單?,在解決Tomcat啓動時一直卡住問題時,可以發現的是,咱們可使用cd, ls
等基礎命令,但沒法使用vi
命令(須要我本身去下載)。
咱們能夠推斷出,pull
下來的鏡像由不少層鏡像組成【這些鏡像都是精簡過的(甚至連vi
命令都不支持)】
Tomcat
鏡像要的基礎環境比Centos
鏡像要多,因此Tomcat
鏡像的SIZE比Centos
要大關於Docker鏡像,有如下特色:
Dockerfile
生成json
元數據信息圖像來源:http://open.daocloud.io/allen-tan-docker-xi-lie-zhi-shen-ke-li-jie-docker-jing-xiang-da-xiao/
聯合文件系統(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
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,不妨閱讀我以前寫過的文章:
Docker每一層鏡像的json
文件,都扮演着一個很是重要的角色,其主要的做用以下:
Docker鏡像的json
文件能夠認爲是鏡像的元數據信息
今天簡單地聊了一下Docker鏡像的一些細節,但沒去深刻了解,想要繼續深刻的同窗還得經過官方文檔等途徑去學習哈。
參考資料:
樂於輸出乾貨的Java技術公衆號:Java3y。公衆號內有200多篇原創技術文章、海量視頻資源、精美腦圖,不妨來關注一下!
以爲個人文章寫得不錯,不妨點一下贊!