Docker映象例項剖析

現在越來越多的企業基於容器和雲來構建自己的基礎架構,管理的容器越來越多,時而會遇到一些容器映象不知道是幹嘛的?容器執行時引數是什麼?容器跑的應用是什麼?針對這些疑問今天就是學習如何剖析線上的容器及其映象的構造和內容。

映象內容

首先容器映象實際上是一個tarball打包的檔案。

我們可以用docker save把映象輸出為tar檔案。

docker save vbkunin/itop:2。7。0 >/tmp/itop。tar

然後解開該tar包

tar xvf itop。tar

解開後目錄中,是一層層的映象雜湊命名的目錄,每一層(一個目錄)有三個檔案VERSION、json和layer。tar,總體還有一個manifest。json,一個配置json和repositories

我們首先看看manifest。json的內容,格式混亂不便理解,為了檢視其內容我們使用jq(蟲蟲之前的文章專門介紹過)。

jq 。 manifest。json

可見itop 2。7。0這個映象由25層構成。我們再來看看配置的json裡面有什麼內容?

jq 。 ecd46ce38fdec1e882d665ecdc1831e25986080676529951fa6663a4bab6b577。json

檔案內容較長,我們看最前面部分:

可以用jq keys列出其配置專案裡面的鍵:

jq keys ecd46ce38fdec1e882d665ecdc1831e25986080676529951fa6663a4bab6b577。json

包括容器基本資訊專案 architecture、author、config、container、container-config、created、docker_version、history、os和rootfs,其中最重要是中間的history部分,列出了映象中的每層構成,基本上對應Dockerfile中的每一個條語句,一句對應一層,然後整個堆疊起來就構成了完整的映象。

jq 。history ecd46ce38fdec1e882d665ecdc1831e25986080676529951fa6663a4bab6b577。json

我們常常看到Dockerfile中會把一系列的操作都放在一起,就是為了減少執行的語句,減少層數從節省空間,比如本映象中最關鍵安裝步驟為:

{

“created”: “2020-04-26T15:46:29。315124814Z”,

“author”: “Vladimir Kunin ”,

“created_by”: “|2 ITOP_FILENAME=iTop-2。7。0-1-5541。zip ITOP_VERSION=2。7。0-1 /bin/sh -c apt-get install -y software-properties-common && add-apt-repository -y ppa:ondrej/php && a

pt-get update && apt-get install -y apache2 php7。3 php7。3-xml php7。3-mysql php7。3-json php7。3-mbstring php7。3-ldap php7。3-soap php7。3-zip php7。3-gd php-apcu graph

viz curl unzip git && apt-get clean && rm -rf /var/lib/apt/lists/* && update-alternatives ——set php /usr/bin/php7。3”

},

有了history部分的內容,根據這些內容,基本就可以完整的重構Dockerfile。

但是我們還缺少一個基本From基礎映象,上面的內容中我並沒有這部分內容。我們從 manifest。json檔案中審查第一個映象層為:

0bd213ebb246d391914dc365aebe90da94db49690f0e1130611e68e344ab4ee1,看看該層的構成: tar tf 0bd213ebb246d391914dc365aebe90da94db49690f0e1130611e68e344ab4ee1/ layer。tar

大體上估算,這是一個基礎Linux映象,還有如下內容

解開包

tar xf 。。/layer。tar

cat etc/lsb-release

這可以作為Dockerfile的基礎映象,作為From語句的內容了。

自動工具dive

以上步驟實際上很複雜,學習來用還可以,但是實踐中這樣搞,太過蠻煩。沒關係這自然有其他人已經解決了,有專門的工具幫你自動分析,這個工具叫dive,一個用golang開發的工具,可以用分析探索Docker映象,各層內容以及最佳化縮小Docker/OCI映象大小。該工具在GitHub開放,目前已經25800星。

安裝

安裝很簡單,從github下載個發行版的對應二進位制包,然後安裝即可。

使用

使用更簡單

dive

比如我們分析第一步的itop映象:

dive vbkunin/itop:2。7。0

就進入互動介面,可以用鍵盤上下鍵,移動到各層檢視對應的資源:

左上窗體Layer列出各個層,鍵盤可以移動。

左邊中間窗體是層細節內容,包括Tags、Digest和Command。

左邊下邊窗體是映象細節內容其中潛在的空間浪費(Potential wasted space)和映象效率分(Image efficiency score)可以用來分析映象和最佳化參考。

右邊窗體是具體內容檔案系統。

還有一個特色功能是和CI結合用於在自動映象打包的質量分析,詳見官方文件。

執行時引數

最後說下容器的執行時引數,這個很重要,透過執行時引數設定,給一個映象配置了具體個性化的引數,這樣執行起來才是真正的容器,才有使用價值。

很多時候大家都是直接複製執行命令執行的,過了一段時間後就忘記當初怎麼執行的,要對重新啟用或者要修改一些引數再執行就成了個問題。

Docker執行時引數儲存在宿主機檔案中的,預設情況下位置為:

/var/lib/docker/containers/容器ID

hostconfig。json和config。v2。json兩個配置檔案,其中config。v2。json就是 docker inspect的內容。

當然這兩個配置檔案都新增額外的,內容要直接還原為啟動命令比較費勁,需要藉助兩個工具來實現rekcod和runlike,兩個工具一個用js,一個用python開發(應該搞個golang版的)安裝依賴都太多,容易搞亂環境,建議用docker方式使用。

docker run ——rm -v /var/run/docker。sock:/var/run/docker。sock nexdrew/rekcod <容器ID>

docker run ——rm -v /var/run/docker。sock:/var/run/docker。sock assaflavie/runlike <容器ID>

就能比較準確還原出出大概的啟動引數了(有些額外多餘的引數)。當然還有個方法就是用容器編排系統,比如K8s 或者基於docker-compose啟容器,因為這都是基於配置檔案的,就不怕忘記配置引數了。

相關文章