當想讓一個容器做兩件事情,或者使一個Docker映象包含來自兩個不同映象的依賴庫時,就需要知道每個映象的Dockerfile。本文介紹瞭如何透過dockerhistory命令來對Docker映象進行反向工程,得到它們的Dockerfile,並組織到一個Dockerfile裡然後build,從而實現想做的事情。
常言道,“不要重複發明輪子!”
在使用Docker時,構建自己的映象之前,最好在DockerHub尋找一些可以直接使用的映象做練習。把軟體架構分佈到一系列容器中,每一個容器只做一件事情,這樣的效果非常好。構建分散式應用的最好的基石是使用來自DockerHub的官方映象,因為可以信任它們的質量。
在某些情況下,可能想讓一個容器做兩件不同的事情。而在另外一些情況下,可能想讓一個Docker映象包含來自兩個不同映象的依賴庫。如果有每個映象的Dockerfile,這是非常簡單的。將它們組織到一個Dockerfile裡然後build就行。
然而,大多數時間都在使用DockerHub上準備好的映象,不會有它們的源Dockerfile。我花時間找一個可以合併(或flatten)兩個不同Docker映象的工具,當然沒有它們的Dockerfile。也就是說在找一個能做下面這件事的東西:
image1--
\
--->merged_image_12
/
image2--
這可能嗎?
那麼,是否存在工具能夠像這樣做嗎:dockermergeimage2image2merged_image?
沒有!
你甚至不可以用下面的方式來構建Dockerfile:
FROMimage1
FROMimage2
簡而言之,在一個Dockerfile裡不能有多個基礎映象。
但是我需要這個功能!
唯一的解決辦法是取得這些映象的Dockerfile,然後把它們組織到一個檔案中,再進行構建。那麼,我能在DockerHub上獲得一個映象的Dockerfile嗎?幸運的是可以。它不能離線獲取(譯註:原文是online,但顯然online時對於來自GitHub的自動構建映象是可以直接獲取的),但是你可以使用dockerhistory命令,透過反向工程獲取。
怎麼來使用?
在你的機器上使用dockerpull從DockerHub下載映象。
dockerpullimage1
dockerpullimage2
然後使用dockerhistory來取得構建這兩個容器時執行的命令。
dockerhistory--no-trunc=trueimage>image1-dockerfile
dockerhistory--no-trunc=trueimage2>image2-dockerfile
接下來開啟這兩個檔案,你可以看到每個映象的命令堆疊。這是因為Docker映象透過層(閱讀更多)的方式來構建。即你在Dockerfile中鍵入的每一個命令所構建的新映象,都是在之前的命令產生的映象之上。所以你可以對映象進行逆向工程。
限制
不能對映象進行反向工程的唯一場景,是映象的維護者在他的Dockerfile中使用了ADD或COPY命令。你會看到這樣一行:
ADDfile:1ac56373f7983caf22
或ADDdir:cf6fe659e9d21535844
這是因為不知道維護者在他自己的機器上,包括映象裡使用了什麼本地檔案。
當想讓一個容器做兩件事情,或者使一個Docker映象包含來自兩個不同映象的依賴庫時,就需要知道每個映象的Dockerfile。本文介紹瞭如何透過dockerhistory命令來對Docker映象進行反向工程,得到它們的Dockerfile,並組織到一個Dockerfile裡然後build,從而實現想做的事情。
常言道,“不要重複發明輪子!”
在使用Docker時,構建自己的映象之前,最好在DockerHub尋找一些可以直接使用的映象做練習。把軟體架構分佈到一系列容器中,每一個容器只做一件事情,這樣的效果非常好。構建分散式應用的最好的基石是使用來自DockerHub的官方映象,因為可以信任它們的質量。
在某些情況下,可能想讓一個容器做兩件不同的事情。而在另外一些情況下,可能想讓一個Docker映象包含來自兩個不同映象的依賴庫。如果有每個映象的Dockerfile,這是非常簡單的。將它們組織到一個Dockerfile裡然後build就行。
然而,大多數時間都在使用DockerHub上準備好的映象,不會有它們的源Dockerfile。我花時間找一個可以合併(或flatten)兩個不同Docker映象的工具,當然沒有它們的Dockerfile。也就是說在找一個能做下面這件事的東西:
image1--
\
--->merged_image_12
/
image2--
這可能嗎?
那麼,是否存在工具能夠像這樣做嗎:dockermergeimage2image2merged_image?
沒有!
你甚至不可以用下面的方式來構建Dockerfile:
FROMimage1
FROMimage2
簡而言之,在一個Dockerfile裡不能有多個基礎映象。
但是我需要這個功能!
唯一的解決辦法是取得這些映象的Dockerfile,然後把它們組織到一個檔案中,再進行構建。那麼,我能在DockerHub上獲得一個映象的Dockerfile嗎?幸運的是可以。它不能離線獲取(譯註:原文是online,但顯然online時對於來自GitHub的自動構建映象是可以直接獲取的),但是你可以使用dockerhistory命令,透過反向工程獲取。
怎麼來使用?
在你的機器上使用dockerpull從DockerHub下載映象。
dockerpullimage1
dockerpullimage2
然後使用dockerhistory來取得構建這兩個容器時執行的命令。
dockerhistory--no-trunc=trueimage>image1-dockerfile
dockerhistory--no-trunc=trueimage2>image2-dockerfile
接下來開啟這兩個檔案,你可以看到每個映象的命令堆疊。這是因為Docker映象透過層(閱讀更多)的方式來構建。即你在Dockerfile中鍵入的每一個命令所構建的新映象,都是在之前的命令產生的映象之上。所以你可以對映象進行逆向工程。
限制
不能對映象進行反向工程的唯一場景,是映象的維護者在他的Dockerfile中使用了ADD或COPY命令。你會看到這樣一行:
ADDfile:1ac56373f7983caf22
或ADDdir:cf6fe659e9d21535844
這是因為不知道維護者在他自己的機器上,包括映象裡使用了什麼本地檔案。