天天看點

kubernetes Spring Cloud 微服務架構— (3)Kubernetes spring cloud 微服務-Docker 鏡像存儲機制

3.1  Linux 系統運作基礎

Linux 系統正常運作, 通常需要兩個檔案系統:

3.1.1 boot file system (bootfs)

1)包含 Boot Loader與Kernel檔案,使用者不能修改這些檔案。并且在系統啟動過程完成之後, 整個系統的核心都會被加載進記憶體。此時bootfs會被解除安裝, 進而釋放出所占用的系統記憶體。

2)在容器中可以運作不同版本的Linux, 說明對于同樣核心版本的不同的 Linux 發行版的bootfs 都是一緻的, 否則會無法啟動。是以可以推斷, Docker運作是需要核心支援的。

3) Linux系統中典型的bootfs目錄: (核心) /boot/vmlinuz、(核心解壓縮所需 RAM Disk)

/boot/initramfs

3.1.2 root file system (rootfs)

1) 不同的Linux發行版本, bootfs相同, rootfs不同(二進制檔案)。

2)每個容器有自己的 rootfs, 它來自不同的Linux 發行版的基礎鏡像,包括 Ubuntu,

Debian 和 SUSE 等。

3)   使用不同的rootfs 就決定了, 在建構鏡像的過程中, 可以使用哪些系統的指令。

4)   典型的rootfs 目錄: /dev、/proc、/bin、/etc、 /lib、/usr

3.2  OverlayFS 存儲原理

OverlayFS 結構分為三個層: LowerDir、Upperdir、MergedDir

1)LowerDir (隻讀) 隻讀的 image layer,其實就是 rootfs, 在使用 Dockfile 建構鏡像的時候, Image Layer 可以分很多層,是以對應的 lowerdir 會很多(源鏡像)。

2) Upperdir (讀寫)

upperdir 則是在 lowerdir 之上的一層, 為讀寫層。容器在啟動的時候會建立, 所有對容器的修改, 都是在這層。比如容器啟動寫入的日志檔案,或者是應用程式寫入的臨時檔案。

3)MergedDir (展示)  merged 目錄是容器的挂載點,在使用者視角能夠看到的所有檔案,都是從這層展示的。

3.3 分析鏡像存儲結構

3.3.1 擷取鏡像存儲路徑 #通過鏡像資訊擷取到實體存儲位置

