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

此文中部分信息、圖片需要 fan qiang , 如果未能正常顯示,文末有原文連接 。


【Kubernetes培訓通知】DockOne將會于2018年5月18日在上海舉辦Kubernetes技術培訓,培訓內容包括:容器介紹、容器網絡、Kubernetes架構基礎介紹、安裝、設計理念、架構詳解、設計原則、常用對象、監控方案、Kubernetes高階設計和實現、微服務、實踐案例分享等。同時6月份在北京的培訓也已經啟動,詳情請點擊

這篇文章希望能夠幫助讀者深入理解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└──?volumes7?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命令都能夠被很好理解。如果我有什么地方說的不好,歡迎大家指出。

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

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

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

相關文章

k8s強制刪除pod

有時候pod一直在Terminating kubectl delete pod xxx --force --grace-period0 轉載于:https://www.cnblogs.com/floud/p/10620783.html

錢與命的八句真實話(圖)

窮人失去健康&#xff0c;等于雪上加霜。富人失去健康&#xff0c;等于一輩子白忙。 男人失去健康&#xff0c;她會成為別人的新娘。 女人失去健康&#xff0c;他將會重新妝點自己的洞房。 老人失去健康&#xff0c;天倫之樂成為奢望。 兒童失去健康&#xff0c;他的父母會…

一個“Internal”牽扯出的代碼泄露,阿里云獨家回應

近日&#xff0c;阿里云云效平臺被曝出現源代碼泄露企業&#xff0c;涉及40家企業共200余項目&#xff0c;甚至波及用戶隱私敏感數據。晚些時候&#xff0c;阿里云就此事作出回應&#xff0c;并在網站醒目標識并給出告警。今天&#xff0c;一篇題為《獨家 | 阿里云出現源代碼泄…

真格量化——依托均線購買期權策略

# coding:utf-8 #!/usr/bin/env python from PoboAPI import * import datetime import time import numpy as np#開始時間,用于初始化一些參數 def OnStart(context) :print "I\m starting..."#登錄交易賬號,需在主頁用戶管理中設置賬號,并把證券測試替換成您的賬…

BZOJ 3329: Xorequ(數位dp+遞推)

傳送門 解題思路 可以把原式移項得\(x\)^\(2x\)\(3x\)&#xff0c;而\(x2x3x\)&#xff0c;說明\(x\)二進制下不能有兩個連續的\(1\)。那么第一問就是一個簡單的數位\(dp\)&#xff0c;第二問考慮遞推按位做&#xff0c;設\(f(i)\)表示最后一位為\(0\)的答案&#xff0c;\(g(i)…

ps -ef 命令說明

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 PS是LINUX下最常用的也是非常強大的進程查看命令 //以下這條命令是檢查java 進程是否存在. ps -ef | grep java下面對命令選項進行說明…

JS module的導出和導入

最近看了些Vue框架寫的程序&#xff0c;發現自己的前端知識還停留在幾年以前&#xff0c;發現現在Javascript程序里有各種各樣的對module的導入和到處&#xff0c;導入乍一看跟python的語法挺像的無非就是把from和import這兩個關鍵詞的使用顛倒了一下順序。仔細看下來還是和pyt…

專訪雷果國:從1.5K到18K 一個程序員的5年成長之路

摘要&#xff1a;上段時間CSDN博客上流傳了一篇比較勵志的博文&#xff0c;講述了一個程序員從基礎薄弱到入職心儀公司的5年成長經歷&#xff0c;為了給那些待畢業或已畢業但對未來仍很迷茫的朋友指引前行的方向&#xff0c;CSDN專訪了這篇博文的作者。 導語:今年三月份&#…

真格量化——商品期權基本策略

#!/usr/bin/env python # coding:utf-8 from PoboAPI import * import datetime import time import numpy as np from copy import *#開始時間,用于初始化一些參數 def OnStart(context) :context.myacc = None#登錄交易賬號if context.accounts["回測期貨"].Login…

關于windows下的libtorch配置

