1. 程式人生 > >docker映象的製作(二)----新手指南:如何將應用打包成為 Docker 映象?

docker映象的製作(二)----新手指南:如何將應用打包成為 Docker 映象?

雖然 DockerHub 提供了大量的映象,但是由於企業環境的多樣性,並不是每個應用都能在 DockerHub 找到對應的映象來使用。那就要求企業的運維人員掌握製作 Docker 映象的技能。在開始打包應用前,你首先要明白這兩件事:第一件事是選擇適合你的方式來生成映象: 1. 通過 Dockerfile 來自動編譯生成映象,實現構建映象的需求。 2.通過容器內操作,並進行 Commit 來實現打包生成映象。第一種思路多用於使用者互動較少的時刻,比如軟體部署時無需輸入任何命令的應用。第二種思路用於使用者互動較多、安裝過程中配置較多的應用。第二件事是你需要注意,如何拆分現有的應用,來實現打包。Docker 容器化的應用應當是功能最小化的應用。

這裡的拆分並不是指將每個軟體拆分成為一個容器,而是強調實現功能最小化。拿最常見的 LAMP 架構來討論。最小化的結構應當是 Apache 和 PHP 在一個容器內, MySQL 在一個容器內。而不是將 Apache 、 PHP 、 MySQL 各自拆分一個容器。 Apache 和 PHP 的有機結合使結構內的應用完整的實現了 PHP 解析和 Web 頁面的功能,而 MySQL 獨自承擔了資料儲存的功能。而各自拆分一個容器會導致架構極為複雜,在進行容器擴容時也容易受到影響。一般來說,你可以將應用拆分成為 2-3 個容器, 2 個容器的情況下,是資料儲存和應用程式各自一個容器。對於部分應用,可能還有快取系統,同樣也要單獨放置在一個容器內。這樣的結構下,在你需要擴容時,就比較容易,根據你的需要,可以隨時擴容快取系統或應用程式。

明瞭了上面的兩件事,接下來進入應用打包的環節。

Dockerfile 打包

首先,我們先看下 Docker 官方打包的 Tomcat 映象的 Dockerfile.

Dockerfile

我們可以看到,裡面大量執行了 Linux 命令,來安裝,部署軟體,並且對於需要確認的命令都加入-f 來強制執行。確保沒有互動,因為在編譯映象的過程中,無法進行互動操作,如果碰到互動操作,卡住就會導致映象編譯的失敗,故而 DockerFile 不支援需要輸入命令的安裝指令碼等

錯誤互動演示

當然,對於 Dockerfile,我們同樣也有一些最佳實踐:

  • 通過 Dockerfile 構建的映象應當儘可能精簡。
  • 儘量不安裝非必要的軟體包。
  • 一個容器只執行一個單獨的例項,將具有耦合度的應用分別安裝到不同的容器裡面。
  • 慎重引入新的資料層
  • 將準備安裝的軟體包按安裝的字母順序排列,這樣可以避免重複安裝軟體包的情況,同時也有助於進行軟體更新。通過新增 “\” 分割命令,增加程式碼的可讀性
  • 儘量選擇官方提供的映象版本來作為基礎映象,減小映象的體積。
  • 將多條 RUN 命令使用"/"連線起來,這樣更易於理解,可以方便維護。
  • 為映象定義一個比較通用的埠,比如提供 HTTP Web 服務的映象,最好是暴露 80 埠。
  • Dockerfile 的開頭幾行的指令應當固定下來,不要每次都隨意更改,這樣可以利用快取
  • 通過 – t 標記來構建映象,有助於使用者管理每個建立的映象。
  • 不要在 Dockerfile 中對映公有埠。
  • 使用 CMD 和 ENTRYPOINT 時,一定要用陣列語法,而且 CMD 和 ENTRYPOINT 結合使用更好
  • 不要開機初始化
  • 在 Push 之前,現在本地構建執行一下,確保本地構建的映象可以在任何地方正常執行。
  • 不要在構建中升級版本,如果更新時試圖修改 Init 或改變容器的內容,更新可能會失敗,還可能產生不一致的映象。
  • FROM 命令應該包含基礎映象的完整倉庫名和標籤
  • 使用指令組合,比如 apt-get update 應該和 apt-get install 結合。

基礎映象 Commit 生成映象

除了通過 Dockerfile 來打包生成映象外,也可以通過 Docker Commit 來生成映象。通過 Commit 打包的映象多是由於應用本身在部署時有大量的互動內容,無法通過命令來指定。在通過 Commit 打包映象時,我們需要如下操作:

1.啟動一個基礎映象容器,並進入 consoledocker run -i – t centos:6.7上面的命令建立了一個基於 CentOS 6.7 的容器,並進入到容器內

進入容器

2.執行配置環境的命令登陸容器後,可以執行各種 Linux 下的命令。

安裝軟體

等配置完環境後,開啟一個新的控制檯執行命令docker ps,可以看到正在執行的容器

容器列表

比如我的容器的 ID 就是 35f1c2ae1f7e

3.將容器打包成映象執行命令 docker commit 35f1c2ae1f7e mynewimage將容器35f1c2ae1f7e打包為新的映象mynewimage

打包映象

可以執行docker images檢視映象

映象列表

另外,蜂巢的儲存為映象的功能,就是基於此功能製作的,通過雲端容器 Console 的操作,並打包成為映象,大大降低了上雲的難度。無需在本地部署 Docker 環境,即可實現應用的容器化;同時雲端打包映象比本地打包速度也要更快些,大大提升了上雲的速度。儲存映象

PS.其實官方推薦:單個映象單個程序。這樣的情況下,有利有弊利在於,單程序容器更加適合縱向擴充套件和複用。但是,在較大的產品框架下,可能容器之間的關聯會非常複雜。建立一個應用可能會需要建立非常多的容器。所以,在我看來如何劃分,還是應該看使用場景和技術路線,量身定製.

例一:jpress應用容器 映象搭建

例二:

# Base
FROM java:jdk-7

COPY ./.src/target/app-1.0.jar /app/

# ENTRYPOINT
WORKDIR /app
CMD [ "java", "-Dfile.encoding=UTF-8", "-jar", "./app-1.0.jar" ]

這是很簡單的 Dockerfile,不要看他簡單,我推薦的是各位用 Docker 就應該這麼用。不需要在 Dockerfile 裡寫一堆 apt-get install ,一大堆 run 命令這些東西,記住 Dockerfile 就是宣告應用環境和應用本身。Docker 現在做的功能太多了,很多都是不怎麼靠譜的,Docker 需要更專注於它本身作為容器的技術。完成無狀態化應用和寫完 Dockerfile 之後,這個程式就可以被打報成 Docker image 了,放到一個 Docker Host 上執行起來就得到了無狀態的應用容器,也就完成了把應用裝容器的過程。