root@master jdk]# docker image inspect jre8:1.3 
 "Architecture": "amd64", 
 "Os": "linux", 
 "Size": 136406576, 
 "VirtualSize": 136406576, 
 "GraphDriver": { 
     "Data": { 
         "LowerDir": 
"/var/lib/docker/overlay2/ba469a9497fe6894e9022c2cb8b4217cd5aa1d0b35653ccd927a247bff3d2a81/diff:/var/lib/docker/overlay2/785564c2852e5b5b8f53d84ab4350c7aec6cb5a0 f44e457779877f06a95354ad/diff:/var/lib/docker/overlay2/101c2e9852e1b3e4a593f1b4ca8770fdd2b2c4656b3447dc96799527f03767c6/diff:/var/lib/docker/overlay2/fb940d476e39c
51cace728b5d709fff21c5c6421227c7ec7b2c421875767bc26/diff:/var/lib/docker/overlay2/271a364d00b2aabce86f2cb7d6c1abead3e1c8903cdd25e07a901964e3534978/diff",
         "MergedDir": "/var/lib/docker/overlay2/6700cb0c98e3e7af8bdd97d4e40d673e3a0cf0fc6768323e8d4372afde12aff2/merged",
         "UpperDir": "/var/lib/docker/overlay2/6700cb0c98e3e7af8bdd97d4e40d673e3a0cf0fc6768323e8d4372afde12aff2/diff",
         "WorkDir": "/var/lib/docker/overlay2/6700cb0c98e3e7af8bdd97d4e40d673e3a0cf0fc6768323e8d4372afde12aff2/work"
     }, 
     "Name": "overlay2" 
 }, 
 "RootFS": { 
     "Type": "layers", 
     "Layers": [ 
        "sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10",
        "sha256:3219209e108e14824bd77c247110bbdb0e8ab392a016c634b8f031b610673fac",
        "sha256:d5aea7d9c0743772a38d8d81c4f1be709890827bc915465a7048a7d718fbf859",
        "sha256:3ff10a379107fb9e679ac8c001e5edbc4a01ec7b3bd86162e5932aa5ea2f8808",
        "sha256:c86fc31cf85edab6d1b9aa4750656496e0925186c112092ddd0a5909ba4a8b9b",
        "sha256:27d22f85ea93e4cbdf47b565433be94f6ce46f4e822abe6352c0f5b028bd2150"
     ]      

3.3.2 分析Lower層

#LowerDir 層的存儲是不允許建立檔案, 此時的LowerDir實際上是其他的鏡像的UpperDir層,也就是說在建構鏡像的時候, 如果發現建構的内容相同, 那麼不會重複的建構目錄,而是使用其他鏡像的Upper 層來作為本鏡像的Lower

[root@master jdk]# touch /var/lib/docker/overlay2/ba469a9497fe6894e9022c2cb8b4217cd5aa1d0b35653ccd927a247bff3d2a81/diff/lower.txt      

3.3.3 分析Upper層

#在Upper層建立檔案

[root@master jdk]# touch /var/lib/docker/overlay2/6700cb0c98e3e7af8bdd97d4e40d673e3a0cf0fc6768323e8d4372afde12aff2/diff/upper.txt      

3.4 運作中容器的存儲結構

3.4.1 啟動容器

#前台啟動,直接進入到容器

[root@master jdk]# docker run -it jre8:1.3 bash      

3.4.2 檢視容器挂在資訊

#容器啟動以後,挂載merged、lowerdir、upperdir以及workdir目錄 #lowerdir是隻讀的image layer,其實就是rootfs

#擷取容器 ID

/

[root@master ~]# docker ps 
CONTAINER ID        IMAGE          COMMAND                  CREATED             STATUS              PORTS                  NAMES 
39d421864be6  jre8:1.3 "bash"                  11 seconds ago      Up 10 seconds              agitated_heyrovsky      

3.4.3 檢視容器存儲目錄資訊

#注意在所有的啟動容器中會自動添加init目錄, 此目錄是存放系統的hostname與域名解析檔案。

[root@master ~]# docker inspect 39d421864be6 
        "GraphDriver": { 
            "Data": { 
                "LowerDir":     "/var/lib/docker/overlay2/7397527ac0e1088be96ee714bb6caf78e88badd567477f7bfbec9717a975794dinit/diff:/var/lib/docker/overlay2/6700cb0c98e3e7af8bdd97d4e40d673e3a0cf0fc6768323e8d4372afde12aff2/diff:/var/lib/docker/overlay2/ba469a9497fe6 894e9022c2cb8b4217cd5aa1d0b35653ccd927a247bff3d2a81/diff:/var/lib/docker/overlay2/785564c2852e5b5b8f53d84ab4350c7aec6cb5a0f44e4577798 77f06a95354ad/diff:/var/lib/docker/overlay2/101c2e9852e1b3e4a593f1b4ca8770fdd2b2c4656b3447dc96799527f03767c6/diff:/var/lib/docker/overlay2/f b940d476e39c51cace728b5d709fff21c5c6421227c7ec7b2c421875767bc26/diff:/var/lib/docker/overlay2/271a364d00b2aabce86f2cb7d6c1abead3e1c89
03cdd25e07a901964e3534978/diff", 
                "MergedDir": "/var/lib/docker/overlay2/7397527ac0e1088be96ee714bb6caf78e88badd567477f7bfbec9717a975794d/merged", 
                "UpperDir": "/var/lib/docker/overlay2/7397527ac0e1088be96ee714bb6caf78e88badd567477f7bfbec9717a975794d/diff", 
                "WorkDir": "/var/lib/docker/overlay2/7397527ac0e1088be96ee714bb6caf78e88badd567477f7bfbec9717a975794d/work" 
            }, 
            "Name": "overlay2" 
        }, 
        "Mounts": [], 
        "Config": { 
            "Env": [ 
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/java/jdk/jre1.8.0_211/bin",                 "GLIBC_VERSION=2.31-r0", 
                "JAVA_HOME=/usr/java/jdk/jre1.8.0_211" 
            ], 
            "Cmd": [ 
                "bash" 
            ], 
            "Image": "jre8:1.3", 
            "Volumes": null, 
            "WorkingDir": "/opt", 
            "Entrypoint": null, 
            "OnBuild": null, 
            "Labels": {} 
        }, 
    } 
] 
 
      

3.5 容器檔案存儲解析

