Docker修煉之旅(二)—— 利用Dockerfile文件加docker build命令構(gòu)建鏡像


title: Docker修煉之旅(二)
date: 2019-06-26 15:19:11
tags:
- Docker
categories:
- Study
- Docker


Docker鏡像和倉庫,寫寫Docker鏡像的一些相關(guān)命令,還有如何通過編寫Dockerfile文件構(gòu)建自己的鏡像


繼續(xù)Docker學(xué)習(xí),這一篇主要寫Docker鏡像

Docker鏡像是什么

Docker鏡像是由文件系統(tǒng)疊加而成烈疚。最底端是一個文件引導(dǎo)系統(tǒng)吏奸,即bootfs荆秦。Docker用戶不會與引導(dǎo)文件系統(tǒng)有直接的交互凹嘲。Docker鏡像的第二層是root文件系統(tǒng)rootfs,通常是一種或多種操作系統(tǒng)灌旧,例如ubuntu等。
在Docker中绰筛,文件系統(tǒng)永遠(yuǎn)都是只讀的枢泰,在每次修改時,都是進(jìn)行拷貝疊加從而形成最終的文件系統(tǒng)铝噩。Docker稱這樣的文件為鏡像衡蚂。一個鏡像可以迭代在另一個鏡像的頂部。位于下方的鏡像稱之為父鏡像,最底層的鏡像稱之為基礎(chǔ)鏡像毛甲。最后年叮,當(dāng)從一個鏡像啟動容器時,Docker會在最頂層加載一個讀寫文件系統(tǒng)作為容器玻募。

Docker文件系統(tǒng)層圖:

image

Docker鏡像一些相關(guān)命令

列出本地鏡像

我們可以用docker images列出所有本地的鏡像只损,可以看到列出的鏡像有一個TAG標(biāo)簽屬性,像圖中的Ubuntu鏡像七咧,就有三種標(biāo)簽14.04跃惫、18.04、latest艾栋,分別代表Ubuntu的不同版本爆存,這種標(biāo)簽屬性機(jī)制使得在同一個倉庫里可以存儲多個鏡像』壤可以在拉取鏡像的時候通過冒號:指定tag先较,如:docker run ubuntu:14.04或docker pull Ubuntu:14.04

image

本地的鏡像保存的位置在/var/lib/docker/目錄下。每個鏡像都保存在Docker所采用的存儲驅(qū)動目錄下遥诉。本地容器都保存在/var/lib/docker/containers/目錄下拇泣。

image

查找、拉取鏡像

可以用docker search <鏡像名>命令在Docker Hub上面查找鏡像矮锈。
比如我們這里查找一下fedora基礎(chǔ)鏡像霉翔,可以看到列出的Docker Hub上面的所以fedora鏡像,包括每個鏡像的描述苞笨、收藏量债朵、是否是官方鏡像等屬性,然后供我們自己選擇進(jìn)行拉取瀑凝。

image

我們這里就選擇fedora官方鏡像進(jìn)行拉取序芦,使用docker pull命令,如下圖粤咪。

image

拉取了鏡像后谚中,就可以用這個鏡像來構(gòu)造我們的容器,容器的操作具體見上一篇文章寥枝。

刪除鏡像

可以通過docker rmi命令刪除鏡像宪塔,前提是這個鏡像沒有被容器使用(包括運(yùn)行或停止的容器)
如下圖示,我們嘗試刪除被運(yùn)行容器和已停止容器使用的鏡像囊拜,均失敗某筐。

image

只有把使用了該鏡像的容器刪除后,才能刪除鏡像冠跷。

image


構(gòu)建鏡像

一般來說南誊,我們不是真正的"創(chuàng)建"新鏡像身诺,而是基于一個已有的基礎(chǔ)鏡像,如Ubuntu或fedora等抄囚,構(gòu)建新鏡像而已霉赡。

構(gòu)建鏡像一般有兩種方法:

  1. 通過docker commit命令
  2. 使用docker build命令和Dockerfile文件

使用docker commit命令

先說第一種方法。docker commit命令怠苔,可以把這種方法視為我們在往版本控制系統(tǒng)里提交變更同廉。
我們首先先用Ubuntu鏡像構(gòu)建一個容器,如下圖柑司,我們可以看到迫肖,創(chuàng)建的容器是沒有安裝vim的,我們可以用apt-get install命令安裝一下

