前言java
本文將講解如何將應用 Docker 化的一些很實用的技巧和準則,推薦一讀。python
1、選擇基礎鏡像nginx
每種對應技術幾乎都有本身的基礎鏡像,例如:面試
若是不能直接使用這些鏡像,咱們就須要從基礎操做系統鏡像開始安裝全部的依賴。docker
網上大多數教程使用的都是以 Ubuntu(例如:Ubuntu:16.04 )做爲基礎鏡像,這並非一個問題,可是我建議優先考慮 Alpine 鏡像:vim
Alpine 是一個很是小的基礎鏡像(它的容量大約只有 5MB)。緩存
注:在基於 Alpine 的鏡像中你沒法使用 apt-get 命令。不過你沒必要擔憂,由於 Alpine 系統有本身的軟件包倉庫和包管理工具 apk。關於 apk 的具體使用你能夠詳細參考:「Alpine Linux配置使用技巧」一文。安全
2、安裝必要軟件包性能優化
這個步驟一般比較瑣碎,有一些容易忽略的細節:服務器
注:我見過有人在他們的鏡像中安裝了 vim 和其餘開發工具。若是這是必要的,應該針對構建、調試和開發環境建立不一樣的 Dockerfile。這不只僅關係到鏡像大小,還涉及到安全性、可維護性等等。
3、添加自定義文件
一些優化 Dockerfile 的小提示:
4、定義容器運行時的用戶權限
注:如今很多熱門應用程序鏡像都須要用特定的用戶 ID 來運行(例如:Elastic Search 須要 uid:gid = 1000:1000),請儘可能不要在寫出這樣的鏡像。更多關於容器內運行應用程序的權限說明可參考此文。
5、定義暴露的端口
不要爲了暴露特權端口(例如:80)而將容器以 root 權限運行。若是有這樣的需求,可讓容器暴露一個非特權端口(例如:8080),而後在啓動時進行端口映射。
注:低於 1024 的 TCP / IP 端口號就是特權端口,由於不容許普通用戶在這些端口上運行服務。
6、定義入口點(entrypoint)
7、定義一種配置方式
每一個應用程序都須要參數化,你基本上能夠遵循如下兩個原則:
注:使用環境變量方式並不意味着您須要丟棄配置文件並重構應用程序的配置機制,你只須要經過 envsubst 命令來替換配置文件模板中的值就能夠了(這個流程通常須要在 docker-entrypoint.sh 文件中完成,由於這須要在容器進程運行前完成)。例如:在 Nginx 配置中使用環境變量,具體方法可參考此文。
這種方式能夠將應用程序的配置文件封裝在容器內部。
8、外部化數據
關於數據存儲有一條黃金法則:絕對不要將任何持久化數據保存到容器內。
容器的文件系統自己是被設計成臨時和短暫的。所以任何由應用程序生成的內容、數據文件和處理結果都應該保存到掛載的卷或者操做系統綁定掛載點上(既:將宿主機操做系統的目錄掛載到容器中)。
若是將數據保存到綁定掛載點,對於要綁定到容器的宿主機上的目錄,你須要注意如下幾點:
9、確保處理好日誌
若是這是一個新的應用程序,而且但願它可以堅持 Docker 約定,就不該該將日誌寫入任何文件。應用程序應該使用標準輸出和標準錯誤輸出日誌,這和以前推薦使用環境變量傳遞參數同樣,這也是 12-factors 之一,具體能夠參見這裏。
Docker 會自動捕捉應用程序的標準輸出,並能夠經過 docker logs 命令查看。有關於 docker logs 的具體使用你能夠參考這裏。
可是在一些實際場景下你可能會遇到問題,例如:運行一個簡單的 Nginx 容器,至少會有兩種不一樣的日誌文件:
對於這種按照特定結構輸出日誌的應用,就不太適合將它們的日誌輸出到標準輸出。這種狀況下,你須要按持久化的方式處理這些日誌,並確保這些日誌文件的能正常的輪轉。
10、輪轉日誌
若是應用程序將日誌寫到文件,或者會無限追加內容到文件,就須要關注這些文件的輪轉(rotation),這對於防止服務器空間耗盡很是有用的。
若是使用綁定掛載,咱們能夠依靠宿主機的一些工具來實現文件輪轉功能。例如:logrotate,關於 logrotate 的使用你能夠參考示例1、示例二。
在此我向你們推薦一個Java高級羣 :725633148 裏面會分享一些資深架構師錄製的視頻錄像:(有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構、面試資料)等這些成爲架構師必備的知識體系 進羣立刻免費領取,目前受益良多!