您好,登錄后才能下訂單哦!
10、指令10:RUN指令
RUM命令是基于Dockerfile構建鏡像的時候要運行的命令
比如基于url的方式獲取nginx安裝包:獲取到gz包以后需要使用RUN指令來運行tar來解壓展開這個nginx的包了。
案例:編寫docker file,并制作鏡像
#my?first?docker?file FROM?busybox:latest MAINTAINER?"zxhk?<237745635@qq.com>" ENV?DOC_ROOT=/data/?\ ????WORK_DIR=/var/usr/src/?\ ????REPO_DIR=/etc/yum.repos.d/?\ ????MYSQL_DIR=/data/mysql/ ???? COPY?index.html?${DOC_ROOT:-/var/www/html/} COPY?yum.repos.d?$REPO_DIR WORKDIR?$WORK_DIR ADD?http://nginx.org/download/nginx-1.17.6.tar.gz?./ RUN?cd?${WORK_DIR}?&&?tar?-xf?nginx-1.17.6.tar.gz?&&?mv?nginx-1.17.6?nginx VOLUME?$MYSQL_DIR EXPOSE?80/tcp?53/udp
[root@host1?img1]#?docker?build?-t?miniser:v1-8?./
基于鏡像啟動一個容器,檢測是否已經解壓
[root@host1?img1]#?docker?run?--rm?--name?t1?miniser:v1-8?ls?/var/usr/src/ nginx nginx-1.17.6.tar.gz
11、指令11:CMD指令
CMD是定義一個鏡像文件啟動為容器的時候,默認要運行的程序,也就是那個pid為1的程序
CMD可以有多個,但是只有最后一個才是生效的。
CMD指令有三種格式
格式1:CMD <命令>
這種格式的話,會自動的將這個命令運行為shell的子進程,這樣的好處就是在這個命令中可以有各種的特殊的符號,但是缺點就得是這個命令的進程號不是 1
也可以借助于exec,讓這個進程的ID成為1
格式2:CMD ["<命令>", "<參數1>","<參數2>"]
這種格式的話是直接將這個進程啟動為ID為1的進程
格式3:CMD ["<參數1>","<參數2>"]
這種格式需要借助于ENTRYPOINT才能運行
案例1:使用格式1讓容器運行的時候,自動運行apache
第一步:創建dockerfile
FROM?busybox LABEL?maintainer="zxhk<237745635@qq.com>" ENV?DOC_ROOT="/var/www/html/" RUN?mkdir?-p?${DOC_ROOT}?&&?\ ????echo?"<h2>test</h2>">${DOC_ROOT}index.html CMD?/bin/httpd?-f?-h?${DOC_ROOT}
第二步:制作鏡像
[root@host1?img2]#?docker?build?-t?miniser:v2-1?./
第三步:查看鏡像的詳細信息
[root@host1?img2]#?docker?inspect?miniser:v2-1?-f?'{{.ContainerConfig.Cmd}}' [/bin/sh?-c?#(nop)??CMD?["/bin/sh"?"-c"?"/bin/httpd?-f?-h?${DOC_ROOT}"]]
第四步:創建容器
[root@host1?img2]#?docker?run?--name?t1?--rm?-d?miniser:v2-1
第五步:登錄容器,查看容器信息
[root@host1?img2]#?docker?exec?-it?t1?/bin/sh /?#? /?#?netstat?-an Active?Internet?connections?(servers?and?established) Proto?Recv-Q?Send-Q?Local?Address???????????Foreign?Address?????????State??????? tcp????????0??????0?:::80???????????????????:::*????????????????????LISTEN?????? /?#? /?#?ps PID???USER?????TIME??COMMAND ????1?root??????0:00?/bin/httpd?-f?-h?/var/www/html/ ???10?root??????0:00?/bin/sh ???15?root??????0:00?ps /?#
案例2:使用格式2讓容器運行的時候,自動運行apache
FROM?busybox LABEL?maintainer="zxhk<237745635@qq.com>" ENV?DOC_ROOT="/var/www/html/" RUN?mkdir?-p?${DOC_ROOT}?&&?\ ????echo?"<h2>test</h2>">${DOC_ROOT}index.html CMD?["/bin/sh",?"-c",?"/bin/httpd",?"-f",?"-h",?"${DOC_ROOT}"]
11、指令11:ENTRYPOINT指令
ENTRYPOINT的功能就是和CMD類似的,用于指定容器啟動后要默認運行的程序
在啟動容器的時候,run后面指定的命令,可以覆蓋鏡像中的CMD命令
ENTRYPOINT所運行的命令不會不被docker run所指定的命令覆蓋
案例:用ENTRYPOINT制作鏡像實現啟動容器自動運行apache
FROM?busybox LABEL?maintainer="zxhk<237745635@qq.com>" ENV?DOC_ROOT="/var/www/html/" RUN?mkdir?-p?${DOC_ROOT}?&&?\ ????echo?"<h2>test</h2>">${DOC_ROOT}index.html ENTRYPOINT?/bin/httpd?-f?-h?${DOC_ROOT}
制作鏡像并啟動容器測試
[root@host1?img2]#?docker?build?-t?miniser:v2-2?./ [root@host1?img2]#?docker?run?--name?t2?--rm?-it?miniser:v2-2?ls?/data
此時命令會卡住
ls /data會作為參數傳遞給httpd -f -h? /data,因為httpd無法識別這個參數,因此會卡住
ENTRYPOINT和CMD組合使用的情況
此時CMD后的內容就會作為默認參數傳遞給ENTRYPOINT
FROM?busybox LABEL?maintainer="zxhk<237745635@qq.com>" ENV?DOC_ROOT="/var/www/html/" RUN?mkdir?-p?${DOC_ROOT}?&&?\ ????echo?"<h2>test</h2>">${DOC_ROOT}index.html CMD?["/bin/httpd",?"-f",?"-h",?"${DOC_ROOT}"] ENTRYPOINT?["/bin/sh","-c"]
使用ENTRYPOINT的好處是,他比CMD更方便,因為他可以在啟動容器的時候,直接向容器傳遞命令
案例:在啟動容器的時候,動態生成配置文件
1、創建工作目錄
[root@host1?img3]#?mkdir?/img3 [root@host1?img3]#?cd?/img3
2、準備一個shell腳本,用于生成配置文件
[root@host1?img3]#?vim?entrypoint.sh
#!/bin/sh cat>/etc/nginx/conf.d/www.conf<<EOF server?{ ????server_name?$HOSTNAME; ????listen?${IP:-0.0.0.0}:${PORT:-80}; ????root?${NGX_DOC_ROOT:-/usr/share/nginx/html}; } EOF exec?"$@"
3、創建測試頁面
[root@host1?img3]#?echo?"test?page">index.html
4、編寫Dockerfile文件
[root@host1?img3]#?vim?Dockerfile
FROM?nginx:1.14-alpine LABEL?author="zxhk<237745635@qq.com>" ENV?NGX_DOC_ROOT='/data/web/html/' ADD?index.html?${NGX_DOC_ROOT} ADD?entrypoint.sh?/bin/ #nginx的配置文件必須以;為結尾 CMD?["/usr/sbin/nginx","-g","daemon?off;"] ENTRYPOINT?["/bin/entrypoint.sh"]
在執行dockerfile的時候,CMD的內容會傳遞到ENTRYPOINT中
ENTRYPOIN會啟動運行這個shell腳本,shell腳本就是pid為1的進程,shell腳本就會生成配置文件
在腳本的最后會通過exec 來執行nginx,讓nginx工作在前臺,同時nginx進程頂替shell成為pid為1的進程
5、構建鏡像
[root@host1?img3]#?docker?build?-t?miniser:v2-4?./
6、啟動容器
[root@host1?img3]#?docker?run?--name?nginx1?--rm?miniser:v2-4
登錄容器看看
[root@host1?~]#?docker?exec?-it?nginx1?/bin/sh /?#? /?#?cat?/etc/nginx/conf.d/www.conf? server?{ ????server_name?c1d255997da4; ????listen?0.0.0.0:80; ????root?/data/web/html/; } /?#
7、再重新啟動一個容器,讓nginx監聽127.0.0.1的8080端口
[root@host1?img3]#?docker?run?--name?nginx1?--rm?\ >?-e?"PORT=8080"?-e?"IP=1.2.3.4"?miniser:v2-4
再登錄容器看看
[root@host1?~]#?docker?exec?-it?nginx1?/bin/sh /?#? /?#? /?#?cat?/etc/nginx/conf.d/www.conf? server?{ ????server_name?92c978c97b3c; ????listen?127.0.0.1:8080; ????root?/data/web/html/; } /?#
通過這種方式可以快速的為不同的環境準備特定的配置文件
12、指令12:USER指令
用于指定容器中的主進程是以哪個用戶的身份來運行
也可以用來指定在執行dockerfile的CMD? RUN? ENTRYPOIND的時候,以那個用戶的身份來運行
需要確保容器的/etc/passwd中有這個用戶,否則會報錯
語法格式:
USER <UID> | <USERNAME>
13、指令13:HEALTHCHECK指令
檢查容器和容器中的服務是否正常工作
HEALTHCHECK的功能選項
--interval=xx? 指定每隔多久檢查一次(默認每隔30s檢查一次)
--timeout=xx? 指定等待超時時間(默認也是30s)
--start-period=xx 啟動容器后,等待多久開始做健康檢查(默認是0秒,也就是不等)
--retries=xx? 指定請求幾次數據都沒獲得返回的情況下才認為是出現了異常(默認是3次)
HEALTHCHECK的返回值
0:success成功
1:unhealth不健康
2:預留,沒有意義
案例:每隔5分鐘檢查一次,超時時間是3秒
HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://1.2.3.4 || exit 1
如果健康檢查失敗,就返回1
14、指令14:SHELL指令
這個是用來指定運行程序的時候默認要用的程序
舉例:
SHELL?["/bin/sh","-c"]
15、指令15:STOPSIGNAL指令
這個指令可以指定在執行docker stop的時候,本質上是向容器發送什么什么指令,默認是發送15,如果想執行stop的時候發送9的指令
格式
STOPSIGNAL?9
16、指令16:ARG指令
ARG也是定義一個變量,只是這個變量是用在執行build dockerfile的過程中
可以將nginx的版本定義成變量,然后在構建鏡像的時候可以通過變量來動態指定作者
編寫鏡像文件
FROM?nginx:1.14-alpine ARG?info="zxhk<237745635@qq.com>" LABEL?author="${info}" ENV?NGX_DOC_ROOT='/data/web/html/' ADD?index.html?${NGX_DOC_ROOT} ADD?entrypoint.sh?/bin/ #nginx的配置文件必須以;為結尾 CMD?["/usr/sbin/nginx","-g","daemon?off;"] ENTRYPOINT?["/bin/entrypoint.sh"]
制作鏡像
[root@host1?img3]#?docker?build?-t?miniser:v2-5?--build-arg?new="tom@qq.com"?./
Dockerfile中的arg相當于是配置了一個默認值,在制作鏡像的時候,如果沒有傳值,就用默認值
注意區分ENV和ARG
docker run的時候可以傳值,但是在docker build的時候是無法傳值的
ENV所定義的變量在夠構建鏡像的時候使用的,而在構建鏡像的時候是只能用ARG的默認值的
17、指令17:ONBUILD指令
本指令其實是定義一個觸發器
通過ONBUILD定義的Dcokerfile,在執行docker build的時候不執行,只有別人基于這個鏡像做新鏡像的時候,才會被執行
案例:如果別人基于這個鏡像做新鏡像,就讓其下載一個文件
第一步:制作一個基礎鏡像
[root@host1?img3]#?vim?Dockerfile
FROM?nginx:1.14-alpine LABEL?author="zxhk<237745635@qq.com>" ENV?NGX_DOC_ROOT='/data/web/html/' ADD?index.html?${NGX_DOC_ROOT} ADD?entrypoint.sh?/bin/ ONBUILD?ADD?http://x.x.x.x/xxx?/data/web/html/ #nginx的配置文件必須以;為結尾 CMD?["/usr/sbin/nginx","-g","daemon?off;"] ENTRYPOINT?["/bin/entrypoint.sh"]
制作鏡像
[root@host1?img3]#?docker?build?-t?base:v1.1?./
第二步:基于基礎鏡像做新鏡像
[root@host1?~]#?mkdir?/img4 [root@host1?img4]#?cd?/img4 [root@host1?img4]#?vim?Dockerfile
FROM?base:v1-1 RUN?mkdir?/data
制作鏡像
[root@host1?img4]#?docker?build?-t?newimg:v1-1?./
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。