原文發表於cu:2016-06-01html
參考文檔: docker
Dockefile建立image是被推薦的方式,不一樣於"docker build"須要手動commit與rm中間層鏡像,dockerfile是自動化的建立image(二者原理均是使用基礎鏡像啓動容器後commit)。shell
如下優化建議僅爲我的觀點。vim
在構建image時,不須要安裝沒必要要的程序,這樣能夠保證構建出的image輕小,依賴性小且構建速度快。centos
大多數狀況下,建議1個容器運行1個服務便可,這樣能夠減小服務的耦合性,充分發揮容器複用及快速橫向擴展的優點。緩存
1條dockerfile指令會生成1層新的鏡像,鏡像層越多,image越大,容器啓動速度越慢;建議儘量減小image層數,但同時須要注意dockerfile的可讀性,即合理控制image層數。bash
對指令參數的排序主要是爲了dockerfile的可讀性與確保不會重複輸入參數。如:ssh
RUN yum install -y \ Git \ net-tools \ openssh-server
前面講到1條dockerfile指令會生成1層新的鏡像,下一條指令會基於上一步生成的鏡像構建新的鏡像層,若是一個鏡像存在相同的父鏡像與指令("ADD"指令除外),默認docker會使用緩存的鏡像,而不是從新執行dockerfile指令。ide
因此在修改Dockerfile時,爲了有效利用鏡像,能夠儘可能不動Dockerfile的前面幾行。優化
例如"MAINTAINER"通常在第二行,若是修改此處,那後續的"RUN"指令會所有執行,而不是使用緩存的鏡像層。
Dockerfile第一條指令,此指令指定dockerfile構建image的基礎鏡像,若是宿主機倉庫沒有指定的基礎鏡像,則從遠端倉庫pull。
語法:FROM <image>:<tag>
指明image做者,方便聯繫。
語法:MAINTAINER <author name> (author information, email and so on)
在當前鏡像生成的容器的外層(可讀寫層)執行命令,並commit成1個新的鏡像層,接下來的指令會在這個新的鏡像層生成的容器裏執行。
語法(2種):
#shell form:在shell環境下執行,調用"/bin/sh –c"
#exec form:不會觸發shell,因此環境變量沒法調用,但能夠在沒有bash的image中執行
複製文件,有兩個參數<source>和<destination>。
注意:
語法:ADD <source> <destination>
基本與ADD相同,但不支持遠程URL(source),與自動解壓的功能。
注意:官方最佳實踐中建議儘可能使用copy,使用RUN與COPY的組合代替ADD,由於COPY處理更透明。
配置給容器一個可執行的命令,相似將容器變爲1個可執行文件/命令。
意味着在每次使用鏡像建立容器時,一個特定的應用程序能夠被設置爲默認程序;同時也意味着該鏡像每次被調用時僅能運行指定的應用。
注意:
語法(2種):
#exec form:推薦使用的格式
#shell form:會屏蔽掉docker run時後面加的命令參數與CMD裏的參數
指定製做出的image在啓動成容器時運行的默認命令或參數。
注意:
語法(3種):
#exec form:推薦使用的格式,可執行文件+參數
#傳遞到ENTRYPOINT,做爲ENTRYPOINT的參數
#shell form:做爲"/bin/sh –c"的參數
指定容器運行時須要監聽的端口,用在多容器之間通訊使用。
語法:EXPOSE <port>
設置環境變量,增長運行程序的靈活性,使用鍵值對格式。
若是須要更改鏡像生成容器時改變環境變量,可在運行"docker run"是帶"-env <key>=<value>"參數修改既定環境變量。
語法:ENV <key> <value>
指令用來設置一些觸發的指令,用於在當該鏡像被做爲基礎鏡像來建立其餘鏡像時執行一些操做,ONBUILD中定義的指令會在用於生成其餘鏡像的Dockerfile文件的FROM指令以後被執行,能夠用來執行一些由於環境而變化的操做,使鏡像更加通用,dockerfile全部指令均可以用於ONBUILD指令
注意:
鏡像正在運行時或接下來的RUN指令設定用戶名或UID。
語法:USER <uid>
指定RUN、CMD與ENTRYPOINT命令的工做目錄,默認爲"/"目錄。
可在dockerfile中屢次出現,若是使用相對路徑,後一次的相對路徑是上一次WORKDIR的值。
語法:WORKDIR /path/to/workdir
指定掛載點,能夠用來讓其餘容器掛載以實現數據共享或對容器數據的備份、恢復或遷移。
語法:VOLUME ["path"]
#使用Dockerfile構建1個可ssh的image [root@localhost ~]# touch Dockerfile #注意"Dockerfile"首字母大寫; #此示例將RUN須要執行的指令合併爲1條指令,可減小image層數; #yum安裝程序是按字母順序排列的(非強制要求) [root@localhost ~]# vim Dockerfile # Get a base image. FROM centos:latest # Author MAINTAINER Netonline "xxxxx@gmail.com" # Install some CLI tools. RUN yum install -y \ net-tools \ openssh-clients \ openssh-server && \ sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config && \ # Modify root password. echo "root:123456" | chpasswd && \ # Generate keys for sshd. ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key && \ ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key && \ ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key # Open sshd port and execute service. EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"]
#"docker build"執行時使用同目錄的"Dockerfile"文件;另外"centos:ssh"爲構建的image名,注意命令最後帶的"." [root@localhost ~]# docker build -t centos:ssh .
[root@localhost ~]# docker images