10張圖帶你深入理解Docker容器和鏡像

【編者的話】本文用圖文并茂的方式介紹了容器、鏡像的區別和Docker每個命令后面的技術細節,能夠很好的幫助讀者深入理解Docker。

這篇文章希望能夠幫助讀者深入理解Docker的命令,還有容器(container)和鏡像(image)之間的區別,并深入探討容器和運行中的容器之間的區別。

pasted_image_0.png



當我對Docker技術還是一知半解的時候,我發現理解Docker的命令非常困難。于是,我花了幾周的時間來學習Docker的工作原理,更確切地說,是關于Docker統一文件系統(the union file system)的知識,然后回過頭來再看Docker的命令,一切變得順理成章,簡單極了。

題外話:就我個人而言,掌握一門技術并合理使用它的最好辦法就是深入理解這項技術背后的工作原理。通常情況下,一項新技術的誕生常常會伴隨著媒體的大肆宣傳和炒作,這使得用戶很難看清技術的本質。更確切地說,新技術總是會發明一些新的術語或者隱喻詞來幫助宣傳,這在初期是非常有幫助的,但是這給技術的原理蒙上了一層砂紙,不利于用戶在后期掌握技術的真諦。

Git就是一個很好的例子。我之前不能夠很好的使用Git,于是我花了一段時間去學習Git的原理,直到這時,我才真正明白了Git的用法。我堅信只有真正理解Git內部原理的人才能夠掌握這個工具。

Image Definition

鏡像(Image)就是一堆只讀層(read-only layer)的統一視角,也許這個定義有些難以理解,下面的這張圖能夠幫助讀者理解鏡像的定義。

1.png



從左邊我們看到了多個只讀層,它們重疊在一起。除了最下面一層,其它層都會有一個指針指向下一層。這些層是Docker內部的實現細節,并且能夠在主機(譯者注:運行Docker的機器)的文件系統上訪問到。統一文件系統(union file system)技術能夠將不同的層整合成一個文件系統,為這些層提供了一個統一的視角,這樣就隱藏了多層的存在,在用戶的角度看來,只存在一個文件系統。我們可以在圖片的右邊看到這個視角的形式。

你可以在你的主機文件系統上找到有關這些層的文件。需要注意的是,在一個運行中的容器內部,這些層是不可見的。在我的主機上,我發現它們存在于/var/lib/docker/aufs目錄下。

sudo tree -L 1 /var/lib/docker/

/var/lib/docker/
├──?aufs
├──?containers
├──?graph
├──?init
├──?linkgraph.db
├──?repositories-aufs
├──?tmp
├──?trust
└──?volumes
7?directories,?2?files

?

Container Definition

容器(container)的定義和鏡像(image)幾乎一模一樣,也是一堆層的統一視角,唯一區別在于容器的最上面那一層是可讀可寫的。

2.png



細心的讀者可能會發現,容器的定義并沒有提及容器是否在運行,沒錯,這是故意的。正是這個發現幫助我理解了很多困惑。

要點:容器 = 鏡像 + 讀寫層。并且容器的定義并沒有提及是否要運行容器。

接下來,我們將會討論運行態容器。

Running Container Definition

一個運行態容器(running container)被定義為一個可讀寫的統一文件系統加上隔離的進程空間和包含其中的進程。下面這張圖片展示了一個運行中的容器。

3.png



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

4.png



我們可以通過運行以下命令來驗證我們上面所說的:

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)這個概念。下面的這張圖描述了一個鏡像層,通過圖片我們能夠發現一個層并不僅僅包含文件系統的改變,它還能包含了其他重要信息。

5.png



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

6.png



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

8.png



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>

create.jpg


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

11.png



docker start <container-id>

start.jpg


Docker start命令為容器文件系統創建了一個進程隔離空間。注意,每一個容器只能夠有一個進程隔離空間。

docker run <image-id>

run.jpg


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

7.png



從圖片可以看出,docker run 命令先是利用鏡像創建了一個容器,然后運行這個容器。這個命令非常的方便,并且隱藏了兩個命令的細節,但從另一方面來看,這容易讓用戶產生誤解。

題外話:繼續我們之前有關于Git的話題,我認為docker run命令類似于git pull命令。git pull命令就是git fetch 和 git merge兩個命令的組合,同樣的,docker run就是docker create和docker start兩個命令的組合。

docker ps

