文章結(jié)構(gòu):
(一)Docker常用知識點(diǎn)
(二)Dockerfile指令詳解
文章最后附一份docker教學(xué)視頻,本篇的Dockerfile指令詳解是看該教學(xué)視頻做的筆記
(一)Docker常用知識點(diǎn)
【1.1】進(jìn)入一個(gè)正在運(yùn)行的Docker容器命令:?
~]# docker ps?
?~]# docker exec -it 775c7c9ee1e1 /bin/bash
【1.2】Docker 退出容器但不關(guān)閉當(dāng)前容器:
按Ctrl+P+Q進(jìn)行退出容器
【1.3】docker狀態(tài)轉(zhuǎn)換和事件:

【1.4】常用操作:

【1.5】四種Docker容器網(wǎng)絡(luò)

【1.6】在容器中使用Volumes
Volume(卷)為docker提供了獨(dú)立于容器的數(shù)據(jù)管理機(jī)制
可以把“鏡像”想象成靜態(tài)文件,例如“程序”,把卷類比為動(dòng)態(tài)內(nèi)容,例如“數(shù)據(jù)”;于是,鏡像可以重用,而卷可以共享;
卷實(shí)現(xiàn)了? ?“程序(鏡像)”? ?和? ?“數(shù)據(jù)(卷)” 分離,以及? ?“程序(鏡像)”? ? 和? ? “制作鏡像的主機(jī)”? ?分離。用戶在制作鏡像時(shí)無須再考慮鏡像運(yùn)行的容器所在的主機(jī)的環(huán)境
一共有兩種volume可以用,都能實(shí)現(xiàn)數(shù)據(jù)持久化,使用方式都一樣,宿主機(jī)內(nèi)修改容器內(nèi)也改了,容器內(nèi)修改宿主機(jī)內(nèi)也改了。兩種方式不同在于宿主機(jī)上存放位置是隨機(jī)還是指定。
docker inspect 查看時(shí)在Mounts對象里可以看到type不一樣
(1)Docker-managed volume,這種volume在宿主機(jī)上存在放的路徑是隨機(jī)的
~]# docker run -it -name bbox1 -v /data busybox
~]# docker inspect -f {{.Mounts}} bbox1
? ? 查看bbox1容器的卷、卷標(biāo)識符及掛載的主機(jī)目錄
(2)Bind-mount Volume,這種volume可以指定具體在宿主機(jī)上存放的位置
~]# docker run -it -v HOSTDIR:VOLUMEDIR --name bbox2 busybox
~]# docker inspect -f {{.Mounts}} bbox2
(二)Dockerfile指令詳解:
【2.1】Dockerfile語法格式

注意:
1.Dockerfile中json數(shù)組中引號都為雙引號,不能寫單引號
2.通常一行一個(gè)指令
3..找一個(gè)專用工作目錄放Dockerfile,Dockerfile首字母要大寫
4.如果需要打包很多文件進(jìn)鏡像,必須要把文件放到當(dāng)前Dockerfile所在的工作目錄下。即Dockerfile中引用文件的路徑不能是其父路徑,可以是子路徑
5.Dockerfile還支持專用的工作目錄下做一個(gè)隱藏文件,叫.dockeringore,這也是個(gè)文本文件。在這個(gè)文件中可以寫文件路徑,可以使用通配符。所有在打包時(shí)的文件只要在.dockeringore中寫的路徑,打包時(shí)都不包含進(jìn)去。
【2.2】Dockerfile中FROM指令

【2.3】Dockerfile中LABEL指令
LABEL為鏡像制定各種元數(shù)據(jù)

【2.4】Dockerfile中COPY指令

舉個(gè)栗子:
COPY index.html /data/web/html/
COPY yum.repos.d /etc/
【2.5】Dockerfile中ADD指令

舉個(gè)栗子:
ADD? ?nginx-1.15.2.tar.gz? ?./src/
注意:上面的./src是相對路徑,相對于WORKDIR設(shè)置的工作路徑
【2.6】Dockerfile中WORKDIR指令
用來設(shè)置容器的當(dāng)前工作路徑,設(shè)置完之后的COPY和ADD指令中<dest>可以寫成相對于WORKDIR的路徑 ./ 或者 ./src等等,可以設(shè)置多個(gè)工作路徑。
【2.7】Dockerfile中EXPOSE指令

舉個(gè)栗子:
EXPOSE? 80/tcp
【2.8】Dockerfile中ENV指令

舉個(gè)栗子:
ENV? ? DOC_ROOT? ? /data/web/html/
COPY? ?index.html? ? $DOC_ROOT
#給DOC_ROOT加個(gè)默認(rèn)值:
COPY index.html? ?${doc_root:-/data/web/html/}
#一次設(shè)置多個(gè)變量:
ENV? DOC_ROOT=/data/web/html/? \
? ? ? ? ? WEB_SERVER_PACKAGE="NGINX-1.15.2"0
【2.9】Dockerfile中VOLUME指令
舉個(gè)栗子:
VOLUME? /data/mysql/
【2.10】Dockerfile中RUN指令
RUN指令是在由基礎(chǔ)鏡像生成目標(biāo)鏡像docker build過程中執(zhí)行的。RUN指令可以在Dockerfile中寫多個(gè),多個(gè)RUN指令都起作用,逐一運(yùn)行。如果多個(gè)Command之間有關(guān)聯(lián)關(guān)系建議用一條RUN寫下來,因?yàn)镈ockerfile中一條指令就會(huì)生成一個(gè)鏡像層。

