1. 程式人生 > 其它 >3.docker映象探究

3.docker映象探究

0x01. 映象是什麼

映象是一種輕量級, 可執行的獨立軟體包, 用來打包軟體執行環境和基於執行環境開發的軟體, 它包含執行某個軟體所需的所有內容, 包括程式碼, 執行時, 庫, 環境變數和配置變數

所有的應用, 直接打包docker映象, 就可以直接跑起來!

如何得到映象呢?

  • 從遠端倉庫下載
  • 基友copy給你
  • 自己製作一個映象 DockerFile

0x02. Docker映象載入原理

UnionFS ( 聯合檔案系統 )

我們下載的時候看到的一層層就是這個

UnionFS ( 聯合檔案系統 ) : Union檔案系統 ( UnionFS ) 是一種分層, 輕量級並且高效能的檔案系統, 它支援對檔案系統的修改作為一次提交來一層層的疊加, 同時可以將不同目錄掛載到同一虛擬檔案系統下, Union檔案系統是Docker 映象的基礎 , 映象可以通過分層來進行繼承, 基於基礎映象 ( 沒有父映象 ) , 可以製作各種具體的應用映象

特性 : 一次同時載入多個檔案系統, 但從外面看起來, 只能看到一個檔案系統, 聯合載入會把各層檔案系統疊加起來,這樣最終的檔案系統會包含所有底層的檔案和目錄

docker 映象載入原理

docker的映象實際上由一層一層的檔案系統組成, 這種層級的檔案系統就是UnionFS

bootfs( boot filesysytem ) 主要包含bootloader 和 kernel , bootloader 主要是引導載入kernel, linux剛啟動時會載入bootfs檔案系統,在docker映象的最底層是bootfs。這一層與我們典型的linux、uninx系統是一樣的,包含boot載入器和核心。當boot載入完成之後整個核心都在記憶體中了,此時記憶體的使用權已由bootfs轉交給核心,此時系統也會解除安裝bootfs

rootfs ( root file system ) , 在bootfs之上, 包含的就是典型linux系統中的 /dev /proc /bin /etc 等標準目錄和檔案, rootfs就是各種不同的作業系統發行版, 比如 Ubuntu , Centos等等

平時我們安裝進虛擬機器的CentOS都是好幾個G,為什麼Docker這裡才200M ?

對於一個精簡的o0S , rootfs可以很小,只需要包含最基本的命令,工具和程式庫就可以了,因為底層直接用Host的kerne,自己只需要提供rootfs就可以了。由此可見對於不同的linux發行版, bootfs基本是一致的, rootfs會有差別,因此不同的發行版可以公用bootfs。

0x03. 分層原理

分層的映象

我們可以去下載一個映象, 注意觀察下載的日誌輸出, 可以看到是一層一層的在下載

思考 : 為什麼Docker映象要採用這種分層的結構呢?

最大的好處, 我覺得莫過於是資源共享! 比如有多個映象都從相同的Base映象構建而來,那麼宿主機只需要在磁碟上保留一份base映象, 同時記憶體中也是需要載入一份base映象, 這樣就可以為所有的容器服務了,而且映象的每一層都可以共享

檢視映象分層的方式可以通過 docker images inspect 命令

