日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

(一)容器从入门到深入-容器和镜像

發(fā)布時(shí)間:2023/12/13 编程问答 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (一)容器从入门到深入-容器和镜像 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、容器與鏡像

什么是容器?

在介紹容器的具體概念之前,先簡(jiǎn)單回顧一下操作系統(tǒng)是如何管理進(jìn)程的。

首先,當(dāng)我們登錄到操作系統(tǒng)之后,可以通過 ps 等操作看到各式各樣的進(jìn)程,這些進(jìn)程包括系統(tǒng)自帶的服務(wù)和用戶的應(yīng)用進(jìn)程。那么,這些進(jìn)程都有什么樣的特點(diǎn)?

  • 第一,這些進(jìn)程可以相互看到、相互通信;
  • 第二,它們使用的是同一個(gè)文件系統(tǒng),可以對(duì)同一個(gè)文件進(jìn)行讀寫操作;
  • 第三,這些進(jìn)程會(huì)使用相同的系統(tǒng)資源。

這樣的三個(gè)特點(diǎn)會(huì)帶來什么問題呢?

  • 因?yàn)檫@些進(jìn)程能夠相互看到并且進(jìn)行通信,高級(jí)權(quán)限的進(jìn)程可以攻擊其他進(jìn)程;
  • 因?yàn)樗鼈兪褂玫氖峭粋€(gè)文件系統(tǒng),因此會(huì)帶來兩個(gè)問題:這些進(jìn)程可以對(duì)于已有的數(shù)據(jù)進(jìn)行增刪改查,具有高級(jí)權(quán)限的進(jìn)程可能會(huì)將其他進(jìn)程的數(shù)據(jù)刪除掉,破壞掉其他進(jìn)程的正常運(yùn)行;此外,進(jìn)程與進(jìn)程之間的依賴可能會(huì)存在沖突,如此一來就會(huì)給運(yùn)維帶來很大的壓力;
  • 因?yàn)檫@些進(jìn)程使用的是同一個(gè)宿主機(jī)的資源,應(yīng)用之間可能會(huì)存在資源搶占的問題,當(dāng)一個(gè)應(yīng)用需要消耗大量 CPU 和內(nèi)存資源的時(shí)候,就可能會(huì)破壞其他應(yīng)用的運(yùn)行,導(dǎo)致其他應(yīng)用無法正常地提供服務(wù)。

針對(duì)上述的三個(gè)問題,如何為進(jìn)程提供一個(gè)獨(dú)立的運(yùn)行環(huán)境呢?

  • 針對(duì)不同進(jìn)程使用同一個(gè)文件系統(tǒng)所造成的問題而言,Linux 和 Unix 操作系統(tǒng)可以通過 chroot 系統(tǒng)調(diào)用將子目錄變成根目錄,達(dá)到視圖級(jí)別的隔離;進(jìn)程在 chroot 的幫助下可以具有獨(dú)立的文件系統(tǒng),對(duì)于這樣的文件系統(tǒng)進(jìn)行增刪改查不會(huì)影響到其他進(jìn)程;
  • 因?yàn)檫M(jìn)程之間相互可見并且可以相互通信,使用 Namespace 技術(shù)來實(shí)現(xiàn)進(jìn)程在資源的視圖上進(jìn)行隔離。在 chroot 和 Namespace 的幫助下,進(jìn)程就能夠運(yùn)行在一個(gè)獨(dú)立的環(huán)境下了;
  • 但在獨(dú)立的環(huán)境下,進(jìn)程所使用的還是同一個(gè)操作系統(tǒng)的資源,一些進(jìn)程可能會(huì)侵蝕掉整個(gè)系統(tǒng)的資源。為了減少進(jìn)程彼此之間的影響,可以通過 Cgroup 來限制其資源使用率,設(shè)置其能夠使用的 CPU 以及內(nèi)存量。

那么,應(yīng)該如何定義這樣的進(jìn)程集合呢?

其實(shí),容器就是一個(gè)視圖隔離、資源可限制、獨(dú)立文件系統(tǒng)的進(jìn)程集合。所謂“視圖隔離”就是能夠看到部分進(jìn)程以及具有獨(dú)立的主機(jī)名等;控制資源使用率則是可以對(duì)于內(nèi)存大小以及 CPU 使用個(gè)數(shù)等進(jìn)行限制。容器就是一個(gè)進(jìn)程集合,它將系統(tǒng)的其他資源隔離開來,具有自己獨(dú)立的資源視圖。

