應用最好不要跑在特權用戶( root )底下git
Docker 默認全部的應用都會跑在容器的 root user 底下,可是這樣會形成一些潛在的安全隱患。在 production 環境跑的 Container 最好是經過 USER 命令跑在非特權用戶底下。docker
隱患在哪,求補充。數據庫
安全隱患是說若是這個 container 被 compromise 了,那麼若是是 root 在跑這個 container 更可能使系統出現問題。可是用 root user 自己應該是沒問題的。promise
是指的若是用 root 跑 container 會有問題嗎?那爲何推薦用 USER 命令來改變 docker 的非 root ?緩存
就是 Docker 的隔離效力有限,若是一個 container 裏的應用是惡意的,並且是 root ,那若是它改了系統配置( root 權限,好比 unload 某個系統 module ,更改了某個系統文件),也會影響其餘的 container ( share 一個 kernel )。安全
避免使用 apt-get upgrade運維
Upgrade 命令是用來升級當前基礎鏡像的。非特權用戶沒法 Upgrade 一些核心的應用。並且 Upgrade 命令會打亂已經緩存的鏡像,使得編譯時間加長。在通常狀況下,選用正確的基礎鏡像是不須要升級的,若是真的須要,最好聯繫基本鏡像的維護方,這樣全部使用者都能從中獲益。若是隻是須要更新某個程序 foo ,那麼使用 apt-get install – y foo 就能到達這個目的。優化
儘可能合併命令get
Dockerfile 中的每個命令都會建立一個新的 layer ,而一個容器可以擁有的最多 layer 數是有限制的。因此儘可能將邏輯上連貫的命令合併能夠減小 layer 的層數,合併命令的方法能夠包括將多個能夠合併的命令( EXPOSE , ENV , VOLUME , COPY )合併。it
Dockerfile 中的每個命令都會建立一個新的 layer ,而一個容器可以擁有的最多 layer 數是有限制的。因此儘可能將邏輯上連貫的命令合併能夠減小 layer 的層數,這也能夠加快編譯速度?
將多個能夠合併的命令( EXPOSE , ENV , VOLUME , COPY )合併,好比:
使用「&&」來鏈接 RUN 命令,好比:
不過過分合並命令可能會影響 Dockerfile 的可讀性,因此須要在優化代碼和可讀性之間作出權衡。
合理安排命令的順序
命令的順序會影響編譯所須要的時間。每個命令都會產生一個 layer 。若是一個 layer 已經在緩存中,那麼生成這個 layer 所須要的時間就很短。從第一個不在緩存的 layer 起,全部之後的命令都會被從新編譯。由於這個緣由,咱們推薦將不常變更的命令放在前面,這樣可使得更多的 layer 被成功緩存,從而減小編譯時間。
避免在容器中存儲數據
容器須要是無狀態的,這樣方便啓動新的 Container 來替代 down 掉的 Container 。若是容器中包含狀態,那麼就須要額外的運維人員來恢復 down 掉 Container 的狀態。
使用.dockerignore
使用.dockerignore 能夠減小拷貝沒必要要的文件到 Container ,這樣能夠減小鏡像大小。好比不少地方都有.git 文件,可是這個文件就不須要拷貝到 Container 裏面。
避免安裝沒必要要的軟件
安裝沒必要要的軟件既浪費空間又增長編譯時間。好比一個數據庫的 Container 就沒有必要安裝文字編輯軟件。 更進一步,若是程序可以在本地編譯,那麼就不用在 Container 裏安裝編譯程序所須要的軟件和 lib 了。直接把本地編譯好的 binary 拷貝到 Container 裏就好。