使用Dockerfile制作镜像
組成部分
- 基礎鏡像信息?????? FROM
- 維護者信息??? MAINTAINER、LABEL
- 鏡像操作指令?????? RUN、COPY、ADD、EXPOSE、WORKDIR、ONBUILD、USER等
- 容器啟動時執行指令??? CMD、ENTRYPOINT
?
1、MAINTAINER
?(docker1.7以后的版本已被LABEL替代,但仍兼容此字段)
格式:
??? MAINTAINER <name>
2、LABEL
用鍵值對的方式提供比MAINTAINER更多的詳細信息
LABEL maintainer="WangChuang 123@qq.com" app="httpd
3、copy和add
COPY: 拷貝數據,不會自動解壓數據
從宿主機的當前工作目錄中將文件copy到目標鏡像文件的系統中
語法如下:
1. COPY <src>... <dest>
2. COPY ["<src1>""<src2>""<dest>"]
<src>: 要復制的源文件或目錄,支持通配符
<dest>:目標路徑,建議使用絕對路徑
?
文件復制準則
<src>必須是構建目錄中的文件
如果<src>是目錄,則其內部文件或子目錄會被遞歸復制,但<src>目錄自身不會被復制
如果指定了多個<src>,或在<src>中使用了通配符,則<dest>必須是一個目錄,且必須以"/"結尾
如果<dest>事先不存在,它將會被自動創建,這包括其父目錄路徑
?
ADD:
功能和copy類似,但ADD支持使用tar文件和url網絡路徑
ADD http://nginx.org/download/nginx-1.15.12.tar.gz /usr/local/src/?? #如果src是網絡路徑,就不會解壓
ADD nginx-1.15.12.tar.gz /usr/local/src/? #會解壓
?
4、WORKDIR
可以指定多次,
WORKDIR /usr/local/src/
ADD nginx-1.15.12.tar.gz ./
?
5、VOLUME存儲卷
例:
VOLUME /data/mysql/
?
當容器創建好后,可以查看宿主機對應的存儲目錄
docker inspect 6c |grep "/data"
?
6、EXPOSE
語法
EXPOSE 11211/udp 11211/tcp
?
關于端口暴露:容器端口暴露一般有兩種方式:隨機暴露 、指定端口暴露
?
隨機暴露端口-P(大寫)
隨機暴露,Dockerfile中需有EXPOSE關鍵字, 定義待暴露的端口,但容器啟動時并不會直接暴露到宿主機,如果需要暴露可以加上-P
?
指定端口-p(小寫)
指定端口就和EXPOSE沒有關系了。可以用-p 80:80,直接指定宿主機和容器間對應的端口?
?
結論:可以看到管哪種方式容,器默認啟動時端口是不會主動暴露到宿主機,并且容器中必須有真實存在的端口,加上-p或者-P才生效
?
7、ENV
ENV NAME wang? #設置單個變量
ENV NAME=wang? PASSWD=123?? #一次定義多個變量
?
引用
$NAME或者${NAME}
?
注意:
Dockerfile中的環境變量可以在兩個階段引用使用
生成鏡像階段,
運行容器階段,啟動容器加上-e還可以修改變量值
?
?
?
7、USER
用于指定運行image時,或運行Dockerfilez
默認情況下,container的運行身份為root用戶
?
語法:
USER u01? #確保鏡像內有這個用戶
?
?
8、HEALTHCHECK
默認情況下docker是判斷容器主進程運行與否,來判斷容器是否健康
HEALTHCHECK:指定命令判斷主進程是否真正正常提供服務,判斷容器是否健康
?
語法:
HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost:8080 || exit 1
每隔5分鐘檢測一次,超時時間為3秒, CMD指定檢測命令,檢測成功返回0,失敗返回1
?
參數:
CMD? #指定檢測命令
--interval? #持續監測,默認每隔30秒
--timeout? #超時時間,默認30s
--start-period #有些容器比如tomcat,剛啟動的時候主進程啟動的慢,如果立即檢測肯定是失敗的,所以等容器啟動多少時間以后再去檢測 (默認0s,直接檢測)
--retries=N??? #失敗多少次,判斷容器為故障 (默認3)
響應值:
0:表示檢測成功
1:檢測失敗
2:預留的值,沒意義
重點:RUN、CMD 和 ENTRYPOINT
容器內沒有后臺服務的概念,其啟動程序就是容器應用進程,容器就是為了主進程而存在的,主進程退出,容器就失去了存在的意義,從而退出,其它輔助進程不是它需要關心的東西。
1、RUN
RUN 指令通常用于安裝應用和軟件包。
RUN 在當前鏡像的頂部執行命令,并通過創建新的鏡像層。Dockerfile 中常常包含多個 RUN 指令。
RUN 有兩種格式:
Shell 格式:RUN
Exec 格式:RUN ["executable", "param1", "param2"]
?
2、CMD
CMD 指令允許用戶指定容器的默認執行的命令。此命令會在容器啟動且 docker run 沒有指定其他命令時運行。
l? 如果 docker run 指定了其他命令,CMD 指定的默認命令將被忽略。
l? 如果 Dockerfile 中有多個 CMD 指令,只有最后一個 CMD 有效。
?
CMD 有三種格式:
Exec 格式:CMD ["executable","param1","param2"] ?#這是 CMD 的推薦格式。
Shell 格式:CMD command param1 param2
Exec 格式,提供參數:CMD ["param1","param2"] ?#為 ENTRYPOINT 提供額外的參數,此時 ENTRYPOINT 必須使用 Exec 格式,shell格式無效。
?
3、ENTRYPOINT
ENTRYPOINT 指令可讓容器以應用程序或者服務的形式運行。
ENTRYPOINT 看上去與 CMD 很像,它們都可以指定要執行的命令及其參數。
不同的地方在于 ENTRYPOINT 不會被忽略,一定會被執行,即使運行 docker run 時指定了其他命令。
?
ENTRYPOINT 有兩種格式:
Exec格式:ENTRYPOINT ["executable", "param1", "param2"] #這是 ENTRYPOINT 的推薦格式。
Shell 格式:ENTRYPOINT command param1 param2
?
在為 ENTRYPOINT 選擇格式時必須小心,因為這兩種格式的效果差別很大。
?
#@ 就是代表參數,參數可調用可不調用
?
?
?
?
第一種格式:PID不為1,自動為shell的子進程
<command>通常是一個shell命令,且以"/bin/sh -c"來運行它,這意味著此進程在容器中的PID不為1,不能接收Unix信號。因此當docker stop <container>命令停止容器時,此進程接收不到SIGTERM信號
第二種格式:PID為1,不會自動成為shell的子進程
語法中的參數是一個列表,其中<executable>為要運行的命令,后面的為參數或選項;然而此種格式不會以"/bin/sh -c"來運行,因此常見的shell操作,如變量替換以及通配符(?/*等)替換將不會進行;不過如果要運行的命令依賴此shell特性的話,可以將其替換為類似下面的格式
RUN ["/bin/bash","-c","<executable>","<param1>"]
?
?
關于Shell 和 Exec 格式
Shell 格式
<instruction> <command>
例如:
RUN apt-get install python3 ?
CMD echo "Hello world" ?
ENTRYPOINT echo "Hello world"?
當指令執行時,shell 格式底層會調用 /bin/sh -c <command>。
例如下面的 Dockerfile 片段:
ENV name Cloud Man ?
ENTRYPOINT echo "Hello, $name"?
執行 docker run <image> 將輸出:
Hello, Cloud Man
?
注意環境變量?name?已經被值?Cloud Man?替換。
下面來看 Exec 格式。
Exec 格式
<instruction> ["executable", "param1", "param2", ...]
?
例如:
RUN ["apt-get", "install", "python3"] ?
CMD ["/bin/echo", "Hello world"] ?
ENTRYPOINT ["/bin/echo", "Hello world"]
?
當指令執行時,會直接調用 <command>,不會被 shell 解析。
例如下面的 Dockerfile 片段:
ENV name Cloud Man ?
ENTRYPOINT ["/bin/echo", "Hello, $name"]
?
運行容器將輸出:
Hello, $name
?
注意環境變量“name”沒有被替換。
如果希望使用環境變量,照如下修改
ENV name Cloud Man ?
ENTRYPOINT ["/bin/sh", "-c", "echo Hello, $name"]
?
運行容器將輸出:
Hello, Cloud Man
?
CMD 和 ENTRYPOINT 推薦使用 Exec 格式,因為指令可讀性更強,更容易理解。RUN 則兩種格式都可以。
?
轉載于:https://www.cnblogs.com/chuangcc/p/11234806.html
總結
以上是生活随笔為你收集整理的使用Dockerfile制作镜像的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DataSnap 2009 系列之二 (
- 下一篇: GEE windows 环境配置