格式:
RUN COMMAND1 && \
? ? ? ? ?COMMAND2
舉個(gè)栗子:
RUN? cd? /usr/local/src? &&? \
? ? ? ? tar? xf? ${WEB_SERVER_PACKAGE}

【2.11】Dockerfile中的CMD指令
CMD是定義一個(gè)鏡像文件啟動(dòng)容器時(shí)默認(rèn)要運(yùn)行的程序塊。Docker程序默認(rèn)只運(yùn)行一個(gè)程序。Dockerfile中只能有一個(gè)CMD指令有效。如果寫了多個(gè)只有最后一個(gè)CMD起作用。

【2.12】Dockerfile中ENTRYPOINT指令

【2.13】Dockerfile案例
Dockerfile案例需求介紹:
運(yùn)行nginx時(shí),nginx通過接收變量來生成配置文件。接收的變量能在啟動(dòng)容器時(shí)進(jìn)行傳遞。
案例中三個(gè)文件entrypoint.sh,Dockerfile,index.html在同一個(gè)目錄下
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 "$@"
上面的exec用來替換當(dāng)前進(jìn)程,“$@”含義是腳本的所有參數(shù),即傳什么就運(yùn)行什么
Dockerfile文件:
FROM nginx:1.14-alpine
LABEL maintainer="Andy <andy@qq.com>"
ENV NGX_DOC_ROOT="/data/web/html/"
ADD index.html ${NGX_DOC_ROOT}
ADD entrypoint.sh /bin/
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]
index.html文件:
<h1>New Doc Root for Nginx</h1>
docker build:
[root@node01 img3]# docker build -t myweb:v0.3-6 ./
docker run:
[root@node01 ~]# docker run --name myweb1 --rm -P myweb:v0.3-6
啟動(dòng)時(shí)設(shè)置端口號,監(jiān)聽到8080上
[root@node01 ~]# docker run --name myweb1 --rm -P -e "PORT=8080" myweb:v0.3-6
進(jìn)入容器驗(yàn)證:
[root@node01 ~]# docker exec -it myweb1 /bin/sh
/ # cat /etc/nginx/conf.d/www.conf
/ # netstat -tnl
/ # wget -o - -q 主機(jī)名(在www.conf中查看到的server_name)
殺掉一個(gè)運(yùn)行中的容器:
[root@node01 ~]# docker kill myweb1
【2.14】Dockerfile中USER指令

【2.15】Docker中HEALTHCHECK指令
主進(jìn)程健康檢測不能通過看進(jìn)程在不在來確定,而是應(yīng)該通過看是否能提供服務(wù)來確定。通過HEALTHCHECK來檢測是否能提供服務(wù)。


option釋義:
--interval含義是每隔多久檢測一次主進(jìn)程
--timeout含義是超時(shí)時(shí)長,即多久沒響應(yīng)算為主進(jìn)程不健康
--start-period含義是容器啟動(dòng)后等多久開始進(jìn)行健康檢測
--retries含義是檢測多少次失敗后認(rèn)定為不健康
三個(gè)返回值中reserved表示預(yù)留的,可以自己定義
【2.16】Dockerfile中ARG指令
在Dockerfile中定義的ARG指令可以在docker build 命令中通過--build-arg <變量名>=<變量值>的方式傳遞自定義參數(shù)。
注意:在docker run時(shí)可以向環(huán)境變量傳值,docker build時(shí)不能向環(huán)境變量傳值,只能用默認(rèn)值。如果想在docker build時(shí)也能給變量定義值,那就得使用ARG。

舉個(gè)栗子:
在Dockerfile中:
ARG author="pony <pony@qq.com>"
LABEL maintainer="${author}"
在docker build命令中:
docker build --build-arg author="andy <andy@qq.com>" -t myweb:v0.3-10 ./
【2.17】Dockerfile中ONBUILD指令
ONBUILD指令后面跟的是正常的Dockerfile中的指令如RUN、ADD等等。
自己做的鏡像可以被別人作為基礎(chǔ)鏡像使用,如果自己做的鏡像Dockerfile中寫了ONBUILD指令,這個(gè)指令后面的Dockerfile指令在自己做image時(shí)不會(huì)執(zhí)行。而當(dāng)別人把你的鏡像當(dāng)做基礎(chǔ)鏡像,并寫在Dockerfile,在他的build時(shí)才會(huì)執(zhí)行。

結(jié)束語:到此為止就可以愉快的做鏡像了,如果還是不熟練,可以到?docker hub?上看看別人怎么寫的,讀別人寫的Dockerfile可以了解怎么用他的鏡像更合適。多讀幾個(gè)應(yīng)該就會(huì)寫了。