看圖帶你深入理解Docker容器和鏡像
發布時間:2020-02-12 責任編輯:lina
【導讀】本篇文章希望能夠幫助讀者深入理解Docker的命令,還有容器(container)和鏡像(image)之間的區別,並深入探討容器和運行中的容器之間的區別。
本篇文章希望能夠幫助讀者深入理解Docker的命令,還有容器(container)和鏡像(image)之間的區別,並深入探討容器和運行中的容器之間的區別。

當我對Docker技術還是一知半解的時候,我發現理解Docker的命令非常困難。於是,我花了幾周的時間來學習Docker的工作原理,更確切地說,是關於Docker統一文件係統(the union file system)的知識,然後回過頭來再看Docker的命令,一切變得順理成章,簡單極了。
題外話:就(jiu)我(wo)個(ge)人(ren)而(er)言(yan),掌(zhang)握(wo)一(yi)門(men)技(ji)術(shu)並(bing)合(he)理(li)使(shi)用(yong)它(ta)的(de)最(zui)好(hao)辦(ban)法(fa)就(jiu)是(shi)深(shen)入(ru)理(li)解(jie)這(zhe)項(xiang)技(ji)術(shu)背(bei)後(hou)的(de)工(gong)作(zuo)原(yuan)理(li)。通(tong)常(chang)情(qing)況(kuang)下(xia),一(yi)項(xiang)新(xin)技(ji)術(shu)的(de)誕(dan)生(sheng)常(chang)常(chang)會(hui)伴(ban)隨(sui)著(zhe)媒(mei)體(ti)的(de)大(da)肆(si)宣(xuan)傳(chuan)和(he)炒(chao)作(zuo),這(zhe)使(shi)得(de)用(yong)戶(hu)很(hen)難(nan)看(kan)清(qing)技(ji)術(shu)的(de)本(ben)質(zhi)。更(geng)確(que)切(qie)地(di)說(shuo),新(xin)技(ji)術(shu)總(zong)是(shi)會(hui)發(fa)明(ming)一(yi)些(xie)新(xin)的(de)術(shu)語(yu)或(huo)者(zhe)隱(yin)喻(yu)詞(ci)來(lai)幫(bang)助(zhu)宣(xuan)傳(chuan),這(zhe)在(zai)初(chu)期(qi)是(shi)非(fei)常(chang)有(you)幫(bang)助(zhu)的(de),但(dan)是(shi)這(zhe)給(gei)技(ji)術(shu)的(de)原(yuan)理(li)蒙(meng)上(shang)了(le)一(yi)層(ceng)砂(sha)紙(zhi),不(bu)利(li)於(yu)用(yong)戶(hu)在(zai)後(hou)期(qi)掌(zhang)握(wo)技(ji)術(shu)的(de)真(zhen)諦(di)。
Git就是一個很好的例子。我之前不能夠很好的使用Git,於是我花了一段時間去學習Git的原理,直到這時,我才真正明白了Git的用法。我堅信隻有真正理解Git內部原理的人才能夠掌握這個工具。
Image Definition
鏡像(Image)就是一堆隻讀層(read-only layer)的統一視角,也許這個定義有些難以理解,下麵的這張圖能夠幫助讀者理解鏡像的定義。

從左邊我們看到了多個隻讀層,它們重疊在一起。除了最下麵一層,其它層都會有一個指針指向下一層。這些層是Docker內部的實現細節,並且能夠在主機(譯者注:運行Docker的機器)的文件係統上訪問到。統一文件係統(union file system)技ji術shu能neng夠gou將jiang不bu同tong的de層ceng整zheng合he成cheng一yi個ge文wen件jian係xi統tong,為wei這zhe些xie層ceng提ti供gong了le一yi個ge統tong一yi的de視shi角jiao,這zhe樣yang就jiu隱yin藏zang了le多duo層ceng的de存cun在zai,在zai用yong戶hu的de角jiao度du看kan來lai,隻zhi存cun在zai一yi個ge文wen件jian係xi統tong。我wo們men可ke以yi在zai圖tu片pian的de右you邊bian看kan到dao這zhe個ge視shi角jiao的de形xing式shi。
nikeyizainidezhujiwenjianxitongshangzhaodaoyouguanzhexiecengdewenjian。xuyaozhuyideshi,zaiyigeyunxingzhongderongqineibu,zhexiecengshibukejiande。zaiwodezhujishang,wofaxiantamencunzaiyu/var/lib/docker/aufs目錄下。
1./var/lib/docker/
2.├── aufs
3.├── containers
4.├── graph
5.├── init
6.├── linkgraph.db
7.├── repositories-aufs
8.├── tmp
9.├── trust
10.└── volumes
11.7 directories, 2 files
12.Container Definition
容器(container)的定義和鏡像(image)幾乎一模一樣,也是一堆層的統一視角,唯一區別在於容器的最上麵那一層是可讀可寫的。

