深入浅出Docker 镜像 | 技术头条
戳藍(lán)字“CSDN云計(jì)算”關(guān)注我們哦!
技術(shù)頭條:干貨、簡(jiǎn)潔、多維全面。更多云計(jì)算精華知識(shí)盡在眼前,get要點(diǎn)、solve難題,統(tǒng)統(tǒng)不在話下!
作為云計(jì)算的當(dāng)紅明星Docker?來(lái)勢(shì)洶洶,它就像一場(chǎng)森林大火,燒到了我們中間。因?yàn)楣ぷ鞯脑?#xff0c;每天都會(huì)和容器云打交道。但是,我發(fā)現(xiàn)經(jīng)常會(huì)有些新加入的同事在理解Docker命令方面存在一些問(wèn)題,尤其是在Docker 鏡像底層的工作原理和容器與容器鏡像的關(guān)系上。
通常情況下一項(xiàng)新的技術(shù)誕生時(shí)往往會(huì)伴隨著較多的媒體宣傳甚至炒作,且在推廣產(chǎn)品的過(guò)程中往往會(huì)出現(xiàn)一些新的技術(shù)名詞,讓人感覺(jué)云里霧里。Docker 的誕生和推廣正是在這種情況下進(jìn)行的。
對(duì)于產(chǎn)品本身而言媒體的宣傳和炒作可以幫助他們快速的在市場(chǎng)中進(jìn)行推廣,但是這種宣傳和炒作也會(huì)導(dǎo)致很多用戶很難看清被宣傳產(chǎn)品的技術(shù)的本質(zhì),不利于用戶對(duì)技術(shù)的掌握,更加不利于用戶對(duì)產(chǎn)品的深度使用。
?
一般情況下只有真正理解了某門(mén)技術(shù)的原理才能真正掌握這一門(mén)技術(shù),接下來(lái)才能去深入的使用這門(mén)技術(shù)。下面我們會(huì)由淺入深出的帶大家了解下Docker 鏡像及其相關(guān)技術(shù)的原理和本質(zhì)。
?
?容器 VS 容器鏡像
?
在說(shuō)Docker 鏡像的原理知識(shí)之前,我們先看下docker 容器和docker 鏡像的區(qū)別,因?yàn)檫@部分我們后面會(huì)涉及到。
?
簡(jiǎn)單說(shuō)來(lái),我們可以將Docker 鏡像看成是Docker 容器的靜態(tài)時(shí),也可將Docker 容器看成是Docker鏡像的運(yùn)行時(shí)。
?
從Docker 的官方文檔來(lái)看,Docker 容器的定義和 Docker 鏡像的定義幾乎是相同,Docker 容器和Docker 鏡像的區(qū)別主要在于docker 容器多出了一個(gè)可寫(xiě)層。
?
?
容器中的進(jìn)程就運(yùn)行在這個(gè)可寫(xiě)層,這個(gè)可寫(xiě)層有兩個(gè)狀態(tài),即運(yùn)行態(tài)和退出態(tài)。當(dāng)我們docker run 運(yùn)行容器后,docker 容器就進(jìn)入了運(yùn)行態(tài),當(dāng)我們停止正在運(yùn)行中的容器時(shí),docker 容器就進(jìn)入了退出態(tài)。
?
我們將容器從運(yùn)行態(tài)轉(zhuǎn)為退出態(tài)時(shí),期間發(fā)生的變更都會(huì)寫(xiě)入到容器的文件系統(tǒng)中(需要注意的是,此處不是寫(xiě)入到了docker 鏡像中),這方面的變化下文中我們還會(huì)再細(xì)說(shuō)。
?????????????
Docker 存儲(chǔ)簡(jiǎn)介
?
簡(jiǎn)單說(shuō)來(lái)Docker 鏡像就是一組只讀的目錄,或者叫只讀的 Docker 容器模板,鏡像中含有一個(gè)Docker 容器運(yùn)行所需要的文件系統(tǒng),所以我們說(shuō)Docker 鏡像是啟動(dòng)一個(gè)Docker 容器的基礎(chǔ)。
?
如果這樣不是很好理解,我們可以通過(guò)一個(gè)圖一起看下:
從圖中可以看出除了最上面的一層為讀寫(xiě)層之外,下面的其他的層都是只讀的鏡像層,并且除了最下面的一層外,其他的層都有會(huì)有一個(gè)指針指向自己下面的一層鏡像。
雖然統(tǒng)一文件系統(tǒng)(union file system)技術(shù)將不同的鏡像層整合成一個(gè)統(tǒng)一的文件系統(tǒng),為構(gòu)成一個(gè)完整容器鏡像的層提供了一個(gè)統(tǒng)一的視角,隱藏了多個(gè)層的復(fù)雜性,對(duì)用戶來(lái)說(shuō)只存在一個(gè)文件系統(tǒng),但圖中的這些層并不是不能看到的,如果需要查看的話可以進(jìn)入運(yùn)行Docker的機(jī)器上進(jìn)行查看,從這些層中可以看到Docker 內(nèi)部實(shí)現(xiàn)的一些細(xì)節(jié),接下來(lái)我們一起看下。
?
一般剛接觸Docker 不久的話可能會(huì)不太清楚Docker 的存儲(chǔ)方式是怎樣的,并且可能也不太清楚Docker 容器的鏡像到底存儲(chǔ)在什么路徑下,比較迷茫。
?
有些同學(xué)想了解下Docker 的鏡像數(shù)據(jù)存儲(chǔ)在什么位置,然后谷歌了下幾篇博文,說(shuō)是在/var/lib/docker 下有個(gè)aufs目錄,結(jié)果在自己機(jī)器上進(jìn)到這個(gè)路徑后發(fā)現(xiàn)沒(méi)有aufs相關(guān)的目錄,然后以為是版本的問(wèn)題,其實(shí)不然。
?
以Linux服務(wù)器為例,其實(shí)Docker 的容器鏡像和容器本身的數(shù)據(jù)都存放在服務(wù)器的 /var/lib/docker/ 這個(gè)路徑下。不過(guò)不同的linux發(fā)行版存儲(chǔ)方式上有差別,比如,在ubuntu發(fā)行版上存儲(chǔ)方式為AUFS,CentOS發(fā)行版上的存儲(chǔ)方式為device mapper。
?
/var/lib/docker 路徑下的信息在不同的階段會(huì)有變化,從筆者個(gè)人經(jīng)驗(yàn)來(lái)看,了解這幾個(gè)階段中新增的數(shù)據(jù)以及容器與鏡像的存儲(chǔ)結(jié)構(gòu)的變化非常有利于我們對(duì)Docker容器以及Docker鏡像的理解。
接下來(lái)我們一起看下Docker運(yùn)行后、下載鏡像后、運(yùn)行容器后三個(gè)階段中Docker 存儲(chǔ)的變化。
?
環(huán)境信息:
?
系統(tǒng)發(fā)行版:CentOS7.2。
內(nèi)核版本:3.10.0-327.36.1.el7.x86_64
Docker 版本:1.8
啟動(dòng)Docker后
?
在此我們假設(shè)大家已經(jīng)安裝好了Docker環(huán)境,具體安裝的過(guò)程不再贅述。
?
???# 啟動(dòng)Docker 服務(wù)
???[root@influxdb ~]# systemctl start docker
?
???# 查看/var/lib/docker路徑下的文件結(jié)構(gòu)
?
???[root@localhost docker]# tree .
├── containers
├── devicemapper
│?? ├── devicemapper
│?? │?? ├── data
│?? │?? └── metadata
│?? └── metadata
│?? ????├── base
│?? ????├── deviceset-metadata
│?? ????└── transaction-metadata
├── graph
├── linkgraph.db
├── repositories-devicemapper
├── tmp
├── trust
└── volumes
?
8 directories, 7 files
?
注:必須啟動(dòng)Docker 服務(wù)后查看,如果沒(méi)有啟動(dòng)Docker 進(jìn)程則路徑/var/lib/docker 不存在。
?
前文中我們已經(jīng)提到過(guò),CentOS發(fā)行版中Docker 服務(wù)使用的存儲(chǔ)方式為devicemapper,所以我們從前面tree命令的結(jié)果中可以看到出現(xiàn)了目錄devicemapper。
?
有些同學(xué)可能會(huì)問(wèn)什么是devicemapper?
?
太陽(yáng)底下無(wú)新鮮事,devicemapper 并不是伴隨著Docker 才出現(xiàn)的,早在linux2.6版本的內(nèi)核時(shí)其實(shí)就已經(jīng)引入了devicemapper,且當(dāng)時(shí)是作為一個(gè)很重要的技術(shù)出現(xiàn)的。
?
簡(jiǎn)單說(shuō)來(lái)devicemapper 就是Docker 服務(wù)的一個(gè)存儲(chǔ)驅(qū)動(dòng),或者叫Docker 服務(wù)的存儲(chǔ)后端。Devicemapper 其實(shí)是一個(gè)基于內(nèi)核的框架,這個(gè)框架中對(duì)linux上很多的功能進(jìn)行了增強(qiáng),比如對(duì)linux上高級(jí)卷管理功能的增強(qiáng)。
Devicemapper 存儲(chǔ)驅(qū)動(dòng)將我們的每個(gè)docker鏡像和docker容器都存在在自己的虛擬設(shè)備中,devicemapper的這些設(shè)備相當(dāng)于我們常見(jiàn)的一般的寫(xiě)時(shí)復(fù)制快照設(shè)備的超配版本。通過(guò)上面的介紹,有些同學(xué)可能以為devicemapper 存儲(chǔ)驅(qū)動(dòng)是工作在塊級(jí)別的,但是devicempper 實(shí)際是工作在文件級(jí)別的,也就是說(shuō)devicemapper 存儲(chǔ)驅(qū)動(dòng)和寫(xiě)時(shí)復(fù)制操作都是直接操作塊,而不是對(duì)文件進(jìn)行操作。
?
以上是我們關(guān)于Docker 服務(wù)的devicemapper 存儲(chǔ)驅(qū)動(dòng)的一個(gè)簡(jiǎn)單的介紹,Docker 官方文檔中提供了很多的有關(guān)Docker 存儲(chǔ)驅(qū)動(dòng)的介紹,感興趣的同學(xué)可以自行查閱。
?
進(jìn)一步的查看的話,可以看到路徑/var/lib/docker/devicemapper下面有兩個(gè)目錄,分別為devicemapper和data,其中目錄devicemapper 下存在兩個(gè)名為data和metadata的文件,兩個(gè)文件從名稱(chēng)即可看出一個(gè)是鏡像數(shù)據(jù)的存儲(chǔ)池,一個(gè)為鏡像相關(guān)的元數(shù)據(jù)。接下去我們會(huì)逐個(gè)看下這個(gè)路徑下的文件。
?
進(jìn)入上面提到的目錄metadata下,可以看到這個(gè)目錄中已經(jīng)存在三個(gè)文件,分別為:base、deviceset-metadata和transction-metadata,這三個(gè)文分別用來(lái)存放上文中我們提到的元數(shù)據(jù)的id、大小和uuid等信息。
[root@localhost metadata]# pwd
/var/lib/docker/devicemapper/metadata
[root@localhost metadata]# ls
base ?deviceset-metadata ?transaction-metadata
除了上面提到的幾個(gè)目錄,上文中tree的結(jié)果中還有幾個(gè)目錄,分別為:containers、devicemapper、graph、linkgraph.db、repositories-devicemapper、tmp、trust和volumes。這幾個(gè)文件對(duì)于docker 的鏡像存儲(chǔ)來(lái)說(shuō)都很重要,我們以文件repositories-devicemapper為例,看下這個(gè)文件對(duì)于鏡像存儲(chǔ)所起到的作用。
?
[root@localhost docker]# pwd
/var/lib/docker
[root@localhost docker]# ls
containers ?devicemapper ?graph ?linkgraph.db ?repositories-devicemapper ?tmp ?trust ?volumes
?
我們可以先看下repositories-devicemapper 這個(gè)文件中在當(dāng)前的階段中有什么:
root@localhost docker]# cat repositories-devicemapper
{"Repositories":{}}[root@localhost docker]#
從上面cat的結(jié)果中我們不難看出,文件repositories-devicemapper 中其實(shí)記錄的就是docker 鏡像的屬性信息,比如鏡像名稱(chēng)、鏡像標(biāo)簽、鏡像的ID等信息,如果鏡像剛好沒(méi)有標(biāo)簽的話默認(rèn)會(huì)以lastet作為標(biāo)簽。
以上是對(duì)Docker 服務(wù)運(yùn)行后pull鏡像之前/var/lib/docker 路徑下數(shù)據(jù)的一個(gè)簡(jiǎn)單的解讀,相信大家通過(guò)上面的描述已經(jīng)對(duì)docker鏡像有了一些更深入的認(rèn)識(shí)。下面我們看下在我們pull 自己的第一個(gè)docker鏡像之后路徑/var/lib/docker 之下的數(shù)據(jù)會(huì)發(fā)生怎樣的變化。
?
Pull 鏡像后
?
在此我們以一個(gè)nginx鏡像為例一起看下這個(gè)階段的變化。
?
????# pull 示例鏡像
[root@localhost docker]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
22f3bf58cd09: Pull complete
ea2fc476f5f0: Pull complete
81d728438afe: Pull complete
303a6dec1190: Pull complete
d43816b44a22: Pull complete
dc02db50a25a: Pull complete
6f650a34b308: Pull complete
a634e96a9de9: Pull complete
72f3ebe1e4d7: Pull complete
c2c9e418b22c: Pull complete
Digest: sha256:a82bbaf63c445ee9b854d182254c62e34e6fa92f63d7b4fdf6cea7e76665e06e
Status: Downloaded newer image for nginx:latest
?
# 查看鏡像是否已經(jīng)在本地
[root@localhost docker]# docker images
REPOSITORY ?????????TAG ????????????????IMAGE ID ???????????CREATED ????????????VIRTUAL SIZE
nginx ??????????????latest ?????????????c2c9e418b22c ???????2 weeks ago ????????109.3 MB
[root@localhost docker]#
?
在此我們沒(méi)有指定nginx鏡像的tag,因此默認(rèn)拉去了最新的版本。然后我們看下路徑/var/lib/docker 下是否有變化:
[root@localhost docker]# tree .
.
├── containers
├── devicemapper
│?? ├── devicemapper
│?? │?? ├── data
│?? │?? └── metadata
……
省略若干數(shù)據(jù)
……
│?? │?? ├── checksum
│?? │?? ├── json
│?? │?? ├── layersize
│?? │?? ├── tar-data.json.gz
│?? │?? └── v1Compatibility
│?? ├── 303a6dec11900c97f5d7555d31adec02d2e5e4eaa1a77537e7a5ebd45bb7fcd2
│?? │?? ├── checksum
│?? │?? ├── json
│?? │?? ├── layersize
│?? │?? ├── tar-data.json.gz
│?? │?? └── v1Compatibility
│?? ├── 6f650a34b3083c96cf8b7babc7a391227c0f78e0d07067071c46e31bd834de3a
│?? │?? ├── checksum
│?? │?? ├── json
│?? │?? ├── layersize
│?? │?? ├── tar-data.json.gz
│?? │?? └── v1Compatibility
│?? ├── 72f3ebe1e4d793a50836d4e070c94ef7497c80111d178e867014981f64696a39
│?? │?? ├── checksum
│?? │?? ├── json
│?? │?? ├── layersize
│?? │?? ├── tar-data.json.gz
│?? │?? └── v1Compatibility
│?? ├── 81d728438afe98602e2e692c20299ecf41b93173fb12351c1b59820b17fb16b9
│?? │?? ├── checksum
│?? │?? ├── json
│?? │?? ├── layersize
│?? │?? ├── tar-data.json.gz
│?? │?? └── v1Compatibility
│?? ├── a634e96a9de9f1e280efaecdd43c7273ac43e109a42ab6c76ab2d2261c8cdc50
│?? │?? ├── checksum
│?? │?? ├── json
│?? │?? ├── layersize
│?? │?? ├── tar-data.json.gz
│?? │?? └── v1Compatibility
│?? ├──
……
省略若干數(shù)據(jù)
……
│?? ├── ea2fc476f5f055f9e44963987903ecfe0cb480b7e387d8b5cb64006832110afc
│?? │?? ├── checksum
│?? │?? ├── json
│?? │?? ├── layersize
│?? │?? ├── tar-data.json.gz
│?? │?? └── v1Compatibility
│?? └── _tmp
├── linkgraph.db
├── repositories-devicemapper
├── tmp
├── trust
└── volumes
?
30 directories, 67 files
[root@localhost docker]#
?
從結(jié)尾的目錄數(shù)和文件數(shù)也可以看出,在我們拉取鏡像后/var/lib/docker 下多出了很多的文件(拉取鏡像之前,只有8個(gè)目錄,7個(gè)文件),下面我們一步步的分析。
?
如果這個(gè)時(shí)候看下路徑/var/lib/docker下的文件的話,可以很容易的看到發(fā)生變化的主要是下面這三個(gè)文件:/var/lib/docker/devicemapper/metadata、/var/lib/docker/devicemapper/mnt以及/var/lib/docker/graph。我們先看下metadata這個(gè)文件:
?
?從結(jié)果可以看出除了上一個(gè)階段中已經(jīng)有的base、deviceset-metadata等幾個(gè)文件外,還多出了一些名字較長(zhǎng)的文件,我們挨個(gè)看下這幾個(gè)文件中的數(shù)據(jù):
[root@localhost metadata]# cat base
{"device_id":1,"size":107374182400,"transaction_id":1,"initialized":true} [root@localhost metadata]# cat 22f3bf58cd0949b57df2dc161e7026a8cc77699b6a8be7d0e3085e252a5439c3
{"device_id":2,"size":107374182400,"transaction_id":2,"initialized":false}
[root@localhost metadata]# cat ea2fc476f5f055f9e44963987903ecfe0cb480b7e387d8b5cb64006832110afc
{"device_id":3,"size":107374182400,"transaction_id":3,"initialized":false}
?
[root@localhost metadata]# cat 81d728438afe98602e2e692c20299ecf41b93173fb12351c1b59820b17fb16b9
{"device_id":4,"size":107374182400,"transaction_id":4,"initialized":false} [root@localhost metadata]# cat d43816b44a2280148da8d9b6ce2f357bff9b2e59ef386181f36a4a433a9aad6c
{"device_id":6,"size":107374182400,"transaction_id":6,"initialized":false} [root@localhost metadata]# cat 303a6dec11900c97f5d7555d31adec02d2e5e4eaa1a77537e7a5ebd45bb7fcd2
{"device_id":5,"size":107374182400,"transaction_id":5,"initialized":false} [root@localhost metadata]# cat a634e96a9de9f1e280efaecdd43c7273ac43e109a42ab6c76ab2d2261c8cdc50
{"device_id":9,"size":107374182400,"transaction_id":9,"initialized":false} [root@localhost metadata]# cat dc02db50a25a87ca227492197721e97d19f1822701fe3ec73533a0811a6393a7
{"device_id":7,"size":107374182400,"transaction_id":7,"initialized":false} [root@localhost metadata]# cat 6f650a34b3083c96cf8b7babc7a391227c0f78e0d07067071c46e31bd834de3a
{"device_id":8,"size":107374182400,"transaction_id":8,"initialized":false} [root@localhost metadata]# cat 72f3ebe1e4d793a50836d4e070c94ef7497c80111d178e867014981f64696a39
{"device_id":10,"size":107374182400,"transaction_id":10,"initialized":false} [root@localhost metadata]# cat c2c9e418b22ca5a0b02ef0c2bd02c34ad792d1fc271e5580fdb3252979ccc092
{"device_id":11,"size":107374182400,"transaction_id":11,"initialized":false}
?
從上面的結(jié)果可以看出上面的幾個(gè)文件中的device_id數(shù)值是按照順序排列下來(lái)的,換句話說(shuō)就是除了上一個(gè)階段中已經(jīng)存在的base文件,上面結(jié)果中其他的幾個(gè)文件都是nginx鏡像的中間鏡像層,也就是我們經(jīng)常執(zhí)行的命令docker images –a 的結(jié)果中看到的構(gòu)成當(dāng)前鏡像的各個(gè)鏡像層。
?
? 接下來(lái)我們?cè)倏匆粋€(gè)變化較大的文件/var/lib/docker/graph。
?
??[root@localhost graph]# tree .
.
├── 22f3bf58cd0949b57df2dc161e7026a8cc77699b6a8be7d0e3085e252a5439c3
│?? ├── checksum
│?? ├── json
│?? ├── layersize
│?? ├── tar-data.json.gz
│?? └── v1Compatibility
├── 303a6dec11900c97f5d7555d31adec02d2e5e4eaa1a77537e7a5ebd45bb7fcd2
│?? ├── checksum
│?? ├── json
│?? ├── layersize
│?? ├── tar-data.json.gz
│?? └── v1Compatibility
├── 6f650a34b3083c96cf8b7babc7a391227c0f78e0d07067071c46e31bd834de3a
│?? ├── checksum
│?? ├── json
│?? ├── layersize
│?? ├── tar-data.json.gz
│?? └── v1Compatibility
├── 72f3ebe1e4d793a50836d4e070c94ef7497c80111d178e867014981f64696a39
│?? ├── checksum
│?? ├── json
│?? ├── layersize
│?? ├── tar-data.json.gz
│?? └── v1Compatibility
├── 81d728438afe98602e2e692c20299ecf41b93173fb12351c1b59820b17fb16b9
│?? ├── checksum
│?? ├── json
│?? ├── layersize
│?? ├── tar-data.json.gz
│?? └── v1Compatibility
├── a634e96a9de9f1e280efaecdd43c7273ac43e109a42ab6c76ab2d2261c8cdc50
│?? ├── checksum
│?? ├── json
│?? ├── layersize
│?? ├── tar-data.json.gz
│?? └── v1Compatibility
├── c2c9e418b22ca5a0b02ef0c2bd02c34ad792d1fc271e5580fdb3252979ccc092
│?? ├── checksum
│?? ├── json
│?? ├── layersize
│?? ├── tar-data.json.gz
│?? └── v1Compatibility
├── d43816b44a2280148da8d9b6ce2f357bff9b2e59ef386181f36a4a433a9aad6c
│?? ├── checksum
│?? ├── json
│?? ├── layersize
│?? ├── tar-data.json.gz
│?? └── v1Compatibility
├── dc02db50a25a87ca227492197721e97d19f1822701fe3ec73533a0811a6393a7
│?? ├── checksum
│?? ├── json
│?? ├── layersize
│?? ├── tar-data.json.gz
│?? └── v1Compatibility
├── ea2fc476f5f055f9e44963987903ecfe0cb480b7e387d8b5cb64006832110afc
│?? ├── checksum
│?? ├── json
│?? ├── layersize
│?? ├── tar-data.json.gz
│?? └── v1Compatibility
└── _tmp
?
11 directories, 50 files
?
?從上面的結(jié)果中可以很明顯的看到我們的鏡像nginx及其每一個(gè)nginx鏡像的中間層對(duì)應(yīng)的目錄下都包含如下幾個(gè)文件:checksum、json、layerrize、tar-data.json.gz和v1Compatibility。我們?nèi)我庹乙粋€(gè)文件看下這幾個(gè)文件中存放了什么數(shù)據(jù)。
?
(1)?Checksum
?
???
其實(shí)從文件名稱(chēng)即可看出每個(gè)鏡像層中的checksum文件存放的是當(dāng)前鏡像層的md5值,用于核對(duì)當(dāng)前鏡像層的數(shù)據(jù)是否完整。
?
(2)?json
?
?
? ?從cat 的結(jié)果中可以看出json文件中存放的數(shù)據(jù)較多,比如Hostname、Domainname、User、Image等信息,而且很多參數(shù)和我們經(jīng)常接觸的Dockerfile中的參數(shù)相似。相比較前面的checksum文件這個(gè)文件中的內(nèi)容相對(duì)較復(fù)雜,在此我們也解釋下。
?
? ? ?此處的json文件中一般主要用于存放鏡像中涉及的動(dòng)態(tài)信息,但需要注意的是此處的json文件并不僅僅被用于存儲(chǔ)docker鏡像的動(dòng)態(tài)信息(很多同學(xué)可能會(huì)認(rèn)為此處的json文件只是被用來(lái)描述Docker容器的動(dòng)態(tài)信息的),我們?cè)谑褂肈ockerfile 構(gòu)建鏡像時(shí),Dockerfile 構(gòu)建過(guò)程中涉及到的所有操作基本都被記錄到這個(gè)json文件中。
??????
? ? ?說(shuō)到這兒,有些同學(xué)可能會(huì)問(wèn)這個(gè)json是在什么階段被使用到的,好問(wèn)題。通過(guò)下面這個(gè)圖我想大家應(yīng)該就能看明白了:
?
?
? ? ?從圖中我們可以看出每個(gè)鏡像層的json文件其實(shí)是由Docker 守護(hù)進(jìn)程進(jìn)行解析的。Docker 守護(hù)進(jìn)程通過(guò)json文件可以解析出運(yùn)行容器需要的各種數(shù)據(jù),比如環(huán)境變量、workdir以及容器啟動(dòng)時(shí)需要執(zhí)行的ENTRYPOINT或者CMD命令等。Docker 守護(hù)進(jìn)程從json文件中獲取到這些數(shù)據(jù)后,接下來(lái)就開(kāi)始進(jìn)行容器進(jìn)程的初始化。
?
(3)?layersize
?
? ? ?從文件名稱(chēng)即可看出,這個(gè)文件中存放的為當(dāng)前鏡像層的占用空間大小:
??????
?
(4)?repositories-devicemapper
?
上一階段中我們解釋過(guò)這個(gè)文件中記錄的為當(dāng)前鏡像層的屬性信息,比如鏡像名稱(chēng)信息、鏡像標(biāo)簽信息、鏡像的ID信息等:
?
?
以上是對(duì)pull鏡像之后運(yùn)行容器之前鏡像存儲(chǔ)信息的簡(jiǎn)單介紹,相信大家在看下之后對(duì)docker容器鏡像已經(jīng)有了更加深入的認(rèn)識(shí)。下面我們看下本文中我們要說(shuō)的最后一個(gè)階段,即運(yùn)行容器后docker 的存儲(chǔ)又發(fā)生了哪些變化。
?
運(yùn)行容器后
?
我們運(yùn)行下前面從dockerhub pull的鏡像nginx:latest:
[root@localhost metadata]# docker images
REPOSITORY ?????????TAG ????????????????IMAGE ID ???????????CREATED ????????????VIRTUAL SIZE
nginx ??????????????latest ?????????????c2c9e418b22c ???????2 weeks ago ????????109.3 MB
[root@localhost metadata]#
[root@localhost metadata]#
[root@localhost metadata]#
[root@localhost metadata]# docker run --name nginx -d nginx:latest
814ec80839669e235c94978ed3d07eab0e2b2bebd7d7a64fd6488cddca51be41
[root@localhost metadata]# docker ps
CONTAINER ID ???????IMAGE ??????????????COMMAND ?????????????????CREATED ????????????STATUS ?????????????PORTS ??????????????NAMES
814ec8083966 ???????nginx:latest ???????"nginx -g 'daemon off" ??3 seconds ago ??????Up 2 seconds ???????80/tcp ?????????????nginx
?
按照慣例,然后我們看下/var/lib/docker路徑下的文件結(jié)構(gòu):
?
?和上一階段不同,這個(gè)階段發(fā)生變化的文件主要是:/var/lib/docker/devicemapper/metadata、/var/lib/docker/devicemapper/mnt以及/var/lib/docker/container,下面我們逐個(gè)看下。
?
(1)?metadata
?
我們看下metadata這個(gè)目錄下的文件:
?
?
從圖中的結(jié)果可以看出,相比上一個(gè)階段,當(dāng)前階段中metadata目錄下多出了兩個(gè)文件,即以51be4e和51b44e-init結(jié)尾的兩個(gè)文件。
?
我們都知道docker 借助容器鏡像運(yùn)行起容器之后,會(huì)在當(dāng)前鏡像的最頂層添加一個(gè)特殊的層,和其他的層相比這個(gè)層不但有可讀的權(quán)限還有可寫(xiě)的權(quán)限。說(shuō)到這,相信多出的兩個(gè)文件的功能就不難理解了。
?
(2)?mnt
?
在查看mnt下的數(shù)據(jù)之前,我們先看下這個(gè)目錄下的文件結(jié)構(gòu):
?
對(duì)比上面說(shuō)過(guò)的metadata目錄,發(fā)現(xiàn)這兩個(gè)目錄下的文件是一樣的,相比前一個(gè)階段的話也是新增了兩個(gè)文件,即以51be4e和51b44e-init結(jié)尾的兩個(gè)文件。
?
(3)?container
?
我們先看下當(dāng)前目錄下的文件結(jié)構(gòu):
?
?
Container目錄為容器本身的目錄,此目錄中存放了諸如容器的配置文件等文件。如果我們刪掉這個(gè)目錄(docker 進(jìn)程hang死導(dǎo)致docker rm、docker kill殺不掉容器時(shí)常用此種方式處理)的話正在運(yùn)行的容器就會(huì)被刪掉,我們看下這幾個(gè)文件都存放了什么數(shù)據(jù)。
?
(1)?xxx.json.log、config.json
從文件名稱(chēng)即可看出,這兩個(gè)文件存放的為當(dāng)前容器的配置信息及其數(shù)據(jù):
(2)?hosts
?
hosts配置信息,在此不再贅述。
?
(3)?hostname
容器host名稱(chēng),可以cat查看后再進(jìn)入容器查看hostname,核對(duì)下看是否是一樣的。
?
(4)?resolv.conf
dns配置信息。
?
?小結(jié)
?
前面分析了那么多涉及到docker 存儲(chǔ)的文件,在查閱各個(gè)文件或者目錄作用時(shí)可能不是很方便,在此我們給大家總結(jié)了一下各個(gè)文件的作用(每個(gè)文件都是在/var/lib/docker路徑下):
?
(1)?devicemapper/devicemapper/data
存儲(chǔ)存儲(chǔ)池相關(guān)的數(shù)據(jù)。
(2)?devicemapper/devicemapper/metdata
存儲(chǔ)元數(shù)據(jù)。
(3)?devicemapper/metadata/
存儲(chǔ)device_id、layersize等信息。
(4)?devicemapper/mnt
存儲(chǔ)掛載相關(guān)的信息。
(5)?container/
存儲(chǔ)容器本身的信息。
(6)?graph/
存儲(chǔ)各個(gè)鏡像層的詳細(xì)信息。
(7)?repositores-devicemapper
存儲(chǔ)鏡像的一些基本信息。
(8)?tmp
存儲(chǔ)docker的臨時(shí)目錄。
(9)?trust
存儲(chǔ)docker的信任目錄。
(10)??volumes
存儲(chǔ)docker的卷目錄。
福利
掃描添加小編微信,備注“姓名+公司職位”,加入【云計(jì)算學(xué)習(xí)交流群】,和志同道合的朋友們共同打卡學(xué)習(xí)!
推薦閱讀:
云計(jì)算之基,一文帶你速懂虛擬化KVM和XEN
OpenStack網(wǎng)絡(luò)的下一步原來(lái)這么走 | 技術(shù)頭條
用一枚比特幣環(huán)游世界? 他是不是瘋了...
程序員逆襲為美國(guó)最佳 CEO,他說(shuō)因?yàn)閻?ài)情
斯坦福區(qū)塊鏈匪幫傳奇,那些睡地毯、沒(méi)日沒(méi)夜寫(xiě)代碼的編程少年
Erlang 之父去世,他留給程序員兩點(diǎn)忠告
開(kāi)什么玩笑?股票價(jià)格如何經(jīng)得起AI的推敲?| 技術(shù)頭條
真香,朕在看了!
總結(jié)
以上是生活随笔為你收集整理的深入浅出Docker 镜像 | 技术头条的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Boost:双图bimap与Boost
- 下一篇: Boost:双图bimap与Boost类