
當我對Docker技識訓是一知半解的時候,我發現理解Docker的命令非常困難,于是,我花了幾周的時間來學習Docker的作業原理,更確切地說,是關于Docker統一檔案系統(the union file system)的知識,然后回過頭來再看Docker的命令,一切變得順理成章,簡單極了,
題外話:就我個人而言,掌握一門技術并合理使用它的最好辦法就是深入理解這項技術背后的作業原理,通常情況下,一項新技術的誕生常常會伴隨著媒體的大肆宣傳和炒作,這使得用戶很難看清技術的本質,更確切地說,新技術總是會發明一些新的術語或者隱喻詞來幫助宣傳,這在初期是非常有幫助的,但是這給技術的原理蒙上了一層砂紙,不利于用戶在后期掌握技術的真諦,大學期間學那么多理論基礎概念也不是為了更好的理解概念,
# Image Definition
鏡像(Image)就是一堆只讀層(read-only layer)的統一視角,也許這個定義有些難以理解,下面的這張圖能夠幫助讀者理解鏡像的定義,

從左邊我們看到了多個只讀層,它們重疊在一起,除了最下面一層,其它層都會有一個指標指向下一層,這些層是Docker內部的實作細節,并且能夠在主機(譯者注:運行Docker的機器)的檔案系統上訪問到,統一檔案系統(union file system)技術能夠將不同的層整合成一個檔案系統,為這些層提供了一個統一的視角,這樣就隱藏了多層的存在,在用戶的角度看來,只存在一個檔案系統,我們可以在圖片的右邊看到這個視角的形式,
你可以在你的主機檔案系統上找到有關這些層的檔案,需要注意的是,在一個運行中的容器內部,這些層是不可見的,在我的主機上,我發現它們存于/var/lib/docker/aufs目錄下,
# Container Definition
容器(container)的定義和鏡像(image)幾乎一模一樣,也是一堆層的統一視角,唯一區別在于容器的最上面那一層是可讀可寫的

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

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

我們可以通過運行以下命令來驗證我們上面所說的:
docker run ubuntu touch happiness.txt
即便是這個ubuntu容器不再運行,我們依舊能夠在主機的檔案系統上找到這個新檔案,
find / -name happiness.txt
# Image Layer Definition
為了將零星的資料整合起來,我們提出了鏡像層(image layer)這個概念,下面的這張圖描述了一個鏡像層,通過圖片我們能夠發現一個層并不僅僅包含檔案系統的改變,它還能包含了其他重要資訊,

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

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

Metadata Location:
我發現在我自己的主機上,鏡像層(image layer)的元資料被保存在名為”json”的檔案中,比如說:
/var/lib/docker/graph/e809f156dc985.../json
一個容器的元資料好像是被分成了很多檔案,但或多或少能夠在/data/docker/lib/containers/<id>目錄下找到,<id>就是一個可讀層的id,這個目錄下的檔案大多是運行時的資料,比如說網路,日志等等,
# 全域理解(Tying It All Together)
docker create <image-id>

docker start <container-id>

Docker start命令為容器檔案系統創建了一個行程隔離空間,注意,每一個容器只能夠有一個行程隔離空間,
docker run <image-id>

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

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

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

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

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

docker build


docker save <image-id>

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

docker export命令創建一個tar檔案,并且移除了元資料和不必要的層,將多個層整合成了一個層,只保存了當前統一視角看到的內容(譯者注:expoxt后的容器再import到Docker中,通過docker images –tree命令只能看到一個鏡像;而save后的鏡像則不同,它能夠看到這個鏡像的歷史鏡像)
作者 | bethal
來源 | http://sina.lt/gfmf
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/69111.html
標籤:Linux