3.5.1 容器運作時的UpperDir目錄結構

[root@master ~]# touch /var/lib/docker/overlay2/7397527ac0e1088be96ee714bb6caf78e88badd567477f7bfbec9717a975794d/diff/c1.txt 
#在進入到操作檢視 
bash-4.3# cat /c1.txt 
      

3.5.1.1 Work 目錄

work目錄用于聯合挂載指定的工作目錄,在overlay 把檔案挂載到 upperdir後, work内容會被清空,且在使用過程中(為空)其内容使用者不可見。

3.5.1.3 使用者視角層Merged

#    後給使用者展示的層,一般看到為一個完整的作業系統檔案系統結構

[root@master ~]# ll    /var/lib/docker/overlay2/7397527ac0e1088be96ee714bb6caf78e88badd567477f7bfbec9717a975794d/merged   
total 4 
….省略…… 
-rw-r--r-- 1 root root    0 Mar 14 03:58 lower.txt -rw-r--r-- 1   root root    0 Mar 14 04:03 upper.txt drwxr-xr-x 1 root   root   18 Mar 14 03:10 usr      

3.5.2 Lower 層

Lower 包括兩個層:

a. 系統的init。b.容器的鏡像層

Lower 記錄父層的連結名稱

[root@node-2 ~]# cat /var/lib/docker/overlay2/d4dc057329ecbf5a2f97293b6d49078e9cce6869a9f049ba5bc365f6fba424d2/lower  l/QCXVWDWYPFM5NRVMB2ZC2BE5WU:l/PUSOZBTJKJ2OBNKK2UQDNQLHCU init 層 / 容器鏡像層      

3.5.2.1 檢視init層位址指向

#容器在啟動的過程中, Lower 會自動挂載init的一些檔案

[root@master~]#ls /var/lib/docker/overlay2/7397527ac0e1088be96ee714bb6caf78e88badd567477f7bfbec9717a975794d-init/diff/etc/hostname  hosts mtab  resolv.conf      

3.5.2.2 init層主要内容是什麼?

init層是以一個uuid+-init結尾表示,放在隻讀層(Lower)和讀寫層(upperdir)之間, 作用隻是存放/etc/hosts、/etc/resolv.conf 等檔案,

3.4.2.3 為什麼需要init層?

1)容器在啟動以後, 預設情況下lower層是不能夠修改内容的, 但是使用者有需求需要修改主機名與域名位址, 那麼就需要添加init層中的檔案(hostname, resolv.conf), 用于解決此類問題. 2) 修改的内容隻對目前的容器生效,而在docker commit送出為鏡像時候,并不會将init層送出。

3) init 檔案存放的目錄為/var/lib/docker/overlay2/<init_id>/diff

3.5.2.4 檢視init層檔案

#hostname與resolv.conf 全部為空檔案, 在系統啟動以後由系統寫入.

[root@master ~]# ll   /var/lib/docker/overlay2/7397527ac0e1088be96ee714bb6caf78e88badd567477f7bfbec9717a975794d-init/diff/etc/ 
total 0 
-rwxr-xr-x 1 root root  0 Mar 14 04:09 hostname -rwxr-xr-x 1 root   root  0 Mar 14 04:09 hosts lrwxrwxrwx 1   root root 12 Mar 14 04:09 mtab -> /proc/mounts 
-rwxr-xr-x 1 root   root  0 Mar 14 04:09 resolv.conf      

#總結

1)鏡像所挂載的目錄層為 Lower 層,然後通過 Merged 展示所有的檔案目錄與檔案。使用者寫入的所有檔案都是在 UpperDir 目錄,并且會在UpperDir 建立于 Merged 層展示的檔案目錄結構,是以使用者就可以看到寫入的檔案。并且底層的鏡像是不能被修改(如果挂載目錄為 UpperDir,則可以修改源鏡像)。

2)在下次重新啟動已經停止的容器的時候, 如果容器的 ID 沒有發生改變,那麼所寫入的檔案是存在實體系統中的; 反之就會是一個新的容器,之前手工建立的檔案是不存在的。

3)基于容器建立的鏡像,就相當于容器的快照, 可以删除原來的容器, 但是不能删除原來的鏡像

4) 基于鏡像建立的鏡像,原來的鏡像就是新鏡像的low 層 (build), tag 則是沒有差別

5) 容器啟動以後,鏡像就存在于容器的 lower層,所有的寫入都是在 upper