<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          再見 Dockerfile,擁抱新型鏡像構(gòu)建技術(shù) Buildpacks

          共 12044字,需瀏覽 25分鐘

           ·

          2022-01-10 17:59

          云原生正在吞并軟件世界,容器改變了傳統(tǒng)的應(yīng)用開發(fā)模式,如今研發(fā)人員不僅要構(gòu)建應(yīng)用,還要使用 Dockerfile 來完成應(yīng)用的容器化,將應(yīng)用及其依賴關(guān)系打包,從而獲得更可靠的產(chǎn)品,提高研發(fā)效率。

          隨著項(xiàng)目的迭代,達(dá)到一定的規(guī)模后,就需要運(yùn)維團(tuán)隊(duì)和研發(fā)團(tuán)隊(duì)之間相互協(xié)作。運(yùn)維團(tuán)隊(duì)的視角與研發(fā)團(tuán)隊(duì)不同,他們對(duì)鏡像的需求是安全標(biāo)準(zhǔn)化。比如:

          • 不同的應(yīng)用應(yīng)該選擇哪種基礎(chǔ)鏡像?
          • 應(yīng)用的依賴有哪些版本?
          • 應(yīng)用需要暴露的端口有哪些?

          為了優(yōu)化運(yùn)維效率,提高應(yīng)用安全性,研發(fā)人員需要不斷更新 Dockerfile 來實(shí)現(xiàn)上述目標(biāo)。同時(shí)運(yùn)維團(tuán)隊(duì)也會(huì)干預(yù)鏡像的構(gòu)建,如果基礎(chǔ)鏡像中有 CVE 被修復(fù)了,運(yùn)維團(tuán)隊(duì)就需要更新 Dockerfile,使用較新版本的基礎(chǔ)鏡像。總之,運(yùn)維與研發(fā)都需要干預(yù) Dockerfile,無法實(shí)現(xiàn)解耦。

          為了解決這一系列的問題,涌現(xiàn)出了更加優(yōu)秀的產(chǎn)品來構(gòu)建鏡像,其中就包括 Cloud Native Buildpacks[1] (СNB)。CNB 基于模塊化提供了一種更加快速、安全、可靠的方式來構(gòu)建符合 OCI 規(guī)范的鏡像,實(shí)現(xiàn)了研發(fā)與運(yùn)維團(tuán)隊(duì)之間的解耦。

          在介紹 CNB 之前,我們先來闡述幾個(gè)基本概念。

          符合 OCI 規(guī)范的鏡像

          如今,容器運(yùn)行時(shí)早就不是 Docker 一家獨(dú)大了。為了確保所有的容器運(yùn)行時(shí)都能運(yùn)行任何構(gòu)建工具生成的鏡像,Linux 基金會(huì)與 Google,華為,惠普,IBM,Docker,Red Hat,VMware 等公司共同宣布成立開放容器項(xiàng)目(OCP),后更名為開放容器倡議(OCI)[2]。OCI 定義了圍繞容器鏡像格式和運(yùn)行時(shí)的行業(yè)標(biāo)準(zhǔn),給定一個(gè) OCI 鏡像,任何實(shí)現(xiàn) OCI 運(yùn)行時(shí)標(biāo)準(zhǔn)[3]的容器運(yùn)行時(shí)都可以使用該鏡像運(yùn)行容器。

          如果你要問 Docker 鏡像與 OCI 鏡像之間有什么區(qū)別,如今的答案是:幾乎沒有區(qū)別。有一部分舊的 Docker 鏡像在 OCI 規(guī)范之前就已經(jīng)存在了,它們被稱為 Docker v1 規(guī)范,與 Docker v2 規(guī)范是不兼容的。而 Docker v2 規(guī)范捐給了 OCI,構(gòu)成了 OCI 規(guī)范的基礎(chǔ)。如今所有的容器鏡像倉庫、Kubernetes 平臺(tái)和容器運(yùn)行時(shí)都是圍繞 OCI 規(guī)范建立的。

          什么是 Buildpacks

          Buildpacks 項(xiàng)目最早由 Heroku 在 2011 年發(fā)起, 被以 Cloud Foundry 為代表的 PaaS 平臺(tái)廣泛采用。

          一個(gè) buildpack 指的就是一個(gè)將源代碼變成 PaaS 平臺(tái)可運(yùn)行的壓縮包的程序,通常情況下,每個(gè) buildpack 封裝了單一的語言生態(tài)系統(tǒng)的工具鏈,例如 Ruby、Go、NodeJs、Java、Python 等都有專門的 buildpack。

          你可以將 buildpack 理解成一坨腳本,這坨腳本的作用是將應(yīng)用的可執(zhí)行文件及其依賴的環(huán)境、配置、啟動(dòng)腳本等打包,然后上傳到 Git 等倉庫中,打好的壓縮包被稱為 droplet

          然后 Cloud Foundry 會(huì)通過調(diào)度器選擇一個(gè)可以運(yùn)行這個(gè)應(yīng)用的虛擬機(jī),然后通知這個(gè)機(jī)器上的 Agent 下載應(yīng)用壓縮包,按照 buildpack 指定的啟動(dòng)命令,啟動(dòng)應(yīng)用。

          到了 2018 年 1 月,PivotalHeroku 聯(lián)合發(fā)起了 Cloud Native Buildpacks(CNB)[4] 項(xiàng)目,并在同年 10 月讓這個(gè)項(xiàng)目進(jìn)入了 CNCF

          2020 年 11 月,CNCF 技術(shù)監(jiān)督委員會(huì)(TOC)投票決定將 CNB 從沙箱項(xiàng)目晉升為孵化項(xiàng)目[5]。是時(shí)候好好研究一下 CNB 了。

          為什么需要 Cloud Native Buildpacks

          Cloud Native Buildpacks(CNB) 可以看成是基于云原生的 Buildpacks 技術(shù),它支持現(xiàn)代語言生態(tài)系統(tǒng),對(duì)開發(fā)者屏蔽了應(yīng)用構(gòu)建、部署的細(xì)節(jié),如選用哪種操作系統(tǒng)、編寫適應(yīng)鏡像操作系統(tǒng)的處理腳本、優(yōu)化鏡像大小等等,并且會(huì)產(chǎn)出 OCI 容器鏡像,可以運(yùn)行在任何兼容 OCI 鏡像標(biāo)準(zhǔn)的集群中。CNB 還擁抱了很多更加云原生的特性,例如跨鏡像倉庫的 blob 掛載和鏡像層級(jí) rebasing[6]

          由此可見 CNB 的鏡像構(gòu)建方式更加標(biāo)準(zhǔn)化、自動(dòng)化,與 Dockerfile 相比,Buildpacks 為構(gòu)建應(yīng)用提供了更高層次的抽象,Buildpacks 對(duì) OCI 鏡像構(gòu)建的抽象,就類似于 Helm 對(duì) Deployment 編排的抽象

          2020 年 10 月,Google Cloud 開始宣布全面支持 Buildpacks,包含 Cloud Run、Anthos 和 Google Kubernetes Engine (GKE)。目前 IBM Cloud、Heroku 和 Pivital 等公司皆已采用 Buildpacks,如果不出意外,其他云供應(yīng)商很快就會(huì)效仿。

          Buildpacks 的優(yōu)點(diǎn):

          • 針對(duì)同一構(gòu)建目的的應(yīng)用,不用重復(fù)編寫構(gòu)建文件(只需要使用一個(gè) Builder)。
          • 不依賴 Dockerfile。
          • 可以根據(jù)豐富的元數(shù)據(jù)信息(buildpack.toml)輕松地檢查到每一層(buildpacks)的工作內(nèi)容。
          • 在更換了底層操作系統(tǒng)之后,不需要重新改寫鏡像構(gòu)建過程。
          • 保證應(yīng)用構(gòu)建的安全性和合規(guī)性,而無需開發(fā)者干預(yù)。

          Buildpacks 社區(qū)還給出了一個(gè)表格來對(duì)比同類應(yīng)用打包工具:

          可以看到 Buildpacks 與其他打包工具相比,支持的功能更多,包括:緩存、源代碼檢測、插件化、支持 rebase、重用、CI/CD 多種生態(tài)。

          Cloud Native Buildpacks 工作原理

          Cloud Native Buildpacks 主要由 3 個(gè)組件組成:BuilderBuildpackStack

          Buildpack

          Buildpack 本質(zhì)是一個(gè)可執(zhí)行單元的集合,一般包括檢查程序源代碼、構(gòu)建代碼、生成鏡像等。一個(gè)典型的 Buildpack 需要包含以下三個(gè)文件:

          • buildpack.toml – 提供 buildpack 的元數(shù)據(jù)信息。
          • bin/detect – 檢測是否應(yīng)該執(zhí)行這個(gè) buildpack。
          • bin/build – 執(zhí)行 buildpack 的構(gòu)建邏輯,最終生成鏡像。

          Builder

          Buildpacks 會(huì)通過“檢測”、“構(gòu)建”、“輸出”三個(gè)動(dòng)作完成一個(gè)構(gòu)建邏輯。通常為了完成一個(gè)應(yīng)用的構(gòu)建,我們會(huì)使用到多個(gè) Buildpacks,那么 Builder 就是一個(gè)構(gòu)建邏輯的集合,包含了構(gòu)建所需要的所有組件和運(yùn)行環(huán)境的鏡像。

          我們通過一個(gè)假設(shè)的流水線來嘗試?yán)斫?Builder 的工作原理:

          • 最初,我們作為應(yīng)用的開發(fā)者,準(zhǔn)備了一份應(yīng)用源代碼,這里我們將其標(biāo)識(shí)為 “0”。
          • 然后應(yīng)用 “0” 來到了第一道工序,我們使用 Buildpacks1 對(duì)其進(jìn)行加工。在這個(gè)工序中,Buildpacks1 會(huì)檢查應(yīng)用是否具有 “0” 標(biāo)識(shí),如果有,則進(jìn)入構(gòu)建過程,即為應(yīng)用標(biāo)識(shí)添加 “1”,使應(yīng)用標(biāo)識(shí)變更為 “01”。
          • 同理,第二道、第三道工序也會(huì)根據(jù)自身的準(zhǔn)入條件判斷是否需要執(zhí)行各自的構(gòu)建邏輯。

          在這個(gè)例子中,應(yīng)用滿足了三道工序的準(zhǔn)入條件,所以最終輸出的 OCI 鏡像的內(nèi)容為 “01234” 的標(biāo)識(shí)。

          對(duì)應(yīng)到 Buildpacks 的概念中,Builders 就是 Buildpacks 的有序組合,包含一個(gè)基礎(chǔ)鏡像叫 build image、一個(gè) lifecycle 和對(duì)另一個(gè)基礎(chǔ)鏡像 run image 的應(yīng)用。Builders 負(fù)責(zé)將應(yīng)用源代碼構(gòu)建成應(yīng)用鏡像(app image)。

          build imageBuilders 提供基礎(chǔ)環(huán)境(例如 帶有構(gòu)建工具的 Ubuntu Bionic OS 鏡像),而 run image 在運(yùn)行時(shí)為應(yīng)用鏡像(app image)提供基礎(chǔ)環(huán)境。build imagerun image 的組合被稱為 Stack[7]

          Stack

          上面提到,build imagerun image 的組合被稱為 Stack,也就是說,它定義了 Buildpacks 的執(zhí)行環(huán)境和最終應(yīng)用的基礎(chǔ)鏡像。

          你可以將 build image 理解為 Dockerfile 多階段構(gòu)建中第一階段的 base 鏡像,將 run image 理解為第二階段的 base 鏡像。


          上述 3 個(gè)組件都是以 Docker 鏡像的形式存在,并且提供了非常靈活的配置選項(xiàng),還擁有控制所生成鏡像的每一個(gè) layer 的能力。結(jié)合其強(qiáng)大的 caching[8]rebasing[9] 能力,定制的組件鏡像可以被多個(gè)應(yīng)用重復(fù)利用,并且每一個(gè) layer 都可以根據(jù)需要單獨(dú)更新。


          LifecycleBuilder 中最重要的概念,它將由應(yīng)用源代碼到鏡像的構(gòu)建步驟抽象出來,完成了對(duì)整個(gè)過程的編排,并最終產(chǎn)出應(yīng)用鏡像。下面我們單獨(dú)用一個(gè)章節(jié)來介紹 Lifecycle。

          構(gòu)建生命周期(Lifecyle)

          Lifecycle 將所有 Buildpacks 的探測、構(gòu)建過程抽離出來,分成兩個(gè)大的步驟聚合執(zhí)行:Detect 和 Build。這樣一來就降低了 Lifecycle 的架構(gòu)復(fù)雜度,便于實(shí)現(xiàn)自定義的 Builder。

          除了 Detect 和 Build 這兩個(gè)主要步驟,Lifecycle 還包含了一些額外的步驟,我們一起來解讀。

          Detect

          我們之前提到,在 Buildpack 中包含了一個(gè)用于探測的 /bin/detect 文件,那么在 Detect 過程中,Lifecycle 會(huì)指導(dǎo)所有 Buildpacks 中的 /bin/detect 按順序執(zhí)行,并從中獲取執(zhí)行結(jié)果。

          那么 Lifecycle 把 DetectBuild 分開后,又是怎么維系這兩個(gè)過程中的關(guān)聯(lián)關(guān)系呢?

          Buildpacks 在 Detect 和 Build 階段,通常都會(huì)告知在自己這個(gè)過程中會(huì)需要哪些前提,以及自己會(huì)提供哪些結(jié)果。

          在 Lifecycle 中,提供了一個(gè)叫做 Build Plan 的結(jié)構(gòu)體用于存放每個(gè) Buildpack 的所需物和產(chǎn)出物。

          type?BuildPlanEntry?struct?{
          ????Providers?`toml:“providers”`
          ????Requires??`toml:"requires"`

          同時(shí),Lifecycle 也規(guī)定,只有當(dāng)所有產(chǎn)出物都匹配有一個(gè)對(duì)應(yīng)的所需物時(shí),這些 Buildpacks 才能組合成一個(gè) Builder。

          Analysis

          Buildpacks 在運(yùn)行中會(huì)創(chuàng)建一些目錄,在 Lifecycle 中這些目錄被稱為 layer。那么為了這些 layer 中,有一些是可以作為緩存提供給下一個(gè) Buildpacks 使用的,有一些則是需要在應(yīng)用運(yùn)行時(shí)起作用的,還有的則是需要被清理掉。怎么才能更靈活地控制這些 layer

          Lifecycle 提供了三個(gè)開關(guān)參數(shù),用于表示每一個(gè) layer 期望的處理方式:

          • launch 表示這個(gè) layer 是否將在應(yīng)用運(yùn)行時(shí)起作用。
          • build 表示這個(gè) layer 是否將在后續(xù)的構(gòu)建過程中被訪問。
          • cache 則表示這個(gè) layer 是否將作為緩存。

          之后,Lifecycle 再根據(jù)一個(gè)關(guān)系矩陣來判斷 layer 的最終歸宿。我們也可以簡單的理解為,Analysis 階段為構(gòu)建、應(yīng)用運(yùn)行提供了緩存

          Build

          Build 階段會(huì)利用 Detect 階段產(chǎn)出的 build plan,以及環(huán)境中的元數(shù)據(jù)信息,配合保留至本階段的 layers,對(duì)應(yīng)用源碼執(zhí)行 Buildpacks 中的構(gòu)建邏輯。最終生成可運(yùn)行的應(yīng)用工件。

          Export

          Export 階段比較好理解,在完成了上述構(gòu)建之后,我們需要將最后的構(gòu)建結(jié)果產(chǎn)出為一個(gè) OCI 標(biāo)準(zhǔn)鏡像,這樣一來,這個(gè) App 工件就可以運(yùn)行在任何兼容 OCI 標(biāo)準(zhǔn)的集群中。

          Rebase

          在 CNB 的設(shè)計(jì)中,最后 app 工件實(shí)際是運(yùn)行在 stack 的 run image 之上的。可以理解為 run image 以上的工件是一個(gè)整體,它與 run image 以 ABI(application binary interface) 的形式對(duì)接,這就使得這個(gè)工件可以靈活切換到另一個(gè) run image 上。

          這個(gè)動(dòng)作其實(shí)也是 Lifecycle 的一部分,叫做 rebase。在構(gòu)建鏡像的過程中也有一次 rebase,發(fā)生在 app 工件由 build image 切換到 run image 上。

          這種機(jī)制也是 CNB 對(duì)比 Dockerfile 最具優(yōu)勢的地方。比如在一個(gè)大型的生產(chǎn)環(huán)境中,如果容器鏡像的 OS 層出現(xiàn)問題,需要更換鏡像的 OS 層,那么針對(duì)不同類型的應(yīng)用鏡像就需要重寫他們的 dockerfile 并驗(yàn)證新的 dockerfile 是否可行,以及新增加的層與已存在的層之間是否有沖突,等等。而使用 CNB 只需要做一次 rebase 即可,簡化了大規(guī)模生產(chǎn)中鏡像的升級(jí)工作。


          以上就是關(guān)于 CNB 構(gòu)建鏡像的流程分析,總結(jié)來說:

          • Buildpacks 是最小構(gòu)建單元,執(zhí)行具體的構(gòu)建操作;
          • Lifecycle 是 CNB 提供的鏡像構(gòu)建生命周期接口;
          • Builder 是若干 Buildpacks 加上 Lifecycle 以及 stack 形成的具備特定構(gòu)建目的的構(gòu)建器。

          再精減一下:

          • build image + run image = stack
          • stack(build image) + buildpacks + lifecycle = builder
          • stack(run image) + app artifacts = app

          那么現(xiàn)在問題來了,這個(gè)工具怎么使用呢?

          Platform

          這時(shí)候就需要一個(gè) Platform,Platform 其實(shí)是 Lifecycle 的執(zhí)行者。它的作用是將 Builder 作用于給定的源代碼上,完成 Lifecycle 的指令。

          在這個(gè)過程中,Builder 會(huì)將源代碼構(gòu)建為 app,這個(gè)時(shí)候 app 是在 build image 中的。這個(gè)時(shí)候根據(jù) Lifecycle 中的 rebase 接口,底層邏輯是用 ABI(application binary interface)[10] 將 app 工件從 build image 轉(zhuǎn)換到 run image 上。這就是最后的 OCI 鏡像。

          常用的 Platform 有 Tekton 和 CNB 的 Pack[11]。接下來我們將使用 Pack 來體驗(yàn)如何使用 Buildpacks 構(gòu)建鏡像。

          安裝 Pack CLI 工具

          目前 Pack CLI 支持 Linux、MacOS 和 Windows 平臺(tái),以 Ubuntu 為例,安裝命令如下:

          $?sudo?add-apt-repository?ppa:cncf-buildpacks/pack-cli
          $?sudo?apt-get?update
          $?sudo?apt-get?install?pack-cli

          查看版本:

          $?pack?version
          0.22.0+git-26d8c5c.build-2970

          注意:在使用 Pack 之前,需要先安裝并運(yùn)行 Docker。

          目前 Pack CLI 只支持 Docker,不支持其他容器運(yùn)行時(shí)(比如 Containerd 等)。但 Podman 可以通過一些 hack 來變相支持,以 Ubuntu 為例,大概步驟如下:

          先安裝 podman。

          $?.?/etc/os-release
          $?echo?"deb?https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/?/"?|?sudo?tee?/etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
          $?curl?-L?"https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key"?|?sudo?apt-key?add?-
          $?sudo?apt-get?update
          $?sudo?apt-get?-y?upgrade
          $?sudo?apt-get?-y?install?podman

          然后啟用 Podman Socket。

          $?systemctl?enable?--user?podman.socket
          $?systemctl?start?--user?podman.socket

          指定 DOCKER_HOST 環(huán)境變量。

          $?export?DOCKER_HOST="unix://$(podman?info?-f?"{{.Host.RemoteSocket.Path}}")"

          最終就可以實(shí)現(xiàn)在 Podman 容器運(yùn)行時(shí)中使用 Pack 來構(gòu)建鏡像。詳細(xì)配置步驟可參考 Buildpacks 官方文檔[12]

          使用 Pack 構(gòu)建 OCI 鏡像

          安裝完 Pack 之后,我們可以通過 CNB 官方提供的 samples[13] 加深對(duì) Buildpacks 原理的理解。這是一個(gè) Java 示例,構(gòu)建過程中無需安裝 JDK、運(yùn)行 Maven 或其他構(gòu)建環(huán)境,Buildpacks 會(huì)為我們處理好這些。

          首先克隆示例倉庫:

          $?git?clone?https://github.com/buildpacks/samples.git

          后面我們將使用 bionic 這個(gè) Builder 來構(gòu)建鏡像,先來看下該 Builder 的配置:

          $ cat samples/builders/bionic/builder.toml
          # Buildpacks to include in builder
          [[buildpacks]]
          id = "samples/java-maven"
          version = "0.0.1"
          uri = "../../buildpacks/java-maven"

          [[buildpacks]]
          id = "samples/kotlin-gradle"
          version = "0.0.1"
          uri = "../../buildpacks/kotlin-gradle"

          [[buildpacks]]
          id = "samples/ruby-bundler"
          version = "0.0.1"
          uri = "../../buildpacks/ruby-bundler"

          [[buildpacks]]
          uri = "docker://cnbs/sample-package:hello-universe"

          # Order used for detection
          [[order]]
          [[order.group]]
          id = "samples/java-maven"
          version = "0.0.1"

          [[order]]
          [[order.group]]
          id = "samples/kotlin-gradle"
          version = "0.0.1"

          [[order]]
          [[order.group]]
          id = "samples/ruby-bundler"
          version = "0.0.1"

          [[order]]
          [[order.group]]
          id = "samples/hello-universe"
          version = "0.0.1"

          # Stack that will be used by the builder
          [stack]
          id = "io.buildpacks.samples.stacks.bionic"
          run-image = "cnbs/sample-stack-run:bionic"
          build-image = "cnbs/sample-stack-build:bionic"

          builder.toml 文件中完成了對(duì) Builder 的定義,配置結(jié)構(gòu)可以劃分為 3 個(gè)部分:

          • [[buildpacks]] 語法標(biāo)識(shí)用于定義 Builder 所包含的 Buildpacks。
          • [[order]] 用于定義 Builder 所包含的 Buildpacks 的執(zhí)行順序。
          • [[stack]] 用于定義 Builder 將運(yùn)行在哪個(gè)基礎(chǔ)環(huán)境之上。

          我們可以使用這個(gè) builder.toml 來構(gòu)建自己的 builder 鏡像:

          $?cd?samples/builders/bionic

          $?pack?builder?create?cnbs/sample-builder:bionic?--config?builder.toml
          284055322776:?Already?exists
          5b7c18d5e17c:?Already?exists
          8a0af02bbad1:?Already?exists
          0aa0fb9222a5:?Download?complete
          3d56f4bc2c9a:?Already?exists
          5b7c18d5e17c:?Already?exists
          284055322776:?Already?exists
          8a0af02bbad1:?Already?exists
          a967314b5694:?Already?exists
          a00d148009e5:?Already?exists
          dbb2c49b44e3:?Download?complete
          53a52c7f9926:?Download?complete
          0cceee8a8cb0:?Download?complete
          c238db6a02a5:?Download?complete
          e925caa83f18:?Download?complete
          Successfully?created?builder?image?cnbs/sample-builder:bionic
          Tip:?Run?pack?build??--builder?cnbs/sample-builder:bionic?to?use?this?builder

          接著,進(jìn)入 samples/apps 目錄,使用 pack 工具和 builder 鏡像,完成應(yīng)用的構(gòu)建。當(dāng)構(gòu)建成功后,會(huì)產(chǎn)出一個(gè)名為 sample-app 的 OCI 鏡像。

          $?cd?../..
          $?pack?build?--path?apps/java-maven?--builder?cnbs/sample-builder:bionic?sample-app

          最后使用 Docker 運(yùn)行這個(gè) sample-app 鏡像:

          $?docker?run?-it?-p?8080:8080?sample-app

          訪問 http://localhost:8080,如果一切正常,你可以在瀏覽器中看見如下的界面:

          現(xiàn)在我們?cè)賮碛^察一下之前構(gòu)建的鏡像:

          $?docker?images
          REPOSITORY???????????????????????????????TAG??????????????IMAGE?ID???????CREATED????????SIZE
          cnbs/sample-package??????????????????????hello-universe???e925caa83f18???42?years?ago???4.65kB
          sample-app???????????????????????????????latest???????????7867e21a60cd???42?years?ago???300MB
          cnbs/sample-builder??????????????????????bionic???????????83509780fa67???42?years?ago???181MB
          buildpacksio/lifecycle???????????????????0.13.1???????????76412e6be4e1???42?years?ago???16.4MB

          鏡像的創(chuàng)建時(shí)間竟然都是固定的時(shí)間戳:42 years ago。這是為什么呢?如果時(shí)間戳不固定,每次構(gòu)建鏡像的 hash 值都是不同的,一旦 hash 值不一樣,就不太容易判斷鏡像的內(nèi)容是否相同了。使用固定的時(shí)間戳,就可以重復(fù)利用之前的構(gòu)建過程中創(chuàng)建的 layers。

          總結(jié)

          Cloud Native Buildpacks 代表了現(xiàn)代軟件開發(fā)的一個(gè)重大進(jìn)步,在大部分場景下相對(duì)于 Dockerfile 的好處是立桿見影的。雖然大型企業(yè)需要投入精力重新調(diào)整 CI/CD 流程或編寫自定義 Builder,但從長遠(yuǎn)來看可以節(jié)省大量的時(shí)間和維護(hù)成本。

          本文介紹了 Cloud Native Buildpacks(CNB) 的起源以及相對(duì)于其他工具的優(yōu)勢,并詳細(xì)闡述了 CNB 的工作原理,最后通過一個(gè)簡單的示例來體驗(yàn)如何使用 CNB 構(gòu)建鏡像。后續(xù)的文章將會(huì)介紹如何創(chuàng)建自定義的 Builder、Buildpack、Stack,以及函數(shù)計(jì)算平臺(tái)(例如,OpenFunction[14]、Google Cloud Functions)如何利用 CNB 提供的 S2I 能力,實(shí)現(xiàn)從用戶的函數(shù)代碼到最終應(yīng)用的轉(zhuǎn)換過程。

          引用鏈接

          [1]

          Cloud Native Buildpacks: https://buildpacks.io/

          [2]

          開放容器倡議(OCI): https://opencontainers.org/

          [3]

          OCI 運(yùn)行時(shí)標(biāo)準(zhǔn): https://github.com/opencontainers/runtime-spec

          [4]

          Cloud Native Buildpacks(CNB): https://buildpacks.io/

          [5]

          投票決定將 CNB 從沙箱項(xiàng)目晉升為孵化項(xiàng)目: https://www.cncf.io/blog/2020/11/18/toc-approves-cloud-native-buildpacks-from-sandbox-to-incubation/

          [6]

          跨鏡像倉庫的 blob 掛載和鏡像層級(jí) rebasing: https://docs.docker.com/registry/spec/api/

          [7]

          Stack: https://buildpacks.io/docs/concepts/components/stack

          [8]

          caching: https://buildpacks.io/docs/app-developer-guide/using-cache-image/

          [9]

          rebasing: https://buildpacks.io/docs/concepts/operations/rebase/

          [10]

          ABI(application binary interface): https://en.wikipedia.org/wiki/Application_binary_interface

          [11]

          Pack: https://buildpacks.io/docs/tools/pack/

          [12]

          Buildpacks 官方文檔: https://buildpacks.io/docs/app-developer-guide/building-on-podman/

          [13]

          samples: https://github.com/buildpacks/samples

          [14]

          OpenFunction: https://github.com/OpenFunction/OpenFunction/


          關(guān)于?KubeSphere

          KubeSphere (https://kubesphere.io)是在 Kubernetes 之上構(gòu)建的開源容器混合云,提供全棧的 IT 自動(dòng)化運(yùn)維的能力,簡化企業(yè)的 DevOps 工作流。

          KubeSphere?已被?Aqara?智能家居、愛立信、本來生活、東軟、華云、新浪、三一重工、華夏銀行、四川航空、國藥集團(tuán)、微眾銀行、杭州數(shù)跑科技、紫金保險(xiǎn)、去哪兒網(wǎng)、中通、中國人民銀行、中國銀行、中國人保壽險(xiǎn)、中國太平保險(xiǎn)、中國移動(dòng)、中國電信、天翼云、中移金科、Radore、ZaloPay?等海內(nèi)外數(shù)千家企業(yè)采用。KubeSphere 提供了開發(fā)者友好的向?qū)讲僮鹘缑婧拓S富的企業(yè)級(jí)功能,包括?Kubernetes?多云與多集群管理、DevOps?(CI/CD)、應(yīng)用生命周期管理、邊緣計(jì)算、微服務(wù)治理?(Service?Mesh)、多租戶管理、可觀測性、存儲(chǔ)與網(wǎng)絡(luò)管理、GPU?support?等功能,幫助企業(yè)快速構(gòu)建一個(gè)強(qiáng)大和功能豐富的容器云平臺(tái)。

          ???GitHub:https://github.com/kubesphere
          ????官網(wǎng)(中國站):https://kubesphere.com.cn
          ????????微信群:請(qǐng)搜索添加群助手微信號(hào)?kubesphere

          瀏覽 84
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲ⅴ在线 | 成人毛片基地 | 黑人与少妇一级A片 | 欧美日韩无码视频 | 国产理论在线 |