image

可以看到攒驰,我們對最基礎(chǔ)的Ubuntu鏡像做了一些改變蟆湖,安裝了vim軟件,不過這只是這個容器安裝了而已玻粪,再用Ubuntu鏡像創(chuàng)建另一個新容器隅津,還得再重新裝一遍vim,這未免太過麻煩劲室。于是為了解決這個問題伦仍,我們可以把安裝了vim的容器的狀態(tài)保存下來,生成一個新鏡像很洋,這樣就不必重新安裝vim了充蓝。

為了完成這項工作,我們用到了docker commit命令喉磁,首先先用exit命令退出容器谓苟,然后獲取剛剛運(yùn)行的容器的ID(通過docker ps -l -q命令獲取),然后用docker commit <容器ID> <新鏡像名>命令創(chuàng)建新鏡像协怒。

image

我們這里使用docker commit成功創(chuàng)建了一個新鏡像ubuntu:installed-vim涝焙,可以通過docker images查看是否創(chuàng)建成功。

image

這里關(guān)于docker commit命令在說兩句孕暇,這個命令應(yīng)該和git commit差不多仑撞,可以使用-m參數(shù)添加標(biāo)注,而且提交的部分只是創(chuàng)建容器的鏡像和容器的當(dāng)前狀態(tài)之間有差異的部分妖滔,這使得該更新十分輕量

使用Dockerfile文件

實際構(gòu)建鏡像中派草,docker commit命令方法用的較少,大多都是編寫Dockerfile文件铛楣,然后用docker build命令創(chuàng)建新鏡像。Dockerfile文件基于DSL語法

流程如下:

  1. 首先先創(chuàng)建一個目錄艺普,這個目錄就是我們的構(gòu)建環(huán)境簸州,要把Dockerfile放在該目錄下鉴竭,然后再在該目錄直接運(yùn)行docker build命令創(chuàng)建鏡像。
  2. 然后在該目錄下創(chuàng)建編寫Dockerfile文件

我們這里創(chuàng)建了一個Docker_study文件夾岸浑,然后開始編寫Dockerfile文件搏存,文件具體代碼如下。

# version: 0.0.1
FROM ubuntu:14.04
MAINTAINER Miracle778 "Yiitao@163.com"
RUN apt-get update
RUN apt-get install -y nginx
RUN echo 'Hi, I am in Your Container'\
    >/usr/share/nginx/html/index.html
EXPOSE 80

Dockerfile文件由一系列指令和參數(shù)組成矢洲。每天指令璧眠,如FROM,都必須是大寫字符读虏,且后邊要跟隨一個參數(shù)责静,如:FROM ubuntu:14.04。Dockerfile文件中的指令會按順序從上到下執(zhí)行盖桥,所以要合理安排順序

每條指令都會創(chuàng)建一個新的鏡像層并對鏡像進(jìn)行提交灾螃,大致按照如下流程執(zhí)行。

  1. Docker從基礎(chǔ)鏡像運(yùn)行一個容器
  2. 執(zhí)行一條指令揩徊,對容器進(jìn)行修改
  3. 執(zhí)行類似于docker commit的指令腰鬼,提交一個新的鏡像層
  4. Docker基于新提交的鏡像運(yùn)行一個新容器
  5. 執(zhí)行Dockerfile中的下一條指令,重復(fù)上面2-4步過程塑荒,直至所有指令結(jié)束

從上面流程中可以看出熄赡,如果Dockerfile由于某一條指令執(zhí)行失敗了,那么你可以得到一個執(zhí)行完上一條指令后的可以使用的鏡像齿税,這對調(diào)試非常有用彼硫,可以利用這個鏡像運(yùn)行一個具備交互功能的容器,然后執(zhí)行你Dockerfile文件中失敗的指令偎窘,查看失敗原因乌助。
比如我們這里把上面Dockerfile文件中的第五行內(nèi)容改一下,把nginx改為nignx陌知,然后運(yùn)行下docker build命令他托,關(guān)于docker build命令我們等下在后面再講。這里先關(guān)注如何調(diào)試仆葡。

image