ps.jpg


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

docker ps –a

ps0a.jpg


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

docker images

images.jpg


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

docker images –a

images-a.jpg


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

docker stop <container-id>

stop.jpg


docker stop命令會向運行中的容器發送一個SIGTERM的信號,然后停止所有的進程。

docker kill <container-id>

kill.jpg


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

docker pause <container-id>

pause.jpg


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

docker rm <container-id>

rm.jpg


docker rm命令會移除構成容器的可讀寫層。注意,這個命令只能對非運行態容器執行。

docker rmi <image-id>

rmi.jpg


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

docker commit <container-id>

commit.jpg


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

10.png



docker build

build.jpg


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

9.png



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

docker exec <running-container-id>

exec.jpg


docker exec 命令會在運行中的容器執行一個新進程。

docker inspect <container-id> or <image-id>

insepect.jpg


docker inspect命令會提取出容器或者鏡像最頂層的元數據。

docker save <image-id>

save.jpg


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

docker export <container-id>

export.jpg


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

docker history <image-id>

history.jpg


docker history命令遞歸地輸出指定鏡像的歷史鏡像。

結論

我希望你們能喜歡這篇文章。還有其他許多的命令(pull,search,restart,attach等)我沒有提及,但是我相信通過閱讀這篇文章,大部分的Docker命令都能夠被很好理解。我僅僅學習了Docker兩個星期,因此,如果我有什么地方說的不好,歡迎大家指出。

原文鏈接:Visualizing Docker Containers and Images(翻譯:楊潤青)

===========================

譯者介紹
楊潤青,90后博士僧,研究方向是網絡和信息安全。

轉載于:https://www.cnblogs.com/linjiaxin/p/7381421.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/391640.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/391640.shtml
英文地址,請注明出處:http://en.pswp.cn/news/391640.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

matlab界area_Matlab的數據科學界

matlab界area意見 (Opinion) My personal interest in Data Science spans back to 2011. I was learning more about Economies and wanted to experiment with some of the ‘classic’ theories and whilst many of them held ground, at a micro level, many were also pur…

javascript異步_JavaScript異步并在循環中等待

javascript異步Basic async and await is simple. Things get a bit more complicated when you try to use await in loops.基本的async和await很簡單。 當您嘗試在循環中使用await時&#xff0c;事情會變得更加復雜。 In this article, I want to share some gotchas to wat…

白盒測試目錄導航

白盒測試目錄導航&#xff08;更新中&#xff09; 2017-12-29 [1] 白盒測試&#xff1a;為什么要做白盒測試 [2] 白盒測試&#xff1a;理論基礎 [3] 白盒測試實戰&#xff08;上&#xff09; [4] 白盒測試實戰&#xff08;中&#xff09; [5] 白盒測試實戰&#xff08;下&#…

hdf5文件和csv的區別_使用HDF5文件并創建CSV文件

hdf5文件和csv的區別In my last article, I discussed the steps to download NASA data from GES DISC. The data files downloaded are in the HDF5 format. HDF5 is a file format, a technology, that enables the management of very large data collections. Thus, it is…

CSS仿藝龍首頁鼠標移入圖片放大

CSS仿藝龍首頁鼠標移入圖片放大&#xff0c;效果似乎沒有js好。。。。。。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>圖片放大</title><style>*{padding:0;margin:0;}body{padding-…

leetcode 224. 基本計算器(棧)

給你一個字符串表達式 s &#xff0c;請你實現一個基本計算器來計算并返回它的值。 示例 1&#xff1a; 輸入&#xff1a;s “1 1” 輸出&#xff1a;2 示例 2&#xff1a; 輸入&#xff1a;s " 2-1 2 " 輸出&#xff1a;3 示例 3&#xff1a; 輸入&#xff…

機械制圖國家標準的繪圖模板_如何使用p5js構建繪圖應用

機械制圖國家標準的繪圖模板The theme for week #5 of the Weekly Coding Challenge is:每周編碼挑戰第5周的主題是&#xff1a; 創建繪圖應用程序 (Creating a Drawing Application) This is the first application that we are building in the #weeklyCodingChallenge prog…

機器學習常用模型:決策樹_fairmodels:讓我們與有偏見的機器學習模型作斗爭

機器學習常用模型:決策樹TL; DR (TL;DR) The R Package fairmodels facilitates bias detection through model visualizations. It implements a few mitigation strategies that could reduce bias. It enables easy to use checks for fairness metrics and comparison betw…

