本文章是在網(wǎng)易云課堂的課程學習中編寫滚局,部分圖片從網(wǎng)易云課堂ppt引用
【基礎概念】
鏡像的定制實際上就是定制每一層所添加的配置、文件回俐。我們可以把每一層修改麦牺、安裝、構(gòu)建昂拂、操作的命令都寫入一個腳本,這個腳本就是 Dockerfile抛猖,用這個腳本來構(gòu)建格侯、定制鏡像。
Dockerfile 是一個文本文件财著,里面包含了一條條的指令(Instruction)联四,每一條指令構(gòu)建一層。
【使用 Dockerfile構(gòu)建私有鏡像】
接下來撑教,使用 Dockerfile 定制 nginx 鏡像為例:
1朝墩、新建Dockerfile文件
在一個空白目錄中,建立一個文本文件伟姐,并命名為Dockerfile
mkdir mynginx
cd mynginx
touch Dockerfile
2收苏、編輯Dockerfile文件
在Dockerfile文件寫入以下兩條指令
FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
FROM 指定基礎鏡像
我們定制鏡像,是以一個鏡像為基礎愤兵,在其上進行定制鹿霸。基礎鏡像是必須指定的秆乳,一個 Dockerfile中懦鼠,F(xiàn)ROM 是必備的指令钻哩,并且必須是第一條指令。如果不使用任何現(xiàn)有鏡像為基礎肛冶,則可使用 **scratch **鏡像街氢,這是一個虛擬的空白鏡像。RUN 執(zhí)行命令
RUN命令有兩種格式:
- shell 格式:RUN <命令>
比如:RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
- exec 格式:RUN ["可執(zhí)行文件", "參數(shù)1", "參數(shù)2"]
比如:RUN make -C /usr/src/redis
3睦袖、構(gòu)建鏡像
在 Dockerfile 文件所在目錄執(zhí)行:
docker build -t mynginx:1.0 .
現(xiàn)在通過docker images命令珊肃,可以查看到我們自己定制的鏡像了
4、基于該鏡像運行容器
docker run --name mynginx -p 80:80 mynginx:1.0
【Dockerfile指令詳解】
Dockerfile提供了十多個指令扣泊,除了上面已經(jīng)用到的FROM近范、RUN指令,我們來繼續(xù)學習一下其他的指令延蟹。
1评矩、COPY 復制文件
COPY 指令將 從構(gòu)建上下文目錄中 <源路徑> 的文件/目錄 復制到 新的一層的鏡像內(nèi)的 <目標路徑> 位置。
有兩種格式:
COPY <源路徑>... <目標路徑>
COPY ["<源路徑1>",... "<目標路徑>"]
比如:
COPY package.json/usr/src/app/
加上通配符也可以阱飘,要滿足 Go 的 filepath.Match 規(guī)則
COPY hom* /mydir/
COPY hom?.txt /mydir/
2斥杜、ADD 更高級的復制文件
ADD 指令和COPY 的格式和性質(zhì)基本一致,但是在 COPY 基礎上增加了一些功能沥匈。
ADD ubuntu -xenial-core-cloudimg -amd64-root.tar.gz /
根據(jù)官方推薦蔗喂,復制文件推薦還是使用COPY指令。適合使用 ADD 的場合高帖,是需要自動解壓縮的場合缰儿。
在 COPY 和 ADD 指令中選擇的時候,可以遵循這樣的原則散址,所有的文件復制均使用 COPY 指令乖阵,僅在需要自動解壓縮的場合使用 ADD。
3预麸、CMD 容器啟動命令
CMD 指令的格式和 RUN 相似瞪浸,也是兩種格式:
shell 格式:CMD <命令>
exec 格式:CMD ["可執(zhí)行文件", "參數(shù)1", "參數(shù)2"...]
- 參數(shù)列表格式:CMD ["參數(shù)1", "參數(shù)2"...]。在指定了 ENTRYPOINT 指令后吏祸,用 CMD 指定具體的參數(shù)对蒲。
Docker容器是進程,在啟動容器的時候贡翘,需要指定所運行的程序及參數(shù)蹈矮。CMD 指令就是用于指定默認的容器主進程的啟動命令。
4床估、ENTRYPOINT 入口點
ENTRYPOINT 的目的和CMD 一樣含滴,都是在指定容器啟動程序及參數(shù)。ENTRYPOINT 在運行時也可以替代丐巫,不過比 CMD 要略顯繁瑣谈况,需要通過 docker run 的參數(shù) --entrypoint 來指定
5勺美、ENV 設置環(huán)境變量
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2> ...
比如:ENV VERSION=1.0 DEBUG=on NAME="Happy Feet"
6、ARG 構(gòu)建參數(shù)
ARG <參數(shù)名>[=<默認值>]
構(gòu)建參數(shù)和 ENV 的效果一樣碑韵,都是設置環(huán)境變量赡茸。不同的是,ARG 所構(gòu)建的環(huán)境變量祝闻,在將來容器運行時占卧,是不會存在這些環(huán)境變量的。但是不要使用 ARG 保存密碼之類的信息联喘,因為 docker history 還是可以看到所有值的华蜒。
7、VOLUME 定義匿名卷
VOLUME ["<路徑1>", "<路徑2>"...]
VOLUME <路徑>
容器運行時應該盡量保持容器存儲層不發(fā)生寫操作豁遭,對于數(shù)據(jù)庫類需要保存動態(tài)數(shù)據(jù)的應用叭喜,其數(shù)據(jù)庫文件應該保存于卷(volume)中。
為了防止運行時用戶忘記將動態(tài)文件所保存目錄掛載為卷蓖谢,在 Dockerfile 中捂蕴,我們可以事先指定某些目錄掛載為匿名卷,這樣在運行時如果用戶不指定掛載闪幽,其應用也可以正常運行啥辨,不會向容器存儲層寫入大量數(shù)據(jù)。
8盯腌、EXPOSE 暴露端口
EXPOSE <端口1> [<端口2>...]
EXPOSE 指令是聲明運行時容器提供服務端口溉知,這只是一個聲明,在運行時并不會因為這個聲明應用就會開啟這個端口的服務腕够。
在 Dockerfile 中寫入這樣的聲明有兩個好處着倾,一個是幫助鏡像使用者理解這個鏡像服務的守護端口,以方便配置映射燕少;另一個用處則是在運行時使用隨機端口映射時,也就是 docker run -P 時蒿囤,會自動隨機映射 EXPOSE 的端口客们。
9、WORKDIR 指定工作目錄
WORKDIR <工作目錄路徑>
使用 WORKDIR 指令可以來指定工作目錄(或者稱為當前目錄)材诽,以后各層的當前目錄就被改為指定的目錄底挫,如該目錄不存在,WORKDIR 會幫你建立目錄脸侥。如果需要改變以后各層的工作目錄的位置建邓,那么應該使用 WORKDIR 指令。
10睁枕、USER 指定當前用戶
USER <用戶名>
USER 指令和 WORKDIR 相似官边,都是改變環(huán)境狀態(tài)并影響以后的層沸手。WORKDIR 是改變工作目錄,USER 則是改變之后層的執(zhí)行 RUN, CMD 以及 ENTRYPOINT 這類命令的身份注簿。
當然契吉,USER 只是幫助你切換到指定用戶而已,這個用戶必須是事先建立好的诡渴,否則無法切換捐晶。
11、HEALTHCHECK 健康檢查
HEALTHCHECK [選項] CMD <命令>:設置檢查容器健康狀況的命令
HEALTHCHECK NONE:如果基礎鏡像有健康檢查指令妄辩,使用這行可以屏蔽掉其健康檢查指令
HEALTHCHECK 指令是告訴 Docker 應該如何進行判斷容器的狀態(tài)是否正常惑灵,這是 Docker 1.12 引入的新指令。
假設有個鏡像是個簡單的 Web 服務眼耀,我們希望增加健康檢查來判斷其 Web 服務是否在正常工作英支,我們可以用 curl 來幫助判斷,其 Dockerfile 的 HEALTHCHECK 可以這么寫:
FROM nginx
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
HEALTHCHECK --interval=5s --timeout=3s CMD curl -fs http://localhost/ || exit 1
這里我們設置的是每 5 秒檢查一次畔塔,如果健康檢查命令超過 3 秒沒響應就視為失敗潭辈,并且使用 curl -fs http://localhost/ || exit 1 作為健康檢查命令。
12澈吨、ONBUILD 為他人作嫁衣
ONBUILD <其它指令>
ONBUILD 是一個特殊的指令把敢,它后面跟的是其它指令,比如 RUN谅辣,COPY 等修赞,而這些指令,在當前鏡像構(gòu)建時并不會被執(zhí)行桑阶。只有當以當前鏡像為基礎鏡像柏副,去構(gòu)建下一級鏡像的時候才會被執(zhí)行。