[root@centos7 ~]# docker image inspect redis:latest
[.....................
"GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/9bbbbb1513a947ef6798e2ceb33f324546e9c03c0aedaeec6ee94e7ceb6dd43b/diff:/var/lib/docker/overlay2/fca8b5e526ad25bf6e76417950c5bed8d1d71996f3d3246d8f5f66857cc38d2f/diff:/var/lib/docker/overlay2/abc6bcd9360dfd1cde300650cec2dbd98c726424f358565aca237ac67e84b742/diff:/var/lib/docker/overlay2/025bd1abda4e163c69ba5a991b8d0881f48e4f31598343f707a9bf3d0c5c2c56/diff:/var/lib/docker/overlay2/96fabbaf80522fbb4d4bb539ed414e51575c5e385465beb937078fbd61b401f3/diff",
                "MergedDir": "/var/lib/docker/overlay2/9b2059fa46a21c8230660fcbc522bbd14a148b6014ec0df6493b42908955be4c/merged",
                "UpperDir": "/var/lib/docker/overlay2/9b2059fa46a21c8230660fcbc522bbd14a148b6014ec0df6493b42908955be4c/diff",
                "WorkDir": "/var/lib/docker/overlay2/9b2059fa46a21c8230660fcbc522bbd14a148b6014ec0df6493b42908955be4c/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:346fddbbb0ff19bdb026afb053df490c0c73981a8a985882cf8ee3d716735e87",
                "sha256:a6ff16e8451ec08d277c59ee62169c65cca33293b62dddd3336365a1fe94d598",
                "sha256:9829ed4a48087cbe697bc56a7450bb3ab92a41b839d5b9250e410d02395439d9",
                "sha256:b0209f2252898cefd454e3c04a79b19058dbc652e1ded5b14be89df11e832167",
                "sha256:1fbf277d16836740a59ecaa122590826c4286267772b8af2f10ad1c36171881d",
                "sha256:7163f53b2285f2a583ca7a4e5fc788532e41ad093e3307f5767ebd131cce41a4"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

理解 :

所有的Docker映象都起始於一個基礎映象層,當進行修改或增加新的內容時,就會在當前映象層之上,建立新的映象層。
舉一個簡單的例子,假如基於Ubuntu Linux 16.04建立一個新的映象,這就是新映象的第一層;如果在該映象中新增Python包就會在基礎映象層之上建立第二個映象層;如果繼續新增一個安全補丁,就會建立第三個映象層。
該映象當前已經包含3個映象層,如下圖所示(這只是一個用於演示的很簡單的例子)。

在新增額外的映象層的同時,映象始終保持是當前所有映象的組合,理解這一點非常重要。下圖中舉了一個簡單的例子,每個映象層包含3個檔案,而映象包含了來自兩個映象層的6個檔案。

上圖中的映象層跟之前圖中的略有區別,主要目的是便於展示檔案。
下圖中展示了一個稍微複雜的三層映象,在外部看來整個映象只有6個檔案,這是因為最上層中的檔案7是檔案5的一個更新版本。

這種情況下,上層映象層中的檔案覆蓋了底層映象層中的檔案。這樣就使得檔案的更新版本作為一個新映象層新增到映象當中。Docker通過儲存引擎(新版本採用快照機制)的方式來實現映象層堆疊,並保證多映象層對外展示為統一的檔案系統。
Linux上可用的儲存引擎有AUFS、Overlay2、Device Mapper、Btrfs以及ZFS。顧名思義,每種儲存引擎都基於Linux 中對應的檔案系統或者塊裝置技術,並且每種儲存引擎都有其獨有的效能特點。
Docker在 Windows上僅支援windowsfilter一種儲存引擎,該引擎基於NTFS檔案系統之上實現了分層和CoW[1].下圖展示了與系統顯示相同的三層映象。所有映象層堆疊併合並,對外提供統一的檢視。

特點

docker映象都是隻讀的, 當容器啟動的時候, 一個新的可寫層被載入到映象的頂部!

這一層就是我們通常說的容器層, 容器之下的叫做映象層 !

如何提交一個自己的映象 commit

0x04. commit映象

docker commit   提交容器成為一個新的副本

# 命令和git原理類似
docker commit -m="提交的描述資訊" -a="作者" 容器id 目標映象名:[tag]

實戰測試

# 1.啟動一個預設的tomcat

# 2.發現這個預設的tomcat 是沒有webapps應用, 映象的原因, 官方預設映象 webapps下面是沒有檔案的

# 3.我自己copy進去了基本的檔案

# 4.將我們操作過的容器通過commit提交為一個映象!我們以後就使用我們修改過的映象即可
[root@centos7 ~]# docker commit -a="ymn" -m="add webapps app" d4d7a9e338fd tomcat02:1.0
sha256:b94af91084cb67f9e8f394ac024168d8a7b481c298acdabd0fcb07c48374ba87

# 這裡還只是在本地,沒有釋出過去,等到了docker file再說

學習方式說明︰理解概念,但是一定要實踐,最後實踐和理論相結合一次搞定這個知識

如果你想儲存當前容器的狀態, 就可以通過commit來提交獲得一個映象, 就好比我們學習虛擬機器的時候拍攝快照到這裡才算入門docker, 你覺得自己拼勁全力了, 可能只是別人的起點

docker的精髓在 容器資料卷 dockerfile docker網路 然後就是企業實戰