容器具有一個(gè)獨(dú)立的文件系統(tǒng),因?yàn)槭褂玫氖窍到y(tǒng)的資源,所以在獨(dú)立的文件系統(tǒng)內(nèi)不需要具備內(nèi)核相關(guān)的代碼或者工具,我們只需要提供容器所需的二進(jìn)制文件、配置文件以及依賴即可。只要容器運(yùn)行時(shí)所需的文件集合都能夠具備,那么這個(gè)容器就能夠運(yùn)行起來。

什么是鏡像?

綜上所述,我們將這些容器運(yùn)行時(shí)所需要的所有的文件集合稱之為容器鏡像。

那么,一般都是通過什么樣的方式來構(gòu)建鏡像的呢?通常情況下,我們會(huì)采用 Dockerfile 來構(gòu)建鏡像,這是因?yàn)?Dockerfile 提供了非常便利的語法糖,能夠幫助我們很好地描述構(gòu)建的每個(gè)步驟。當(dāng)然,每個(gè)構(gòu)建步驟都會(huì)對(duì)已有的文件系統(tǒng)進(jìn)行操作,這樣就會(huì)帶來文件系統(tǒng)內(nèi)容的變化,我們將這些變化稱之為 changeset。當(dāng)我們把構(gòu)建步驟所產(chǎn)生的變化依次作用到一個(gè)空文件夾上,就能夠得到一個(gè)完整的鏡像。 changeset 的分層以及復(fù)用特點(diǎn)能夠帶來幾點(diǎn)優(yōu)勢(shì):

  • 第一,能夠提高分發(fā)效率,簡(jiǎn)單試想一下,對(duì)于大的鏡像而言,如果將其拆分成各個(gè)小塊就能夠提高鏡像的分發(fā)效率,這是因?yàn)殓R像拆分之后就可以并行下載這些數(shù)據(jù);
  • 第二,因?yàn)檫@些數(shù)據(jù)是相互共享的,也就意味著當(dāng)本地存儲(chǔ)上包含了一些數(shù)據(jù)的時(shí)候,只需要下載本地沒有的數(shù)據(jù)即可,舉個(gè)簡(jiǎn)單的例子就是 golang 鏡像是基于 alpine 鏡像進(jìn)行構(gòu)建的,當(dāng)本地已經(jīng)具有了 alpine 鏡像之后,在下載 golang 鏡像的時(shí)候只需要下載本地 alpine 鏡像中沒有的部分即可;
  • 第三,因?yàn)殓R像數(shù)據(jù)是共享的,因此可以節(jié)約大量的磁盤空間,簡(jiǎn)單設(shè)想一下,當(dāng)本地存儲(chǔ)具有了 alpine 鏡像和 golang 鏡像,在沒有復(fù)用的能力之前,alpine 鏡像具有 5M 大小,golang 鏡像有 300M 大小,因此就會(huì)占用 305M 空間;而當(dāng)具有了復(fù)用能力之后,只需要 300M 空間即可。

如何構(gòu)建鏡像?

如下圖所示的 Dockerfile 適用于描述如何構(gòu)建 golang 應(yīng)用的。