細心的讀者可能會發現,容器的定義並沒有提及容器是否在運行,沒錯,這是故意的。正是這個發現幫助我理解了很多困惑。
要點:容器 = 鏡像 + 讀寫層。並且容器的定義並沒有提及是否要運行容器。
接下來,我們將會討論運行態容器。
Running Container Definition
一個運行態容器(running container)被定義為一個可讀寫的統一文件係統加上隔離的進程空間和包含其中的進程。下麵這張圖片展示了一個運行中的容器。

正是文件係統隔離技術使得Docker成為了一個前途無量的技術。一個容器中的進程可能會對文件進行修改、刪除、創建,這些改變都將作用於可讀寫層(read-write layer)。下麵這張圖展示了這個行為。

我們可以通過運行以下命令來驗證我們上麵所說的:
docker run ubuntu touch happiness.txt
即便是這個ubuntu容器不再運行,我們依舊能夠在主機的文件係統上找到這個新文件。
find / -name happiness.txt
/var/lib/docker/aufs/diff/860a7b...889/happiness.txt
Image Layer Definition
為了將零星的數據整合起來,我們提出了鏡像層(image layer)這(zhe)個(ge)概(gai)念(nian)。下(xia)麵(mian)的(de)這(zhe)張(zhang)圖(tu)描(miao)述(shu)了(le)一(yi)個(ge)鏡(jing)像(xiang)層(ceng),通(tong)過(guo)圖(tu)片(pian)我(wo)們(men)能(neng)夠(gou)發(fa)現(xian)一(yi)個(ge)層(ceng)並(bing)不(bu)僅(jin)僅(jin)包(bao)含(han)文(wen)件(jian)係(xi)統(tong)的(de)改(gai)變(bian),它(ta)還(hai)能(neng)包(bao)含(han)了(le)其(qi)他(ta)重(zhong)要(yao)信(xin)息(xi)。

元數據(metadata)就是關於這個層的額外信息,它不僅能夠讓Docker獲取運行和構建時的信息,還包括父層的層次信息。需要注意,隻讀層和讀寫層都包含元數據。

除此之外,每一層都包括了一個指向父層的指針。如果一個層沒有這個指針,說明它處於最底層。

Metadata Location:
我發現在我自己的主機上,鏡像層(image layer)的元數據被保存在名為”json”的文件中,比如說:
/var/lib/docker/graph/e809f156dc985.../json
e809f156dc985...就是這層的id
一個容器的元數據好像是被分成了很多文件,但或多或少能夠在/var/lib/docker/containers/<id>目錄下找到,<id>就是一個可讀層的id。這個目錄下的文件大多是運行時的數據,比如說網絡,日誌等等。
全局理解(Tying It All Together)
現在,讓我們結合上麵提到的實現細節來理解Docker的命令。
docker create <image-id>

docker create 命令為指定的鏡像(image)添加了一個可讀寫層,構成了一個新的容器。注意,這個容器並沒有運行。

docker start <container-id>

Docker start命令為容器文件係統創建了一個進程隔離空間。注意,每一個容器隻能夠有一個進程隔離空間。
docker run <image-id>

看到這個命令,讀者通常會有一個疑問:docker start 和 docker run命令有什麼區別。

從圖片可以看出,docker run 命ming令ling先xian是shi利li用yong鏡jing像xiang創chuang建jian了le一yi個ge容rong器qi,然ran後hou運yun行xing這zhe個ge容rong器qi。這zhe個ge命ming令ling非fei常chang的de方fang便bian,並bing且qie隱yin藏zang了le兩liang個ge命ming令ling的de細xi節jie,但dan從cong另ling一yi方fang麵mian來lai看kan,這zhe容rong易yi讓rang用yong戶hu產chan生sheng誤wu解jie。
題外話:繼續我們之前有關於Git的話題,我認為docker run命令類似於git pull命令。git pull命令就是git fetch 和 git merge兩個命令的組合,同樣的,docker run就是docker create和docker start兩個命令的組合。
docker ps

docker ps 命令會列出所有運行中的容器。這隱藏了非運行態容器的存在,如果想要找出這些容器,我們需要使用下麵這個命令。
docker ps –a

docker ps –a命令會列出所有的容器,不管是運行的,還是停止的。
docker images

docker images命令會列出了所有頂層(top-level)鏡像。實際上,在這裏我們沒有辦法區分一個鏡像和一個隻讀層,所以我們提出了top-level鏡像。隻有創建容器時使用的鏡像或者是直接pull下來的鏡像能被稱為頂層(top-level)鏡像,並且每一個頂層鏡像下麵都隱藏了多個鏡像層。
docker images –a

