天天看點

DockerCon 2017: Docker新特性初體驗

dockercon2017已經結束了,從去年的版本到現在,docker産生了很多的變化。docker的開發者們一直強調他們希望docker的體驗越簡單越好。觀察下最近幾個月docker的新特性,你會發現所言非虛,dockercon2017大會也向我們展示了這一點。下面介紹下docker最近幾個月釋出的新特性

建構一個鏡像一般需要多個階段。

編譯你的應用

然後跑測試

當測試通過時,你将你的應用打包成可部署的軟體包

最後你把軟體包添加到鏡像裡面

你可以将這些步驟都放進一個dockerfile中,但是這會導緻鏡像膨脹,加入了很多最終産品不需要的内容。例如編譯和建構的架構,docker鏡像存儲需要的空間也會變得很大。

一個解決方法是在docker外面編譯測試打包應用程式,或者使用多個dockerfile。你可以用一個dockerfile來編譯測試打包你的應用,用另外一個dockerfile來添加之前打好的軟體包,并做最終的傳遞。

然而,整個建構的過程通過一個腳本捆綁在一起,而并不是以docker的方式來執行建構。

docker對于添加新的特性或者文法到dockerfile中是謹慎的,當他們最終決定着手通過一個簡單而優雅的方式來解決這個建構的問題。通過引入<code>多階段建構(multi-stage builds)</code>,使得通過使用多個<code>from</code>指令來定義多個建構的階段成為可能。示例如下

每一次使用<code>from</code>指令時,相當于定義了一個新的建構階段,一直到下一個<code>from</code>指令之前或者到檔案的結束為止,執行的指令均屬于該建構階段。通過<code>as</code>指令來給這一建構階段命名,同時指定了該階段使用的基礎鏡像。在接下來的建構階段,可以使用<code>copy --from=&lt;stage&gt;</code>指令來拷貝之前建構階段的軟體制成品到目前建構階段,繼續進行建構,直到最後一個建構階段生成的鏡像,才是最終的傳遞鏡像。通過對最終建構階段的基礎鏡像選擇,可以隻讓傳遞鏡像包含最小的運作時和需要傳遞軟體制成品,使得鏡像變小,上傳下載下傳更加迅速。

在dockerfile中使用參數,并不是一件新鮮的事物,我們已經可以使用<code>arg</code>指令來傳遞參數給建構過程,這些參數的值在dockerfile中是可變的,經常被用來傳遞版本号,密碼,例如ssh的密鑰等。現在通過參數來指定基礎鏡像的版本也成為了可能,示例如下:

通過使用上面的dockerfile,我們可以建構基于另外一個go語言版本的鏡像:

使用docker的開發者經常會抱怨docker占用了太多的存儲空間,如果不定期清理,這确實是個問題。docker增加了<code>docker system</code>子指令來檢查磁盤的使用空間,同時清理無用的資源。

下面的指令列出了磁盤使用情況:

你可以使用<code>prune</code>來清理不再需要的資源:

隻清理特定子系統的資源也是支援的:

由于指定端口的文法讓人困惑,docker的使用者經常在了解和定義一個容器釋出的端口時有困難。當你在使用或者定義容器的端口時,可能的格式如下:

當使用用戶端時,這些文法還比較容易了解,但是當你需要在一個compose模版中定義許多這樣的端口時,可讀性就會變得很差。為了解決這一問題,現在你可以使用一個更加詳細的格式來定義端口:

跟端口一樣,<code>資料卷(volume)</code>也有類似的文法:

也增加了一個更加詳細的文法來聲明和指定<code>資料卷(volume)</code>: