摘要:結束語命令干的活比較少,主要是準備的和配置文件,配置文件中的項比較多,后續會挑一些常用的項進行專門介紹。
有了image之后,就可以開始創建并啟動容器了,平時我們都是用docker run命令直接創建并運行一個容器,它的背后其實包含獨立的兩步,一步是docker create創建容器,另一步是docker start啟動容器,本篇將先介紹在docker create這一步中,docker做了哪些事情。
簡單點來說,dockerd在收到客戶端的創建容器請求后,做了兩件事情,一是準備容器需要的layer,二是檢查客戶端傳過來的參數,并和image配置文件中的參數進行合并,然后存儲成容器的配置文件。
創建容器創建一個容器用于示例
#創建一個容器,并取名為docker_test, #-i是為了讓容器能接受用戶的輸入,-t是指定docker為容器創建一個tty, #因為ubuntu這個鏡像默認啟動的進程是bash,而bash需要tty,否則會異常退出 dev@dev:~$ docker create -it --name docker_test ubuntu 967438113fba0b7a3005bcb6efae6a77055d6be53945f30389888802ea8b0368 dev@dev:~$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 967438113fba ubuntu "/bin/bash" 6 seconds ago Created docker_testlayer的元數據
創建容器時,docker會為每個容器創建兩個新的layer,一個是只讀的init layer,里面包含docker為容器準備的一些文件,另一個是容器的可寫mount layer,以后在容器里面對rootfs的所有增刪改操作的結果都會存在這個layer中。
# layer的元數據存儲在layerdb/mounts/目錄下,目錄名稱就是容器的ID # 里面包含了三個文件 root@dev:/var/lib/docker/image/aufs/layerdb/mounts/967438113fba0b7a3005bcb6efae6a77055d6be53945f30389888802ea8b0368# ls init-id mount-id parent # mount-id文件包含了mount layer的cacheid root@dev:/var/lib/docker/image/aufs/layerdb/mounts/967438113fba0b7a3005bcb6efae6a77055d6be53945f30389888802ea8b0368# cat mount-id 305226f2e0755956ada28b3baf39b18fa328f1a59fd90e0b759a239773db2281 # init-id文件包含了init layer的cacheid # init layer的cacheid就是在mount layer的cacheid后面加上了一個“-init” root@dev:/var/lib/docker/image/aufs/layerdb/mounts/967438113fba0b7a3005bcb6efae6a77055d6be53945f30389888802ea8b0368# cat init-id 305226f2e0755956ada28b3baf39b18fa328f1a59fd90e0b759a239773db2281-init # parent里面包含的是image的最上一層layer的chainid # 表示這個容器的init layer的父layer是image的最頂層layer root@dev:/var/lib/docker/image/aufs/layerdb/mounts/967438113fba0b7a3005bcb6efae6a77055d6be53945f30389888802ea8b0368# cat parent sha256:9840d207a275f956f3e634148044e63dc78df511fd72e22d8cb3dad57dc49bf6 # 可以根據parent的chainid得到它的diffid, # 這個diffid對應的確實是ubuntu:latest的最頂層layer # 如何得到image的layer信息請參考上一篇文章: # 走進docker(05):docker在本地如何管理image(鏡像)? root@dev:/var/lib/docker/image# cat ./aufs/layerdb/sha256/9840d207a275f956f3e634148044e63dc78df511fd72e22d8cb3dad57dc49bf6/diff sha256:d8b353eb3025c49e029567b2a01e517f7f7d32537ee47e64a7eac19fa68a33f3
新加的這兩層layer比較特殊,只保存在layerdb/mounts下面,在layerdb/sha256目錄下沒有相關信息,說明docker將container的layer和image的layer的元數據放在了不同的兩個目錄中
layer的數據container layer的數據和image layer的數據的管理方式是一樣的,都存在/var/lib/docker/
該目錄下包含了每個layer的祖先layer的cacheid
root@dev:/var/lib/docker/aufs# cat ./layers/305226f2e0755956ada28b3baf39b18fa328f1a59fd90e0b759a239773db2281-init 7938f2b32c53a9e0d3974f9579dd9dbb450202e1e11fe514e31556d4ea808c4e 4c10796e21c796a6f3d83eeb3613c566ca9e0fd0a596f4eddf5234b87955b3c8 fd0ba28a44491fd7559c7ffe0597fb1f95b63207a38a3e2680231fb2f6fe92bd b656bf5f0688069cd90ab230c029fdfeb852afcfd0d1733d087474c86a117da3 1e83d2ea184e08eed978127311cc96498e319426abe2fb5004d4b1454598bd76 #從這里可以看出mount layer在init layer的上面 root@dev:/var/lib/docker/aufs# cat ./layers/305226f2e0755956ada28b3baf39b18fa328f1a59fd90e0b759a239773db2281 305226f2e0755956ada28b3baf39b18fa328f1a59fd90e0b759a239773db2281-init 7938f2b32c53a9e0d3974f9579dd9dbb450202e1e11fe514e31556d4ea808c4e 4c10796e21c796a6f3d83eeb3613c566ca9e0fd0a596f4eddf5234b87955b3c8 fd0ba28a44491fd7559c7ffe0597fb1f95b63207a38a3e2680231fb2f6fe92bd b656bf5f0688069cd90ab230c029fdfeb852afcfd0d1733d087474c86a117da3 1e83d2ea184e08eed978127311cc96498e319426abe2fb5004d4b1454598bd76 #上面的7938f2...就是ubuntu:latest最上一層layer的cacheid root@dev:~# find /var/lib/docker/image/ -name cache-id|xargs grep 7938f2b32c53a9e0d3974f9579dd9dbb450202e1e11fe514e31556d4ea808c4e /var/lib/docker/image/aufs/layerdb/sha256/9840d207a275f956f3e634148044e63dc78df511fd72e22d8cb3dad57dc49bf6/cache-id:7938f2b32c53a9e0d3974f9579dd9dbb450202e1e11fe514e31556d4ea808c4e #9840d2...是ubuntu:latest最上一層layer的chainiddiff目錄
該目錄下存放著每個layer所包含的數據
#mount layer是新建的供容器寫數據layer, #由于容器還沒有運行,所以這里沒有任何數據 root@dev:/var/lib/docker/aufs/diff# tree 305226f2e0755956ada28b3baf39b18fa328f1a59fd90e0b759a239773db2281 305226f2e0755956ada28b3baf39b18fa328f1a59fd90e0b759a239773db2281 0 directories, 0 files #init layer包含了docker為每個容器所預先準備的文件 root@dev:/var/lib/docker/aufs/diff# tree 305226f2e0755956ada28b3baf39b18fa328f1a59fd90e0b759a239773db2281-init/ 305226f2e0755956ada28b3baf39b18fa328f1a59fd90e0b759a239773db2281-init/ ├── dev │?? └── console └── etc ├── hostname ├── hosts ├── mtab -> /proc/mounts └── resolv.conf 2 directories, 5 files
init layer里面的文件有什么作用呢?從下面的結果可以看出,除了mtab文件是指向/proc/mounts的軟連接之外,其他的都是空的普通文件。
root@dev:/var/lib/docker/aufs/diff/305226f2e0755956ada28b3baf39b18fa328f1a59fd90e0b759a239773db2281-init# ls -l dev total 0 -rwxr-xr-x 1 root root 0 Jun 25 11:25 console root@dev:/var/lib/docker/aufs/diff/305226f2e0755956ada28b3baf39b18fa328f1a59fd90e0b759a239773db2281-init# ls -l etc total 0 -rwxr-xr-x 1 root root 0 Jun 25 11:25 hostname -rwxr-xr-x 1 root root 0 Jun 25 11:25 hosts lrwxrwxrwx 1 root root 12 Jun 25 11:25 mtab -> /proc/mounts -rwxr-xr-x 1 root root 0 Jun 25 11:25 resolv.conf
這幾個文件都是Linux運行時必須的文件,如果缺少的話會導致某些程序或者庫出現異常,所以docker需要為容器準備好這些文件:
/dev/console: 在Linux主機上,該文件一般指向主機的當前控制臺,有些程序會依賴該文件。在容器啟動的時候,docker會為容器創建一個pts,然后通過bind mount的方式將pts綁定到容器里面的/dev/console上,這樣在容器里面往這個文件里面寫東西就相當于往容器的控制臺上打印數據。這里創建一個空文件相當于占個坑,作為后續bind mount的目的路徑。
hostname,hosts,resolv.conf:對于每個容器來說,容器內的這幾個文件內容都有可能不一樣,這里也只是占個坑,等著docker在外面生成這幾個文件,然后通過bind mount的方式將這些文件綁定到容器中的這些位置,即這些文件都會被宿主機中的文件覆蓋掉。
/etc/mtab:這個文件在新的Linux發行版中都指向/proc/mounts,里面包含了當前mount namespace中的所有掛載信息,很多程序和庫會依賴這個文件。
mnt目錄注意: 這里mtab指向的路徑是固定的,但內容是變化的,取決于你從哪里打開這個文件,當在宿主機上打開時,是宿主機上/proc/mounts的內容,當啟動并進入容器后,在容器中打開看到的就是容器中/proc/mounts的內容。
里面存放的是經過aufs文件系統mount之后的layer數據,即當前layer和所有的下層layer合并之后的數據,對于aufs文件系統來說,只有在運行容器的時候才會被docker所mount,所以容器沒啟動的時候,這里看不到任何文件。
root@dev:/var/lib/docker/aufs/mnt# tree 305226f2e0755956ada28b3baf39b18fa328f1a59fd90e0b759a239773db2281 305226f2e0755956ada28b3baf39b18fa328f1a59fd90e0b759a239773db2281 0 directories, 0 files root@dev:/var/lib/docker/aufs/mnt# tree 305226f2e0755956ada28b3baf39b18fa328f1a59fd90e0b759a239773db2281-init/ 305226f2e0755956ada28b3baf39b18fa328f1a59fd90e0b759a239773db2281-init/ 0 directories, 0 files配置文件
docker將用戶指定的參數和image配置文件中的部分參數進行合并,然后將合并后生成的容器的配置文件放在/var/lib/docker/containers/下面,目錄名稱就是容器的ID
root@dev:/var/lib/docker/containers/967438113fba0b7a3005bcb6efae6a77055d6be53945f30389888802ea8b0368# tree . ├── checkpoints ├── config.v2.json └── hostconfig.json 1 directory, 2 files
config.v2.json: 通用的配置,如容器名稱,要執行的命令等
hostconfig.json: 主機相關的配置,跟操作系統平臺有關,如cgroup的配置
checkpoints: 容器的checkpoint這個功能在當前版本還是experimental狀態。
這里不詳細介紹配置項的內容,后續介紹某些具體配置項的時候再來看這些文件。
結束語checkpoints這個功能很強大,可以在當前node做一個checkpoint,然后再到另一個node上繼續運行,相當于無縫的將一個正在運行的進程先暫停,然后遷移到另一個node上并繼續運行。
docker create命令干的活比較少,主要是準備container的layer和配置文件,配置文件中的項比較多,后續會挑一些常用的項進行專門介紹。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/26938.html
摘要:包含的內容本系列主要介紹三個上的項目由于只介紹核心的東西,所以不會包含下面這些項目使用語言開發,將多個相關的容器配置在一起,從而可以同時創建啟動停止和監控它們。由于本人時間安排發生變化,本系列停止更新,后面不確定是否會繼續,非常抱歉。 本人docker初學者,邊學習邊總結,一方面加深自己的理解,另一方面希望對其他想深入了解docker的同學有所幫助。 由于本人缺乏實戰經驗,錯誤在所難免...
摘要:進程啟動后,就會按照的標準準備好相關運行時環境,然后啟動進程。涉及到標準輸入輸出重定向,這里不細說這里是它們之間的交互流程流程對應的文字描述如下客戶端發送創建容器請求給,收到請求后,發現本地沒有相應的額,于是返回失敗。 在程序員的世界里,hello world是個很特殊的存在,當我們接觸一門新的語言、新的開發庫或者框架時,第一時間想了解的一般都是怎么實現一個hello world,然后...
摘要:首先來看看收到客戶端的啟動容器請求后,做了些什么。待上面的文件都準備好了之后,通過的方式給發送請求,通知啟動容器。主要功能是啟動并管理運行時的所有。包含容器中進程相關的一些屬性信息,后續在這個容器上執行命令時會用到這個文件。 在上一篇介紹過了docker create之后,這篇來看看docker start是怎么根據create之后的結果運行容器的。 啟動容器 在這里我們先啟動上一篇中...
摘要:包含的內容一個由可選和四部分組成。對于這兩種不同類型的文件格式,標準定義了兩個新的,分別是和。最新的標準里面并沒有涉及到,不過估計后續會加上。 上一篇介紹了hello-world的大概流程,那么hello-world的image里面到底包含了些什么呢?里面的格式是怎么樣的呢? image所包含的內容以及格式都是有標準的,由Open Containers Initiative(OCI)負...
閱讀 3564·2021-10-15 09:43
閱讀 3487·2021-09-02 15:21
閱讀 2193·2021-08-11 11:23
閱讀 3238·2019-08-30 15:54
閱讀 1923·2019-08-30 13:54
閱讀 3199·2019-08-29 18:35
閱讀 668·2019-08-29 16:58
閱讀 1736·2019-08-29 12:49