關于windows下的libtorch配置 1.環境 Windows service 2012 R2/Windows10Cuda 9.0OpenCV3.4.1Libtorch1.0VS2017/VS20152.配置 第一步:CUDA 9.0cudnn7.5安裝(也可以用CUDA8.0) 如果已經安裝了cuda8.0及以上版本,可以忽略此步驟。 libtorch有cuda8.0 和cuda9.0的版本,為了與vs版…

spring集成多個rabbitMQ

轉自&#xff1a;https://blog.csdn.net/zz775854904/article/details/81092892 MQ全稱為Message Queue, 消息隊列&#xff08;MQ&#xff09;是一種應用程序對應用程序的通信方法。應用程序通過讀寫出入隊列的消息&#xff08;針對應用程序的數據&#xff09;來通信&#xff0…

解決(springboot項目)mysql表名大寫,造成jpa Table doesn't exist問題

這個問題有2種解決方法&#xff1a; 我的報錯是&#xff1a;java.sql.SQLSyntaxErrorException: Table gaei_ms.gaei_work_task doesnt exist方法一&#xff1a; 轉自&#xff1a;https://confluence.atlassian.com/fishkb/table-xxx-doesn-t-exist-error-with-mysql-server-30…

一個三流學校程序員的奮斗歷程

寫作用意 這些日子我一直在寫一個實時操作系統內核&#xff0c;已有小成了&#xff0c;等寫完我會全部公開&#xff0c;希望能夠為國內IT的發展盡自己一份微薄的力量。最近看到很多學生朋友和我當年一樣沒有方向&#xff0c;所以把我的經歷寫出來與大家共勉&#xff0c;希望能…

真格量化——做空波動率策略

# coding:utf-8 #!/usr/bin/env python # EmuCounter2 from PoboAPI import * import datetime import numpy as np#開始時間,用于初始化一些參數 def OnStart(context) :print "system starting..."#設定全局變量品種g.code1 = "m1901-C-3300.DCE" #豆粕…

搭建webpack基礎配置

搭建webpack基礎步驟&#xff1a; 1.去官方網站下載node.js&#xff08;根據自己電腦的系統類型選擇&#xff09; 2.安裝node.js完成后打開cmd命令提示符&#xff1a; 出現版本號證明安裝成功 3.cd到工程目錄下 npm install -g vue-cli&#xff08;這里使用的是vue-cli腳手架安…

JPA 中 sql 預編譯 -- EntityManager 使用 預編譯

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 實現方式 &#xff1a; 1. 注入em: PersistenceContextprivate EntityManager entityManager; 注入方式 2&#xff1a; PersistenceUn…

持續記函數

自己寫文章的緣由 juejin.im/post/5c7368… 2019年2月26日 星期二 array_shift — 將數組開頭的單元移出數組 <?php $stack array("orange", "banana", "apple", "raspberry"); $fruit array_shift($stack); print_r($stack); ?…

研究:多感官教學增強記憶 學習效率事半功倍

人們在記憶外部信息時&#xff0c;必須先要去接受這些信息&#xff0c;而接受信息的“通道”不止一個&#xff0c;有視覺、聽覺、嗅覺、味覺、觸覺等等。有多種感官參加的記憶叫做“多通道”記憶。圖為臺中一幼稚園戶外寫生活動。 生動的教學方法往往可以吸引大多數孩子&#…

330 div+css Experience

今天學習的div&#xff0c;感覺對編輯html更為方便快捷&#xff0c;但還是需要多練&#xff0c;多熟悉一下思路和邏輯方式 越來越感覺&#xff0c;代碼不是重要的&#xff0c;重要的是方向和思路&#xff0c;am的float clearfloat 及屬性&#xff0c;還有overflow 溢出的三個屬…

時間序列的平穩性檢驗方法匯總

時間序列平穩性檢驗方法&#xff0c;可分為三類&#xff1a; 圖形分析方法 簡單統計方法 假設檢驗方法 一、圖形分析方法 可視化數據 可視化數據即繪制時間序列的折線圖&#xff0c;看曲線是否圍繞某一數值上下波動&#xff08;判斷均值是否穩定&#xff09;&#xff0c;看…