Docker 鏡像

典型的 Linux 文件系統(tǒng)

bootfs(bootfilesystem)

  • Bootloader - 引導(dǎo)加載 kernel
  • Kernel - 當(dāng) kernel 被加載到內(nèi)存中后 umount bootfs

rootfs(rootfilesystem)

  • /dev沈自,/proc徐勃,/bin,/etc 等標(biāo)準(zhǔn)目錄和文件

對(duì)于不同的 Linux 發(fā)行版刺洒,bootfs 基本是一致的豫尽,但 rootfs 會(huì)有差別

Docker 的文件系統(tǒng)如何啟動(dòng)

Linux

  • 在啟動(dòng)后篙梢,首先將 rootfs 置為 readonly,進(jìn)行一系列檢查,然后將其切換為“readwrite”共用戶(hù)使用

Docker

  • 也是將 rootfs 以 readonly 方式加載并檢查,然而接下來(lái)利用 union mount 將一個(gè) readwrite 文件系統(tǒng)掛載在 readonly 的 rootfs 之上

  • 并且允許再次將下層的 file system 設(shè)定為 readonly 并且向上疊加

  • 這樣一組 readonly 和一個(gè) writeable 的結(jié)構(gòu)構(gòu)成一個(gè) container 的運(yùn)行目錄逼友,每一個(gè)被稱(chēng)作一個(gè) Layer

AUFS

AUFS 是一種 Union File System,所謂 UnionFS 就是把不同物理位置的目錄合并 mount 到同一個(gè)目錄中妄呕。UnionFS 的一個(gè)最主要的應(yīng)用是,把一張CD/DVD 和一個(gè)硬盤(pán)目錄給聯(lián)合 mount 在一起嗽测,然后绪励,你就可以對(duì)這個(gè)只讀的 CD/DVD 上的文件進(jìn)行修改(當(dāng)然,修改的文件存于硬盤(pán)上的目錄里)

AUFS 是將多個(gè)目錄合并成一個(gè)虛擬文件系統(tǒng)唠粥,成員目錄稱(chēng)為虛擬文件系統(tǒng)的一個(gè)分支(branch)疏魏,每個(gè) branch 可以指定 readwrite/whiteout-able/readonly 權(quán)限,只讀(ro)晤愧,讀寫(xiě)(rw)大莫,寫(xiě)隱藏(wo)。一般情況下养涮,aufs 只有最上層的 branch 具有讀寫(xiě)權(quán)限葵硕,其余 branch 均為只讀權(quán)限眉抬。只讀 branch 只能邏輯上修改贯吓,AUFS 每層branch 可以動(dòng)態(tài)的增加刪除,每增加一層蜀变,下層默認(rèn)置為 ro悄谐,最上一層為 rw。刪除 branch 是在 aufs 掛載點(diǎn)移除库北,并未刪除掛載目錄

AUFS 的文件讀寫(xiě)與刪除

當(dāng)需要修改一個(gè)文件爬舰,而該文件位于低層 branch時(shí)们陆,頂層 branch 會(huì)直接復(fù)制低層 branch 的文件至頂層再進(jìn)行修改,而低層的文件不變情屹,這種方式即是 CoW 技術(shù)(寫(xiě)復(fù)制)坪仇,AUFS 默認(rèn)支持 Cow 技術(shù),當(dāng)容器刪除一個(gè)低層 branch 文件時(shí)垃你,只是在頂層 branch 對(duì)該文件進(jìn)行重命名并隱藏椅文,實(shí)際并未刪除文件,只是不可見(jiàn)惜颇,這種方式即 AUFS 的whiteout(寫(xiě)隱藏)

  • 添加文件:創(chuàng)建文件時(shí)皆刺,新文件被添加到branch中
  • 讀取文件 :讀取某個(gè)文件時(shí),會(huì)從上往下依次在各鏡像層中查找此文件凌摄。一旦找到羡蛾,打開(kāi)并讀入內(nèi)存。
  • 修改文件 :修改已存在的文件時(shí)锨亏,會(huì)從上往下依次在各鏡像層中查找此文件痴怨。一旦找到,立即將其復(fù)制到容器層屯伞,然后修改之腿箩。
  • 刪除文件 :刪除文件時(shí),也是從上往下依次在鏡像層中查找此文件劣摇。找到后珠移,會(huì)在branch中記錄下此刪除操作。

