顯示兩個 Docker 映像之間的差異
一、概述
隨著越來越多的應用程序使用 Docker 部署,我們必須了解其生態系統的一些基本原理。雖然可用工具使打包和部署應用程序變得容易,但在某些時候,我們可能需要對部署的某些方面進行故障排除。
調試部署的最常見任務之一是檢查和比較圖像。在本教程中,我們將了解 Docker 鏡像的結構以及如何查看兩個鏡像之間的差異。
2.關於Docker鏡像
作為一些背景, Docker 圖像是關於如何創建容器的說明。我們可以將它們視為在容器內運行應用程序所需的完整文件和目錄集。這包括操作系統、第 3 方庫和我們的應用程序代碼。
在引擎蓋下,這些圖像本質上只是 tar 文件。在構建圖像時,我們在其中創建不同的層。每一層都是文件和目錄的集合。
通常,我們從現有圖像開始並添加到它。例如,要將 Spring Boot 應用程序構建為鏡像,我們將從現有的OpenJDK Docker 鏡像開始。這包含運行任何 Java 應用程序所需的操作系統和 JDK 文件。從那裡,我們將添加我們自己的 Java 文件,通常是應用程序的 fat jar,以及任何必需的 3rd 方庫。
在構建結束時,我們有一個包含運行應用程序所需的所有文件的單個圖像。接下來,我們將看看如何檢查單個圖像。
3. 檢查 Docker 鏡像
有幾種不同的方法可以檢查圖像。讓我們首先在本地 repo 中查找所有圖像:
$ docker image ls
spring-petclinic 2.7.0-SNAPSHOT 0f9d2d05687b 2 months ago 266MB
spring-petclinic 2.6.0-SNAPSHOT 1d79d5bd7779 3 months ago 265MB
通過可用圖像列表,我們現在可以查看特定圖像。
我們可以做的第一件事是運行inspect
命令:
$ docker inspect 0f9d2d05687b
[
{
"Id": "sha256:0f9d2d05687b8c816cbf54f63cf7e5aa7144d28e1996d468bfaf555a3882610a",
"RepoTags": [
"spring-petclinic:2.7.0-SNAPSHOT"
],
"Architecture": "amd64",
"Os": "linux",
"Size": 266141567,
"VirtualSize": 266141567,
...
}
]
此命令為我們提供了有關圖像的許多詳細信息,包括創建時間、其中的不同層等等。
然而,它並沒有告訴我們太多關於里面的內容。為此,我們必須首先將圖像保存到文件系統:
$ docker save 0f9d2d05687b > 0f9d2d05687b.tar
此命令會將圖像保存為 tar 文件。現在我們可以使用熟悉的tar
命令來檢查它:
$ tar tvf 0f9d2d05687b.tar
drwxr-xr-x 0 0 0 0 Dec 31 1979 02805fa4a4f35efdcf3804bc1218af1bc22d28ee521cc944cab5cac5dbe5abfe/
-rw-r--r-- 0 0 0 3 Dec 31 1979 02805fa4a4f35efdcf3804bc1218af1bc22d28ee521cc944cab5cac5dbe5abfe/VERSION
-rw-r--r-- 0 0 0 477 Dec 31 1979 02805fa4a4f35efdcf3804bc1218af1bc22d28ee521cc944cab5cac5dbe5abfe/json
-rw-r--r-- 0 0 0 1024 Dec 31 1979 02805fa4a4f35efdcf3804bc1218af1bc22d28ee521cc944cab5cac5dbe5abfe/layer.tar
drwxr-xr-x 0 0 0 0 Dec 31 1979 0f915e8772f0e40420852f1e2929e4ae9408327cbda6c546c71cca7c3e2f094a/
-rw-r--r-- 0 0 0 3 Dec 31 1979 0f915e8772f0e40420852f1e2929e4ae9408327cbda6c546c71cca7c3e2f094a/VERSION
-rw-r--r-- 0 0 0 477 Dec 31 1979 0f915e8772f0e40420852f1e2929e4ae9408327cbda6c546c71cca7c3e2f094a/json
-rw-r--r-- 0 0 0 3622400 Dec 31 1979 0f915e8772f0e40420852f1e2929e4ae9408327cbda6c546c71cca7c3e2f094a/layer.tar
tar
命令可以列出並從映像中提取特定文件,具體取決於我們要查找的信息。
4. 顯示兩個 Docker 鏡像之間的差異
到目前為止,我們已經了解了圖像的結構以及如何檢查它。接下來,讓我們看看我們如何比較兩張圖像並找出它們之間的差異。
根據我們想要比較的信息,有不同的工具可以提供幫助。正如我們在上面看到的,內置的image
命令可以為我們提供大小和日期信息。
但是如果我們要比較兩張圖片的內容,就需要藉助第三方工具。下面,我們將看看其中的幾個。
4.1。容器差異
一種這樣的工具是谷歌的 container-diff 。儘管它的名字,它可以比較兩個圖像的各個方面並提供格式良好的報告。
例如,讓我們比較前面示例中的兩個 Spring 寵物診所圖像:
$ /usr/local/bin/container-diff diff \
daemon://spring-petclinic:2.6.0-SNAPSHOT \
daemon://spring-petclinic:2.7.0-SNAPSHOT \
--type=file
這給了我們每個圖像文件的差異。
輸出通常分為三個部分。首先,它告訴第一個圖像中存在哪些文件,而第二個圖像中沒有:
/workspace/BOOT-INF/lib/byte-buddy-1.12.10.jar 3.7M
/workspace/BOOT-INF/lib/classgraph-4.8.139.jar 551.7K
/workspace/BOOT-INF/lib/ehcache-3.10.0.jar 1.7M
/workspace/BOOT-INF/lib/h2-2.1.212.jar 2.4M
/workspace/BOOT-INF/lib/hibernate-core-5.6.9.Final.jar 7.1M
/workspace/BOOT-INF/lib/jackson-annotations-2.13.3.jar 73.9K
接下來,它告訴我們哪些文件存在於第二個圖像中,但不存在於第一個圖像中:
These entries have been deleted from spring-petclinic:2.6.0-SNAPSHOT:
FILE SIZE
/workspace/BOOT-INF/lib/byte-buddy-1.11.22.jar 3.5M
/workspace/BOOT-INF/lib/classgraph-4.8.115.jar 525.4K
/workspace/BOOT-INF/lib/ehcache-3.9.9.jar 1.7M
/workspace/BOOT-INF/lib/h2-1.4.200.jar 2.2M
/workspace/BOOT-INF/lib/hibernate-core-5.6.7.Final.jar 7.1M
/workspace/BOOT-INF/lib/jackson-annotations-2.13.2.jar 73.9K
在這種情況下,結合起來的兩個部分可以非常快速地告訴我們每個應用程序版本之間的依賴關係是如何變化的。
最後,最後一部分說明了兩者中存在哪些文件,但不同:
These entries have been changed between spring-petclinic:2.6.0-SNAPSHOT and spring-petclinic:2.7.0-SNAPSHOT:
FILE SIZE1 SIZE2
/layers/config/metadata.toml 16.6K 1.9K
/workspace/META-INF/maven/org.springframework.samples/spring-petclinic/pom.xml 13.3K 13.3K
/workspace/BOOT-INF/classes/org/springframework/samples/petclinic/owner/OwnerController.class 7.8K 7.7K
/workspace/org/springframework/boot/loader/ExecutableArchiveLauncher.class 6.6K 7.5K
/workspace/org/springframework/boot/loader/JarLauncher.class 3.9K 2.5K
/workspace/BOOT-INF/classpath.idx 3.2K 3.2K
/workspace/org/springframework/boot/loader/data/RandomAccessDataFile$FileAccess.class 3.2K 3.2K
/workspace/BOOT-INF/classes/db/h2/data.sql 2.8K 3K
/workspace/org/springframework/boot/loader/data/RandomAccessDataFile$DataInputStream.class 2.6K 2.7K
本部分使識別在兩個版本之間發生更改的任何特定類和屬性文件變得非常容易。
4.2.潛水
另一個用於檢查 Docker 鏡像的優秀開源工具是dip 。使用dive
檢查圖像可以讓我們更傳統地查看其內容,因為它了解如何檢查圖像中的每一層。這允許它使用傳統的文件系統樹來呈現每個圖像:
使用鍵盤,我們可以瀏覽圖像的每一層,並準確查看它添加、修改或刪除了哪些文件。
雖然dive
工具本身不支持比較圖像,但我們可以通過簡單地在兩個終端上並排運行它來手動完成:
通過這種方式,我們可以看到哪些層是相同的(基於大小),對於不同的層,我們可以看到哪些文件不同。
5. 結論
在本文中,我們查看了 Docker 映像的結構,並了解了檢查它們的各種方法。雖然 Docker 客戶端包含一些用於檢查單個圖像的工具,但比較兩個圖像需要使用 3rd 方工具。
Google 的container-diff
是專門為比較圖像而構建的一個選項。雖然dive
實用程序非常適合檢查單個圖像的圖層,但它也可以通過簡單地同時針對兩個圖像運行來識別差異。