如上圖赏参,如我們所預(yù)期那樣,改變了Dockerfile文件的第五行的命令后沿盅,build過程果然報錯把篓,而且得到了上一條命令運(yùn)行完的容器ID,接下來我們運(yùn)用這個容器ID進(jìn)行調(diào)試腰涧。
我們使用docker run -i -t命令以交互式模式進(jìn)入該容器韧掩,然后執(zhí)行下Dockerfile文件中報錯的指令,這里是apt-get install -y nignx窖铡,然后觀察下結(jié)果疗锐。

image

如上圖示坊谁,確定了出錯原因,并且可以通過在容器中執(zhí)行改正指令達(dá)到調(diào)試效果滑臊,最終我們確定是apt-get install -y nignx命令的nginx拼寫錯了口芍,于是可以在Dockerfile文件中修改過來。這就是調(diào)試過程雇卷。

下面我們用改正過后的正確的Dockerfile文件進(jìn)行鏡像創(chuàng)建鬓椭。執(zhí)行過程如下圖


image

我們來解釋解釋該步驟里的一些過程。

看到創(chuàng)建命令:docker build -t="miracle778/dockerfile_study" .
該命令執(zhí)行過程為先在本地目錄中尋找Dockerfile文件(也可以指定github地址上的Dockerfile文件)关划,找到后安裝Dockerfile命令一步步執(zhí)行小染。

-t 參數(shù)是指定鏡像名字,一般為:<倉庫名>/<鏡像名:標(biāo)簽>祭玉,這里名字不能有大寫字母
最后要注意的是氧映,命令后面那個點 .,不要忘記了

然后是Dockerfile文件里的指令解釋

代表注釋

FROM指令指定一個已經(jīng)存在的鏡像脱货,后續(xù)指令都將基于該鏡像進(jìn)行岛都,這個鏡像被稱為基礎(chǔ)鏡像
MAINTAINER 指令會告訴Docker該鏡像的作者是誰,以及作者的電子郵件地址
EXPOSE指令告訴Docker該容器內(nèi)的應(yīng)用程序?qū)褂萌萜鞯闹付ǘ丝?br> RUN 命令會在當(dāng)前鏡像中運(yùn)行指定的命令
默認(rèn)情況下振峻,RUN指令會在shell中使用命令包裝器/bin/sh -c來執(zhí)行臼疫。
如果是在一個不支持shell的平臺上運(yùn)行或者不希望在shell中運(yùn)行
也可以使用exec格式的RUN指令
RUN ["apt-get", "install" ,"-y" , "nginx"]
這種方式中,要使用一個數(shù)組來指定要運(yùn)行的命令和傳遞給該命令的參數(shù)

Dockerfile還有其他一些命令扣孟,后面的學(xué)習(xí)使用中會逐步用到烫堤,到時候再現(xiàn)學(xué)吧。
這里給個鏈接凤价,隨便百度Dockerfile命令大全得來的鸽斟,https://www.cnblogs.com/dazhoushuoceshi/p/7066041.html

然后再談?wù)凞ockerfile和構(gòu)建緩存

我們可以從上面的Dockerfile執(zhí)行流程和那個調(diào)試?yán)涌吹剑珼ocker鏡像構(gòu)建過程中利诺,每一步都會將結(jié)果提交為鏡像富蓄。換句話說,就是會把之前的鏡像層看做緩存慢逾。這樣會使得構(gòu)建鏡像節(jié)省很多時間立倍。
但有時候鏡像構(gòu)建過程中可能不需要使用緩存,這時就需要在docker build命令里加入--no-cache標(biāo)志

講了這么多侣滩,快來使用下新鏡像吧

使用命令docker run --name Docker_study -d -p 80 miracle778/dockerfile_study nginx -g "daemon off;"創(chuàng)建一個新容器口注,這句命令稍后再來解析,現(xiàn)在先看到命令執(zhí)行后的結(jié)果

image

可以看到君珠,容器創(chuàng)建好后寝志,成功運(yùn)行,建立了一個宿主機(jī)32772端口到docker容器80端口的映射,也就是說澈段,我們訪問本地的32772端口悠菜,就能訪問到容器的80端口,也就是這里的nginx服務(wù)器败富。
我們再回到Dockerfile文件中的最后一條RUN命令,是向/usr/share/nginx/html/index.html文件里寫入了Hi, I am in Your Container這句內(nèi)容摩窃。所以我們訪問docker容器80端口預(yù)期的結(jié)果應(yīng)該是返回Hi, I am in Your Container
我們通過curl命令測試一下兽叮,如下圖,結(jié)果符合預(yù)期猾愿。