Docker 中的 AUFS

Docker 鏡像(Image)是由一個(gè)或多個(gè) AUFS branch 組成末融,并且所有的 branch 均為只讀權(quán)限钧惧。簡(jiǎn)單來(lái)說(shuō),AUFS 所有 robranch 按照一定順序堆積構(gòu)成 Docker Image 鏡像
在運(yùn)行容器的時(shí)候勾习,創(chuàng)建一個(gè) AUFS branch 位于image 層之上浓瞪,具有 rw 權(quán)限,并把這些 branch 聯(lián)合掛載到一個(gè)掛載點(diǎn)下巧婶。這就是 Docker 能夠一個(gè)鏡像運(yùn)行多個(gè)容器的原理所在

寫(xiě)時(shí)復(fù)制(Copy-on-Write)

  • 容器啟動(dòng)時(shí)乾颁,一個(gè)新的可寫(xiě)層被加載到鏡像的頂部,這一層通常被稱(chēng)作“容器層”艺栈,“容器層”之下的都叫“鏡像層”
  • 所有對(duì)容器的改動(dòng)英岭,無(wú)論添加、刪除湿右、還是修改文件都只會(huì)發(fā)生在容器層中
  • 只有容器層是可寫(xiě)的诅妹,容器層下面的所有鏡像層都是只讀的
  • 只有當(dāng)需要修改時(shí)才復(fù)制一份數(shù)據(jù),這種特性被稱(chēng)作 Copy-on-Write】越疲可見(jiàn)尖殃,容器層保存的是鏡像變化的部分, 不會(huì)對(duì)鏡像本身進(jìn)行任何修改

AUFS 的好處

  • 節(jié)省存儲(chǔ)空間:多個(gè)容器可以共享基礎(chǔ)鏡像(Base Image)存儲(chǔ)
  • 快速部署:如果要部署多個(gè)容器划煮,基礎(chǔ)鏡像(Base Image)可以避免多次拷貝
  • 內(nèi)存更仕头帷:因?yàn)槎鄠€(gè)容器共享 Base Image,以及OS 的 Disk 緩存機(jī)制弛秋,多個(gè)容器中的進(jìn)程命中緩存內(nèi)容的幾率大大增加
  • 允許在不更改基礎(chǔ)鏡像的同時(shí)修改其目錄中的文件:所有寫(xiě)操作都發(fā)生在最上層的 writeable 層中蚪战,這樣可以大大增加 Base Image 能共享的文件內(nèi)容

鏡像的定義

鏡像(Image)就是一堆只讀層(read-only layer)的統(tǒng)一視角
從左邊我們看到了多個(gè)只讀層,它們重疊在一起铐懊。除了最下面一層邀桑,其它層都會(huì)有一個(gè)指針指向下一層。這些層是 Docker 內(nèi)部的實(shí)現(xiàn)細(xì)節(jié)科乎,并且能夠在主機(jī)(譯者注:運(yùn)行 Docker 的機(jī)器)的文件系統(tǒng)上訪(fǎng)問(wèn)到壁畸。統(tǒng)一文件系統(tǒng)(union file system)技術(shù)能夠?qū)⒉煌膶诱铣梢粋€(gè)文件系統(tǒng),為這些層提供了一個(gè)統(tǒng)一的視角

鏡像與分層

  1. Docker 鏡像是多個(gè)的茅茂,堆疊的分層的只讀文件系統(tǒng)
  2. 每一層的變化是基于下一層的
  3. 相鄰層之間的改動(dòng)是有延續(xù)性的
  4. 從 docker 1.10 之后捏萍,每個(gè)鏡像層的由一致性的 hash 生成 id,取代了舊版使用隨機(jī)生成的 UUID
