如何 10 步 Docker 化一個應用?

  本文將講解如何將應用 Docker 化的一些很實用的技巧和準則,推薦一讀。

  一、選擇基礎鏡像

  每種對應技術幾乎都有自己的基礎鏡像,例如:

  https://hub.docker.com/_/java/

  https://hub.docker.com/_/python/

  https://hub.docker.com/_/nginx/

  如果不能直接使用這些鏡像,我們就需要從基礎操作系統鏡像開始安裝所有的依賴。

  網上大多數教程使用的都是以 Ubuntu(例如:Ubuntu:16.04 )作爲基礎鏡像,這並不是一個問題,但是我建議優先考慮 Alpine 鏡像:

  https://hub.docker.com/_/alpine/

  Alpine 是一個非常小的基礎鏡像(它的容量大約只有 5MB)。

  注:在基於 Alpine 的鏡像中你無法使用 apt-get 命令。不過你不必擔心,因爲 Alpine 系統有自己的軟件包倉庫和包管理工具 apk。關於 apk 的具體使用你可以詳細參考:「Alpine Linux配置使用技巧」一文。

  二、安裝必要軟件包

  這個步驟通常比較瑣碎,有一些容易忽略的細節:

  apt-get update 和 apt-get install 命令應該寫在一行(如果使用 Alpine 則對應的是 apk 命令)。這不是一個常見的做法,但是在 Dockerfile 中應該要這麼做。否則 apt-get update 命令產出的臨時層可能會被緩存,導致構建時沒有更新包信息。(具體可參見此文)。

  確認是否只安裝了實際需要的軟件(特別是在生產環境中運行這個容器)。

  注:我見過有人在他們的鏡像中安裝了 vim 和其他開發工具。如果這是必要的,應該針對構建、調試和開發環境創建不同的 Dockerfile。這不僅僅關係到鏡像大小,還涉及到安全性、可維護性等等。

  三、添加自定義文件

  一些優化 Dockerfile 的小提示:

  理解 COPY 和 ADD 指令的區別,具體可參考此文。

  儘可能遵照文件系統慣例來存放文件。例如:針對解釋型應用程序(如:Python),使用 /usr/src 目錄。

  檢查添加文件的屬性。如果需要可執行權限,沒有必要在鏡像上新建一個層( 通過 RUN chmod +x … 指令來增加權限)。你只需要在代碼倉庫的源文件上修正這些屬性即可,即使開發平臺是 Windows,也可以參照此文給文件增加可執行權限。

  四、定義容器運行時的用戶權限

  容器中的進程默認情況下是以 root 權限運行的。

  如果容器中的應用程序需要使用特定的用戶或組(/etc/passwd 或 /etc/group)來運行時,可以在容器啓動時使用 docker run 命令的--user 參數來指定其固定的 UID 或 GID。

  儘可能避免容器中的進程以 root 權限運行。

  注:現在不少熱門應用程序鏡像都需要用特定的用戶 ID 來運行(例如:Elastic Search 需要 uid:gid = 1000:1000),請儘量不要在寫出這樣的鏡像。更多關於容器內運行應用程序的權限說明可參考此文。

  五、定義暴露的端口

  不要爲了暴露特權端口(例如:80)而將容器以 root 權限運行。如果有這樣的需求,可以讓容器暴露一個非特權端口(例如:8080),然後在啓動時進行端口映射。

  注:低於 1024 的 TCP / IP 端口號就是特權端口,因爲不允許普通用戶在這些端口上運行服務。

  六、定義入口點(entrypoint)

  普通方式:直接運行可執行文件。

  更好的方式:創建一個 docker-entrypoint.sh 腳本,這樣可以通過環境變量來配置容器的入口點。這也是一個非常普遍的做法,可參考下面這些例子:elasticsearch 的 docker-entrypoint.sh 文件 和 postgres 的 docker-entrypoint.sh 文件。

  七、定義一種配置方式

  每個應用程序都需要參數化,你基本上可以遵循以下兩個原則:

  使用應用程序特定的配置文件:該方式需要通過文檔來說明配置文件的格式、字段、放置位置等等(當運行環境比較複雜,例如:應用程序跨越不同的技術,則不太合適)。

  使用操作系統環境變量:簡單而有效。這也是 12-factors 推薦的方式。

  注:使用環境變量方式並不意味着您需要丟棄配置文件並重構應用程序的配置機制,你只需要通過 envsubst 命令來替換配置文件模板中的值就可以了(這個流程一般需要在 docker-entrypoint.sh 文件中完成,因爲這需要在容器進程運行前完成)。例如:在 Nginx 配置中使用環境變量,具體方法可參考此文。

  這種方式可以將應用程序的配置文件封裝在容器內部。

  八、外部化數據

  關於數據存儲有一條黃金法則:絕對不要將任何持久化數據保存到容器內。

  容器的文件系統本身是被設計成臨時和短暫的。因此任何由應用程序生成的內容、數據文件和處理結果都應該保存到掛載的卷或者操作系統綁定掛載點上(既:將宿主機操作系統的目錄掛載到容器中)。

  如果將數據保存到綁定掛載點,對於要綁定到容器的宿主機上的目錄,你需要注意以下幾點:

  在宿主機操作系統上創建非特權用戶和組。

  所有需要綁定目錄的所有者都是該用戶。

  根據使用場景給授權(僅針對這個特定的用戶和組,其他用戶無權訪問)。

  容器也以該用戶運行。

  容器可以完全控制這些目錄。

  九、確保處理好日誌

  如果這是一個新的應用程序,並且希望它能夠堅持 Docker 約定,就不應該將日誌寫入任何文件。應用程序應該使用標準輸出和標準錯誤輸出日誌,這和之前推薦使用環境變量傳遞參數一樣,這也是 12-factors 之一,具體可以參見這裏。

  Docker 會自動捕捉應用程序的標準輸出,並可以通過 docker logs 命令查看。有關於 docker logs 的具體使用你可以參考這裏。

  但是在一些實際場景下你可能會遇到問題,例如:運行一個簡單的 Nginx 容器,至少會有兩種不同的日誌文件:

  HTTP 訪問日誌(Access Logs)

  錯誤日誌(Error Logs)

  對於這種按照特定結構輸出日誌的應用,就不太適合將它們的日誌輸出到標準輸出。這種情況下,你需要按持久化的方式處理這些日誌,並確保這些日誌文件的能正常的輪轉。

  十、輪轉日誌

  如果應用程序將日誌寫到文件,或者會無限追加內容到文件,就需要關注這些文件的輪轉(rotation),這對於防止服務器空間耗盡非常有用的。

  如果使用綁定掛載,我們可以依靠宿主機的一些工具來實現文件輪轉功能。例如:logrotate,關於 logrotate 的使用你可以參考示例一、示例二。

  注:本文在 「如何 Docker 化任意一個應用」的基礎上整理和修改,原文地址:http://t.cn/ReT0AyJ 。

  大連哪個醫院看×××好 http://mobile.dlbhnk.com/

  大連婦科醫院排行榜 http://xzmobile.84211111.cn/

  大連婦科哪裏好 http://xzmobile.bhbyby.com/


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章