app軟件下載網(wǎng)站免費進入常用的網(wǎng)絡(luò)營銷方法及效果
前言
知識點整理
Dockerfile 簡介
它是一個沒有后綴名的文本文檔,里面是組合鏡像的一些命令,Docker build命令構(gòu)建鏡像時,通過讀取Dockerfile中的指令的順序(自上到下)自動生成鏡像。
Dockerfile 命令
1. FROM
指定基礎(chǔ)鏡像,并且必須是第一條指令。
如果不以任何鏡像為基礎(chǔ),那么寫法為:FROM scratch。
同時意味著接下來所寫的指令將作為鏡像的第一層開始
語法:
FROM <image>
FROM <image>:<tag>
FROM <image>:<digest>
三種寫法,其中和 是可選項,如果沒有選擇,那么默認(rèn)值為latest
2. MAINTAINER
指明鏡像的歸屬者或維護團體/機構(gòu)名稱/域名
語法:
MAINTAINER <name>
示例:
MAINTAINER csdn.xxx
MAINTAINER csdn
MAINTAINER csdn@qq.com
3. RUN
在生成鏡像時需要執(zhí)行的命令
Dockerfile中的RUN命令,只有在docker build 命令構(gòu)建鏡像時會自動運行
docker run的時候,并不會運行
RUN命令有兩種格式
# 第一種后邊直接跟shell命令
RUN <command># 第二種是類似于函數(shù)調(diào)用, 可將executable理解成為可執(zhí)行文件,后面就是兩個參數(shù)
RUN ["executable", "param1", "param2"]
在linux操作系統(tǒng)上默認(rèn) /bin/sh -c
在windows操作系統(tǒng)上默認(rèn) cmd /S /C
注意:多行命令不要寫多個RUN,原因是Dockerfile中每一個指令都會建立一層.
多少個RUN就構(gòu)建了多少層鏡像,會造成鏡像的臃腫、多層,不僅僅增加了構(gòu)件部署的時間,還容易出錯。
RUN書寫時的換行符是\
4. CMD
功能為容器啟動時要運行的命令
語法有三種寫法
# 1. 可執(zhí)行文件加上參數(shù)的形式
CMD ["executable","param1","param2"]
CMD ["param1","param2"]# 2. shell的執(zhí)行方式和寫法
CMD command param1 param2
舉例說明兩種寫法:
CMD [ "sh", "-c", "echo $HOME"
CMD [ "echo", "$HOME" ]
補充細(xì)節(jié):這里邊包括參數(shù)的一定要用雙引號,就是",不能是單引號。千萬不能寫成單引號。
原因是參數(shù)傳遞后,docker解析的是一個JSON array
RUN vs CMD
RUN是構(gòu)件容器時就運行的命令以及提交運行結(jié)果
CMD是容器啟動時執(zhí)行的命令,在構(gòu)件時并不運行,構(gòu)件時緊緊指定了這個命令到底是個什么樣子。Dockerfile中多個CMD命令只有最后一個生效
5. LABEL
功能是為鏡像指定標(biāo)簽;作為MAINTAINE的補充,更為詳細(xì)的一些描述信息
語法:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
一個Dockerfile種可以有多個LABEL,如下:
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates that label-values can span multiple lines."
但是并不建議這樣寫,最好就寫成一行,如太長需要換行的話則使用符號
如下:
LABEL multi.label1="value1"
multi.label2="value2"
other="value3"
說明:LABEL會繼承基礎(chǔ)鏡像種的LABEL,如遇到key相同,則值覆蓋
MAINTAINER vs LABEL
增強鏡像的閱讀性,不會對功能造成影響
6. EXPOSE
指定對外的端口。功能為暴漏容器運行時的監(jiān)聽端口給外部
但是EXPOSE并不會使容器訪問主機的端口
如果想使得容器與主機的端口有映射關(guān)系,必須在容器啟動的時候加上 -P參數(shù)
7. ENV
功能為設(shè)置環(huán)境變量
簡單的說,它就是一個全局常量,被設(shè)置后,進入容器內(nèi)部,在任意位置都可以訪問這個常量的值,比如# echo $var_bl。
好比本地設(shè)置了JAVA_HOME環(huán)境變量一樣,在CMD窗口任意目錄,都可以打印/獲取該常量。
語法有兩種
ENV <key><value>
ENV <key>=<value> ...
兩者的區(qū)別就是第一種是一次設(shè)置一個,第二種是一次設(shè)置多個
示例:
ENV WORKPATH /tmp
ENV http_proxy ""
ENV JAVA_HOME /usr/local/openjdk8
ENV test=mayun-xiaoma
ENV mycat=mimiRUN $JAVA_HOME/bin/java-jar test.jar
盡量使用環(huán)境常量,可提高程序維護性,如果JAVA_HOME需要調(diào)整為其他JDK版本,那么只需要調(diào)整一處位置即可,比如把/usr/local/openjdk8調(diào)整為jdk9。
注意:這些環(huán)境常量可以通過docker run命令的–env 或-e參數(shù)來進行修改。
8. ADD
一個復(fù)制命令,把文件復(fù)制到景象中。
如果把虛擬機與容器想象成兩臺linux服務(wù)器的話,那么這個命令就類似于scp,只是scp需要加用戶名和密碼的權(quán)限驗證,而ADD不用。
語法如下:
# <src> (為宿主機目錄+)文件;<dest>(為容器內(nèi)目錄+)文件
ADD <src>... <dest>
ADD ["<src>",... "<dest>"]
路徑的填寫可以是容器內(nèi)的絕對路徑,也可以是相對于工作目錄的相對路徑
可以是一個本地文件或者是一個本地壓縮文件,還可以是一個url
如果把寫成一個url,那么ADD就類似于wget命令
盡量不要把寫成一個文件夾,如果是一個文件夾了,復(fù)制整個目錄的內(nèi)容,包括文件系統(tǒng)元數(shù)據(jù)
如以下寫法都是可以的:
#把hello從宿主機復(fù)制到容器內(nèi)部的根路徑
ADD hello /
#把壓縮包從宿主機添加到容器的根目錄后,自動解壓
ADD test.tar.gz /
#把hello文件復(fù)制到當(dāng)前workdir工作目錄的根目錄
ADD hello .
#僅從宿主機復(fù)制文件到容器內(nèi)部的指定目錄
COPY test.txt /etc/nginx
#復(fù)制文件,并自動解壓到指定目錄
ADD demo.tar.gz /usr/share/nginx/html
宿主目錄,默認(rèn)是執(zhí)行docker build時所在的宿主機目錄 ;
示例中,后面的/是指容器內(nèi)部根目錄,而 . 是容器內(nèi)部的當(dāng)前目錄(默認(rèn)是WORKDIR的目錄)
9. COPY
復(fù)制命令
語法如下:
COPY <src>... <dest>
COPY ["<src>",... "<dest>"]
ADD vs COPY
- COPY 的只能是本地文件,ADD可以充當(dāng)wget命令添加遠程文件
- ADD 是增強版的COPY,ADD自帶解壓,COPY不帶解壓。兩者都支持目錄中有空格。
注意:
- ADD指令不支持認(rèn)證,從遠程獲取資源如果需要認(rèn)證(交互),則只能使用RUN wget或RUN curl替代。
- 如果不是需要解壓,優(yōu)先使用COPY命令,效率更高、更節(jié)省資源。
10. ENTRYPOINT
功能是啟動時的默認(rèn)命令
語法如下:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
CMD vs ENTRYPOINT
相同點:
- 只能寫一條,如果寫了多條,那么只有最后一條生效
- 容器啟動時才運行,運行時機相同
不同點:
ENTRYPOINT不會被運行的command覆蓋,而CMD則會被覆蓋
如果我們在Dockerfile種同時寫了ENTRYPOINT和CMD,并且CMD指令不是一個完整的可執(zhí)行命令,那么CMD指定的內(nèi)容將會作為ENTRYPOINT的參數(shù)
如下:
FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
如果我們在Dockerfile種同時寫了ENTRYPOINT和CMD,并且CMD是一個完整的指令,那么它們兩個會互相覆蓋,誰在最后誰生效
如下:
FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ls -al
那么將執(zhí)行l(wèi)s -al ,top -b不會執(zhí)行。
11. VOLUME
設(shè)置卷,掛載主機目錄??蓪崿F(xiàn)掛載功能,可以將內(nèi)地文件夾或者其他容器種得文件夾掛載到這個容器中
語法為:
VOLUME ["/data"]
說明:
[“/data”]可以是一個JsonArray ,也可以是多個值。所以如下幾種寫法都是正確的
VOLUME ["/var/log/"]
VOLUME /var/log
VOLUME /var/log /var/db
一般的使用場景為需要持久化存儲數(shù)據(jù)時
容器使用的是AUFS,這種文件系統(tǒng)不能持久化數(shù)據(jù),當(dāng)容器關(guān)閉后,所有的更改都會丟失。
所以當(dāng)數(shù)據(jù)需要持久化時用這個命令。
12. USER
設(shè)置啟動容器的用戶,可以是用戶名或UID
只有下面的兩種寫法是正確的
USER daemo
USER UID
注意:如果設(shè)置了容器以daemon用戶去運行,那么RUN, CMD 和 ENTRYPOINT 都會以這個用戶去運行
13. WORKDIR
WORKDIR 設(shè)置的,目錄需要是絕對路徑,如果不存在,會自動創(chuàng)建。
在Dockerfile最外層首次出現(xiàn),則是指明通過docker exec -it 進入容器內(nèi)部后,默認(rèn)進入的工作目錄(無需再用cd命令切換)。
如果Dockerfile中命令比較多,需要來回切換工作目錄,則可以隨時再次定義新的WORKDIR
語法:
WORKDIR /path/to/workdir
設(shè)置工作目錄,對RUN,CMD,ENTRYPOINT,COPY,ADD生效。如果不存在則會創(chuàng)建,也可以設(shè)置多次。如:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
pwd執(zhí)行的結(jié)果是/a/b/c
14. ARG
設(shè)置變量命令
語法:
# 設(shè)置變量命令,ARG命令定義了一個變量,在docker build創(chuàng)建鏡像的時候,使用 --build-arg <varname>=<value>來指定參數(shù)
ARG <name>[=<default value>]
如果用戶在build鏡像時指定了一個參數(shù)沒有定義在Dockerfile種,那么將有一個Warning
提示如下:
[Warning] One or more build-args [foo] were not consumed.
我們可以定義一個或多個參數(shù),如下:
FROM busybox
ARG user1
ARG buildno
...
也可以給參數(shù)一個默認(rèn)值:
FROM busybox
ARG user1=someuser
ARG buildno=1
...
如果我們給了ARG定義的參數(shù)默認(rèn)值,那么當(dāng)build鏡像時沒有指定參數(shù)值,將會使用這個默認(rèn)值
15. ONBUILD
這個命令只對當(dāng)前鏡像的子鏡像生效
語法:
ONBUILD [INSTRUCTION]
比如當(dāng)前鏡像為A,在Dockerfile中添加:
ONBUILD RUN ls -al
這個 ls -al 命令不會在A鏡像構(gòu)建或啟動的時候執(zhí)行
此時有一個鏡像B是基于A鏡像構(gòu)建的,那么這個ls -al 命令會在B鏡像構(gòu)建的時候被執(zhí)行。
16. STOPSIGNAL
作用是當(dāng)容器退出時給系統(tǒng)發(fā)送什么樣的指令
語法:
STOPSIGNAL signal
17. HEALTHCHECK
容器健康狀況檢查命令
語法有兩種:
# 在容器內(nèi)部運行一個命令來檢查容器的健康狀況
HEALTHCHECK [OPTIONS] CMD command# 在基礎(chǔ)鏡像中取消健康檢查命令
HEALTHCHECK NONE
[OPTIONS]的選項支持以下三中選項:
- interval=DURATION 兩次檢查默認(rèn)的時間間隔為30秒
- timeout=DURATION 健康檢查命令運行超時時長,默認(rèn)30秒
- retries=N 當(dāng)連續(xù)失敗指定次數(shù)后,則容器被認(rèn)為是不健康的,狀態(tài)為unhealthy,默認(rèn)次數(shù)是3
注意:
HEALTHCHECK命令只能出現(xiàn)一次,如果出現(xiàn)了多次,只有最后一個生效。
CMD后邊的命令的返回值決定了本次健康檢查是否成功,具體的返回值如下:
0: success - 表示容器是健康的
1: unhealthy - 表示容器已經(jīng)不能工作了
2: reserved - 保留值
例子:
HEALTHCHECK --interval=5m --timeout=3s
CMD curl -f http://localhost/ || exit 1
健康檢查命令是:curl -f http://localhost/ || exit 1
兩次檢查的間隔時間是5秒
命令超時時間為3秒
Dockerfile案例
部署JavaWeb項目
新建并編輯 Dockerfile:
# 指定基于的容器鏡像
FROM tomcat
# 維護者信息
MAINTAINER "itstyle <12345678@qq.com>"
# 復(fù)制項目到Tomcat指定目錄
ADD test.war /usr/local/tomcat/webapps/
# 容器啟動時執(zhí)行指令
CMD ["catalina.sh", "run"]
構(gòu)建鏡像:
docker build -t itstyle/tomcat .
PS:
- 文件名只能是Dockerfile,不同的構(gòu)建文件通過文件夾名稱來區(qū)分
- 命令最后的點 “.” 表示讀取當(dāng)前目錄下的 Dockerfile 進行構(gòu)建
- -t:表示為當(dāng)前鏡像命名
運行鏡像:
docker run -d -p 8888:8080 -v /home/docker/web:/usr/local/tomcat/webapps --name app itstyle/tomcat
在 /home/docker/web 目錄下存放項目War
案例2:部署SpringBoot微服務(wù)
# 基礎(chǔ)鏡像:倉庫是java
FROM java:8-jre
# 當(dāng)前鏡像的維護者和聯(lián)系方式
MAINTAINER "itstyle 12345678@qq.com"
# 掛載卷
VOLUME /tmp
# 將打包好的springBoot程序拷貝到容器中的指定位置
ADD itstyle_stats.jar /opt/app.jar
# 容器對外暴露端口
EXPOSE 8080
# 容器啟動后需要執(zhí)行的命令
CMD java -jar /opt/app.jar
# ENTRYPOINT ["java","-jar","-Denv=DEV","/opt/app.jar"]
知識回顧
構(gòu)建鏡像
# 這里的 -f 用于指定Dockerfile文件路徑
docker bulid -t -f Dockerfile路徑
# 使用當(dāng)前目錄下的Dockerfile構(gòu)建鏡像,鏡像命名為 nginx:env
docker build . -t nginx:env
#啟動容器
docker run -t --rm --name nginx-env nginx:env
#啟動容器,并進入容器內(nèi)部
docker run -it --rm --name nginx-env nginx:env /bin/sh
#直接進入容器內(nèi)部
docker exec -it nginx:env /bin/bash
#打印環(huán)境變量
echo $mycat
#退出容器,返回宿主機
exit
本文參考鏈接