image

現(xiàn)在我們再來看到使用新鏡像生成新容器的命令鹦聪,主要是看到-p參數(shù),這個參數(shù)用來控制Docker在運(yùn)行時應(yīng)該公開哪些網(wǎng)絡(luò)端口給外部蒂秘,這個參數(shù)會覆蓋掉Dockerfile中EXPOSE指定的端口泽本。而且有兩種分配方法,一種是Docker隨機(jī)分配一個比較大的端口號來映射到容器的80端口上姻僧,也就是我們圖中這里使用的方法;另一種方法是可以指定宿主機(jī)端口來映射到容器的指定端口规丽,如:-p 7777:80就是把宿主機(jī)的7777端口映射給Docker容器的80端口。

然后我們在看到命令最后部分的nginx -g "daemon off;"這里撇贺,這樣寫會以前臺運(yùn)行的方式啟動nginx赌莺,這里可能有點好奇為什么要這樣寫,如果不這么寫的話松嘶,可能會導(dǎo)致run命令執(zhí)行完創(chuàng)建好容器后艘狭,容器自動退出的情況,這里我也查了查資料翠订,出現(xiàn)這種情況的原因見下巢音。

Docker 容器啟動時,默認(rèn)會把容器內(nèi)部第一個進(jìn)程尽超,也就是pid=1的程序官撼,作為docker容器是否正在運(yùn)行的依據(jù),如果 docker 容器pid=1的進(jìn)程掛了橙弱,那么docker容器便會直接退出歧寺。
Docker未執(zhí)行自定義的CMD之前,nginx的pid是1棘脐,執(zhí)行到CMD之后斜筐,nginx就在后臺運(yùn)行,bash或sh腳本的pid變成了1蛀缝。
所以一旦執(zhí)行完自定義CMD顷链,nginx容器也就退出了。

具體見:https://blog.csdn.net/youcijibi/article/details/88781014


總結(jié)

這篇文章主要是講些Docker鏡像相關(guān)的命令以及構(gòu)造自己的Docker鏡像的方法屈梁,重點是通過Dockerfile文件加docker build命令構(gòu)建自己的鏡像嗤练,其中Dockerfile文件的編寫語法這里只講到一點榛了,其他的ADD | ENTRYPOINT | VOLUME | CMD等命令這里都沒有提到,應(yīng)該會在后面的搭建具體應(yīng)用時用到煞抬,到時候再寫霜大。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市革答,隨后出現(xiàn)的幾起案子战坤,更是在濱河造成了極大的恐慌,老刑警劉巖残拐,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件途茫,死亡現(xiàn)場離奇詭異,居然都是意外死亡溪食,警方通過查閱死者的電腦和手機(jī)囊卜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來错沃,“玉大人栅组,你說我怎么就攤上這事∩臃希” “怎么了笑窜?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長登疗。 經(jīng)常有香客問我排截,道長,這世上最難降的妖魔是什么辐益? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任断傲,我火速辦了婚禮,結(jié)果婚禮上智政,老公的妹妹穿的比我還像新娘认罩。我一直安慰自己,他們只是感情好续捂,可當(dāng)我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布垦垂。 她就那樣靜靜地躺著,像睡著了一般牙瓢。 火紅的嫁衣襯著肌膚如雪劫拗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天矾克,我揣著相機(jī)與錄音页慷,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛酒繁,可吹牛的內(nèi)容都是我干的滓彰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼州袒,長吁一口氣:“原來是場噩夢啊……” “哼揭绑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起郎哭,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤洗做,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后彰居,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡撰筷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年陈惰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片毕籽。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡抬闯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出关筒,到底是詐尸還是另有隱情溶握,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布蒸播,位于F島的核電站睡榆,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏袍榆。R本人自食惡果不足惜胀屿,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望包雀。 院中可真熱鬧宿崭,春花似錦、人聲如沸才写。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赞草。三九已至讹堤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間房资,已是汗流浹背蜕劝。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人岖沛。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓暑始,卻偏偏與公主長得像,于是被迫代替她去往敵國和親婴削。 傳聞我的和親對象是個殘疾皇子廊镜,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,066評論 2 355