高德地圖如何將比例尺放大到10米?

2019獨角獸企業重金招聘Python工程師標準>>> var map new AMap.Map(container, {resizeEnable: true,expandZoomRange:true,zoom:20,zooms:[3,20],center: [116.397428, 39.90923] }); alert(map.getZoom());http://lbs.amap.com/faq/web/javascript-api/expand-zo…

Android 手把手帶你玩轉自己定義相機

本文已授權微信公眾號《鴻洋》原創首發&#xff0c;轉載請務必注明出處。概述 相機差點兒是每一個APP都要用到的功能&#xff0c;萬一老板讓你定制相機方不方&#xff1f;反正我是有點方。關于相機的兩天奮斗總結免費送給你。Intent intent new Intent(); intent.setAction(M…

如何在JavaScript中克隆數組

JavaScript has many ways to do anything. I’ve written on 10 Ways to Write pipe/compose in JavaScript, and now we’re doing arrays.JavaScript有許多方法可以執行任何操作。 我已經寫了10種用JavaScript編寫管道/組合的方法 &#xff0c;現在我們正在做數組。 1.傳播…

leetcode 227. 基本計算器 II(棧)

給你一個字符串表達式 s &#xff0c;請你實現一個基本計算器來計算并返回它的值。 整數除法僅保留整數部分。 示例 1&#xff1a; 輸入&#xff1a;s “32*2” 輸出&#xff1a;7 解題思路 利用兩個棧&#xff0c;一個記錄操作數&#xff0c;一個記錄操作符&#xff0c;…

100米隊伍,從隊伍后到前_我們的隊伍

100米隊伍,從隊伍后到前The last twelve months have brought us a presidential impeachment trial, the coronavirus pandemic, sweeping racial justice protests triggered by the death of George Floyd, and a critical presidential election. News coverage of these e…

idea使用 git 撤銷commit

2019獨角獸企業重金招聘Python工程師標準>>> 填寫commit的id 就可以取消這一次的commit 轉載于:https://my.oschina.net/u/3559695/blog/1596669

ES6標準入門(第二版)pdf

下載地址&#xff1a;網盤下載 內容簡介 ES6&#xff08;又名 ES2105&#xff09;是 JavaScript 語言的新標準&#xff0c;2015 年 6 月正式發布后&#xff0c;得到了迅速推廣&#xff0c;是目前業界超級活躍的計算機語言。《ES6標準入門&#xff08;第2版&#xff09;》…

hexo博客添加暗色模式_我如何向網站添加暗模式

hexo博客添加暗色模式同一個網站&#xff0c;兩種不同的配色方案 (Same website, two different color schemes) Last year I made it a point to redesign my website from scratch. I wanted something simple and minimalist looking that clearly stated what this was — …

leetcode 331. 驗證二叉樹的前序序列化

序列化二叉樹的一種方法是使用前序遍歷。當我們遇到一個非空節點時&#xff0c;我們可以記錄下這個節點的值。如果它是一個空節點&#xff0c;我們可以使用一個標記值記錄&#xff0c;例如 #。_9_/ \3 2/ \ / \4 1 # 6 / \ / \ / \ # # # # # # 例如&#xff0…

mongodb數據可視化_使用MongoDB實時可視化開放數據

mongodb數據可視化Using Python to connect to Taiwan Government PM2.5 open data API, and schedule to update data in real time to MongoDB — Part 2使用Python連接到臺灣政府PM2.5開放數據API&#xff0c;并計劃將數據實時更新到MongoDB —第2部分 目標 (Goal) This ti…

4.kafka的安裝部署

為了安裝過程對一些參數的理解&#xff0c;我先在這里提一下kafka一些重點概念,topic,broker,producer,consumer,message,partition,依賴于zookeeper, kafka是一種消息隊列,他的服務端是由若干個broker組成的&#xff0c;broker會向zookeeper&#xff0c;producer生成者對應一個…

javascript初學者_針對JavaScript初學者的調試技巧和竅門

javascript初學者by Priyanka Garg由Priyanka Garg My intended audience for this tutorial is beginner programmers. You’ll learn about frustration-free debugging with chrome dev tools.本教程的目標讀者是初學者。 您將學習使用chrome開發工具進行無挫折的調試。 D…