1. 程式人生 > 實用技巧 >dokcer映象詳解

dokcer映象詳解

映象是什麼

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

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

獲取映象的途徑

1.從映象倉庫下載

2.從映象壓縮包

3.自己製作的dockerfile

Docker映象載入原理

UnionFs (聯合檔案系統)

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

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

Docker映象載入原理

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

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

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

虛擬機器是分鐘級別,容器是秒級!

映象原理之分層理解

為什麼docker映象會採用種方式?

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

#我們檢視下mysql映象的詳細資訊
[root@localhost ~]# docker image inspect mysql
[
    {
        "Id": "sha256:e1d7dc9731daa2c79858307d65ef35f543daf97457b9c11b681f78bb86f7a158",
        "RepoTags": [
            "mysql:latest"
        ],
        "RepoDigests": [
            "mysql@sha256:e1bfe11693ed2052cb3b4e5fa356c65381129e87e38551c6cd6ec532ebe0e808"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2020-09-10T06:53:58.046364521Z",
        "Container": "4a20d34c487d787e9094710172924054541f179b2f2082f159ce65e9506252d7",
        "ContainerConfig": {
            "Hostname": "4a20d34c487d",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "3306/tcp": {},
                "33060/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.12",
                "MYSQL_MAJOR=8.0",
                "MYSQL_VERSION=8.0.21-1debian10"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"mysqld\"]"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:145f837222dc7be65e5db56e4ab4d4bcf62fed0902d522732101b21ea681b8d4",
            "Volumes": {
                "/var/lib/mysql": {}
            },
            "WorkingDir": "",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {}
        },
        "DockerVersion": "18.09.7",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "3306/tcp": {},
                "33060/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.12",
                "MYSQL_MAJOR=8.0",
                "MYSQL_VERSION=8.0.21-1debian10"
            ],
            "Cmd": [
                "mysqld"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:145f837222dc7be65e5db56e4ab4d4bcf62fed0902d522732101b21ea681b8d4",
            "Volumes": {
                "/var/lib/mysql": {}
            },
            "WorkingDir": "",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": null
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 544193603,
        "VirtualSize": 544193603,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/eac1b28e5eeccf446cf9b122130a0761b1ce19eb50c500f04c69bed0da333521/diff:/var/lib/docker/overlay2/52e8db187192ee8d52b74347809023f4d4989318d517b71ecc39db95b4db717b/diff:/var/lib/docker/overlay2/cc98255084914f1f38518e92c3bd1d69ac316cb8218fac134c47a1dcd51349c2/diff:/var/lib/docker/overlay2/a7937b4cc17e5c19b65d4e9f9ed69ef12f170ef0dbe2693f83628625429cb9f8/diff:/var/lib/docker/overlay2/bdb1d89a22e53bddc97c756f6aa1c7cd1b37e64b7c5e9adb91b358befeb18e57/diff:/var/lib/docker/overlay2/1c854d0a0f91fe80a44b36e4e8a878dddb8a6e3e62379226b3f6d6384c6b572c/diff:/var/lib/docker/overlay2/b563e53761d60fcfc229adcb80c08c38c32ec7bbe1e28579594a3c999eab4a1d/diff:/var/lib/docker/overlay2/f389d58ec12144138c574c483546a5544af85bba51eaf9f877c63c92bec5777a/diff:/var/lib/docker/overlay2/9acaabfed69e8d07fc2b20cbf0b641beb1008e6ff76edf2d6d62d61ada4c2d57/diff:/var/lib/docker/overlay2/0e36e7ad27559688836e84d437e0a0856c047aff62294a2ac0caedeaa728f32c/diff:/var/lib/docker/overlay2/d68cbded916a426e7612c238e7414b4535c0b6abf1fbcf0e697e3c8bd20dfbc3/diff",
                "MergedDir": "/var/lib/docker/overlay2/4c822dd9bf616bfce6ab26be4a5946630a5464281f948ed9b988fa604b55f5f6/merged",
                "UpperDir": "/var/lib/docker/overlay2/4c822dd9bf616bfce6ab26be4a5946630a5464281f948ed9b988fa604b55f5f6/diff",
                "WorkDir": "/var/lib/docker/overlay2/4c822dd9bf616bfce6ab26be4a5946630a5464281f948ed9b988fa604b55f5f6/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {                     
            "Type": "layers",
            "Layers": [
                "sha256:07cab433985205f29909739f511777a810f4a9aff486355b71308bb654cdc868",
                "sha256:99f2b905661ad6da61a7daa03441f86868e5dc621ea9a53696f98d40a51361d4",
                "sha256:705e0a5709e5bfe1bcad6bca71c0677e2088f49b387bc0c070135ab38209b575",
                "sha256:73b2ff2d449dc8cc7525999a8876aec53f61066bff7649e4b0576a0355631c76",
                "sha256:18c57f967c0e8c90e26279c89d172b3e84fac30c48fd14066bc1d0481895b161",
                "sha256:4ff56402c7c53062e1c7aba89dab4779b4929bcc19f21564fcb2b35b3b8d0e63",
                "sha256:d2055cc0a7aa80c180028c7970c43e09cefc492a0d323de2604e55c98cb398c2",
                "sha256:e929be3696cafce09e09dc6f62fd48d4e23fe96a6583d1e66d03a78627d79725",
                "sha256:2a0bd3a9cd29a9c065c946f5df05676a3996abd4c126769d06cbecbc839e62a1",
                "sha256:d086c9717c2b03114f508febcfca6671f098054c283834731ce78411bfeac42e",
                "sha256:35864924eb5e64b1fc86db107a241d1bc1e1b713e0faef59f60f88c2699c9b13",
                "sha256:612c87e75ba549972e70f0224092d8722709304f2b69a91ad6cfb6315654a273"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

理解:

所有的 Docker映象都起始於一個基礎映象層,當進行修改或培加新的內容時,就會在當前映象層之上,建立新的映象層。

舉一個簡單的例子,假如基於 Ubuntu Linux16.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 映象

docker commit #將一個容器提交成一個新的標籤
docker commit -m="描述資訊" -a="作者" 容器id 目標映象名:[版本TAG]

例項演示:

1.執行一個tomcat容器
docker run -d -it --name=tomcat01 -p 8080:8080 tomcat
2.發現沒有頁面
3.我們新增一個頁面
[root@localhost ~]# docker exec -it tomcat01 /bin/bash
root@a711ca484d49:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@a711ca484d49:/usr/local/tomcat# 
4.使用docker commit 將容器提交成一個新的映象
[root@localhost ~]# docker commit -m="copy webapps.dis/* to webapps " -a="martin<[email protected]>" tomcat01 martin/tomcat02:0.1
sha256:75448ab287079920a9fca99a2de91a893a4da4443702f8ed16870fb45c504321
[root@localhost ~]# docker images
REPOSITORY               TAG                 IMAGE ID            CREATED                  SIZE
martin/tomcat02          0.1                 75448ab28707        6 seconds ago            652MB
[root@localhost ~]# docker run -d -it --name=tomact02 -p 8081:8080 martin/tomcat02:0.1