docker images –a命令列出了所有的鏡像,也可以說是列出了所有的可讀層。如果你想要查看某一個image-id下的所有層,可以使用docker history來查看。
docker stop <container-id>

docker stop命令會向運行中的容器發送一個SIGTERM的信號,然後停止所有的進程。
docker kill <container-id>

docker kill 命令向所有運行在容器中的進程發送了一個不友好的SIGKILL信號。
docker pause <container-id>

docker stop和docker kill命令會發送UNIX的信號給運行中的進程,docker pause命令則不一樣,它利用了cgroups的特性將運行中的進程空間暫停。具體的內部原理你可以在這裏找到:https://www.kernel.org/doc/Doc ... m.txt,但是這種方式的不足之處在於發送一個SIGTSTP信號對於進程來說不夠簡單易懂,以至於不能夠讓所有進程暫停。
docker rm <container-id>

docker rm命令會移除構成容器的可讀寫層。注意,這個命令隻能對非運行態容器執行。
docker rmi <image-id>

docker rmi 命令會移除構成鏡像的一個隻讀層。你隻能夠使用docker rmi來移除最頂層(top level layer)(也可以說是鏡像),你也可以使用-f參數來強製刪除中間的隻讀層。
docker commit <container-id>

docker commit命令將容器的可讀寫層轉換為一個隻讀層,這樣就把一個容器轉換成了不可變的鏡像。
docker build

docker build命令非常有趣,它會反複的執行多個命令。

我們從上圖可以看到,build命令根據Dockerfile文件中的FROM指令獲取到鏡像,然後重複地1)run(create和start)、2)修改、3)commit。在循環中的每一步都會生成一個新的層,因此許多新的層會被創建。
docker exec <running-container-id>

docker exec 命令會在運行中的容器執行一個新進程。
docker inspect <container-id> or <image-id>

docker inspect命令會提取出容器或者鏡像最頂層的元數據。
docker save <image-id>

docker save命令會創建一個鏡像的壓縮文件,這個文件能夠在另外一個主機的Docker上使用。和export命令不同,這個命令為每一個層都保存了它們的元數據。這個命令隻能對鏡像生效。
docker export <container-id>

docker export命令創建一個tar文件,並且移除了元數據和不必要的層,將多個層整合成了一個層,隻保存了當前統一視角看到的內容(譯者注:expoxt後的容器再import到Docker中,通過docker images –tree命令隻能看到一個鏡像;而save後的鏡像則不同,它能夠看到這個鏡像的曆史鏡像)。
docker history <image-id>

docker history命令遞歸地輸出指定鏡像的曆史鏡像。
特別推薦
- 噪聲中提取真值!瑞盟科技推出MSA2240電流檢測芯片賦能多元高端測量場景
- 10MHz高頻運行!氮矽科技發布集成驅動GaN芯片,助力電源能效再攀新高
- 失真度僅0.002%!力芯微推出超低內阻、超低失真4PST模擬開關
- 一“芯”雙電!聖邦微電子發布雙輸出電源芯片,簡化AFE與音頻設計
- 一機適配萬端:金升陽推出1200W可編程電源,賦能高端裝備製造
技術文章更多>>
- 算力爆發遇上電源革新,大聯大世平集團攜手晶豐明源線上研討會解鎖應用落地
- 築基AI4S:摩爾線程全功能GPU加速中國生命科學自主生態
- 一秒檢測,成本降至萬分之一,光引科技把幾十萬的台式光譜儀“搬”到了手腕上
- AI服務器電源機櫃Power Rack HVDC MW級測試方案
- 突破工藝邊界,奎芯科技LPDDR5X IP矽驗證通過,速率達9600Mbps
技術白皮書下載更多>>
- 車規與基於V2X的車輛協同主動避撞技術展望
- 數字隔離助力新能源汽車安全隔離的新挑戰
- 汽車模塊拋負載的解決方案
- 車用連接器的安全創新應用
- Melexis Actuators Business Unit
- Position / Current Sensors - Triaxis Hall
熱門搜索
微波功率管
微波開關
微波連接器
微波器件
微波三極管
微波振蕩器
微電機
微調電容
微動開關
微蜂窩
位置傳感器
溫度保險絲
溫度傳感器
溫控開關
溫控可控矽
聞泰
穩壓電源
穩壓二極管
穩壓管
無焊端子
無線充電
無線監控
無源濾波器
五金工具
物聯網
顯示模塊
顯微鏡結構
線圈
線繞電位器
線繞電阻