FROM ubuntu:15.10
COPY . /app
RUN make /app
CMD python /app/app.py

鏡像命名規(guī)則

registry.abc.net/orgname/imagename:tag

  • registry.abc.net:Remote registry 的地址
    -(docker.io,gcr.io)
  • orgname:(optional)組織區(qū)分的鏡像集合
  • imagename:鏡像名稱(chēng)
  • tag:標(biāo)簽

docker.io/oracle/mysql:v5.7.1
k8s.gcr.io/kube-apiserver-amd64:v1.11.0

小心 latest空闲,千萬(wàn)別被 latest tag 給誤導(dǎo)了令杈。latest 其實(shí)并沒(méi)有什么特殊的含義。當(dāng)沒(méi)指明鏡像
tag 時(shí)碴倾,Docker 會(huì)使用默認(rèn)值 latest逗噩,僅此而已,所以我們?cè)谑褂苗R像時(shí)最好還是避免使用 latest跌榔,明確指定某個(gè) tag异雁,比如 httpd:2.3

容器的定義

  • 容器(container)的定義和鏡像(image)幾乎一模一樣,也是一堆層的統(tǒng)一視角僧须,
    唯一區(qū)別在于容器的最上面那一層是可讀可寫(xiě)的
  • 要點(diǎn):容器 = 鏡像 + 讀寫(xiě)層纲刀,并且容器的定義并沒(méi)有提及是否要運(yùn)行容器

Dockerfile

dockerfile

FROM debian
RUN apt-get install emacs
RUN apt-get install apache2
CMD ["/bin/bash"]
  1. 新鏡像不再是從 scratch 開(kāi)始,而是直接在 Debian base 鏡像上構(gòu)建
  2. 安裝 emacs 編輯器
  3. 安裝 apache2
  4. 容器啟動(dòng)時(shí)運(yùn)行 bash

構(gòu)建過(guò)程如下圖所示:


Dockerfile 是 docker 構(gòu)建鏡像的基礎(chǔ)担平,也是 docker區(qū)別于其他容器的重要特征示绊,正是有了 Dockerfile,docker 的自動(dòng)化和可移植性才成為可能

編寫(xiě)Dockerfile命令:
FROM:從一個(gè)基礎(chǔ)鏡像構(gòu)建新的鏡像

  • FROM ubuntu

MAINTAINER:維護(hù)者信息

RUN:非交互式運(yùn)行shell命令

  • RUN apt-get -y update
  • RUN apt-get -y install nginx

ENV:設(shè)置環(huán)境變量

  • ENV MYSQL 5.7

WORKDIR /path/to/workdir:設(shè)置工作目錄

  • WORKDIR /var/www

USER:設(shè)置用戶(hù)ID

  • USER nginx

VOLUME <#dir>:設(shè)置volume

  • VOLUME [‘/data’]

EXPOSE:暴露哪些端口

  • EXPOSE 80 443

ENTRYPOINT [‘executable’, ‘param1’,’param2’]:執(zhí)行命令

  • ENTRYPOINT ["/usr/sbin/nginx"]

CMD [“param1”,”param2”]

  • CMD ["start"]

注意:

  • ENTRYPOINT 指令和 CMD 指令雖然是在 Dockerfile 中定義暂论,但是在構(gòu)建鏡像的時(shí)候并不會(huì)被執(zhí)行面褐,只有在執(zhí)行 docker run 命令啟動(dòng)容器時(shí)才會(huì)起作用
  • 在 Dockerfile 中,只能有一個(gè) ENTRYPOINT 指令空另,如果有多個(gè) ENTRYPOINT 指令則以最后一個(gè)為準(zhǔn)
  • 在 Dockerfile 中盆耽,只能有一個(gè) CMD 指令蹋砚,如果有多個(gè) CMD 指令則以最后一個(gè)為準(zhǔn)
  • 在 Dockerfile 中扼菠,ENTRYPOINT 指令或 CMD指令摄杂,至少必有其一,如果設(shè)置了 ENTRYPOINT循榆,則 CMD 將作為參數(shù)