8 分鐘入門 K8s | 詳解容器基本概念
如圖所示:

  • FROM 行表示以下的構(gòu)建步驟基于什么鏡像進(jìn)行構(gòu)建,正如前面所提到的,鏡像是可以復(fù)用的;
  • WORKDIR 行表示會(huì)把接下來的構(gòu)建步驟都在哪一個(gè)相應(yīng)的具體目錄下進(jìn)行,其起到的作用類似于 Shell 里面的 cd;
  • COPY 行表示的是可以將宿主機(jī)上的文件拷貝到容器鏡像內(nèi);
  • RUN 行表示在具體的文件系統(tǒng)內(nèi)執(zhí)行相應(yīng)的動(dòng)作。當(dāng)我們運(yùn)行完畢之后就可以得到一個(gè)應(yīng)用了;
  • CMD 行表示使用鏡像時(shí)的默認(rèn)程序名字。
  • 當(dāng)有了 Dockerfile 之后,就可以通過 docker build 命令構(gòu)建出所需要的應(yīng)用。構(gòu)建出的結(jié)果存儲(chǔ)在本地,一般情況下,鏡像構(gòu)建會(huì)在打包機(jī)或者其他的隔離環(huán)境下完成。

    那么,這些鏡像如何運(yùn)行在生產(chǎn)環(huán)境或者測(cè)試環(huán)境上呢?這時(shí)候就需要一個(gè)中轉(zhuǎn)站或者中心存儲(chǔ),我們稱之為 docker registry,也就是鏡像倉(cāng)庫(kù),其負(fù)責(zé)存儲(chǔ)所有產(chǎn)生的鏡像數(shù)據(jù)。我們只需要通過 docker push 就能夠?qū)⒈镜冂R像推動(dòng)到鏡像倉(cāng)庫(kù)中,這樣一來,就能夠在生產(chǎn)環(huán)境上或者測(cè)試環(huán)境上將相應(yīng)的數(shù)據(jù)下載下來并運(yùn)行了。

    如何運(yùn)行容器?

    運(yùn)行一個(gè)容器一般情況下分為三步:

    • 第一步:從鏡像倉(cāng)庫(kù)中將相應(yīng)的鏡像下載下來;
    • 第二步:當(dāng)鏡像下載完成之后就可以通過 docker images 來查看本地鏡像,這里會(huì)給出一個(gè)完整的列表,我們可以在列表中選中想要的鏡像;
    • 第三步:當(dāng)選中鏡像之后,就可以通過 docker run 來運(yùn)行這個(gè)鏡像得到想要的容器,當(dāng)然可以通過多次運(yùn)行得到多個(gè)容器。一個(gè)鏡像就相當(dāng)于是一個(gè)模板,一個(gè)容器就像是一個(gè)具體的運(yùn)行實(shí)例,因此鏡像就具有了一次構(gòu)建、到處運(yùn)行的特點(diǎn)。

    小結(jié)

    簡(jiǎn)單回顧一下,容器就是和系統(tǒng)其它部分隔離開來的進(jìn)程集合,這里的其他部分包括進(jìn)程、網(wǎng)絡(luò)資源以及文件系統(tǒng)等。而鏡像就是容器所需要的所有文件集合,其具備一次構(gòu)建、到處運(yùn)行的特點(diǎn)。

    二、容器的生命周期

    容器運(yùn)行時(shí)的生命周期

    容器是一組具有隔離特性的進(jìn)程集合,在使用 docker run 的時(shí)候會(huì)選擇一個(gè)鏡像來提供獨(dú)立的文件系統(tǒng)并指定相應(yīng)的運(yùn)行程序。這里指定的運(yùn)行程序稱之為 initial 進(jìn)程,這個(gè) initial 進(jìn)程啟動(dòng)的時(shí)候,容器也會(huì)隨之啟動(dòng),當(dāng) initial 進(jìn)程退出的時(shí)候,容器也會(huì)隨之退出。

    因此,可以認(rèn)為容器的生命周期和 initial 進(jìn)程的生命周期是一致的。當(dāng)然,因?yàn)槿萜鲀?nèi)不只有這樣的一個(gè) initial 進(jìn)程,initial 進(jìn)程本身也可以產(chǎn)生其他的子進(jìn)程或者通過 docker exec 產(chǎn)生出來的運(yùn)維操作,也屬于 initial 進(jìn)程管理的范圍內(nèi)。當(dāng) initial 進(jìn)程退出的時(shí)候,所有的子進(jìn)程也會(huì)隨之退出,這樣也是為了防止資源的泄漏。 但是這樣的做法也會(huì)存在一些問題,首先應(yīng)用里面的程序往往是有狀態(tài)的,其可能會(huì)產(chǎn)生一些重要的數(shù)據(jù),當(dāng)一個(gè)容器退出被刪除之后,數(shù)據(jù)也就會(huì)丟失了,這對(duì)于應(yīng)用方而言是不能接受的,所以需要將容器所產(chǎn)生出來的重要數(shù)據(jù)持久化下來。容器能夠直接將數(shù)據(jù)持久化到指定的目錄上,這個(gè)目錄就稱之為數(shù)據(jù)卷。

    數(shù)據(jù)卷有一些特點(diǎn),其中非常明顯的就是數(shù)據(jù)卷的生命周期是獨(dú)立于容器的生命周期的,也就是說容器的創(chuàng)建、運(yùn)行、停止、刪除等操作都和數(shù)據(jù)卷沒有任何關(guān)系,因?yàn)樗且粋€(gè)特殊的目錄,是用于幫助容器進(jìn)行持久化的。簡(jiǎn)單而言,我們會(huì)將數(shù)據(jù)卷掛載到容器內(nèi),這樣一來容器就能夠?qū)?shù)據(jù)寫入到相應(yīng)的目錄里面了,而且容器的退出并不會(huì)導(dǎo)致數(shù)據(jù)的丟失。

    通常情況下,數(shù)據(jù)卷管理主要有兩種方式:

    • 第一種是通過 bind 的方式,直接將宿主機(jī)的目錄直接掛載到容器內(nèi);這種方式比較簡(jiǎn)單,但是會(huì)帶來運(yùn)維成本,因?yàn)槠湟蕾囉谒拗鳈C(jī)的目錄,需要對(duì)于所有的宿主機(jī)進(jìn)行統(tǒng)一管理。
    • 第二種是將目錄管理交給運(yùn)行引擎。

    三、容器項(xiàng)目架構(gòu)

    moby 容器引擎架構(gòu)

    moby 是目前最流行的容器管理引擎,mobydaemon 會(huì)對(duì)上提供有關(guān)于容器、鏡像、網(wǎng)絡(luò)以及 Volume的管理。moby daemon 所依賴的最重要的組件就是 containerd,containerd 是一個(gè)容器運(yùn)行時(shí)管理引擎,其獨(dú)立于 moby daemon ,可以對(duì)上提供容器、鏡像的相關(guān)管理。

    containerd 底層有 containerd shim 模塊,其類似于一個(gè)守護(hù)進(jìn)程,這樣設(shè)計(jì)的原因有幾點(diǎn):

    • 首先,containerd 需要管理容器生命周期,而容器可能是由不同的容器運(yùn)行時(shí)所創(chuàng)建出來的,因此需要提供一個(gè)靈活的插件化管理。而 shim 就是針對(duì)于不同的容器運(yùn)行時(shí)所開發(fā)的,這樣就能夠從 containerd 中脫離出來,通過插件的形式進(jìn)行管理。
    • 其次,因?yàn)?shim 插件化的實(shí)現(xiàn),使其能夠被 containerd 動(dòng)態(tài)接管。如果不具備這樣的能力,當(dāng) moby daemon 或者 containerd daemon 意外退出的時(shí)候,容器就沒人管理了,那么它也會(huì)隨之消失、退出,這樣就會(huì)影響到應(yīng)用的運(yùn)行。
    • 最后,因?yàn)殡S時(shí)可能會(huì)對(duì) moby 或者 containerd 進(jìn)行升級(jí),如果不提供 shim 機(jī)制,那么就無法做到原地升級(jí),也無法做到不影響業(yè)務(wù)的升級(jí),因此 containerd shim 非常重要,它實(shí)現(xiàn)了動(dòng)態(tài)接管的能力。

    本節(jié)課程只是針對(duì)于 moby 進(jìn)行一個(gè)大致的介紹,在后續(xù)的課程也會(huì)詳細(xì)介紹。

    四、容器 VS VM

    容器和 VM 之間的差異

    VM 利用 Hypervisor 虛擬化技術(shù)來模擬 CPU、內(nèi)存等硬件資源,這樣就可以在宿主機(jī)上建立一個(gè) Guest OS,這是常說的安裝一個(gè)虛擬機(jī)。

    每一個(gè) Guest OS 都有一個(gè)獨(dú)立的內(nèi)核,比如 Ubuntu、CentOS 甚至是 Windows 等,在這樣的 Guest OS 之下,每個(gè)應(yīng)用都是相互獨(dú)立的,VM 可以提供一個(gè)更好的隔離效果。但這樣的隔離效果需要付出一定的代價(jià),因?yàn)樾枰岩徊糠值挠?jì)算資源交給虛擬化,這樣就很難充分利用現(xiàn)有的計(jì)算資源,并且每個(gè) Guest OS 都需要占用大量的磁盤空間,比如 Windows 操作系統(tǒng)的安裝需要 10~30G 的磁盤空間,Ubuntu 也需要 5~6G,同時(shí)這樣的方式啟動(dòng)很慢。正是因?yàn)樘摂M機(jī)技術(shù)的缺點(diǎn),催生出了容器技術(shù)。 容器是針對(duì)于進(jìn)程而言的,因此無需 Guest OS,只需要一個(gè)獨(dú)立的文件系統(tǒng)提供其所需要文件集合即可。所有的文件隔離都是進(jìn)程級(jí)別的,因此啟動(dòng)時(shí)間快于 VM,并且所需的磁盤空間也小于 VM。當(dāng)然了,進(jìn)程級(jí)別的隔離并沒有想象中的那么好,隔離效果相比 VM 要差很多。

    總體而言,容器和 VM 相比,各有優(yōu)劣,因此容器技術(shù)也在向著強(qiáng)隔離方向發(fā)展。

    總結(jié)

    以上是生活随笔為你收集整理的(一)容器从入门到深入-容器和镜像的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。