Dockerfile 例子

Dockerfile Best Practices

  • 使用統(tǒng)一的base鏡像 - Centos, Ubuntu
  • 使用小型基礎(chǔ)鏡像 - 生成鏡像也較小
  • 動(dòng)靜分離 - 經(jīng)常變化的內(nèi)容和基本不會(huì)變化的內(nèi)容要分開(kāi)析恢,把不怎么變化的內(nèi)容放在下層, 創(chuàng)建出來(lái)不同基礎(chǔ)鏡像供上層使用秧饮。
  • 最小原則:只安裝必需的東西
  • 一個(gè)原則:每個(gè)鏡像只有一個(gè)功能 - 不要在容器里運(yùn)行多個(gè)不同功能的進(jìn)程映挂,每個(gè)鏡像中只安裝一個(gè)應(yīng)用的軟件包和文件,需要交互的程序通過(guò) pod 或者容器之間的網(wǎng)絡(luò)進(jìn)行交流盗尸。
  • 使用更少的層 - 盡量把相關(guān)的內(nèi)容放到同一個(gè)層柑船,使用換行符進(jìn)行分割
  • 切勿映射公有端口 - 鏡像應(yīng)該可以多次運(yùn)行在任何主機(jī)上
  • 不要在構(gòu)建中升級(jí)軟件版本 - 應(yīng)在基礎(chǔ)鏡像中更新,類(lèi)似于類(lèi)的繼承泼各,在基類(lèi)里實(shí)現(xiàn)
  • 利用 cache 來(lái)加快構(gòu)建速度 - docker build --cache-from 參數(shù)可以手動(dòng)指定一個(gè)鏡像來(lái)使用它的緩存鞍时。
  • 版本控制和自動(dòng)構(gòu)建 - 最好把Dockerfile和對(duì)應(yīng)的應(yīng)用代碼一起放到版本控制中,然后能夠自動(dòng)構(gòu)建鏡像扣蜻。

Docker 鏡像實(shí)操演示

參考 03 Docker 鏡像實(shí)操演示

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末逆巍,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子莽使,更是在濱河造成了極大的恐慌锐极,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芳肌,死亡現(xiàn)場(chǎng)離奇詭異灵再,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)亿笤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)檬嘀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人责嚷,你說(shuō)我怎么就攤上這事鸳兽。” “怎么了罕拂?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵揍异,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我爆班,道長(zhǎng)衷掷,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任柿菩,我火速辦了婚禮戚嗅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己懦胞,他們只是感情好替久,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著躏尉,像睡著了一般蚯根。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上胀糜,一...
    開(kāi)封第一講書(shū)人閱讀 50,096評(píng)論 1 291
  • 那天颅拦,我揣著相機(jī)與錄音,去河邊找鬼教藻。 笑死距帅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的括堤。 我是一名探鬼主播锥债,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼痊臭!你這毒婦竟也來(lái)了哮肚?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤广匙,失蹤者是張志新(化名)和其女友劉穎允趟,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鸦致,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡潮剪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了分唾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抗碰。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖绽乔,靈堂內(nèi)的尸體忽然破棺而出弧蝇,到底是詐尸還是另有隱情,我是刑警寧澤折砸,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布看疗,位于F島的核電站,受9級(jí)特大地震影響睦授,放射性物質(zhì)發(fā)生泄漏两芳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一去枷、第九天 我趴在偏房一處隱蔽的房頂上張望怖辆。 院中可真熱鬧是复,春花似錦、人聲如沸竖螃。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)斑鼻。三九已至,卻和暖如春猎荠,著一層夾襖步出監(jiān)牢的瞬間坚弱,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工关摇, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留荒叶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓输虱,卻偏偏與公主長(zhǎng)得像些楣,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宪睹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351